Merge from Chromium at DEPS revision r198571
This commit was generated by merge_to_master.py.
Change-Id: I951118a03836157090561764dd2627f0add8118f
diff --git a/content/DEPS b/content/DEPS
index 79b961e..141bb04 100644
--- a/content/DEPS
+++ b/content/DEPS
@@ -20,6 +20,7 @@
"+crypto",
"+grit/content_resources.h",
"+grit/ui_resources.h",
+ "+grit/ui_strings.h",
"+grit/webkit_chromium_resources.h",
"+grit/webkit_resources.h",
"+grit/webkit_strings.h",
@@ -53,6 +54,7 @@
"+third_party/angle",
"+third_party/flac",
"+third_party/gpsd",
+ "+third_party/libjingle",
"+third_party/mozilla",
"+third_party/npapi/bindings",
"+third_party/skia",
@@ -60,6 +62,7 @@
"+third_party/tcmalloc",
"+third_party/khronos",
"+third_party/webrtc",
+ "+third_party/zlib/google",
"+third_party/WebKit/Source/Platform/chromium",
"+third_party/WebKit/Source/WebKit/chromium",
diff --git a/content/OWNERS b/content/OWNERS
index 7a05d15..467710c 100644
--- a/content/OWNERS
+++ b/content/OWNERS
@@ -9,6 +9,8 @@
per-file *.sb=set noparent
per-file *.sb=jeremy@chromium.org
+per-file *.isolate=csharp@chromium.org
+per-file *.isolate=maruel@chromium.org
per-file content_components_navigation_interception.gypi=jknotten@chromium.org
per-file content_components_navigation_interception.gypi=joth@chromium.org
per-file content_components_navigation_interception.gypi=mkosiba@chromium.org
diff --git a/content/app/android/child_process_service.cc b/content/app/android/child_process_service.cc
index c0deb83..99e801b 100644
--- a/content/app/android/child_process_service.cc
+++ b/content/app/android/child_process_service.cc
@@ -10,7 +10,6 @@
#include "base/android/jni_array.h"
#include "base/logging.h"
#include "base/posix/global_descriptors.h"
-#include "content/common/android/scoped_java_surface.h"
#include "content/common/android/surface_texture_peer.h"
#include "content/common/child_process.h"
#include "content/common/child_thread.h"
@@ -19,6 +18,7 @@
#include "content/public/common/content_descriptors.h"
#include "ipc/ipc_descriptors.h"
#include "jni/ChildProcessService_jni.h"
+#include "ui/gl/android/scoped_java_surface.h"
using base::android::AttachCurrentThread;
using base::android::CheckException;
@@ -45,7 +45,7 @@
virtual void EstablishSurfaceTexturePeer(
base::ProcessHandle pid,
- scoped_refptr<content::SurfaceTextureBridge> surface_texture_bridge,
+ scoped_refptr<gfx::SurfaceTextureBridge> surface_texture_bridge,
int primary_id,
int secondary_id) {
JNIEnv* env = base::android::AttachCurrentThread();
@@ -58,7 +58,7 @@
virtual gfx::AcceleratedWidget AcquireNativeWidget(int surface_id) OVERRIDE {
JNIEnv* env = base::android::AttachCurrentThread();
- ScopedJavaSurface surface(
+ gfx::ScopedJavaSurface surface(
content::Java_ChildProcessService_getViewSurface(
env, service_.obj(), surface_id));
@@ -105,7 +105,7 @@
}
void QuitMainThreadMessageLoop() {
- MessageLoop::current()->Quit();
+ base::MessageLoop::current()->Quit();
}
} // namespace <anonymous>
diff --git a/content/app/android/content_main.cc b/content/app/android/content_main.cc
index 4059de4..e9cd1fd 100644
--- a/content/app/android/content_main.cc
+++ b/content/app/android/content_main.cc
@@ -7,6 +7,7 @@
#include "base/at_exit.h"
#include "base/base_switches.h"
#include "base/command_line.h"
+#include "base/debug/trace_event.h"
#include "base/lazy_instance.h"
#include "content/public/app/content_main.h"
#include "content/public/app/content_main_delegate.h"
@@ -35,6 +36,7 @@
}
static jint Start(JNIEnv* env, jclass clazz) {
+ TRACE_EVENT0("startup", "content::Start");
const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
// This is only for browser process. We want to start waiting as early as
diff --git a/content/app/android/library_loader_hooks.cc b/content/app/android/library_loader_hooks.cc
index 93a9d07..3d0cb9c 100644
--- a/content/app/android/library_loader_hooks.cc
+++ b/content/app/android/library_loader_hooks.cc
@@ -27,6 +27,7 @@
#include "media/base/android/media_jni_registrar.h"
#include "net/android/net_jni_registrar.h"
#include "ui/android/ui_jni_registrar.h"
+#include "ui/gl/android/gl_jni_registrar.h"
#include "ui/shell_dialogs/android/shell_dialogs_jni_registrar.h"
namespace {
@@ -42,8 +43,9 @@
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kTraceStartup)) {
- base::debug::TraceLog::GetInstance()->SetEnabled(
- command_line->GetSwitchValueASCII(switches::kTraceStartup),
+ base::debug::CategoryFilter category_filter(
+ command_line->GetSwitchValueASCII(switches::kTraceStartup));
+ base::debug::TraceLog::GetInstance()->SetEnabled(category_filter,
base::debug::TraceLog::RECORD_UNTIL_FULL);
}
@@ -79,6 +81,9 @@
if (!ui::android::RegisterJni(env))
return RESULT_CODE_FAILED_TO_REGISTER_JNI;
+ if (!ui::gl::android::RegisterJni(env))
+ return RESULT_CODE_FAILED_TO_REGISTER_JNI;
+
if (!ui::shell_dialogs::RegisterJni(env))
return RESULT_CODE_FAILED_TO_REGISTER_JNI;
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc
index 50930fa..9f1947a 100644
--- a/content/app/content_main_runner.cc
+++ b/content/app/content_main_runner.cc
@@ -66,8 +66,7 @@
#elif defined(OS_MACOSX)
#include "base/mac/scoped_nsautorelease_pool.h"
#if !defined(OS_IOS)
-#include "base/mach_ipc_mac.h"
-#include "base/system_monitor/system_monitor.h"
+#include "base/power_monitor/power_monitor.h"
#include "content/browser/mach_broker_mac.h"
#include "content/common/sandbox_init_mac.h"
#endif // !OS_IOS
@@ -82,6 +81,9 @@
#if !defined(OS_MACOSX)
#include "content/public/common/zygote_fork_delegate_linux.h"
#endif
+#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
+#include "content/zygote/zygote_main.h"
+#endif
#endif // OS_POSIX
@@ -101,10 +103,6 @@
extern int RendererMain(const content::MainFunctionParams&);
extern int UtilityMain(const MainFunctionParams&);
extern int WorkerMain(const MainFunctionParams&);
-#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
-extern int ZygoteMain(const MainFunctionParams&,
- ZygoteForkDelegate* forkdelegate);
-#endif
} // namespace content
namespace {
@@ -126,7 +124,11 @@
DCHECK(current_station);
HWINSTA winsta0 = ::OpenWindowStationA("WinSta0", FALSE, GENERIC_READ);
- if (!winsta0 || !::SetProcessWindowStation(winsta0)) {
+ if (!winsta0) {
+ DLOG(INFO) << "Unable to open to WinSta0, we: "<< ::GetLastError();
+ return;
+ }
+ if (!::SetProcessWindowStation(winsta0)) {
// Could not set the alternate window station. There is a possibility
// that the theme wont be correctly initialized.
NOTREACHED() << "Unable to switch to WinSta0, we: "<< ::GetLastError();
@@ -176,32 +178,6 @@
static CAppModule _Module;
-#elif defined(OS_MACOSX) && !defined(OS_IOS)
-
-// Completes the Mach IPC handshake by sending this process' task port to the
-// parent process. The parent is listening on the Mach port given by
-// |GetMachPortName()|. The task port is used by the parent to get CPU/memory
-// stats to display in the task manager.
-void SendTaskPortToParentProcess() {
- const mach_msg_timeout_t kTimeoutMs = 100;
- const int32_t kMessageId = 0;
- std::string mach_port_name = MachBroker::GetMachPortName();
-
- base::MachSendMessage child_message(kMessageId);
- if (!child_message.AddDescriptor(mach_task_self())) {
- LOG(ERROR) << "child AddDescriptor(mach_task_self()) failed.";
- return;
- }
-
- base::MachPortSender child_sender(mach_port_name.c_str());
- kern_return_t err = child_sender.SendMessage(child_message, kTimeoutMs);
- if (err != KERN_SUCCESS) {
- LOG(ERROR) <<
- base::StringPrintf("child SendMessage() failed: 0x%x %s", err,
- mach_error_string(err));
- }
-}
-
#endif // defined(OS_WIN)
#if defined(OS_POSIX) && !defined(OS_IOS)
@@ -531,6 +507,13 @@
const char** argv,
ContentMainDelegate* delegate) OVERRIDE {
+#if defined(OS_ANDROID)
+ // See note at the initialization of ExitManager, below; basically,
+ // only Android builds have the ctor/dtor handlers set up to use
+ // TRACE_EVENT right away.
+ TRACE_EVENT0("startup", "ContentMainRunnerImpl::Initialize");
+#endif // OS_ANDROID
+
// NOTE(willchan): One might ask why these TCMalloc-related calls are done
// here rather than in process_util_linux.cc with the definition of
// EnableTerminationOnOutOfMemory(). That's because base shouldn't have a
@@ -600,6 +583,8 @@
// The exit manager is in charge of calling the dtors of singleton objects.
// On Android, AtExitManager is set up when library is loaded.
// On iOS, it's set up in main(), which can't call directly through to here.
+ // A consequence of this is that you can't use the ctor/dtor-based
+ // TRACE_EVENT methods on Linux or iOS builds till after we set this up.
#if !defined(OS_ANDROID) && !defined(OS_IOS)
exit_manager_.reset(new base::AtExitManager);
#endif // !OS_ANDROID && !OS_IOS
@@ -612,10 +597,11 @@
autorelease_pool_.reset(new base::mac::ScopedNSAutoreleasePool());
#endif
- // On Android, the command line is initialized when library is loaded.
+ // On Android, the command line is initialized when library is loaded and
+ // we have already started our TRACE_EVENT0.
#if !defined(OS_ANDROID)
CommandLine::Init(argc, argv);
-#endif
+#endif // !OS_ANDROID
int exit_code;
if (delegate && delegate->BasicStartupComplete(&exit_code))
@@ -640,16 +626,24 @@
// Enable startup tracing asap to avoid early TRACE_EVENT calls being
// ignored.
if (command_line.HasSwitch(switches::kTraceStartup)) {
+ base::debug::CategoryFilter category_filter(
+ command_line.GetSwitchValueASCII(switches::kTraceStartup));
base::debug::TraceLog::GetInstance()->SetEnabled(
- command_line.GetSwitchValueASCII(switches::kTraceStartup),
+ category_filter,
base::debug::TraceLog::RECORD_UNTIL_FULL);
}
+#if !defined(OS_ANDROID)
+ // Android tracing started at the beginning of the method.
+ // Other OSes have to wait till we get here in order for all the memory
+ // management setup to be completed.
+ TRACE_EVENT0("startup", "ContentMainRunnerImpl::Initialize");
+#endif // !OS_ANDROID
#if defined(OS_MACOSX) && !defined(OS_IOS)
// We need to allocate the IO Ports before the Sandbox is initialized or
- // the first instance of SystemMonitor is created.
+ // the first instance of PowerMonitor is created.
// It's important not to allocate the ports for processes which don't
- // register with the system monitor - see crbug.com/88867.
+ // register with the power monitor - see crbug.com/88867.
if (process_type.empty() ||
process_type == switches::kPluginProcess ||
process_type == switches::kRendererProcess ||
@@ -657,12 +651,12 @@
process_type == switches::kWorkerProcess ||
(delegate &&
delegate->ProcessRegistersWithSystemProcess(process_type))) {
- base::SystemMonitor::AllocateSystemIOPorts();
+ base::PowerMonitor::AllocateSystemIOPorts();
}
if (!process_type.empty() &&
(!delegate || delegate->ShouldSendMachPort(process_type))) {
- SendTaskPortToParentProcess();
+ MachBroker::ChildSendTaskPortToParent();
}
#elif defined(OS_WIN)
// This must be done early enough since some helper functions like
diff --git a/content/browser/DEPS b/content/browser/DEPS
index 9e0a508..200aada 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -5,6 +5,7 @@
"+content/public/browser",
"+media/audio", # For audio input for speech input feature.
"+media/base", # For Android JNI registration and kDisableEncryptedMedia.
+ "+sql",
"+ui/webui",
"+win8/util",
diff --git a/content/browser/accessibility/accessibility_tree_formatter.cc b/content/browser/accessibility/accessibility_tree_formatter.cc
index f8b4cc7..84f200a 100644
--- a/content/browser/accessibility/accessibility_tree_formatter.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/string_util.h"
+#include "base/stringprintf.h"
#include "base/strings/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
@@ -18,11 +19,12 @@
namespace {
const int kIndentSpaces = 4;
const char* kSkipString = "@NO_DUMP";
+const char* kChildrenDictAttr = "children";
}
AccessibilityTreeFormatter::AccessibilityTreeFormatter(
- BrowserAccessibility* node)
- : node_(node) {
+ BrowserAccessibility* root)
+ : root_(root) {
Initialize();
}
@@ -45,33 +47,59 @@
AccessibilityTreeFormatter::~AccessibilityTreeFormatter() {
}
+scoped_ptr<DictionaryValue>
+AccessibilityTreeFormatter::BuildAccessibilityTree() {
+ scoped_ptr<DictionaryValue> dict(new DictionaryValue);
+ RecursiveBuildAccessibilityTree(*root_, dict.get());
+ return dict.Pass();
+}
+
void AccessibilityTreeFormatter::FormatAccessibilityTree(
string16* contents) {
- RecursiveFormatAccessibilityTree(node_, contents, 0);
+ scoped_ptr<DictionaryValue> dict = BuildAccessibilityTree();
+ RecursiveFormatAccessibilityTree(*(dict.get()), contents);
+}
+
+void AccessibilityTreeFormatter::RecursiveBuildAccessibilityTree(
+ const BrowserAccessibility& node, DictionaryValue* dict) {
+ AddProperties(node, dict);
+ ListValue* children = new ListValue;
+ dict->Set(kChildrenDictAttr, children);
+ for (size_t i = 0; i < node.children().size(); ++i) {
+ BrowserAccessibility* child_node = node.children()[i];
+ DictionaryValue* child_dict = new DictionaryValue;
+ children->Append(child_dict);
+ RecursiveBuildAccessibilityTree(*child_node, child_dict);
+ }
}
void AccessibilityTreeFormatter::RecursiveFormatAccessibilityTree(
- BrowserAccessibility* node, string16* contents, int indent) {
- scoped_array<char> prefix(new char[indent + 1]);
- for (int i = 0; i < indent; ++i)
- prefix[i] = ' ';
- prefix[indent] = '\0';
-
- string16 line = ToString(node, prefix.get());
+ const DictionaryValue& dict, string16* contents, int depth) {
+ string16 line = ToString(dict, string16(depth * kIndentSpaces, ' '));
if (line.find(ASCIIToUTF16(kSkipString)) != string16::npos)
return;
*contents += line;
- for (size_t i = 0; i < node->children().size(); ++i) {
- RecursiveFormatAccessibilityTree(node->children()[i], contents,
- indent + kIndentSpaces);
+ const ListValue* children;
+ dict.GetList(kChildrenDictAttr, &children);
+ const DictionaryValue* child_dict;
+ for (size_t i = 0; i < children->GetSize(); i++) {
+ children->GetDictionary(i, &child_dict);
+ RecursiveFormatAccessibilityTree(*child_dict, contents, depth + 1);
}
}
#if (!defined(OS_WIN) && !defined(OS_MACOSX))
-string16 AccessibilityTreeFormatter::ToString(BrowserAccessibility* node,
- char* prefix) {
- return UTF8ToUTF16(prefix) + base::IntToString16(node->renderer_id()) +
+void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility& node,
+ DictionaryValue* dict) {
+ dict->SetInteger("id", node.renderer_id());
+}
+
+string16 AccessibilityTreeFormatter::ToString(const DictionaryValue& node,
+ const string16& indent) {
+ int id_value;
+ node.GetInteger("id", &id_value);
+ return indent + base::IntToString16(id_value) +
ASCIIToUTF16("\n");
}
@@ -80,28 +108,28 @@
// static
const base::FilePath::StringType
AccessibilityTreeFormatter::GetActualFileSuffix() {
- return FILE_PATH_LITERAL("");
+ return base::FilePath::StringType();
}
// static
const base::FilePath::StringType
AccessibilityTreeFormatter::GetExpectedFileSuffix() {
- return FILE_PATH_LITERAL("");
+ return base::FilePath::StringType();
}
// static
const std::string AccessibilityTreeFormatter::GetAllowEmptyString() {
- return "";
+ return std::string();
}
// static
const std::string AccessibilityTreeFormatter::GetAllowString() {
- return "";
+ return std::string();
}
// static
const std::string AccessibilityTreeFormatter::GetDenyString() {
- return "";
+ return std::string();
}
#endif
@@ -127,23 +155,31 @@
return allow;
}
-void AccessibilityTreeFormatter::StartLine() {
- line_.clear();
+string16 AccessibilityTreeFormatter::FormatCoordinates(
+ const char* name, const char* x_name, const char* y_name,
+ const DictionaryValue& value) {
+ int x, y;
+ value.GetInteger(x_name, &x);
+ value.GetInteger(y_name, &y);
+ std::string xy_str(base::StringPrintf("%s=(%d, %d)", name, x, y));
+
+ return UTF8ToUTF16(xy_str);
}
-void AccessibilityTreeFormatter::Add(
- bool include_by_default, const string16& attr) {
+void AccessibilityTreeFormatter::WriteAttribute(
+ bool include_by_default, const std::string& attr, string16* line) {
+ WriteAttribute(include_by_default, UTF8ToUTF16(attr), line);
+}
+
+void AccessibilityTreeFormatter::WriteAttribute(
+ bool include_by_default, const string16& attr, string16* line) {
if (attr.empty())
return;
if (!MatchesFilters(attr, include_by_default))
return;
- if (!line_.empty())
- line_ += ASCIIToUTF16(" ");
- line_ += attr;
-}
-
-string16 AccessibilityTreeFormatter::FinishLine() {
- return line_;
+ if (!line->empty())
+ *line += ASCIIToUTF16(" ");
+ *line += attr;
}
} // namespace content
diff --git a/content/browser/accessibility/accessibility_tree_formatter.h b/content/browser/accessibility/accessibility_tree_formatter.h
index ca51a68..17beff7 100644
--- a/content/browser/accessibility/accessibility_tree_formatter.h
+++ b/content/browser/accessibility/accessibility_tree_formatter.h
@@ -10,6 +10,7 @@
#include "base/files/file_path.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
+#include "base/values.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/common/content_export.h"
@@ -23,11 +24,33 @@
// implemented.
class CONTENT_EXPORT AccessibilityTreeFormatter {
public:
- explicit AccessibilityTreeFormatter(BrowserAccessibility* node);
+ explicit AccessibilityTreeFormatter(BrowserAccessibility* root);
virtual ~AccessibilityTreeFormatter();
static AccessibilityTreeFormatter* Create(RenderViewHost* rvh);
+ // Populates the given DictionaryValue with the accessibility tree.
+ // The dictionary contains a key/value pair for each attribute of the node,
+ // plus a "children" attribute containing a list of all child nodes.
+ // {
+ // "AXName": "node", /* actual attributes will vary by platform */
+ // "position": { /* some attributes may be dictionaries */
+ // "x": 0,
+ // "y": 0
+ // },
+ // /* ... more attributes of |node| */
+ // "children": [ { /* list of children created recursively */
+ // "AXName": "child node 1",
+ // /* ... more attributes */
+ // "children": [ ]
+ // }, {
+ // "AXName": "child name 2",
+ // /* ... more attributes */
+ // "children": [ ]
+ // } ]
+ // }
+ scoped_ptr<DictionaryValue> BuildAccessibilityTree();
+
// Dumps a BrowserAccessibility tree into a string.
void FormatAccessibilityTree(string16* contents);
@@ -76,25 +99,45 @@
static const std::string GetDenyString();
protected:
- void RecursiveFormatAccessibilityTree(BrowserAccessibility* node,
+ void RecursiveFormatAccessibilityTree(const BrowserAccessibility& node,
string16* contents,
int indent);
+ void RecursiveBuildAccessibilityTree(const BrowserAccessibility& node,
+ DictionaryValue* tree_node);
+ void RecursiveFormatAccessibilityTree(const DictionaryValue& tree_node,
+ string16* contents,
+ int depth = 0);
+
+ // Overridden by each platform to add the required attributes for each node
+ // into the given dict.
+ void AddProperties(const BrowserAccessibility& node, DictionaryValue* dict);
+
+ string16 FormatCoordinates(const char* name,
+ const char* x_name,
+ const char* y_name,
+ const DictionaryValue& value);
// Returns a platform specific representation of a BrowserAccessibility.
// Should be zero or more complete lines, each with |prefix| prepended
// (to indent each line).
- string16 ToString(BrowserAccessibility* node, char* prefix);
+ string16 ToString(const DictionaryValue& node, const string16& indent);
void Initialize();
bool MatchesFilters(const string16& text, bool default_result) const;
- void StartLine();
- void Add(bool include_by_default, const string16& attr);
- string16 FinishLine();
- BrowserAccessibility* node_;
+ // Writes the given attribute string out to |line| if it matches the filters.
+ void WriteAttribute(bool include_by_default,
+ const string16& attr,
+ string16* line);
+ void WriteAttribute(bool include_by_default,
+ const std::string& attr,
+ string16* line);
+
+ BrowserAccessibility* root_;
+
+ // Filters used when formatting the accessibility tree as text.
std::vector<Filter> filters_;
- string16 line_;
DISALLOW_COPY_AND_ASSIGN(AccessibilityTreeFormatter);
};
diff --git a/content/browser/accessibility/accessibility_tree_formatter_mac.mm b/content/browser/accessibility/accessibility_tree_formatter_mac.mm
index f5f1964..4e25596 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_mac.mm
+++ b/content/browser/accessibility/accessibility_tree_formatter_mac.mm
@@ -6,69 +6,84 @@
#import <Cocoa/Cocoa.h>
+#include "base/basictypes.h"
#include "base/files/file_path.h"
+#include "base/json/json_writer.h"
+#include "base/stringprintf.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "content/browser/accessibility/browser_accessibility_cocoa.h"
#include "content/browser/accessibility/browser_accessibility_mac.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
+using base::StringPrintf;
+using base::SysNSStringToUTF8;
+using base::SysNSStringToUTF16;
+using std::string;
+
namespace content {
namespace {
-string16 Format(const char *prefix,
- id value,
- const char *suffix) {
- if (value == nil)
- return UTF8ToUTF16("");
- NSString* format_str =
- [NSString stringWithFormat:@"%s%%@%s", prefix, suffix];
- NSString* tmp = [NSString stringWithFormat:format_str, value];
- return UTF8ToUTF16([tmp cStringUsingEncoding:NSUTF8StringEncoding]);
-}
+const char* kPositionDictAttr = "position";
+const char* kXCoordDictAttr = "x";
+const char* kYCoordDictAttr = "y";
+const char* kSizeDictAttr = "size";
+const char* kWidthDictAttr = "width";
+const char* kHeightDictAttr = "height";
+const char* kRangeLocDictAttr = "loc";
+const char* kRangeLenDictAttr = "len";
-string16 FormatPosition(BrowserAccessibility* node) {
+scoped_ptr<DictionaryValue> PopulatePosition(const BrowserAccessibility& node) {
+ scoped_ptr<DictionaryValue> position(new DictionaryValue);
// The NSAccessibility position of an object is in global coordinates and
// based on the lower-left corner of the object. To make this easier and less
// confusing, convert it to local window coordinates using the top-left
// corner when dumping the position.
- BrowserAccessibility* root = node->manager()->GetRoot();
+ BrowserAccessibility* root = node.manager()->GetRoot();
BrowserAccessibilityCocoa* cocoa_root = root->ToBrowserAccessibilityCocoa();
NSPoint root_position = [[cocoa_root position] pointValue];
NSSize root_size = [[cocoa_root size] sizeValue];
int root_top = -static_cast<int>(root_position.y + root_size.height);
int root_left = static_cast<int>(root_position.x);
- BrowserAccessibilityCocoa* cocoa_node = node->ToBrowserAccessibilityCocoa();
+ BrowserAccessibilityCocoa* cocoa_node =
+ const_cast<BrowserAccessibility*>(&node)->ToBrowserAccessibilityCocoa();
NSPoint node_position = [[cocoa_node position] pointValue];
NSSize node_size = [[cocoa_node size] sizeValue];
- NSString* position_str =
- [NSString stringWithFormat:@"position=(%d, %d)",
- static_cast<int>(node_position.x - root_left),
- static_cast<int>(
- -node_position.y - node_size.height - root_top)];
- return UTF8ToUTF16([position_str cStringUsingEncoding:NSUTF8StringEncoding]);
+ position->SetInteger(kXCoordDictAttr,
+ static_cast<int>(node_position.x - root_left));
+ position->SetInteger(kYCoordDictAttr,
+ static_cast<int>(-node_position.y - node_size.height - root_top));
+ return position.Pass();
}
-string16 FormatSize(BrowserAccessibility* node) {
- BrowserAccessibilityCocoa* cocoa_node = node->ToBrowserAccessibilityCocoa();
+scoped_ptr<DictionaryValue>
+PopulateSize(const BrowserAccessibilityCocoa* cocoa_node) {
+ scoped_ptr<DictionaryValue> size(new DictionaryValue);
NSSize node_size = [[cocoa_node size] sizeValue];
- NSString* size_str =
- [NSString stringWithFormat:@"size=(%d, %d)",
- static_cast<int>(node_size.width),
- static_cast<int>(node_size.height)];
- return UTF8ToUTF16([size_str cStringUsingEncoding:NSUTF8StringEncoding]);
+ size->SetInteger(kHeightDictAttr, static_cast<int>(node_size.height));
+ size->SetInteger(kWidthDictAttr, static_cast<int>(node_size.width));
+ return size.Pass();
}
-} // namespace
+scoped_ptr<DictionaryValue> PopulateRange(NSRange range) {
+ scoped_ptr<DictionaryValue> rangeDict(new DictionaryValue);
+ rangeDict->SetInteger(kRangeLocDictAttr, static_cast<int>(range.location));
+ rangeDict->SetInteger(kRangeLenDictAttr, static_cast<int>(range.length));
+ return rangeDict.Pass();
+}
-void AccessibilityTreeFormatter::Initialize() {}
+// Returns true if |value| is an NSValue containing a NSRange.
+bool IsRangeValue(id value) {
+ if (![value isKindOfClass:[NSValue class]])
+ return false;
+ return 0 == strcmp([value objCType], @encode(NSRange));
+}
-string16 AccessibilityTreeFormatter::ToString(BrowserAccessibility* node,
- char* prefix) {
- StartLine();
- NSArray* requestedAttributes = [NSArray arrayWithObjects:
+NSArray* BuildAllAttributesArray() {
+ return [NSArray arrayWithObjects:
NSAccessibilityRoleDescriptionAttribute,
NSAccessibilityTitleAttribute,
NSAccessibilityValueAttribute,
@@ -85,51 +100,122 @@
@"AXARIABusy",
@"AXARIALive",
@"AXARIARelevant",
+ NSAccessibilityColumnIndexRangeAttribute,
NSAccessibilityEnabledAttribute,
NSAccessibilityFocusedAttribute,
+ NSAccessibilityIndexAttribute,
@"AXLoaded",
@"AXLoadingProcess",
NSAccessibilityNumberOfCharactersAttribute,
NSAccessibilityOrientationAttribute,
@"AXRequired",
+ NSAccessibilityRowIndexRangeAttribute,
NSAccessibilityURLAttribute,
NSAccessibilityVisibleCharacterRangeAttribute,
@"AXVisited",
nil];
+}
- NSArray* defaultAttributes = [NSArray arrayWithObjects:
- NSAccessibilityTitleAttribute,
- NSAccessibilityValueAttribute,
- nil];
+} // namespace
- BrowserAccessibilityCocoa* cocoa_node = node->ToBrowserAccessibilityCocoa();
+void AccessibilityTreeFormatter::Initialize() {
+}
+
+
+void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility& node,
+ DictionaryValue* dict) {
+ BrowserAccessibilityCocoa* cocoa_node =
+ const_cast<BrowserAccessibility*>(&node)->ToBrowserAccessibilityCocoa();
NSArray* supportedAttributes = [cocoa_node accessibilityAttributeNames];
- Add(true,
- Format("", [cocoa_node accessibilityAttributeValue:
- NSAccessibilityRoleAttribute],
- ""));
- Add(false,
- Format("subrole=", [cocoa_node accessibilityAttributeValue:
- NSAccessibilitySubroleAttribute],
- ""));
- for (NSString* requestedAttribute in requestedAttributes) {
+ string role = SysNSStringToUTF8(
+ [cocoa_node accessibilityAttributeValue:NSAccessibilityRoleAttribute]);
+ dict->SetString(SysNSStringToUTF8(NSAccessibilityRoleAttribute), role);
+
+ NSString* subrole =
+ [cocoa_node accessibilityAttributeValue:NSAccessibilitySubroleAttribute];
+ if (subrole != nil) {
+ dict->SetString(SysNSStringToUTF8(NSAccessibilitySubroleAttribute),
+ SysNSStringToUTF8(subrole));
+ }
+
+ CR_DEFINE_STATIC_LOCAL(NSArray*, all_attributes, (BuildAllAttributesArray()));
+ for (NSString* requestedAttribute in all_attributes) {
if (![supportedAttributes containsObject:requestedAttribute]) {
continue;
}
- NSString* methodName =
- [cocoa_node methodNameForAttribute:requestedAttribute];
- Add([defaultAttributes containsObject:requestedAttribute],
- Format([[NSString stringWithFormat:@"%@='", methodName]
- cStringUsingEncoding:NSUTF8StringEncoding],
- [cocoa_node accessibilityAttributeValue:
- requestedAttribute],
- "'"));
+ id value = [cocoa_node accessibilityAttributeValue:requestedAttribute];
+ if (IsRangeValue(value)) {
+ dict->Set(
+ SysNSStringToUTF8(requestedAttribute),
+ PopulateRange([value rangeValue]).release());
+ } else if (value != nil) {
+ dict->SetString(
+ SysNSStringToUTF8(requestedAttribute),
+ SysNSStringToUTF16([NSString stringWithFormat:@"%@", value]));
+ }
}
- Add(false, FormatPosition(node));
- Add(false, FormatSize(node));
+ dict->Set(kPositionDictAttr, PopulatePosition(node).release());
+ dict->Set(kSizeDictAttr, PopulateSize(cocoa_node).release());
+}
- return ASCIIToUTF16(prefix) + FinishLine() + ASCIIToUTF16("\n");
+string16 AccessibilityTreeFormatter::ToString(const DictionaryValue& dict,
+ const string16& indent) {
+ string16 line;
+ NSArray* defaultAttributes =
+ [NSArray arrayWithObjects:NSAccessibilityTitleAttribute,
+ NSAccessibilityValueAttribute,
+ nil];
+ string s_value;
+ dict.GetString(SysNSStringToUTF8(NSAccessibilityRoleAttribute), &s_value);
+ WriteAttribute(true, UTF8ToUTF16(s_value), &line);
+
+ string subroleAttribute = SysNSStringToUTF8(NSAccessibilitySubroleAttribute);
+ if (dict.GetString(subroleAttribute, &s_value)) {
+ WriteAttribute(false,
+ StringPrintf("%s=%s",
+ subroleAttribute.c_str(), s_value.c_str()),
+ &line);
+ }
+
+ CR_DEFINE_STATIC_LOCAL(NSArray*, all_attributes, (BuildAllAttributesArray()));
+ for (NSString* requestedAttribute in all_attributes) {
+ string requestedAttributeUTF8 = SysNSStringToUTF8(requestedAttribute);
+ const DictionaryValue* d_value;
+ if (dict.GetDictionary(requestedAttributeUTF8, &d_value)) {
+ std::string json_value;
+ base::JSONWriter::Write(d_value, &json_value);
+ WriteAttribute(
+ [defaultAttributes containsObject:requestedAttribute],
+ StringPrintf("%s=%s",
+ requestedAttributeUTF8.c_str(),
+ json_value.c_str()),
+ &line);
+ }
+ if (!dict.GetString(requestedAttributeUTF8, &s_value))
+ continue;
+ WriteAttribute([defaultAttributes containsObject:requestedAttribute],
+ StringPrintf("%s='%s'",
+ requestedAttributeUTF8.c_str(),
+ s_value.c_str()),
+ &line);
+ }
+ const DictionaryValue* d_value = NULL;
+ if (dict.GetDictionary(kPositionDictAttr, &d_value)) {
+ WriteAttribute(false,
+ FormatCoordinates(kPositionDictAttr,
+ kXCoordDictAttr, kYCoordDictAttr,
+ *d_value),
+ &line);
+ }
+ if (dict.GetDictionary(kSizeDictAttr, &d_value)) {
+ WriteAttribute(false,
+ FormatCoordinates(kSizeDictAttr,
+ kWidthDictAttr, kHeightDictAttr, *d_value),
+ &line);
+ }
+
+ return indent + line + ASCIIToUTF16("\n");
}
// static
@@ -145,17 +231,17 @@
}
// static
-const std::string AccessibilityTreeFormatter::GetAllowEmptyString() {
+const string AccessibilityTreeFormatter::GetAllowEmptyString() {
return "@MAC-ALLOW-EMPTY:";
}
// static
-const std::string AccessibilityTreeFormatter::GetAllowString() {
+const string AccessibilityTreeFormatter::GetAllowString() {
return "@MAC-ALLOW:";
}
// static
-const std::string AccessibilityTreeFormatter::GetDenyString() {
+const string AccessibilityTreeFormatter::GetDenyString() {
return "@MAC-DENY:";
}
diff --git a/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc b/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
index 5e57954..334c8cf 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
@@ -183,6 +183,7 @@
IA_STATE_MAP(MIXED)
IA_STATE_MAP(MOVEABLE)
IA_STATE_MAP(MULTISELECTABLE)
+ IA_STATE_MAP(OFFSCREEN)
IA_STATE_MAP(PRESSED)
IA_STATE_MAP(PROTECTED)
IA_STATE_MAP(READONLY)
@@ -193,10 +194,6 @@
IA_STATE_MAP(TRAVERSED)
IA_STATE_MAP(UNAVAILABLE)
- // Untested states include those that would be repeated on nearly every node,
- // or would vary based on window size.
- // IA_STATE_MAP(OFFSCREEN) // Untested.
-
// IAccessible2 states.
IA2_STATE_MAP(IA2_STATE_ACTIVE)
IA2_STATE_MAP(IA2_STATE_ARMED)
diff --git a/content/browser/accessibility/accessibility_tree_formatter_win.cc b/content/browser/accessibility/accessibility_tree_formatter_win.cc
index 389c0e5..90bef99 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_win.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_win.cc
@@ -19,144 +19,274 @@
#include "third_party/iaccessible2/ia2_api_all.h"
#include "ui/base/win/atl_module.h"
+using base::StringPrintf;
+
namespace content {
+const char* ALL_ATTRIBUTES[] = {
+ "name",
+ "value",
+ "states",
+ "attributes",
+ "role_name",
+ "currentValue",
+ "minimumValue",
+ "maximumValue",
+ "description",
+ "default_action",
+ "keyboard_shortcut",
+ "location",
+ "size",
+ "index_in_parent",
+ "n_relations",
+ "group_level",
+ "similar_items_in_group",
+ "position_in_group",
+ "table_rows",
+ "table_columns",
+ "row_index",
+ "column_index",
+ "n_characters",
+ "caret_offset",
+ "n_selections",
+ "selection_start",
+ "selection_end"
+};
+
void AccessibilityTreeFormatter::Initialize() {
ui::win::CreateATLModuleIfNeeded();
}
-string16 AccessibilityTreeFormatter::ToString(
- BrowserAccessibility* node, char* prefix) {
- BrowserAccessibilityWin* acc_obj = node->ToBrowserAccessibilityWin();
+void AccessibilityTreeFormatter::AddProperties(
+ const BrowserAccessibility& node, DictionaryValue* dict) {
+ BrowserAccessibilityWin* acc_obj =
+ const_cast<BrowserAccessibility*>(&node)->ToBrowserAccessibilityWin();
- // Get the computed name.
VARIANT variant_self;
variant_self.vt = VT_I4;
variant_self.lVal = CHILDID_SELF;
+
+ dict->SetString("role", IAccessible2RoleToString(acc_obj->ia2_role()));
+
CComBSTR msaa_variant;
HRESULT hresult = acc_obj->get_accName(variant_self, &msaa_variant);
- string16 name;
- if (S_OK == hresult)
- name = msaa_variant.m_str;
-
+ if (hresult == S_OK)
+ dict->SetString("name", msaa_variant.m_str);
hresult = acc_obj->get_accValue(variant_self, &msaa_variant);
- string16 value;
- if (S_OK == hresult)
- value = msaa_variant.m_str;
+ if (hresult == S_OK)
+ dict->SetString("value", msaa_variant.m_str);
- hresult = acc_obj->get_accDescription(variant_self, &msaa_variant);
- string16 description;
- if (S_OK == hresult)
- description = msaa_variant.m_str;
-
- hresult = acc_obj->get_accHelp(variant_self, &msaa_variant);
- string16 help;
- if (S_OK == hresult)
- help = msaa_variant.m_str;
-
- hresult = acc_obj->get_accDefaultAction(variant_self, &msaa_variant);
- string16 default_action;
- if (S_OK == hresult)
- default_action = msaa_variant.m_str;
-
- hresult = acc_obj->get_accKeyboardShortcut(variant_self, &msaa_variant);
- string16 keyboard_shortcut;
- if (S_OK == hresult)
- keyboard_shortcut = msaa_variant.m_str;
-
- // Get state strings.
std::vector<string16> state_strings;
- IAccessibleStateToStringVector(acc_obj->ia_state(), &state_strings);
+ int32 ia_state = acc_obj->ia_state();
+
+ // Avoid flakiness: these states depend on whether the window is focused
+ // and the position of the mouse cursor.
+ ia_state &= ~STATE_SYSTEM_HOTTRACKED;
+ ia_state &= ~STATE_SYSTEM_OFFSCREEN;
+
+ IAccessibleStateToStringVector(ia_state, &state_strings);
IAccessible2StateToStringVector(acc_obj->ia2_state(), &state_strings);
-
- // Get the attributes.
- const std::vector<string16>& ia2_attributes = acc_obj->ia2_attributes();
-
- // Build the line.
- StartLine();
- Add(true, IAccessible2RoleToString(acc_obj->ia2_role()));
- Add(true, L"name='" + name + L"'");
- Add(false, L"value='" + value + L"'");
+ ListValue* states = new ListValue;
for (std::vector<string16>::const_iterator it = state_strings.begin();
it != state_strings.end();
++it) {
- Add(false, *it);
+ states->AppendString(UTF16ToUTF8(*it));
}
+ dict->Set("states", states);
+
+ const std::vector<string16>& ia2_attributes = acc_obj->ia2_attributes();
+ ListValue* attributes = new ListValue;
for (std::vector<string16>::const_iterator it = ia2_attributes.begin();
it != ia2_attributes.end();
++it) {
- Add(false, *it);
+ attributes->AppendString(UTF16ToUTF8(*it));
}
- Add(false, L"role_name='" + acc_obj->role_name() + L"'");
+ dict->Set("attributes", attributes);
+
+ dict->SetString("role_name", acc_obj->role_name());
+
VARIANT currentValue;
if (acc_obj->get_currentValue(¤tValue) == S_OK)
- Add(false, base::StringPrintf(L"currentValue=%.2f", V_R8(¤tValue)));
+ dict->SetDouble("currentValue", V_R8(¤tValue));
+
VARIANT minimumValue;
if (acc_obj->get_minimumValue(&minimumValue) == S_OK)
- Add(false, base::StringPrintf(L"minimumValue=%.2f", V_R8(&minimumValue)));
+ dict->SetDouble("minimumValue", V_R8(&minimumValue));
+
VARIANT maximumValue;
if (acc_obj->get_maximumValue(&maximumValue) == S_OK)
- Add(false, base::StringPrintf(L"maximumValue=%.2f", V_R8(&maximumValue)));
- Add(false, L"description='" + description + L"'");
- Add(false, L"default_action='" + default_action + L"'");
- Add(false, L"keyboard_shortcut='" + keyboard_shortcut + L"'");
- BrowserAccessibility* root = node->manager()->GetRoot();
+ dict->SetDouble("maximumValue", V_R8(&maximumValue));
+
+ hresult = acc_obj->get_accDescription(variant_self, &msaa_variant);
+ if (hresult == S_OK)
+ dict->SetString("description", msaa_variant.m_str);
+
+ hresult = acc_obj->get_accDefaultAction(variant_self, &msaa_variant);
+ if (hresult == S_OK)
+ dict->SetString("default_action", msaa_variant.m_str);
+
+ hresult = acc_obj->get_accKeyboardShortcut(variant_self, &msaa_variant);
+ if (hresult == S_OK)
+ dict->SetString("keyboard_shortcut", msaa_variant.m_str);
+
+ hresult = acc_obj->get_accHelp(variant_self, &msaa_variant);
+ if (S_OK == hresult)
+ dict->SetString("help", msaa_variant.m_str);
+
+ BrowserAccessibility* root = node.manager()->GetRoot();
LONG left, top, width, height;
LONG root_left, root_top, root_width, root_height;
- if (S_FALSE != acc_obj->accLocation(
- &left, &top, &width, &height, variant_self) &&
- S_FALSE != root->ToBrowserAccessibilityWin()->accLocation(
- &root_left, &root_top, &root_width, &root_height, variant_self)) {
- Add(false, base::StringPrintf(L"location=(%d, %d)",
- left - root_left, top - root_top));
- Add(false, base::StringPrintf(L"size=(%d, %d)", width, height));
+ if (acc_obj->accLocation(&left, &top, &width, &height, variant_self)
+ != S_FALSE
+ && root->ToBrowserAccessibilityWin()->accLocation(
+ &root_left, &root_top, &root_width, &root_height, variant_self)
+ != S_FALSE) {
+ DictionaryValue* location = new DictionaryValue;
+ location->SetInteger("x", left - root_left);
+ location->SetInteger("y", top - root_top);
+ dict->Set("location", location);
+
+ DictionaryValue* size = new DictionaryValue;
+ size->SetInteger("width", width);
+ size->SetInteger("height", height);
+ dict->Set("size", size);
}
+
LONG index_in_parent;
if (acc_obj->get_indexInParent(&index_in_parent) == S_OK)
- Add(false, base::StringPrintf(L"index_in_parent=%d", index_in_parent));
+ dict->SetInteger("index_in_parent", index_in_parent);
+
LONG n_relations;
if (acc_obj->get_nRelations(&n_relations) == S_OK)
- Add(false, base::StringPrintf(L"n_relations=%d", n_relations));
+ dict->SetInteger("n_relations", n_relations);
+
LONG group_level, similar_items_in_group, position_in_group;
if (acc_obj->get_groupPosition(&group_level,
&similar_items_in_group,
&position_in_group) == S_OK) {
- Add(false, base::StringPrintf(L"group_level=%d", group_level));
- Add(false, base::StringPrintf(L"similar_items_in_group=%d",
- similar_items_in_group));
- Add(false, base::StringPrintf(L"position_in_group=%d", position_in_group));
+ dict->SetInteger("group_level", group_level);
+ dict->SetInteger("similar_items_in_group", similar_items_in_group);
+ dict->SetInteger("position_in_group", position_in_group);
}
LONG table_rows;
if (acc_obj->get_nRows(&table_rows) == S_OK)
- Add(false, base::StringPrintf(L"table_rows=%d", table_rows));
+ dict->SetInteger("table_rows", table_rows);
LONG table_columns;
if (acc_obj->get_nRows(&table_columns) == S_OK)
- Add(false, base::StringPrintf(L"table_columns=%d", table_columns));
+ dict->SetInteger("table_columns", table_columns);
LONG row_index;
if (acc_obj->get_rowIndex(&row_index) == S_OK)
- Add(false, base::StringPrintf(L"row_index=%d", row_index));
+ dict->SetInteger("row_index", row_index);
LONG column_index;
if (acc_obj->get_columnIndex(&column_index) == S_OK)
- Add(false, base::StringPrintf(L"column_index=%d", column_index));
+ dict->SetInteger("column_index", column_index);
LONG n_characters;
if (acc_obj->get_nCharacters(&n_characters) == S_OK)
- Add(false, base::StringPrintf(L"n_characters=%d", n_characters));
+ dict->SetInteger("n_characters", n_characters);
LONG caret_offset;
if (acc_obj->get_caretOffset(&caret_offset) == S_OK)
- Add(false, base::StringPrintf(L"caret_offset=%d", caret_offset));
+ dict->SetInteger("caret_offset", caret_offset);
LONG n_selections;
if (acc_obj->get_nSelections(&n_selections) == S_OK) {
- Add(false, base::StringPrintf(L"n_selections=%d", n_selections));
+ dict->SetInteger("n_selections", n_selections);
if (n_selections > 0) {
LONG start, end;
if (acc_obj->get_selection(0, &start, &end) == S_OK) {
- Add(false, base::StringPrintf(L"selection_start=%d", start));
- Add(false, base::StringPrintf(L"selection_end=%d", end));
+ dict->SetInteger("selection_start", start);
+ dict->SetInteger("selection_end", end);
}
}
}
+}
- return UTF8ToUTF16(prefix) + FinishLine() + ASCIIToUTF16("\n");
+string16 AccessibilityTreeFormatter::ToString(const DictionaryValue& dict,
+ const string16& indent) {
+ string16 line;
+
+ string16 role_value;
+ dict.GetString("role", &role_value);
+ WriteAttribute(true, UTF16ToUTF8(role_value), &line);
+
+ string16 name_value;
+ dict.GetString("name", &name_value);
+ WriteAttribute(true, base::StringPrintf(L"name='%ls'", name_value.c_str()),
+ &line);
+
+ for (int i = 0; i < arraysize(ALL_ATTRIBUTES); i++) {
+ const char* attribute_name = ALL_ATTRIBUTES[i];
+ const Value* value;
+ if (!dict.Get(attribute_name, &value))
+ continue;
+
+ switch (value->GetType()) {
+ case Value::TYPE_STRING: {
+ string16 string_value;
+ value->GetAsString(&string_value);
+ WriteAttribute(false,
+ StringPrintf(L"%ls='%ls'",
+ UTF8ToUTF16(attribute_name).c_str(),
+ string_value.c_str()),
+ &line);
+ break;
+ }
+ case Value::TYPE_INTEGER: {
+ int int_value;
+ value->GetAsInteger(&int_value);
+ WriteAttribute(false,
+ base::StringPrintf(L"%ls=%d",
+ UTF8ToUTF16(attribute_name).c_str(),
+ int_value),
+ &line);
+ break;
+ }
+ case Value::TYPE_DOUBLE: {
+ double double_value;
+ value->GetAsDouble(&double_value);
+ WriteAttribute(false,
+ base::StringPrintf(L"%ls=%.2f",
+ UTF8ToUTF16(attribute_name).c_str(),
+ double_value),
+ &line);
+ break;
+ }
+ case Value::TYPE_LIST: {
+ // Currently all list values are string and are written without
+ // attribute names.
+ const ListValue* list_value;
+ value->GetAsList(&list_value);
+ for (ListValue::const_iterator it = list_value->begin();
+ it != list_value->end();
+ ++it) {
+ string16 string_value;
+ if ((*it)->GetAsString(&string_value))
+ WriteAttribute(false, string_value, &line);
+ }
+ break;
+ }
+ case Value::TYPE_DICTIONARY: {
+ // Currently all dictionary values are coordinates.
+ // Revisit this if that changes.
+ const DictionaryValue* dict_value;
+ value->GetAsDictionary(&dict_value);
+ if (strcmp(attribute_name, "size") == 0) {
+ WriteAttribute(false,
+ FormatCoordinates("size", "width", "height",
+ *dict_value),
+ &line);
+ } else if (strcmp(attribute_name, "location") == 0) {
+ WriteAttribute(false,
+ FormatCoordinates("location", "x", "y", *dict_value),
+ &line);
+ }
+ break;
+ }
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+
+ return indent + line + ASCIIToUTF16("\n");
}
// static
diff --git a/content/browser/accessibility/accessibility_ui.cc b/content/browser/accessibility/accessibility_ui.cc
index 88bc566..dfc7343 100644
--- a/content/browser/accessibility/accessibility_ui.cc
+++ b/content/browser/accessibility/accessibility_ui.cc
@@ -121,7 +121,7 @@
scoped_ptr<DictionaryValue> data(new DictionaryValue());
data->Set("list", rvh_list.release());
scoped_ptr<FundamentalValue> a11y_mode(new FundamentalValue(
- BrowserAccessibilityStateImpl::GetInstance()->GetAccessibilityMode()));
+ BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()));
data->Set("global_a11y_mode", a11y_mode.release());
std::string json_string;
@@ -146,7 +146,7 @@
: WebUIController(web_ui) {
// Set up the chrome://accessibility source.
WebUIDataSource* html_source =
- WebUIDataSource::Create(chrome::kChromeUIAccessibilityHost);
+ WebUIDataSource::Create(kChromeUIAccessibilityHost);
html_source->SetUseJsonJSFormatV2();
web_ui->RegisterMessageCallback(
@@ -205,32 +205,11 @@
void AccessibilityUI::ToggleGlobalAccessibility(const base::ListValue* args) {
BrowserAccessibilityStateImpl* state =
BrowserAccessibilityStateImpl::GetInstance();
- AccessibilityMode mode = state->GetAccessibilityMode();
+ AccessibilityMode mode = state->accessibility_mode();
AccessibilityMode new_mode = (mode == AccessibilityModeOff
? AccessibilityModeComplete
: AccessibilityModeOff);
state->SetAccessibilityMode(new_mode);
- for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
- !it.IsAtEnd(); it.Advance()) {
- RenderProcessHost* render_process_host = it.GetCurrentValue();
- DCHECK(render_process_host);
-
- // Ignore processes that don't have a connection, such as crashed tabs.
- if (!render_process_host->HasConnection())
- continue;
-
- RenderProcessHost::RenderWidgetHostsIterator rwit(
- render_process_host->GetRenderWidgetHostsIterator());
- for (; !rwit.IsAtEnd(); rwit.Advance()) {
- RenderWidgetHost* rwh = const_cast<RenderWidgetHost*>(
- rwit.GetCurrentValue());
- DCHECK(rwh);
- if (!rwh || !rwh->IsRenderView())
- continue;
- RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(rwh);
- rwhi->SetAccessibilityMode(new_mode);
- }
- }
}
void AccessibilityUI::RequestAccessibilityTree(const base::ListValue* args) {
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc
index 1158d7a..b099af9 100644
--- a/content/browser/accessibility/accessibility_win_browsertest.cc
+++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <atlbase.h>
#include <vector>
#include "base/memory/scoped_ptr.h"
-#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
+#include "base/win/scoped_bstr.h"
#include "base/win/scoped_comptr.h"
+#include "base/win/scoped_variant.h"
#include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/public/browser/notification_service.h"
@@ -24,11 +24,6 @@
#include "third_party/iaccessible2/ia2_api_all.h"
#include "third_party/isimpledom/ISimpleDOMNode.h"
-using std::auto_ptr;
-using std::string;
-using std::vector;
-using std::wstring;
-
// TODO(dmazzoni): Disabled accessibility tests on Win64. crbug.com/179717
#if defined(ARCH_CPU_X86_64)
#define MAYBE(x) DISABLED_##x
@@ -40,105 +35,31 @@
namespace {
-class AccessibilityWinBrowserTest : public ContentBrowserTest {
- public:
- AccessibilityWinBrowserTest() {}
- protected:
- void LoadInitialAccessibilityTreeFromHtml(string html);
- IAccessible* GetRendererAccessible();
- void ExecuteScript(wstring script);
-};
+// Helpers --------------------------------------------------------------------
-class AccessibleChecker {
- public:
- AccessibleChecker(
- wstring expected_name,
- int32 expected_role,
- wstring expected_value);
- AccessibleChecker(
- wstring expected_name,
- wstring expected_role,
- int32 expected_ia2_role,
- wstring expected_value);
- AccessibleChecker(
- wstring expected_name,
- int32 expected_role,
- int32 expected_ia2_role,
- wstring expected_value);
-
- // Append an AccessibleChecker that verifies accessibility information for
- // a child IAccessible. Order is important.
- void AppendExpectedChild(AccessibleChecker* expected_child);
-
- // Check that the name and role of the given IAccessible instance and its
- // descendants match the expected names and roles that this object was
- // initialized with.
- void CheckAccessible(IAccessible* accessible);
-
- // Set the expected value for this AccessibleChecker.
- void SetExpectedValue(wstring expected_value);
-
- // Set the expected state for this AccessibleChecker.
- void SetExpectedState(LONG expected_state);
-
- private:
- void CheckAccessibleName(IAccessible* accessible);
- void CheckAccessibleRole(IAccessible* accessible);
- void CheckIA2Role(IAccessible* accessible);
- void CheckAccessibleValue(IAccessible* accessible);
- void CheckAccessibleState(IAccessible* accessible);
- void CheckAccessibleChildren(IAccessible* accessible);
- string16 RoleVariantToString(VARIANT* role_variant);
-
- private:
- typedef vector<AccessibleChecker*> AccessibleCheckerVector;
-
- // Expected accessible name. Checked against IAccessible::get_accName.
- wstring name_;
-
- // Expected accessible role. Checked against IAccessible::get_accRole.
- CComVariant role_;
-
- // Expected IAccessible2 role. Checked against IAccessible2::role.
- int32 ia2_role_;
-
- // Expected accessible value. Checked against IAccessible::get_accValue.
- wstring value_;
-
- // Expected accessible state. Checked against IAccessible::get_accState.
- LONG state_;
-
- // Expected accessible children. Checked using IAccessible::get_accChildCount
- // and ::AccessibleChildren.
- AccessibleCheckerVector children_;
-};
-
-VARIANT CreateI4Variant(LONG value) {
- VARIANT variant = {0};
-
- V_VT(&variant) = VT_I4;
- V_I4(&variant) = value;
-
- return variant;
-}
-
-IAccessible* GetAccessibleFromResultVariant(IAccessible* parent, VARIANT *var) {
+base::win::ScopedComPtr<IAccessible> GetAccessibleFromResultVariant(
+ IAccessible* parent,
+ VARIANT* var) {
+ base::win::ScopedComPtr<IAccessible> ptr;
switch (V_VT(var)) {
- case VT_DISPATCH:
- return CComQIPtr<IAccessible>(V_DISPATCH(var)).Detach();
+ case VT_DISPATCH: {
+ IDispatch* dispatch = V_DISPATCH(var);
+ if (dispatch)
+ ptr.QueryFrom(dispatch);
break;
+ }
case VT_I4: {
- CComPtr<IDispatch> dispatch;
- HRESULT hr = parent->get_accChild(CreateI4Variant(V_I4(var)), &dispatch);
+ base::win::ScopedComPtr<IDispatch> dispatch;
+ HRESULT hr = parent->get_accChild(*var, dispatch.Receive());
EXPECT_TRUE(SUCCEEDED(hr));
- return CComQIPtr<IAccessible>(dispatch).Detach();
+ if (dispatch)
+ dispatch.QueryInterface(ptr.Receive());
break;
}
}
-
- return NULL;
+ return ptr;
}
HRESULT QueryIAccessible2(IAccessible* accessible, IAccessible2** accessible2) {
@@ -146,36 +67,33 @@
// IAccessible fails.
base::win::ScopedComPtr<IServiceProvider> service_provider;
HRESULT hr = accessible->QueryInterface(service_provider.Receive());
- if (FAILED(hr))
- return hr;
-
- hr = service_provider->QueryService(IID_IAccessible2, accessible2);
- return hr;
+ return SUCCEEDED(hr) ?
+ service_provider->QueryService(IID_IAccessible2, accessible2) : hr;
}
// Recursively search through all of the descendants reachable from an
// IAccessible node and return true if we find one with the given role
// and name.
-void RecursiveFindNodeInAccessibilityTree(
- IAccessible* node,
- int32 expected_role,
- const wstring& expected_name,
- int32 depth,
- bool* found) {
- CComBSTR name_bstr;
- node->get_accName(CreateI4Variant(CHILDID_SELF), &name_bstr);
- wstring name(name_bstr.m_str, SysStringLen(name_bstr));
- VARIANT role = {0};
- node->get_accRole(CreateI4Variant(CHILDID_SELF), &role);
+void RecursiveFindNodeInAccessibilityTree(IAccessible* node,
+ int32 expected_role,
+ const std::wstring& expected_name,
+ int32 depth,
+ bool* found) {
+ base::win::ScopedBstr name_bstr;
+ base::win::ScopedVariant childid_self(CHILDID_SELF);
+ node->get_accName(childid_self, name_bstr.Receive());
+ std::wstring name(name_bstr, name_bstr.Length());
+ base::win::ScopedVariant role;
+ node->get_accRole(childid_self, role.Receive());
+ ASSERT_EQ(VT_I4, role.type());
// Print the accessibility tree as we go, because if this test fails
// on the bots, this is really helpful in figuring out why.
- for (int i = 0; i < depth; i++) {
+ for (int i = 0; i < depth; i++)
printf(" ");
- }
- printf("role=%d name=%s\n", role.lVal, WideToUTF8(name).c_str());
+ printf("role=%d name=%s\n", V_I4(&role), WideToUTF8(name).c_str());
- if (expected_role == role.lVal && expected_name == name) {
+ if (expected_role == V_I4(&role) && expected_name == name) {
*found = true;
return;
}
@@ -184,7 +102,7 @@
HRESULT hr = node->get_accChildCount(&child_count);
ASSERT_EQ(S_OK, hr);
- scoped_array<VARIANT> child_array(new VARIANT[child_count]);
+ scoped_ptr<VARIANT[]> child_array(new VARIANT[child_count]);
LONG obtained_count = 0;
hr = AccessibleChildren(
node, 0, child_count, child_array.get(), &obtained_count);
@@ -194,7 +112,7 @@
for (int index = 0; index < obtained_count; index++) {
base::win::ScopedComPtr<IAccessible> child_accessible(
GetAccessibleFromResultVariant(node, &child_array.get()[index]));
- if (child_accessible.get()) {
+ if (child_accessible) {
RecursiveFindNodeInAccessibilityTree(
child_accessible.get(), expected_role, expected_name, depth + 1,
found);
@@ -204,10 +122,33 @@
}
}
+
+// AccessibilityWinBrowserTest ------------------------------------------------
+
+class AccessibilityWinBrowserTest : public ContentBrowserTest {
+ public:
+ AccessibilityWinBrowserTest();
+ virtual ~AccessibilityWinBrowserTest();
+
+ protected:
+ void LoadInitialAccessibilityTreeFromHtml(const std::string& html);
+ IAccessible* GetRendererAccessible();
+ void ExecuteScript(const std::wstring& script);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AccessibilityWinBrowserTest);
+};
+
+AccessibilityWinBrowserTest::AccessibilityWinBrowserTest() {
+}
+
+AccessibilityWinBrowserTest::~AccessibilityWinBrowserTest() {
+}
+
void AccessibilityWinBrowserTest::LoadInitialAccessibilityTreeFromHtml(
- string html) {
+ const std::string& html) {
// Load the html using a data url and wait for the navigation to finish.
- GURL html_data_url(string("data:text/html,") + html);
+ GURL html_data_url("data:text/html," + html);
NavigateToURL(shell(), html_data_url);
// At this point, renderer accessibility is off and the page has completed
@@ -229,8 +170,7 @@
// Retrieve the MSAA client accessibility object for the Render Widget Host View
// of the selected tab.
-IAccessible*
-AccessibilityWinBrowserTest::GetRendererAccessible() {
+IAccessible* AccessibilityWinBrowserTest::GetRendererAccessible() {
HWND hwnd_render_widget_host_view =
shell()->web_contents()->GetRenderWidgetHostView()->GetNativeView();
@@ -251,41 +191,106 @@
return accessible;
}
-void AccessibilityWinBrowserTest::ExecuteScript(wstring script) {
- shell()->web_contents()->GetRenderViewHost()->
- ExecuteJavascriptInWebFrame(L"", script);
+void AccessibilityWinBrowserTest::ExecuteScript(const std::wstring& script) {
+ shell()->web_contents()->GetRenderViewHost()->ExecuteJavascriptInWebFrame(
+ std::wstring(), script);
}
-// This constructor can be used if IA2 role will be the same as MSAA role
-AccessibleChecker::AccessibleChecker(
- wstring expected_name, int32 expected_role, wstring expected_value) :
- name_(expected_name),
- role_(expected_role),
- ia2_role_(expected_role),
- value_(expected_value),
- state_(-1) {
+
+// AccessibleChecker ----------------------------------------------------------
+
+class AccessibleChecker {
+ public:
+ // This constructor can be used if the IA2 role will be the same as the MSAA
+ // role.
+ AccessibleChecker(const std::wstring& expected_name,
+ int32 expected_role,
+ const std::wstring& expected_value);
+ AccessibleChecker(const std::wstring& expected_name,
+ int32 expected_role,
+ int32 expected_ia2_role,
+ const std::wstring& expected_value);
+ AccessibleChecker(const std::wstring& expected_name,
+ const std::wstring& expected_role,
+ int32 expected_ia2_role,
+ const std::wstring& expected_value);
+
+ // Append an AccessibleChecker that verifies accessibility information for
+ // a child IAccessible. Order is important.
+ void AppendExpectedChild(AccessibleChecker* expected_child);
+
+ // Check that the name and role of the given IAccessible instance and its
+ // descendants match the expected names and roles that this object was
+ // initialized with.
+ void CheckAccessible(IAccessible* accessible);
+
+ // Set the expected value for this AccessibleChecker.
+ void SetExpectedValue(const std::wstring& expected_value);
+
+ // Set the expected state for this AccessibleChecker.
+ void SetExpectedState(LONG expected_state);
+
+ private:
+ typedef std::vector<AccessibleChecker*> AccessibleCheckerVector;
+
+ void CheckAccessibleName(IAccessible* accessible);
+ void CheckAccessibleRole(IAccessible* accessible);
+ void CheckIA2Role(IAccessible* accessible);
+ void CheckAccessibleValue(IAccessible* accessible);
+ void CheckAccessibleState(IAccessible* accessible);
+ void CheckAccessibleChildren(IAccessible* accessible);
+ string16 RoleVariantToString(const base::win::ScopedVariant& role);
+
+ // Expected accessible name. Checked against IAccessible::get_accName.
+ std::wstring name_;
+
+ // Expected accessible role. Checked against IAccessible::get_accRole.
+ base::win::ScopedVariant role_;
+
+ // Expected IAccessible2 role. Checked against IAccessible2::role.
+ int32 ia2_role_;
+
+ // Expected accessible value. Checked against IAccessible::get_accValue.
+ std::wstring value_;
+
+ // Expected accessible state. Checked against IAccessible::get_accState.
+ LONG state_;
+
+ // Expected accessible children. Checked using IAccessible::get_accChildCount
+ // and ::AccessibleChildren.
+ AccessibleCheckerVector children_;
+};
+
+AccessibleChecker::AccessibleChecker(const std::wstring& expected_name,
+ int32 expected_role,
+ const std::wstring& expected_value)
+ : name_(expected_name),
+ role_(expected_role),
+ ia2_role_(expected_role),
+ value_(expected_value),
+ state_(-1) {
}
-AccessibleChecker::AccessibleChecker(wstring expected_name,
+AccessibleChecker::AccessibleChecker(const std::wstring& expected_name,
int32 expected_role,
int32 expected_ia2_role,
- wstring expected_value) :
- name_(expected_name),
- role_(expected_role),
- ia2_role_(expected_ia2_role),
- value_(expected_value),
- state_(-1) {
+ const std::wstring& expected_value)
+ : name_(expected_name),
+ role_(expected_role),
+ ia2_role_(expected_ia2_role),
+ value_(expected_value),
+ state_(-1) {
}
-AccessibleChecker::AccessibleChecker(wstring expected_name,
- wstring expected_role,
+AccessibleChecker::AccessibleChecker(const std::wstring& expected_name,
+ const std::wstring& expected_role,
int32 expected_ia2_role,
- wstring expected_value) :
- name_(expected_name),
- role_(expected_role.c_str()),
- ia2_role_(expected_ia2_role),
- value_(expected_value),
- state_(-1) {
+ const std::wstring& expected_value)
+ : name_(expected_name),
+ role_(expected_role.c_str()),
+ ia2_role_(expected_ia2_role),
+ value_(expected_value),
+ state_(-1) {
}
void AccessibleChecker::AppendExpectedChild(
@@ -294,9 +299,7 @@
}
void AccessibleChecker::CheckAccessible(IAccessible* accessible) {
- SCOPED_TRACE(base::StringPrintf(
- "while checking %s",
- UTF16ToUTF8(RoleVariantToString(&role_)).c_str()));
+ SCOPED_TRACE("while checking " + UTF16ToUTF8(RoleVariantToString(role_)));
CheckAccessibleName(accessible);
CheckAccessibleRole(accessible);
CheckIA2Role(accessible);
@@ -305,7 +308,7 @@
CheckAccessibleChildren(accessible);
}
-void AccessibleChecker::SetExpectedValue(wstring expected_value) {
+void AccessibleChecker::SetExpectedValue(const std::wstring& expected_value) {
value_ = expected_value;
}
@@ -314,31 +317,28 @@
}
void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) {
- CComBSTR name;
- HRESULT hr =
- accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
+ base::win::ScopedBstr name;
+ base::win::ScopedVariant childid_self(CHILDID_SELF);
+ HRESULT hr = accessible->get_accName(childid_self, name.Receive());
if (name_.empty()) {
// If the object doesn't have name S_FALSE should be returned.
- EXPECT_EQ(hr, S_FALSE);
+ EXPECT_EQ(S_FALSE, hr);
} else {
// Test that the correct string was returned.
EXPECT_EQ(S_OK, hr);
- EXPECT_STREQ(name_.c_str(),
- wstring(name.m_str, SysStringLen(name)).c_str());
+ EXPECT_EQ(name_, std::wstring(name, name.Length()));
}
}
void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) {
- VARIANT var_role = {0};
- HRESULT hr =
- accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role);
+ base::win::ScopedVariant role;
+ base::win::ScopedVariant childid_self(CHILDID_SELF);
+ HRESULT hr = accessible->get_accRole(childid_self, role.Receive());
ASSERT_EQ(S_OK, hr);
- EXPECT_EQ(role_, var_role);
- if (role_ != var_role) {
- LOG(ERROR) << "Expected role: " << RoleVariantToString(&role_);
- LOG(ERROR) << "Got role: " << RoleVariantToString(&var_role);
- }
+ EXPECT_EQ(0, role_.Compare(role))
+ << "Expected role: " << RoleVariantToString(role_)
+ << "\nGot role: " << RoleVariantToString(role);
}
void AccessibleChecker::CheckIA2Role(IAccessible* accessible) {
@@ -348,54 +348,48 @@
long ia2_role = 0;
hr = accessible2->role(&ia2_role);
ASSERT_EQ(S_OK, hr);
- EXPECT_EQ(ia2_role_, ia2_role);
- if (ia2_role_ != ia2_role) {
- LOG(ERROR) << "Expected ia2 role: " <<
- IAccessible2RoleToString(ia2_role_);
- LOG(ERROR) << "Got ia2 role: " <<
- IAccessible2RoleToString(ia2_role);
- }
+ EXPECT_EQ(ia2_role_, ia2_role)
+ << "Expected ia2 role: " << IAccessible2RoleToString(ia2_role_)
+ << "\nGot ia2 role: " << IAccessible2RoleToString(ia2_role);
}
void AccessibleChecker::CheckAccessibleValue(IAccessible* accessible) {
// Don't check the value if if's a DOCUMENT role, because the value
// is supposed to be the url (and we don't keep track of that in the
// test expectations).
- VARIANT var_role = {0};
- HRESULT hr =
- accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role);
+ base::win::ScopedVariant role;
+ base::win::ScopedVariant childid_self(CHILDID_SELF);
+ HRESULT hr = accessible->get_accRole(childid_self, role.Receive());
ASSERT_EQ(S_OK, hr);
- if (V_VT(&var_role) == VT_I4 &&
- V_I4(&var_role) == ROLE_SYSTEM_DOCUMENT) {
+ if (role.type() == VT_I4 && V_I4(&role) == ROLE_SYSTEM_DOCUMENT)
return;
- }
// Get the value.
- CComBSTR value;
- hr = accessible->get_accValue(CreateI4Variant(CHILDID_SELF), &value);
+ base::win::ScopedBstr value;
+ hr = accessible->get_accValue(childid_self, value.Receive());
EXPECT_EQ(S_OK, hr);
// Test that the correct string was returned.
- EXPECT_STREQ(value_.c_str(),
- wstring(value.m_str, SysStringLen(value)).c_str());
+ EXPECT_EQ(value_, std::wstring(value, value.Length()));
}
void AccessibleChecker::CheckAccessibleState(IAccessible* accessible) {
if (state_ < 0)
return;
- VARIANT var_state = {0};
- HRESULT hr =
- accessible->get_accState(CreateI4Variant(CHILDID_SELF), &var_state);
+ base::win::ScopedVariant state;
+ base::win::ScopedVariant childid_self(CHILDID_SELF);
+ HRESULT hr = accessible->get_accState(childid_self, state.Receive());
EXPECT_EQ(S_OK, hr);
- ASSERT_EQ(VT_I4, V_VT(&var_state));
- EXPECT_EQ(state_, V_I4(&var_state));
- if (state_ != V_I4(&var_state)) {
- LOG(ERROR) << "Expected state: " <<
- IAccessibleStateToString(state_);
- LOG(ERROR) << "Got state: " <<
- IAccessibleStateToString(V_I4(&var_state));
- }
+ ASSERT_EQ(VT_I4, state.type());
+ LONG obj_state = V_I4(&state);
+ // Avoid flakiness. The "offscreen" state depends on whether the browser
+ // window is frontmost or not, and "hottracked" depends on whether the
+ // mouse cursor happens to be over the element.
+ obj_state &= ~(STATE_SYSTEM_OFFSCREEN | STATE_SYSTEM_HOTTRACKED);
+ EXPECT_EQ(state_, obj_state)
+ << "Expected state: " << IAccessibleStateToString(state_)
+ << "\nGot state: " << IAccessibleStateToString(obj_state);
}
void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
@@ -404,7 +398,7 @@
EXPECT_EQ(S_OK, hr);
ASSERT_EQ(child_count, children_.size());
- auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
+ scoped_ptr<VARIANT[]> child_array(new VARIANT[child_count]);
LONG obtained_count = 0;
hr = AccessibleChildren(parent, 0, child_count,
child_array.get(), &obtained_count);
@@ -415,28 +409,35 @@
for (AccessibleCheckerVector::iterator child_checker = children_.begin();
child_checker != children_.end();
++child_checker, ++child) {
- base::win::ScopedComPtr<IAccessible> child_accessible;
- child_accessible.Attach(GetAccessibleFromResultVariant(parent, child));
+ base::win::ScopedComPtr<IAccessible> child_accessible(
+ GetAccessibleFromResultVariant(parent, child));
ASSERT_TRUE(child_accessible.get());
(*child_checker)->CheckAccessible(child_accessible);
}
}
-string16 AccessibleChecker::RoleVariantToString(VARIANT* role_variant) {
- if (V_VT(role_variant) == VT_I4)
- return IAccessibleRoleToString(V_I4(role_variant));
- else if (V_VT(role_variant) == VT_BSTR)
- return string16(V_BSTR(role_variant), SysStringLen(V_BSTR(role_variant)));
+string16 AccessibleChecker::RoleVariantToString(
+ const base::win::ScopedVariant& role) {
+ if (role.type() == VT_I4)
+ return IAccessibleRoleToString(V_I4(&role));
+ if (role.type() == VT_BSTR)
+ return string16(V_BSTR(&role), SysStringLen(V_BSTR(&role)));
return string16();
}
+} // namespace
+
+
+// Tests ----------------------------------------------------------------------
+
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
MAYBE(TestBusyAccessibilityTree)) {
NavigateToURL(shell(), GURL(chrome::kAboutBlankURL));
// The initial accessible returned should have state STATE_SYSTEM_BUSY while
// the accessibility tree is being requested from the renderer.
- AccessibleChecker document1_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
+ AccessibleChecker document1_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
+ std::wstring());
document1_checker.SetExpectedState(
STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_FOCUSED |
STATE_SYSTEM_BUSY);
@@ -452,11 +453,14 @@
"</body></html>");
// Check the browser's copy of the renderer accessibility tree.
- AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON, L"");
- AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON, L"");
- AccessibleChecker body_checker(L"", L"body", IA2_ROLE_SECTION, L"");
- AccessibleChecker document2_checker(
- L"Accessibility Win Test", ROLE_SYSTEM_DOCUMENT, L"");
+ AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON,
+ std::wstring());
+ AccessibleChecker checkbox_checker(std::wstring(), ROLE_SYSTEM_CHECKBUTTON,
+ std::wstring());
+ AccessibleChecker body_checker(std::wstring(), L"body", IA2_ROLE_SECTION,
+ std::wstring());
+ AccessibleChecker document2_checker(L"Accessibility Win Test",
+ ROLE_SYSTEM_DOCUMENT, std::wstring());
body_checker.AppendExpectedChild(&button_checker);
body_checker.AppendExpectedChild(&checkbox_checker);
document2_checker.AppendExpectedChild(&body_checker);
@@ -477,8 +481,9 @@
// Verify that the IAccessible reference still points to a valid object and
// that calls to its methods fail since the tree is no longer valid after
// the page navagation.
- CComBSTR name;
- hr = document_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
+ base::win::ScopedBstr name;
+ base::win::ScopedVariant childid_self(CHILDID_SELF);
+ hr = document_accessible->get_accName(childid_self, name.Receive());
ASSERT_EQ(E_FAIL, hr);
}
@@ -490,15 +495,18 @@
"<li id='li'>li</li></ul>");
// Check the browser's copy of the renderer accessibility tree.
- AccessibleChecker list_marker_checker(L"\x2022", ROLE_SYSTEM_TEXT, L"");
- AccessibleChecker static_text_checker(L"li", ROLE_SYSTEM_TEXT, L"");
- AccessibleChecker list_item_checker(L"", ROLE_SYSTEM_LISTITEM, L"");
- list_item_checker.SetExpectedState(
- STATE_SYSTEM_READONLY);
+ AccessibleChecker list_marker_checker(L"\x2022", ROLE_SYSTEM_TEXT,
+ std::wstring());
+ AccessibleChecker static_text_checker(L"li", ROLE_SYSTEM_TEXT,
+ std::wstring());
+ AccessibleChecker list_item_checker(std::wstring(), ROLE_SYSTEM_LISTITEM,
+ std::wstring());
+ list_item_checker.SetExpectedState(STATE_SYSTEM_READONLY);
AccessibleChecker radio_group_checker(L"ul", ROLE_SYSTEM_GROUPING,
- IA2_ROLE_SECTION, L"");
+ IA2_ROLE_SECTION, std::wstring());
radio_group_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
- AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
+ AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
+ std::wstring());
list_item_checker.AppendExpectedChild(&list_marker_checker);
list_item_checker.AppendExpectedChild(&static_text_checker);
radio_group_checker.AppendExpectedChild(&list_item_checker);
@@ -541,10 +549,13 @@
"<body><input type='checkbox' /></body>");
// Check the browser's copy of the renderer accessibility tree.
- AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON, L"");
+ AccessibleChecker checkbox_checker(std::wstring(), ROLE_SYSTEM_CHECKBUTTON,
+ std::wstring());
checkbox_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
- AccessibleChecker body_checker(L"", L"body", IA2_ROLE_SECTION, L"");
- AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
+ AccessibleChecker body_checker(std::wstring(), L"body", IA2_ROLE_SECTION,
+ std::wstring());
+ AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
+ std::wstring());
body_checker.AppendExpectedChild(&checkbox_checker);
document_checker.AppendExpectedChild(&body_checker);
document_checker.CheckAccessible(GetRendererAccessible());
@@ -571,8 +582,10 @@
LoadInitialAccessibilityTreeFromHtml("<body role=group></body>");
// Check the browser's copy of the renderer accessibility tree.
- AccessibleChecker group_checker(L"", ROLE_SYSTEM_GROUPING, L"");
- AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
+ AccessibleChecker group_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
+ std::wstring());
+ AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
+ std::wstring());
document_checker.AppendExpectedChild(&group_checker);
document_checker.CheckAccessible(GetRendererAccessible());
@@ -587,7 +600,7 @@
loop_runner->Run();
// Check that the accessibility tree of the browser has been updated.
- AccessibleChecker text_checker(L"new text", ROLE_SYSTEM_TEXT, L"");
+ AccessibleChecker text_checker(L"new text", ROLE_SYSTEM_TEXT, std::wstring());
group_checker.AppendExpectedChild(&text_checker);
document_checker.CheckAccessible(GetRendererAccessible());
}
@@ -599,7 +612,8 @@
"<div role=group style='visibility: hidden'>text</div>");
// Check the accessible tree of the browser.
- AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
+ AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
+ std::wstring());
document_checker.CheckAccessible(GetRendererAccessible());
// Change the children of the document body.
@@ -613,8 +627,10 @@
loop_runner->Run();
// Check that the accessibility tree of the browser has been updated.
- AccessibleChecker static_text_checker(L"text", ROLE_SYSTEM_TEXT, L"");
- AccessibleChecker group_checker(L"", ROLE_SYSTEM_GROUPING, L"");
+ AccessibleChecker static_text_checker(L"text", ROLE_SYSTEM_TEXT,
+ std::wstring());
+ AccessibleChecker group_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
+ std::wstring());
document_checker.AppendExpectedChild(&group_checker);
group_checker.AppendExpectedChild(&static_text_checker);
document_checker.CheckAccessible(GetRendererAccessible());
@@ -627,10 +643,11 @@
// Check the browser's copy of the renderer accessibility tree.
SCOPED_TRACE("Check initial tree");
- AccessibleChecker group_checker(L"", ROLE_SYSTEM_GROUPING, L"");
- group_checker.SetExpectedState(
- STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_OFFSCREEN);
- AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
+ AccessibleChecker group_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
+ std::wstring());
+ group_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
+ AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
+ std::wstring());
document_checker.AppendExpectedChild(&group_checker);
document_checker.CheckAccessible(GetRendererAccessible());
@@ -657,8 +674,8 @@
base::win::ScopedComPtr<IAccessible> document_accessible(
GetRendererAccessible());
ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
- HRESULT hr = document_accessible->accSelect(
- SELFLAG_TAKEFOCUS, CreateI4Variant(CHILDID_SELF));
+ base::win::ScopedVariant childid_self(CHILDID_SELF);
+ HRESULT hr = document_accessible->accSelect(SELFLAG_TAKEFOCUS, childid_self);
ASSERT_EQ(S_OK, hr);
loop_runner->Run();
@@ -674,10 +691,13 @@
"<body><input type='text' value='old value'/></body>");
// Check the browser's copy of the renderer accessibility tree.
- AccessibleChecker text_field_checker(L"", ROLE_SYSTEM_TEXT, L"old value");
+ AccessibleChecker text_field_checker(std::wstring(), ROLE_SYSTEM_TEXT,
+ L"old value");
text_field_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
- AccessibleChecker body_checker(L"", L"body", IA2_ROLE_SECTION, L"");
- AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
+ AccessibleChecker body_checker(std::wstring(), L"body", IA2_ROLE_SECTION,
+ std::wstring());
+ AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
+ std::wstring());
body_checker.AppendExpectedChild(&text_field_checker);
document_checker.AppendExpectedChild(&body_checker);
document_checker.CheckAccessible(GetRendererAccessible());
@@ -732,15 +752,17 @@
DISABLED_TestToggleButtonRoleAndStates) {
AccessibleChecker* button_checker;
std::string button_html("data:text/html,");
- AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
- AccessibleChecker body_checker(L"", L"body", IA2_ROLE_SECTION, L"");
+ AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
+ std::wstring());
+ AccessibleChecker body_checker(std::wstring(), L"body", IA2_ROLE_SECTION,
+ std::wstring());
document_checker.AppendExpectedChild(&body_checker);
// Temporary macro
#define ADD_BUTTON(html, ia2_role, state) \
button_html += html; \
button_checker = new AccessibleChecker(L"x", ROLE_SYSTEM_PUSHBUTTON, \
- ia2_role, L""); \
+ ia2_role, std::wstring()); \
button_checker->SetExpectedState(state); \
body_checker.AppendExpectedChild(button_checker)
@@ -823,40 +845,44 @@
reinterpret_cast<void**>(document_isimpledomnode.Receive()));
ASSERT_EQ(S_OK, hr);
- BSTR node_name;
+ base::win::ScopedBstr node_name;
short name_space_id; // NOLINT
- BSTR node_value;
+ base::win::ScopedBstr node_value;
unsigned int num_children;
unsigned int unique_id;
unsigned short node_type; // NOLINT
hr = document_isimpledomnode->get_nodeInfo(
- &node_name, &name_space_id, &node_value, &num_children, &unique_id,
- &node_type);
+ node_name.Receive(), &name_space_id, node_value.Receive(), &num_children,
+ &unique_id, &node_type);
ASSERT_EQ(S_OK, hr);
EXPECT_EQ(NODETYPE_DOCUMENT, node_type);
EXPECT_EQ(1, num_children);
+ node_name.Reset();
+ node_value.Reset();
base::win::ScopedComPtr<ISimpleDOMNode> body_isimpledomnode;
hr = document_isimpledomnode->get_firstChild(
body_isimpledomnode.Receive());
ASSERT_EQ(S_OK, hr);
hr = body_isimpledomnode->get_nodeInfo(
- &node_name, &name_space_id, &node_value, &num_children, &unique_id,
- &node_type);
+ node_name.Receive(), &name_space_id, node_value.Receive(), &num_children,
+ &unique_id, &node_type);
ASSERT_EQ(S_OK, hr);
- EXPECT_STREQ(L"body", wstring(node_name, SysStringLen(node_name)).c_str());
+ EXPECT_EQ(L"body", std::wstring(node_name, node_name.Length()));
EXPECT_EQ(NODETYPE_ELEMENT, node_type);
EXPECT_EQ(1, num_children);
+ node_name.Reset();
+ node_value.Reset();
base::win::ScopedComPtr<ISimpleDOMNode> checkbox_isimpledomnode;
hr = body_isimpledomnode->get_firstChild(
checkbox_isimpledomnode.Receive());
ASSERT_EQ(S_OK, hr);
hr = checkbox_isimpledomnode->get_nodeInfo(
- &node_name, &name_space_id, &node_value, &num_children, &unique_id,
- &node_type);
+ node_name.Receive(), &name_space_id, node_value.Receive(), &num_children,
+ &unique_id, &node_type);
ASSERT_EQ(S_OK, hr);
- EXPECT_STREQ(L"input", wstring(node_name, SysStringLen(node_name)).c_str());
+ EXPECT_EQ(L"input", std::wstring(node_name, node_name.Length()));
EXPECT_EQ(NODETYPE_ELEMENT, node_type);
EXPECT_EQ(0, num_children);
}
@@ -866,13 +892,15 @@
"<fieldset></fieldset><div role=group></div>");
// Check the browser's copy of the renderer accessibility tree.
- AccessibleChecker grouping1_checker(L"", ROLE_SYSTEM_GROUPING, L"");
- AccessibleChecker grouping2_checker(L"", ROLE_SYSTEM_GROUPING, L"");
- AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT, L"");
+ AccessibleChecker grouping1_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
+ std::wstring());
+ AccessibleChecker grouping2_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
+ std::wstring());
+ AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
+ std::wstring());
document_checker.AppendExpectedChild(&grouping1_checker);
document_checker.AppendExpectedChild(&grouping2_checker);
document_checker.CheckAccessible(GetRendererAccessible());
}
-} // namespace.
} // namespace content
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index 2c4b078..fcfd365 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -31,7 +31,6 @@
BrowserAccessibility::BrowserAccessibility()
: manager_(NULL),
parent_(NULL),
- child_id_(0),
index_in_parent_(0),
renderer_id_(0),
role_(0),
@@ -54,12 +53,10 @@
void BrowserAccessibility::InitializeTreeStructure(
BrowserAccessibilityManager* manager,
BrowserAccessibility* parent,
- int32 child_id,
int32 renderer_id,
int32 index_in_parent) {
manager_ = manager;
parent_ = parent;
- child_id_ = child_id;
renderer_id_ = renderer_id;
index_in_parent_ = index_in_parent;
}
@@ -100,6 +97,10 @@
index_in_parent_ = index_in_parent;
}
+void BrowserAccessibility::SetLocation(const gfx::Rect& new_location) {
+ location_ = new_location;
+}
+
bool BrowserAccessibility::IsDescendantOf(
BrowserAccessibility* ancestor) {
if (this == ancestor) {
@@ -205,7 +206,7 @@
AccessibilityNotificationObjectHide, this);
instance_active_ = false;
- manager_->Remove(this);
+ manager_->RemoveNode(this);
NativeReleaseReference();
}
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h
index 62fff55..d70124a 100644
--- a/content/browser/accessibility/browser_accessibility.h
+++ b/content/browser/accessibility/browser_accessibility.h
@@ -70,7 +70,6 @@
void InitializeTreeStructure(
BrowserAccessibilityManager* manager,
BrowserAccessibility* parent,
- int32 child_id,
int32 renderer_id,
int32 index_in_parent);
@@ -82,6 +81,9 @@
// Update the parent and index in parent if this node has been moved.
void UpdateParent(BrowserAccessibility* parent, int index_in_parent);
+ // Update this node's location, leaving everything else the same.
+ virtual void SetLocation(const gfx::Rect& new_location);
+
// Return true if this object is equal to or a descendant of |ancestor|.
bool IsDescendantOf(BrowserAccessibility* ancestor);
@@ -150,7 +152,6 @@
return string_attributes_;
}
- int32 child_id() const { return child_id_; }
const std::vector<BrowserAccessibility*>& children() const {
return children_;
}
@@ -253,9 +254,6 @@
// The parent of this object, may be NULL if we're the root object.
BrowserAccessibility* parent_;
- // The ID of this object; globally unique within the browser process.
- int32 child_id_;
-
// The index of this within its parent object.
int32 index_in_parent_;
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.h b/content/browser/accessibility/browser_accessibility_cocoa.h
index 9733e0c..0d401a0 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.h
+++ b/content/browser/accessibility/browser_accessibility_cocoa.h
@@ -52,6 +52,8 @@
@property(nonatomic, readonly) NSString* ariaRelevant;
@property(nonatomic, readonly) NSArray* children;
@property(nonatomic, readonly) NSArray* columns;
+@property(nonatomic, readonly) NSArray* columnHeaders;
+@property(nonatomic, readonly) NSValue* columnIndexRange;
@property(nonatomic, readonly) NSString* description;
@property(nonatomic, readonly) NSNumber* disclosing;
@property(nonatomic, readonly) id disclosedByRow;
@@ -63,6 +65,8 @@
// isIgnored returns whether or not the accessibility object
// should be ignored by the accessibility hierarchy.
@property(nonatomic, readonly, getter=isIgnored) BOOL ignored;
+// Index of a row, column, or tree item.
+@property(nonatomic, readonly) NSNumber* index;
@property(nonatomic, readonly) NSString* invalid;
@property(nonatomic, readonly) NSNumber* loaded;
@property(nonatomic, readonly) NSNumber* loadingProgress;
@@ -77,6 +81,8 @@
// is concerned.
@property(nonatomic, readonly) NSString* role;
@property(nonatomic, readonly) NSString* roleDescription;
+@property(nonatomic, readonly) NSArray* rowHeaders;
+@property(nonatomic, readonly) NSValue* rowIndexRange;
@property(nonatomic, readonly) NSArray* rows;
// The size of this object.
@property(nonatomic, readonly) NSValue* size;
@@ -91,6 +97,9 @@
@property(nonatomic, readonly) NSString* value;
@property(nonatomic, readonly) NSString* valueDescription;
@property(nonatomic, readonly) NSValue* visibleCharacterRange;
+@property(nonatomic, readonly) NSArray* visibleCells;
+@property(nonatomic, readonly) NSArray* visibleColumns;
+@property(nonatomic, readonly) NSArray* visibleRows;
@property(nonatomic, readonly) NSNumber* visited;
@property(nonatomic, readonly) id window;
@end
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
index e4d695a..f53cb5a 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -10,7 +10,7 @@
#include "base/basictypes.h"
#include "base/string16.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/browser_accessibility_manager_mac.h"
@@ -275,6 +275,9 @@
} attributeToMethodNameContainer[] = {
{ NSAccessibilityChildrenAttribute, @"children" },
{ NSAccessibilityColumnsAttribute, @"columns" },
+ { NSAccessibilityColumnHeaderUIElementsAttribute, @"columnHeaders" },
+ { NSAccessibilityColumnIndexRangeAttribute, @"columnIndexRange" },
+ { NSAccessibilityContentsAttribute, @"contents" },
{ NSAccessibilityDescriptionAttribute, @"description" },
{ NSAccessibilityDisclosingAttribute, @"disclosing" },
{ NSAccessibilityDisclosedByRowAttribute, @"disclosedByRow" },
@@ -282,7 +285,9 @@
{ NSAccessibilityDisclosedRowsAttribute, @"disclosedRows" },
{ NSAccessibilityEnabledAttribute, @"enabled" },
{ NSAccessibilityFocusedAttribute, @"focused" },
+ { NSAccessibilityHeaderAttribute, @"header" },
{ NSAccessibilityHelpAttribute, @"help" },
+ { NSAccessibilityIndexAttribute, @"index" },
{ NSAccessibilityMaxValueAttribute, @"maxValue" },
{ NSAccessibilityMinValueAttribute, @"minValue" },
{ NSAccessibilityNumberOfCharactersAttribute, @"numberOfCharacters" },
@@ -291,6 +296,8 @@
{ NSAccessibilityPositionAttribute, @"position" },
{ NSAccessibilityRoleAttribute, @"role" },
{ NSAccessibilityRoleDescriptionAttribute, @"roleDescription" },
+ { NSAccessibilityRowHeaderUIElementsAttribute, @"rowHeaders" },
+ { NSAccessibilityRowIndexRangeAttribute, @"rowIndexRange" },
{ NSAccessibilityRowsAttribute, @"rows" },
{ NSAccessibilitySizeAttribute, @"size" },
{ NSAccessibilitySubroleAttribute, @"subrole" },
@@ -302,6 +309,9 @@
{ NSAccessibilityValueAttribute, @"value" },
{ NSAccessibilityValueDescriptionAttribute, @"valueDescription" },
{ NSAccessibilityVisibleCharacterRangeAttribute, @"visibleCharacterRange" },
+ { NSAccessibilityVisibleCellsAttribute, @"visibleCells" },
+ { NSAccessibilityVisibleColumnsAttribute, @"visibleColumns" },
+ { NSAccessibilityVisibleRowsAttribute, @"visibleRows" },
{ NSAccessibilityWindowAttribute, @"window" },
{ @"AXAccessKey", @"accessKey" },
{ @"AXARIAAtomic", @"ariaAtomic" },
@@ -381,7 +391,7 @@
// Returns an array of BrowserAccessibilityCocoa objects, representing the
// accessibility children of this object.
- (NSArray*)children {
- if (!children_.get()) {
+ if (!children_) {
children_.reset([[NSMutableArray alloc]
initWithCapacity:browserAccessibility_->child_count()] );
for (uint32 index = 0;
@@ -424,6 +434,40 @@
}
}
+- (NSArray*)columnHeaders {
+ if ([self internalRole] != AccessibilityNodeData::ROLE_TABLE &&
+ [self internalRole] != AccessibilityNodeData::ROLE_GRID) {
+ return nil;
+ }
+
+ NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
+ const std::vector<int32>& uniqueCellIds =
+ browserAccessibility_->unique_cell_ids();
+ for (size_t i = 0; i < uniqueCellIds.size(); ++i) {
+ int id = uniqueCellIds[i];
+ BrowserAccessibility* cell =
+ browserAccessibility_->manager()->GetFromRendererID(id);
+ if (cell && cell->role() == AccessibilityNodeData::ROLE_COLUMN_HEADER)
+ [ret addObject:cell->ToBrowserAccessibilityCocoa()];
+ }
+ return ret;
+}
+
+- (NSValue*)columnIndexRange {
+ if ([self internalRole] != AccessibilityNodeData::ROLE_CELL)
+ return nil;
+
+ int column = -1;
+ int colspan = -1;
+ browserAccessibility_->GetIntAttribute(
+ AccessibilityNodeData::ATTR_TABLE_CELL_COLUMN_INDEX, &column);
+ browserAccessibility_->GetIntAttribute(
+ AccessibilityNodeData::ATTR_TABLE_CELL_COLUMN_SPAN, &colspan);
+ if (column >= 0 && colspan >= 1)
+ return [NSValue valueWithRange:NSMakeRange(column, colspan)];
+ return nil;
+}
+
- (NSArray*)columns {
NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
for (BrowserAccessibilityCocoa* child in [self children]) {
@@ -517,12 +561,53 @@
return ret;
}
+- (id)header {
+ int headerElementId = -1;
+ if ([self internalRole] == AccessibilityNodeData::ROLE_TABLE ||
+ [self internalRole] == AccessibilityNodeData::ROLE_GRID) {
+ browserAccessibility_->GetIntAttribute(
+ AccessibilityNodeData::ATTR_TABLE_HEADER_ID, &headerElementId);
+ } else if ([self internalRole] == AccessibilityNodeData::ROLE_COLUMN) {
+ browserAccessibility_->GetIntAttribute(
+ AccessibilityNodeData::ATTR_TABLE_COLUMN_HEADER_ID, &headerElementId);
+ } else if ([self internalRole] == AccessibilityNodeData::ROLE_ROW) {
+ browserAccessibility_->GetIntAttribute(
+ AccessibilityNodeData::ATTR_TABLE_ROW_HEADER_ID, &headerElementId);
+ }
+
+ if (headerElementId > 0) {
+ BrowserAccessibility* headerObject =
+ browserAccessibility_->manager()->GetFromRendererID(headerElementId);
+ if (headerObject)
+ return headerObject->ToBrowserAccessibilityCocoa();
+ }
+ return nil;
+}
+
- (NSString*)help {
return NSStringForStringAttribute(
browserAccessibility_->string_attributes(),
AccessibilityNodeData::ATTR_HELP);
}
+- (NSNumber*)index {
+ if ([self internalRole] == AccessibilityNodeData::ROLE_COLUMN) {
+ int columnIndex;
+ if (browserAccessibility_->GetIntAttribute(
+ AccessibilityNodeData::ATTR_TABLE_COLUMN_INDEX, &columnIndex)) {
+ return [NSNumber numberWithInt:columnIndex];
+ }
+ } else if ([self internalRole] == AccessibilityNodeData::ROLE_ROW) {
+ int rowIndex;
+ if (browserAccessibility_->GetIntAttribute(
+ AccessibilityNodeData::ATTR_TABLE_ROW_INDEX, &rowIndex)) {
+ return [NSNumber numberWithInt:rowIndex];
+ }
+ }
+
+ return nil;
+}
+
// Returns whether or not this node should be ignored in the
// accessibility tree.
- (BOOL)isIgnored {
@@ -679,11 +764,59 @@
return NSAccessibilityRoleDescription(role, nil);
}
+- (NSArray*)rowHeaders {
+ if ([self internalRole] != AccessibilityNodeData::ROLE_TABLE &&
+ [self internalRole] != AccessibilityNodeData::ROLE_GRID) {
+ return nil;
+ }
+
+ NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
+ const std::vector<int32>& uniqueCellIds =
+ browserAccessibility_->unique_cell_ids();
+ for (size_t i = 0; i < uniqueCellIds.size(); ++i) {
+ int id = uniqueCellIds[i];
+ BrowserAccessibility* cell =
+ browserAccessibility_->manager()->GetFromRendererID(id);
+ if (cell && cell->role() == AccessibilityNodeData::ROLE_ROW_HEADER)
+ [ret addObject:cell->ToBrowserAccessibilityCocoa()];
+ }
+ return ret;
+}
+
+- (NSValue*)rowIndexRange {
+ if ([self internalRole] != AccessibilityNodeData::ROLE_CELL)
+ return nil;
+
+ int row = -1;
+ int rowspan = -1;
+ browserAccessibility_->GetIntAttribute(
+ AccessibilityNodeData::ATTR_TABLE_CELL_ROW_INDEX, &row);
+ browserAccessibility_->GetIntAttribute(
+ AccessibilityNodeData::ATTR_TABLE_CELL_ROW_SPAN, &rowspan);
+ if (row >= 0 && rowspan >= 1)
+ return [NSValue valueWithRange:NSMakeRange(row, rowspan)];
+ return nil;
+}
+
- (NSArray*)rows {
NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
- for (BrowserAccessibilityCocoa* child in [self children]) {
- if ([[child role] isEqualToString:NSAccessibilityRowRole])
- [ret addObject:child];
+
+ if ([self internalRole] == AccessibilityNodeData::ROLE_TABLE||
+ [self internalRole] == AccessibilityNodeData::ROLE_GRID) {
+ for (BrowserAccessibilityCocoa* child in [self children]) {
+ if ([[child role] isEqualToString:NSAccessibilityRowRole])
+ [ret addObject:child];
+ }
+ } else if ([self internalRole] == AccessibilityNodeData::ROLE_COLUMN) {
+ const std::vector<int32>& indirectChildIds =
+ browserAccessibility_->indirect_child_ids();
+ for (uint32 i = 0; i < indirectChildIds.size(); ++i) {
+ int id = indirectChildIds[i];
+ BrowserAccessibility* rowElement =
+ browserAccessibility_->manager()->GetFromRendererID(id);
+ if (rowElement)
+ [ret addObject:rowElement->ToBrowserAccessibilityCocoa()];
+ }
}
return ret;
@@ -827,6 +960,28 @@
NSMakeRange(0, browserAccessibility_->value().length())];
}
+- (NSArray*)visibleCells {
+ NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
+ const std::vector<int32>& uniqueCellIds =
+ browserAccessibility_->unique_cell_ids();
+ for (size_t i = 0; i < uniqueCellIds.size(); ++i) {
+ int id = uniqueCellIds[i];
+ BrowserAccessibility* cell =
+ browserAccessibility_->manager()->GetFromRendererID(id);
+ if (cell)
+ [ret addObject:cell->ToBrowserAccessibilityCocoa()];
+ }
+ return ret;
+}
+
+- (NSArray*)visibleColumns {
+ return [self columns];
+}
+
+- (NSArray*)visibleRows {
+ return [self rows];
+}
+
- (NSNumber*)visited {
return [NSNumber numberWithBool:
GetState(browserAccessibility_, AccessibilityNodeData::STATE_TRAVERSED)];
@@ -914,6 +1069,63 @@
NSMakeRange(start, end - start)];
}
+ if ([attribute isEqualToString:
+ NSAccessibilityCellForColumnAndRowParameterizedAttribute]) {
+ if ([self internalRole] != AccessibilityNodeData::ROLE_TABLE &&
+ [self internalRole] != AccessibilityNodeData::ROLE_GRID) {
+ return nil;
+ }
+ if (![parameter isKindOfClass:[NSArray self]])
+ return nil;
+ NSArray* array = parameter;
+ int column = [[array objectAtIndex:0] intValue];
+ int row = [[array objectAtIndex:1] intValue];
+ int num_columns = 0;
+ int num_rows = 0;
+ browserAccessibility_->GetIntAttribute(
+ AccessibilityNodeData::ATTR_TABLE_COLUMN_COUNT, &num_columns);
+ browserAccessibility_->GetIntAttribute(
+ AccessibilityNodeData::ATTR_TABLE_ROW_COUNT, &num_rows);
+ if (column < 0 || column >= num_columns ||
+ row < 0 || row >= num_rows) {
+ return nil;
+ }
+ for (size_t i = 0;
+ i < browserAccessibility_->child_count();
+ ++i) {
+ BrowserAccessibility* child = browserAccessibility_->GetChild(i);
+ if (child->role() != AccessibilityNodeData::ROLE_ROW)
+ continue;
+ int rowIndex;
+ if (!child->GetIntAttribute(
+ AccessibilityNodeData::ATTR_TABLE_ROW_INDEX, &rowIndex)) {
+ continue;
+ }
+ if (rowIndex < row)
+ continue;
+ if (rowIndex > row)
+ break;
+ for (size_t j = 0;
+ j < child->child_count();
+ ++j) {
+ BrowserAccessibility* cell = child->GetChild(j);
+ if (cell->role() != AccessibilityNodeData::ROLE_CELL)
+ continue;
+ int colIndex;
+ if (!cell->GetIntAttribute(
+ AccessibilityNodeData::ATTR_TABLE_CELL_COLUMN_INDEX,
+ &colIndex)) {
+ continue;
+ }
+ if (colIndex == column)
+ return cell->ToBrowserAccessibilityCocoa();
+ if (colIndex > column)
+ break;
+ }
+ }
+ return nil;
+ }
+
// TODO(dtseng): support the following attributes.
if ([attribute isEqualTo:
NSAccessibilityRangeForPositionParameterizedAttribute] ||
@@ -932,6 +1144,12 @@
// Returns an array of parameterized attributes names that this object will
// respond to.
- (NSArray*)accessibilityParameterizedAttributeNames {
+ if ([[self role] isEqualToString:NSAccessibilityTableRole] ||
+ [[self role] isEqualToString:NSAccessibilityGridRole]) {
+ return [NSArray arrayWithObjects:
+ NSAccessibilityCellForColumnAndRowParameterizedAttribute,
+ nil];
+ }
if ([[self role] isEqualToString:NSAccessibilityTextFieldRole] ||
[[self role] isEqualToString:NSAccessibilityTextAreaRole]) {
return [NSArray arrayWithObjects:
@@ -1023,10 +1241,29 @@
// Specific role attributes.
NSString* role = [self role];
NSString* subrole = [self subrole];
- if ([role isEqualToString:NSAccessibilityTableRole]) {
+ if ([role isEqualToString:NSAccessibilityTableRole] ||
+ [role isEqualToString:NSAccessibilityGridRole]) {
[ret addObjectsFromArray:[NSArray arrayWithObjects:
NSAccessibilityColumnsAttribute,
+ NSAccessibilityVisibleColumnsAttribute,
NSAccessibilityRowsAttribute,
+ NSAccessibilityVisibleRowsAttribute,
+ NSAccessibilityVisibleCellsAttribute,
+ NSAccessibilityHeaderAttribute,
+ NSAccessibilityColumnHeaderUIElementsAttribute,
+ NSAccessibilityRowHeaderUIElementsAttribute,
+ nil]];
+ } else if ([role isEqualToString:NSAccessibilityColumnRole]) {
+ [ret addObjectsFromArray:[NSArray arrayWithObjects:
+ NSAccessibilityIndexAttribute,
+ NSAccessibilityHeaderAttribute,
+ NSAccessibilityRowsAttribute,
+ NSAccessibilityVisibleRowsAttribute,
+ nil]];
+ } else if ([role isEqualToString:NSAccessibilityCellRole]) {
+ [ret addObjectsFromArray:[NSArray arrayWithObjects:
+ NSAccessibilityColumnIndexRangeAttribute,
+ NSAccessibilityRowIndexRangeAttribute,
nil]];
} else if ([role isEqualToString:@"AXWebArea"]) {
[ret addObjectsFromArray:[NSArray arrayWithObjects:
@@ -1073,11 +1310,14 @@
NSAccessibilityDisclosureLevelAttribute,
NSAccessibilityDisclosedRowsAttribute,
nil]];
+ } else {
+ [ret addObjectsFromArray:[NSArray arrayWithObjects:
+ NSAccessibilityIndexAttribute,
+ nil]];
}
}
}
-
// Live regions.
string16 s;
if (browserAccessibility_->GetStringAttribute(
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index ca02fa5..498d853 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -15,13 +15,6 @@
return BrowserAccessibility::Create();
}
-// Start child IDs at -1 and decrement each time, because clients use
-// child IDs of 1, 2, 3, ... to access the children of an object by
-// index, so we use negative IDs to clearly distinguish between indices
-// and unique IDs.
-// static
-int32 BrowserAccessibilityManager::next_child_id_ = -1;
-
#if !defined(OS_MACOSX) && \
!defined(OS_WIN) && \
!defined(TOOLKIT_GTK)
@@ -53,19 +46,6 @@
SetFocus(root_, false);
}
-// static
-int32 BrowserAccessibilityManager::GetNextChildID() {
- // Get the next child ID, and wrap around when we get near the end
- // of a 32-bit integer range. It's okay to wrap around; we just want
- // to avoid it as long as possible because clients may cache the ID of
- // an object for a while to determine if they've seen it before.
- next_child_id_--;
- if (next_child_id_ == -2000000000)
- next_child_id_ = -1;
-
- return next_child_id_;
-}
-
BrowserAccessibilityManager::~BrowserAccessibilityManager() {
if (root_)
root_->Destroy();
@@ -75,26 +55,13 @@
return root_;
}
-BrowserAccessibility* BrowserAccessibilityManager::GetFromChildID(
- int32 child_id) {
- base::hash_map<int32, BrowserAccessibility*>::iterator iter =
- child_id_map_.find(child_id);
- if (iter != child_id_map_.end()) {
- return iter->second;
- } else {
- return NULL;
- }
-}
-
BrowserAccessibility* BrowserAccessibilityManager::GetFromRendererID(
int32 renderer_id) {
- base::hash_map<int32, int32>::iterator iter =
- renderer_id_to_child_id_map_.find(renderer_id);
- if (iter == renderer_id_to_child_id_map_.end())
- return NULL;
-
- int32 child_id = iter->second;
- return GetFromChildID(child_id);
+ base::hash_map<int32, BrowserAccessibility*>::iterator iter =
+ renderer_id_map_.find(renderer_id);
+ if (iter != renderer_id_map_.end())
+ return iter->second;
+ return NULL;
}
void BrowserAccessibilityManager::GotFocus(bool touch_event_context) {
@@ -124,17 +91,11 @@
return bounds.Contains(touch_point);
}
-void BrowserAccessibilityManager::Remove(BrowserAccessibility* node) {
+void BrowserAccessibilityManager::RemoveNode(BrowserAccessibility* node) {
if (node == focus_)
SetFocus(root_, false);
- int child_id = node->child_id();
int renderer_id = node->renderer_id();
- child_id_map_.erase(child_id);
- DCHECK(renderer_id_to_child_id_map_[renderer_id] == child_id);
- // Make sure we don't overwrite a newer entry (see UpdateNode for a possible
- // corner case).
- if (renderer_id_to_child_id_map_[renderer_id] == child_id)
- renderer_id_to_child_id_map_.erase(renderer_id);
+ renderer_id_map_.erase(renderer_id);
}
void BrowserAccessibilityManager::OnAccessibilityNotifications(
@@ -269,12 +230,30 @@
// In a second pass, call PostInitialize on each one - this must
// be called after all of each node's children are initialized too.
for (size_t i = 0; i < nodes.size() && success; i++) {
+ // Note: it's not a bug for nodes[i].id to not be found in the tree.
+ // Consider this example:
+ // Before:
+ // A
+ // B
+ // C
+ // D
+ // E
+ // F
+ // After:
+ // A
+ // B
+ // C
+ // F
+ // D
+ // In this example, F is being reparented. The renderer scans the tree
+ // in order. If can't update "C" to add "F" as a child, when "F" is still
+ // a child of "E". So it first updates "E", to remove "F" as a child.
+ // Later, it ends up deleting "E". So when we get here, "E" was updated as
+ // part of this sequence but it no longer exists in the final tree, so
+ // there's nothing to postinitialize.
BrowserAccessibility* instance = GetFromRendererID(nodes[i].id);
- if (instance) {
+ if (instance)
instance->PostInitialize();
- } else {
- success = false;
- }
}
if (!success) {
@@ -294,13 +273,15 @@
BrowserAccessibility* parent,
int32 renderer_id,
int32 index_in_parent) {
- BrowserAccessibility* instance = factory_->Create();
- int32 child_id = GetNextChildID();
- instance->InitializeTreeStructure(
- this, parent, child_id, renderer_id, index_in_parent);
- child_id_map_[child_id] = instance;
- renderer_id_to_child_id_map_[renderer_id] = child_id;
- return instance;
+ BrowserAccessibility* node = factory_->Create();
+ node->InitializeTreeStructure(
+ this, parent, renderer_id, index_in_parent);
+ AddNodeToMap(node);
+ return node;
+}
+
+void BrowserAccessibilityManager::AddNodeToMap(BrowserAccessibility* node) {
+ renderer_id_map_[node->renderer_id()] = node;
}
bool BrowserAccessibilityManager::UpdateNode(const AccessibilityNodeData& src) {
@@ -326,6 +307,13 @@
instance = CreateNode(NULL, src.id, 0);
}
+ if (src.bool_attributes.find(
+ AccessibilityNodeData::ATTR_UPDATE_LOCATION_ONLY) !=
+ src.bool_attributes.end()) {
+ instance->SetLocation(src.location);
+ return true;
+ }
+
// Update all of the node-specific data, like its role, state, name, etc.
instance->InitializeData(src);
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h
index a9e7a64..ec1df1b 100644
--- a/content/browser/accessibility/browser_accessibility_manager.h
+++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -68,18 +68,11 @@
int type,
BrowserAccessibility* node) { }
- // Returns the next unique child id.
- static int32 GetNextChildID();
-
// Return a pointer to the root of the tree, does not make a new reference.
BrowserAccessibility* GetRoot();
// Removes a node from the manager.
- void Remove(BrowserAccessibility* node);
-
- // Return a pointer to the object corresponding to the given child_id,
- // does not make a new reference.
- BrowserAccessibility* GetFromChildID(int32 child_id);
+ virtual void RemoveNode(BrowserAccessibility* node);
// Return a pointer to the object corresponding to the given renderer_id,
// does not make a new reference.
@@ -163,6 +156,8 @@
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory);
+ virtual void AddNodeToMap(BrowserAccessibility* node);
+
private:
// The following states keep track of whether or not the
// on-screen keyboard is allowed to be shown.
@@ -200,9 +195,6 @@
int32 index_in_parent);
protected:
- // The next unique id for a BrowserAccessibility instance.
- static int32 next_child_id_;
-
// The object that can perform actions on our behalf.
BrowserAccessibilityDelegate* delegate_;
@@ -217,12 +209,8 @@
// The on-screen keyboard state.
OnScreenKeyboardState osk_state_;
- // A mapping from the IDs of objects in the renderer, to the child IDs
- // we use internally here.
- base::hash_map<int32, int32> renderer_id_to_child_id_map_;
-
- // A mapping from child IDs to BrowserAccessibility objects.
- base::hash_map<int32, BrowserAccessibility*> child_id_map_;
+ // A mapping from renderer IDs to BrowserAccessibility objects.
+ base::hash_map<int32, BrowserAccessibility*> renderer_id_map_;
DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManager);
};
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
index ba0dee5..33e4614 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -53,6 +53,22 @@
return empty_document;
}
+void BrowserAccessibilityManagerWin::AddNodeToMap(BrowserAccessibility* node) {
+ BrowserAccessibilityManager::AddNodeToMap(node);
+ LONG unique_id_win = node->ToBrowserAccessibilityWin()->unique_id_win();
+ unique_id_to_renderer_id_map_[unique_id_win] = node->renderer_id();
+}
+
+void BrowserAccessibilityManagerWin::RemoveNode(BrowserAccessibility* node) {
+ unique_id_to_renderer_id_map_.erase(
+ node->ToBrowserAccessibilityWin()->unique_id_win());
+ BrowserAccessibilityManager::RemoveNode(node);
+ if (node == tracked_scroll_object_) {
+ tracked_scroll_object_->Release();
+ tracked_scroll_object_ = NULL;
+ }
+}
+
void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
int type,
BrowserAccessibility* node) {
@@ -135,8 +151,14 @@
break;
}
+ // Pass the node's unique id in the |child_id| argument to NotifyWinEvent;
+ // the AT client will then call get_accChild on the HWND's accessibility
+ // object and pass it that same id, which we can use to retrieve the
+ // IAccessible for this node.
+ LONG child_id = node->ToBrowserAccessibilityWin()->unique_id_win();
+
if (event_id != EVENT_MIN)
- NotifyWinEvent(event_id, parent_hwnd(), OBJID_CLIENT, node->child_id());
+ NotifyWinEvent(event_id, parent_hwnd(), OBJID_CLIENT, child_id);
// If this is a layout complete notification (sent when a container scrolls)
// and there is a descendant tracked object, send a notification on it.
@@ -144,10 +166,11 @@
if (type == AccessibilityNotificationLayoutComplete &&
tracked_scroll_object_ &&
tracked_scroll_object_->IsDescendantOf(node)) {
- NotifyWinEvent(IA2_EVENT_VISIBLE_DATA_CHANGED,
- parent_hwnd(),
- OBJID_CLIENT,
- tracked_scroll_object_->child_id());
+ NotifyWinEvent(
+ IA2_EVENT_VISIBLE_DATA_CHANGED,
+ parent_hwnd(),
+ OBJID_CLIENT,
+ tracked_scroll_object_->ToBrowserAccessibilityWin()->unique_id_win());
tracked_scroll_object_->Release();
tracked_scroll_object_ = NULL;
}
@@ -161,4 +184,16 @@
tracked_scroll_object_->AddRef();
}
+BrowserAccessibilityWin* BrowserAccessibilityManagerWin::GetFromUniqueIdWin(
+ LONG unique_id_win) {
+ base::hash_map<LONG, int32>::iterator iter =
+ unique_id_to_renderer_id_map_.find(unique_id_win);
+ if (iter != unique_id_to_renderer_id_map_.end()) {
+ BrowserAccessibility* result = GetFromRendererID(iter->second);
+ if (result)
+ return result->ToBrowserAccessibilityWin();
+ }
+ return NULL;
+}
+
} // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.h b/content/browser/accessibility/browser_accessibility_manager_win.h
index 2eefae9..e82f065 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.h
+++ b/content/browser/accessibility/browser_accessibility_manager_win.h
@@ -38,13 +38,20 @@
}
// BrowserAccessibilityManager methods
- virtual void NotifyAccessibilityEvent(int type, BrowserAccessibility* node);
+ virtual void AddNodeToMap(BrowserAccessibility* node);
+ virtual void RemoveNode(BrowserAccessibility* node) OVERRIDE;
+ virtual void NotifyAccessibilityEvent(int type, BrowserAccessibility* node)
+ OVERRIDE;
// Track this object and post a VISIBLE_DATA_CHANGED notification when
// its container scrolls.
// TODO(dmazzoni): remove once http://crbug.com/113483 is fixed.
void TrackScrollingObject(BrowserAccessibilityWin* node);
+ // Return a pointer to the object corresponding to the given windows-specific
+ // unique id, does not make a new reference.
+ BrowserAccessibilityWin* GetFromUniqueIdWin(LONG unique_id_win);
+
private:
// The closest ancestor HWND.
HWND parent_hwnd_;
@@ -60,6 +67,10 @@
// TODO(dmazzoni): remove once http://crbug.com/113483 is fixed.
BrowserAccessibilityWin* tracked_scroll_object_;
+ // A mapping from the Windows-specific unique IDs (unique within the
+ // browser process) to renderer ids within this page.
+ base::hash_map<long, int32> unique_id_to_renderer_id_map_;
+
DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManagerWin);
};
diff --git a/content/browser/accessibility/browser_accessibility_state_impl.cc b/content/browser/accessibility/browser_accessibility_state_impl.cc
index 3cb73fe..92bc94e 100644
--- a/content/browser/accessibility/browser_accessibility_state_impl.cc
+++ b/content/browser/accessibility/browser_accessibility_state_impl.cc
@@ -7,7 +7,9 @@
#include "base/command_line.h"
#include "base/metrics/histogram.h"
#include "base/timer.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "ui/gfx/sys_color_change_listener.h"
@@ -80,11 +82,15 @@
SetAccessibilityMode(AccessibilityModeComplete);
}
-void BrowserAccessibilityStateImpl::OnAccessibilityEnabledManually() {
+void BrowserAccessibilityStateImpl::EnableAccessibility() {
// We may want to do something different with this later.
SetAccessibilityMode(AccessibilityModeComplete);
}
+void BrowserAccessibilityStateImpl::DisableAccessibility() {
+ SetAccessibilityMode(AccessibilityModeOff);
+}
+
bool BrowserAccessibilityStateImpl::IsAccessibleBrowser() {
return (accessibility_mode_ == AccessibilityModeComplete);
}
@@ -117,13 +123,33 @@
}
#endif
-AccessibilityMode BrowserAccessibilityStateImpl::GetAccessibilityMode() {
- return accessibility_mode_;
-}
-
void BrowserAccessibilityStateImpl::SetAccessibilityMode(
AccessibilityMode mode) {
+ if (accessibility_mode_ == mode)
+ return;
accessibility_mode_ = mode;
+ for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
+ !it.IsAtEnd(); it.Advance()) {
+ RenderProcessHost* render_process_host = it.GetCurrentValue();
+ DCHECK(render_process_host);
+
+ // Ignore processes that don't have a connection, such as crashed tabs.
+ if (!render_process_host->HasConnection())
+ continue;
+
+ for (RenderProcessHost::RenderWidgetHostsIterator rwit(
+ render_process_host->GetRenderWidgetHostsIterator());
+ !rwit.IsAtEnd();
+ rwit.Advance()) {
+ RenderWidgetHost* rwh = const_cast<RenderWidgetHost*>(
+ rwit.GetCurrentValue());
+ DCHECK(rwh);
+ if (!rwh || !rwh->IsRenderView())
+ continue;
+ RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(rwh);
+ rwhi->SetAccessibilityMode(mode);
+ }
+ }
}
} // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_state_impl.h b/content/browser/accessibility/browser_accessibility_state_impl.h
index 46621ea..3098341 100644
--- a/content/browser/accessibility/browser_accessibility_state_impl.h
+++ b/content/browser/accessibility/browser_accessibility_state_impl.h
@@ -40,14 +40,15 @@
static BrowserAccessibilityStateImpl* GetInstance();
- virtual void OnAccessibilityEnabledManually() OVERRIDE;
+ virtual void EnableAccessibility() OVERRIDE;
+ virtual void DisableAccessibility() OVERRIDE;
virtual void OnScreenReaderDetected() OVERRIDE;
virtual bool IsAccessibleBrowser() OVERRIDE;
virtual void AddHistogramCallback(base::Closure callback) OVERRIDE;
virtual void UpdateHistogramsForTesting() OVERRIDE;
- AccessibilityMode GetAccessibilityMode();
+ AccessibilityMode accessibility_mode() const { return accessibility_mode_; };
void SetAccessibilityMode(AccessibilityMode mode);
private:
diff --git a/content/browser/accessibility/browser_accessibility_state_impl_win.cc b/content/browser/accessibility/browser_accessibility_state_impl_win.cc
index 3290355..e968d99 100644
--- a/content/browser/accessibility/browser_accessibility_state_impl_win.cc
+++ b/content/browser/accessibility/browser_accessibility_state_impl_win.cc
@@ -42,7 +42,7 @@
if (!EnumProcessModules(process, modules, 0, &bytes_required))
return;
- scoped_array<char> buffer(new char[bytes_required]);
+ scoped_ptr<char[]> buffer(new char[bytes_required]);
modules = reinterpret_cast<HMODULE*>(buffer.get());
DWORD ignore;
if (!EnumProcessModules(process, modules, bytes_required, &ignore))
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc
index a7b8843..7f5bc01 100644
--- a/content/browser/accessibility/browser_accessibility_win.cc
+++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -15,7 +15,9 @@
#include "base/win/windows_version.h"
#include "content/browser/accessibility/browser_accessibility_manager_win.h"
#include "content/common/accessibility_messages.h"
+#include "content/public/common/content_client.h"
#include "ui/base/accessibility/accessible_text_utils.h"
+#include "ui/base/win/accessibility_ids_win.h"
#include "ui/base/win/accessibility_misc_utils.h"
namespace content {
@@ -32,6 +34,10 @@
const char16 BrowserAccessibilityWin::kEmbeddedCharacter[] = L"\xfffc";
+// static
+LONG BrowserAccessibilityWin::next_unique_id_win_ =
+ base::win::kFirstBrowserAccessibilityManagerAccessibilityId;
+
//
// BrowserAccessibilityRelation
//
@@ -188,6 +194,16 @@
ia2_state_(0),
first_time_(true),
old_ia_state_(0) {
+ // Start unique IDs at -1 and decrement each time, because get_accChild
+ // uses positive IDs to enumerate children, so we use negative IDs to
+ // clearly distinguish between indices and unique IDs.
+ unique_id_win_ = next_unique_id_win_;
+ if (next_unique_id_win_ ==
+ base::win::kLastBrowserAccessibilityManagerAccessibilityId) {
+ next_unique_id_win_ =
+ base::win::kFirstBrowserAccessibilityManagerAccessibilityId;
+ }
+ next_unique_id_win_--;
}
BrowserAccessibilityWin::~BrowserAccessibilityWin() {
@@ -668,7 +684,7 @@
if (!unique_id)
return E_INVALIDARG;
- *unique_id = child_id_;
+ *unique_id = unique_id_win_;
return S_OK;
}
@@ -837,6 +853,65 @@
}
//
+// IAccessibleApplication methods.
+//
+
+STDMETHODIMP BrowserAccessibilityWin::get_appName(BSTR* app_name) {
+ // No need to check |instance_active_| because this interface is
+ // global, and doesn't depend on any local state.
+
+ if (!app_name)
+ return E_INVALIDARG;
+
+ std::string product_name = GetContentClient()->GetProduct();
+ *app_name = SysAllocString(UTF8ToUTF16(product_name).c_str());
+ DCHECK(*app_name);
+ return *app_name ? S_OK : E_FAIL;
+}
+
+STDMETHODIMP BrowserAccessibilityWin::get_appVersion(BSTR* app_version) {
+ // No need to check |instance_active_| because this interface is
+ // global, and doesn't depend on any local state.
+
+ if (!app_version)
+ return E_INVALIDARG;
+
+ std::string user_agent = GetContentClient()->GetUserAgent();
+ *app_version = SysAllocString(UTF8ToUTF16(user_agent).c_str());
+ DCHECK(*app_version);
+ return *app_version ? S_OK : E_FAIL;
+}
+
+STDMETHODIMP BrowserAccessibilityWin::get_toolkitName(BSTR* toolkit_name) {
+ // No need to check |instance_active_| because this interface is
+ // global, and doesn't depend on any local state.
+
+ if (!toolkit_name)
+ return E_INVALIDARG;
+
+ // This is hard-coded; all products based on the Chromium engine
+ // will have the same toolkit name, so that assistive technology can
+ // detect any Chrome-based product.
+ *toolkit_name = SysAllocString(L"Chrome");
+ DCHECK(*toolkit_name);
+ return *toolkit_name ? S_OK : E_FAIL;
+}
+
+STDMETHODIMP BrowserAccessibilityWin::get_toolkitVersion(
+ BSTR* toolkit_version) {
+ // No need to check |instance_active_| because this interface is
+ // global, and doesn't depend on any local state.
+
+ if (!toolkit_version)
+ return E_INVALIDARG;
+
+ std::string user_agent = GetContentClient()->GetUserAgent();
+ *toolkit_version = SysAllocString(UTF8ToUTF16(user_agent).c_str());
+ DCHECK(*toolkit_version);
+ return *toolkit_version ? S_OK : E_FAIL;
+}
+
+//
// IAccessibleImage methods.
//
@@ -2250,7 +2325,7 @@
*name_space_id = 0;
*node_value = SysAllocString(value_.c_str());
*num_children = children_.size();
- *unique_id = child_id_;
+ *unique_id = unique_id_win_;
if (ia_role_ == ROLE_SYSTEM_DOCUMENT) {
*node_type = NODETYPE_DOCUMENT;
@@ -2516,6 +2591,7 @@
if (guidService == IID_IAccessible ||
guidService == IID_IAccessible2 ||
guidService == IID_IAccessibleAction ||
+ guidService == IID_IAccessibleApplication ||
guidService == IID_IAccessibleHyperlink ||
guidService == IID_IAccessibleHypertext ||
guidService == IID_IAccessibleImage ||
@@ -2879,17 +2955,17 @@
(ia_state_ & STATE_SYSTEM_FOCUSED) &&
!(old_ia_state_ & STATE_SYSTEM_FOCUSED)) {
::NotifyWinEvent(EVENT_OBJECT_FOCUS, hwnd,
- OBJID_CLIENT, child_id());
+ OBJID_CLIENT, unique_id_win());
}
if ((ia_state_ & STATE_SYSTEM_SELECTED) &&
!(old_ia_state_ & STATE_SYSTEM_SELECTED)) {
::NotifyWinEvent(EVENT_OBJECT_SELECTIONADD, hwnd,
- OBJID_CLIENT, child_id());
+ OBJID_CLIENT, unique_id_win());
} else if (!(ia_state_ & STATE_SYSTEM_SELECTED) &&
(old_ia_state_ & STATE_SYSTEM_SELECTED)) {
::NotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE, hwnd,
- OBJID_CLIENT, child_id());
+ OBJID_CLIENT, unique_id_win());
}
old_ia_state_ = ia_state_;
@@ -2910,6 +2986,13 @@
return true;
}
+void BrowserAccessibilityWin::SetLocation(const gfx::Rect& new_location) {
+ BrowserAccessibility::SetLocation(new_location);
+ HWND hwnd = manager_->ToBrowserAccessibilityManagerWin()->parent_hwnd();
+ ::NotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, hwnd,
+ OBJID_CLIENT, unique_id_win());
+}
+
BrowserAccessibilityWin* BrowserAccessibilityWin::NewReference() {
AddRef();
return this;
@@ -2927,7 +3010,8 @@
if (child_id >= 1 && child_id <= static_cast<LONG>(children_.size()))
return children_[child_id - 1]->ToBrowserAccessibilityWin();
- return manager_->GetFromChildID(child_id)->ToBrowserAccessibilityWin();
+ return manager_->ToBrowserAccessibilityManagerWin()->
+ GetFromUniqueIdWin(child_id);
}
HRESULT BrowserAccessibilityWin::GetStringAttributeAsBstr(
diff --git a/content/browser/accessibility/browser_accessibility_win.h b/content/browser/accessibility/browser_accessibility_win.h
index ce1dbe1..b659932 100644
--- a/content/browser/accessibility/browser_accessibility_win.h
+++ b/content/browser/accessibility/browser_accessibility_win.h
@@ -43,6 +43,7 @@
public CComObjectRootEx<CComMultiThreadModel>,
public IDispatchImpl<IAccessible2, &IID_IAccessible2,
&LIBID_IAccessible2Lib>,
+ public IAccessibleApplication,
public IAccessibleHyperlink,
public IAccessibleHypertext,
public IAccessibleImage,
@@ -62,6 +63,7 @@
COM_INTERFACE_ENTRY2(IAccessible, IAccessible2)
COM_INTERFACE_ENTRY2(IAccessibleText, IAccessibleHypertext)
COM_INTERFACE_ENTRY(IAccessible2)
+ COM_INTERFACE_ENTRY(IAccessibleApplication)
COM_INTERFACE_ENTRY(IAccessibleHyperlink)
COM_INTERFACE_ENTRY(IAccessibleHypertext)
COM_INTERFACE_ENTRY(IAccessibleImage)
@@ -91,6 +93,10 @@
CONTENT_EXPORT virtual ~BrowserAccessibilityWin();
+ // The Windows-specific unique ID, used as the child ID for MSAA methods
+ // like NotifyWinEvent, and as the unique ID for IAccessible2 and ISimpleDOM.
+ LONG unique_id_win() const { return unique_id_win_; }
+
//
// BrowserAccessibility methods.
//
@@ -99,6 +105,8 @@
CONTENT_EXPORT virtual void NativeAddReference() OVERRIDE;
CONTENT_EXPORT virtual void NativeReleaseReference() OVERRIDE;
CONTENT_EXPORT virtual bool IsNative() const OVERRIDE;
+ CONTENT_EXPORT virtual void SetLocation(const gfx::Rect& new_location)
+ OVERRIDE;
//
// IAccessible methods.
@@ -251,6 +259,17 @@
}
//
+ // IAccessibleApplication methods.
+ //
+ CONTENT_EXPORT STDMETHODIMP get_appName(BSTR* app_name);
+
+ CONTENT_EXPORT STDMETHODIMP get_appVersion(BSTR* app_version);
+
+ CONTENT_EXPORT STDMETHODIMP get_toolkitName(BSTR* toolkit_name);
+
+ CONTENT_EXPORT STDMETHODIMP get_toolkitVersion(BSTR* toolkit_version);
+
+ //
// IAccessibleImage methods.
//
CONTENT_EXPORT STDMETHODIMP get_description(BSTR* description);
@@ -820,6 +839,11 @@
// does not make a new reference.
BrowserAccessibilityWin* GetFromRendererID(int32 renderer_id);
+ // Windows-specific unique ID (unique within the browser process),
+ // used for get_accChild, NotifyWinEvent, and as the unique ID for
+ // IAccessible2 and ISimpleDOM.
+ LONG unique_id_win_;
+
// IAccessible role and state.
int32 ia_role_;
int32 ia_state_;
@@ -860,6 +884,9 @@
// a hyperlink.
std::vector<int32> hyperlinks_;
+ // The next unique id to use.
+ static LONG next_unique_id_win_;
+
// Give BrowserAccessibility::Create access to our constructor.
friend class BrowserAccessibility;
friend class BrowserAccessibilityRelation;
diff --git a/content/browser/accessibility/browser_accessibility_win_unittest.cc b/content/browser/accessibility/browser_accessibility_win_unittest.cc
index cbf5b82..98a5d40 100644
--- a/content/browser/accessibility/browser_accessibility_win_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_win_unittest.cc
@@ -3,7 +3,9 @@
// found in the LICENSE file.
#include "base/memory/scoped_ptr.h"
+#include "base/win/scoped_bstr.h"
#include "base/win/scoped_comptr.h"
+#include "base/win/scoped_variant.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/browser_accessibility_manager_win.h"
#include "content/browser/accessibility/browser_accessibility_win.h"
@@ -14,54 +16,95 @@
namespace content {
namespace {
+
+// CountedBrowserAccessibility ------------------------------------------------
+
// Subclass of BrowserAccessibilityWin that counts the number of instances.
class CountedBrowserAccessibility : public BrowserAccessibilityWin {
public:
- CountedBrowserAccessibility() { global_obj_count_++; }
- virtual ~CountedBrowserAccessibility() { global_obj_count_--; }
- static int global_obj_count_;
+ CountedBrowserAccessibility();
+ virtual ~CountedBrowserAccessibility();
+
+ static void reset() { num_instances_ = 0; }
+ static int num_instances() { return num_instances_; }
+
+ private:
+ static int num_instances_;
+
+ DISALLOW_COPY_AND_ASSIGN(CountedBrowserAccessibility);
};
-int CountedBrowserAccessibility::global_obj_count_ = 0;
+// static
+int CountedBrowserAccessibility::num_instances_ = 0;
+
+CountedBrowserAccessibility::CountedBrowserAccessibility() {
+ ++num_instances_;
+}
+
+CountedBrowserAccessibility::~CountedBrowserAccessibility() {
+ --num_instances_;
+}
+
+
+// CountedBrowserAccessibilityFactory -----------------------------------------
// Factory that creates a CountedBrowserAccessibility.
-class CountedBrowserAccessibilityFactory
- : public BrowserAccessibilityFactory {
+class CountedBrowserAccessibilityFactory : public BrowserAccessibilityFactory {
public:
- virtual ~CountedBrowserAccessibilityFactory() {}
- virtual BrowserAccessibility* Create() {
- CComObject<CountedBrowserAccessibility>* instance;
- HRESULT hr = CComObject<CountedBrowserAccessibility>::CreateInstance(
- &instance);
- DCHECK(SUCCEEDED(hr));
- instance->AddRef();
- return instance;
- }
+ CountedBrowserAccessibilityFactory();
+
+ private:
+ virtual ~CountedBrowserAccessibilityFactory();
+
+ virtual BrowserAccessibility* Create() OVERRIDE;
+
+ DISALLOW_COPY_AND_ASSIGN(CountedBrowserAccessibilityFactory);
};
-} // anonymous namespace
-
-VARIANT CreateI4Variant(LONG value) {
- VARIANT variant = {0};
-
- V_VT(&variant) = VT_I4;
- V_I4(&variant) = value;
-
- return variant;
+CountedBrowserAccessibilityFactory::CountedBrowserAccessibilityFactory() {
}
+CountedBrowserAccessibilityFactory::~CountedBrowserAccessibilityFactory() {
+}
+
+BrowserAccessibility* CountedBrowserAccessibilityFactory::Create() {
+ CComObject<CountedBrowserAccessibility>* instance;
+ HRESULT hr = CComObject<CountedBrowserAccessibility>::CreateInstance(
+ &instance);
+ DCHECK(SUCCEEDED(hr));
+ instance->AddRef();
+ return instance;
+}
+
+} // namespace
+
+
+// BrowserAccessibilityTest ---------------------------------------------------
+
class BrowserAccessibilityTest : public testing::Test {
public:
- BrowserAccessibilityTest() {}
+ BrowserAccessibilityTest();
+ virtual ~BrowserAccessibilityTest();
private:
- virtual void SetUp() {
- ui::win::CreateATLModuleIfNeeded();
- }
+ virtual void SetUp() OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityTest);
};
+BrowserAccessibilityTest::BrowserAccessibilityTest() {
+}
+
+BrowserAccessibilityTest::~BrowserAccessibilityTest() {
+}
+
+void BrowserAccessibilityTest::SetUp() {
+ ui::win::CreateATLModuleIfNeeded();
+}
+
+
+// Actual tests ---------------------------------------------------------------
+
// Test that BrowserAccessibilityManager correctly releases the tree of
// BrowserAccessibility instances upon delete.
TEST_F(BrowserAccessibilityTest, TestNoLeaks) {
@@ -92,52 +135,45 @@
// AccessibilityNodeData tree and a factory for an instance-counting
// BrowserAccessibility, and ensure that exactly 3 instances were
// created. Note that the manager takes ownership of the factory.
- CountedBrowserAccessibility::global_obj_count_ = 0;
- BrowserAccessibilityManager* manager =
+ CountedBrowserAccessibility::reset();
+ scoped_ptr<BrowserAccessibilityManager> manager(
BrowserAccessibilityManager::Create(
- root,
- NULL,
- new CountedBrowserAccessibilityFactory());
+ root, NULL, new CountedBrowserAccessibilityFactory()));
manager->UpdateNodesForTesting(button, checkbox);
- ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_);
+ ASSERT_EQ(3, CountedBrowserAccessibility::num_instances());
// Delete the manager and test that all 3 instances are deleted.
- delete manager;
- ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
+ manager.reset();
+ ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
// Construct a manager again, and this time use the IAccessible interface
// to get new references to two of the three nodes in the tree.
- manager =
- BrowserAccessibilityManager::Create(
- root,
- NULL,
- new CountedBrowserAccessibilityFactory());
+ manager.reset(BrowserAccessibilityManager::Create(
+ root, NULL, new CountedBrowserAccessibilityFactory()));
manager->UpdateNodesForTesting(button, checkbox);
- ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_);
+ ASSERT_EQ(3, CountedBrowserAccessibility::num_instances());
IAccessible* root_accessible =
manager->GetRoot()->ToBrowserAccessibilityWin();
IDispatch* root_iaccessible = NULL;
IDispatch* child1_iaccessible = NULL;
- VARIANT var_child;
- var_child.vt = VT_I4;
- var_child.lVal = CHILDID_SELF;
- HRESULT hr = root_accessible->get_accChild(var_child, &root_iaccessible);
+ base::win::ScopedVariant childid_self(CHILDID_SELF);
+ HRESULT hr = root_accessible->get_accChild(childid_self, &root_iaccessible);
ASSERT_EQ(S_OK, hr);
- var_child.lVal = 1;
- hr = root_accessible->get_accChild(var_child, &child1_iaccessible);
+ base::win::ScopedVariant one(1);
+ hr = root_accessible->get_accChild(one, &child1_iaccessible);
ASSERT_EQ(S_OK, hr);
// Now delete the manager, and only one of the three nodes in the tree
// should be released.
- delete manager;
- ASSERT_EQ(2, CountedBrowserAccessibility::global_obj_count_);
+ manager.reset();
+ ASSERT_EQ(2, CountedBrowserAccessibility::num_instances());
// Release each of our references and make sure that each one results in
// the instance being deleted as its reference count hits zero.
root_iaccessible->Release();
- ASSERT_EQ(1, CountedBrowserAccessibility::global_obj_count_);
+ ASSERT_EQ(1, CountedBrowserAccessibility::num_instances());
child1_iaccessible->Release();
- ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
+ ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
}
TEST_F(BrowserAccessibilityTest, TestChildrenChange) {
@@ -160,29 +196,30 @@
// Construct a BrowserAccessibilityManager with this
// AccessibilityNodeData tree and a factory for an instance-counting
// BrowserAccessibility.
- CountedBrowserAccessibility::global_obj_count_ = 0;
- BrowserAccessibilityManager* manager =
+ CountedBrowserAccessibility::reset();
+ scoped_ptr<BrowserAccessibilityManager> manager(
BrowserAccessibilityManager::Create(
- root,
- NULL,
- new CountedBrowserAccessibilityFactory());
+ root, NULL, new CountedBrowserAccessibilityFactory()));
manager->UpdateNodesForTesting(text);
// Query for the text IAccessible and verify that it returns "old text" as its
// value.
+ base::win::ScopedVariant one(1);
base::win::ScopedComPtr<IDispatch> text_dispatch;
HRESULT hr = manager->GetRoot()->ToBrowserAccessibilityWin()->get_accChild(
- CreateI4Variant(1), text_dispatch.Receive());
+ one, text_dispatch.Receive());
ASSERT_EQ(S_OK, hr);
base::win::ScopedComPtr<IAccessible> text_accessible;
hr = text_dispatch.QueryInterface(text_accessible.Receive());
ASSERT_EQ(S_OK, hr);
- CComBSTR name;
- hr = text_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
+ base::win::ScopedVariant childid_self(CHILDID_SELF);
+ base::win::ScopedBstr name;
+ hr = text_accessible->get_accName(childid_self, name.Receive());
ASSERT_EQ(S_OK, hr);
- EXPECT_STREQ(L"old text", name.m_str);
+ EXPECT_EQ(L"old text", string16(name));
+ name.Reset();
text_dispatch.Release();
text_accessible.Release();
@@ -200,24 +237,23 @@
// Query for the text IAccessible and verify that it now returns "new text"
// as its value.
hr = manager->GetRoot()->ToBrowserAccessibilityWin()->get_accChild(
- CreateI4Variant(1),
- text_dispatch.Receive());
+ one, text_dispatch.Receive());
ASSERT_EQ(S_OK, hr);
hr = text_dispatch.QueryInterface(text_accessible.Receive());
ASSERT_EQ(S_OK, hr);
- hr = text_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
+ hr = text_accessible->get_accName(childid_self, name.Receive());
ASSERT_EQ(S_OK, hr);
- EXPECT_STREQ(L"new text", name.m_str);
+ EXPECT_EQ(L"new text", string16(name));
text_dispatch.Release();
text_accessible.Release();
// Delete the manager and test that all BrowserAccessibility instances are
// deleted.
- delete manager;
- ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
+ manager.reset();
+ ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
}
TEST_F(BrowserAccessibilityTest, TestChildrenChangeNoLeaks) {
@@ -252,14 +288,12 @@
// AccessibilityNodeData tree and a factory for an instance-counting
// BrowserAccessibility and ensure that exactly 4 instances were
// created. Note that the manager takes ownership of the factory.
- CountedBrowserAccessibility::global_obj_count_ = 0;
- BrowserAccessibilityManager* manager =
+ CountedBrowserAccessibility::reset();
+ scoped_ptr<BrowserAccessibilityManager> manager(
BrowserAccessibilityManager::Create(
- root,
- NULL,
- new CountedBrowserAccessibilityFactory());
+ root, NULL, new CountedBrowserAccessibilityFactory()));
manager->UpdateNodesForTesting(div, text3, text4);
- ASSERT_EQ(4, CountedBrowserAccessibility::global_obj_count_);
+ ASSERT_EQ(4, CountedBrowserAccessibility::num_instances());
// Notify the BrowserAccessibilityManager that the div node and its children
// were removed and ensure that only one BrowserAccessibility instance exists.
@@ -271,12 +305,12 @@
std::vector<AccessibilityHostMsg_NotificationParams> notifications;
notifications.push_back(param);
manager->OnAccessibilityNotifications(notifications);
- ASSERT_EQ(1, CountedBrowserAccessibility::global_obj_count_);
+ ASSERT_EQ(1, CountedBrowserAccessibility::num_instances());
// Delete the manager and test that all BrowserAccessibility instances are
// deleted.
- delete manager;
- ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
+ manager.reset();
+ ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
}
TEST_F(BrowserAccessibilityTest, TestTextBoundaries) {
@@ -293,81 +327,81 @@
root.state = 0;
root.child_ids.push_back(11);
- CountedBrowserAccessibility::global_obj_count_ = 0;
- BrowserAccessibilityManager* manager = BrowserAccessibilityManager::Create(
- root, NULL,
- new CountedBrowserAccessibilityFactory());
+ CountedBrowserAccessibility::reset();
+ scoped_ptr<BrowserAccessibilityManager> manager(
+ BrowserAccessibilityManager::Create(
+ root, NULL, new CountedBrowserAccessibilityFactory()));
manager->UpdateNodesForTesting(text1);
- ASSERT_EQ(2, CountedBrowserAccessibility::global_obj_count_);
+ ASSERT_EQ(2, CountedBrowserAccessibility::num_instances());
BrowserAccessibilityWin* root_obj =
manager->GetRoot()->ToBrowserAccessibilityWin();
BrowserAccessibilityWin* text1_obj =
root_obj->GetChild(0)->ToBrowserAccessibilityWin();
- BSTR text;
- long start;
- long end;
-
long text1_len;
ASSERT_EQ(S_OK, text1_obj->get_nCharacters(&text1_len));
- ASSERT_EQ(S_OK, text1_obj->get_text(0, text1_len, &text));
- ASSERT_EQ(text, text1.value);
- SysFreeString(text);
+ base::win::ScopedBstr text;
+ ASSERT_EQ(S_OK, text1_obj->get_text(0, text1_len, text.Receive()));
+ ASSERT_EQ(text1.value, string16(text));
+ text.Reset();
- ASSERT_EQ(S_OK, text1_obj->get_text(0, 4, &text));
- ASSERT_EQ(text, string16(L"One "));
- SysFreeString(text);
+ ASSERT_EQ(S_OK, text1_obj->get_text(0, 4, text.Receive()));
+ ASSERT_STREQ(L"One ", text);
+ text.Reset();
+ long start;
+ long end;
ASSERT_EQ(S_OK, text1_obj->get_textAtOffset(
- 1, IA2_TEXT_BOUNDARY_CHAR, &start, &end, &text));
- ASSERT_EQ(start, 1);
- ASSERT_EQ(end, 2);
- ASSERT_EQ(text, string16(L"n"));
- SysFreeString(text);
+ 1, IA2_TEXT_BOUNDARY_CHAR, &start, &end, text.Receive()));
+ ASSERT_EQ(1, start);
+ ASSERT_EQ(2, end);
+ ASSERT_STREQ(L"n", text);
+ text.Reset();
ASSERT_EQ(S_FALSE, text1_obj->get_textAtOffset(
- text1_len, IA2_TEXT_BOUNDARY_CHAR, &start, &end, &text));
- ASSERT_EQ(start, text1_len);
- ASSERT_EQ(end, text1_len);
+ text1_len, IA2_TEXT_BOUNDARY_CHAR, &start, &end, text.Receive()));
+ ASSERT_EQ(text1_len, start);
+ ASSERT_EQ(text1_len, end);
+ text.Reset();
ASSERT_EQ(S_OK, text1_obj->get_textAtOffset(
- 1, IA2_TEXT_BOUNDARY_WORD, &start, &end, &text));
- ASSERT_EQ(start, 0);
- ASSERT_EQ(end, 3);
- ASSERT_EQ(text, string16(L"One"));
- SysFreeString(text);
+ 1, IA2_TEXT_BOUNDARY_WORD, &start, &end, text.Receive()));
+ ASSERT_EQ(0, start);
+ ASSERT_EQ(3, end);
+ ASSERT_STREQ(L"One", text);
+ text.Reset();
ASSERT_EQ(S_OK, text1_obj->get_textAtOffset(
- 6, IA2_TEXT_BOUNDARY_WORD, &start, &end, &text));
- ASSERT_EQ(start, 4);
- ASSERT_EQ(end, 7);
- ASSERT_EQ(text, string16(L"two"));
- SysFreeString(text);
+ 6, IA2_TEXT_BOUNDARY_WORD, &start, &end, text.Receive()));
+ ASSERT_EQ(4, start);
+ ASSERT_EQ(7, end);
+ ASSERT_STREQ(L"two", text);
+ text.Reset();
ASSERT_EQ(S_OK, text1_obj->get_textAtOffset(
- text1_len, IA2_TEXT_BOUNDARY_WORD, &start, &end, &text));
- ASSERT_EQ(start, 25);
- ASSERT_EQ(end, 29);
- ASSERT_EQ(text, string16(L"six."));
- SysFreeString(text);
+ text1_len, IA2_TEXT_BOUNDARY_WORD, &start, &end, text.Receive()));
+ ASSERT_EQ(25, start);
+ ASSERT_EQ(29, end);
+ ASSERT_STREQ(L"six.", text);
+ text.Reset();
ASSERT_EQ(S_OK, text1_obj->get_textAtOffset(
- 1, IA2_TEXT_BOUNDARY_LINE, &start, &end, &text));
- ASSERT_EQ(start, 0);
- ASSERT_EQ(end, 15);
- ASSERT_EQ(text, string16(L"One two three.\n"));
- SysFreeString(text);
+ 1, IA2_TEXT_BOUNDARY_LINE, &start, &end, text.Receive()));
+ ASSERT_EQ(0, start);
+ ASSERT_EQ(15, end);
+ ASSERT_STREQ(L"One two three.\n", text);
+ text.Reset();
- ASSERT_EQ(S_OK, text1_obj->get_text(0, IA2_TEXT_OFFSET_LENGTH, &text));
- ASSERT_EQ(text, string16(L"One two three.\nFour five six."));
- SysFreeString(text);
+ ASSERT_EQ(S_OK,
+ text1_obj->get_text(0, IA2_TEXT_OFFSET_LENGTH, text.Receive()));
+ ASSERT_STREQ(L"One two three.\nFour five six.", text);
// Delete the manager and test that all BrowserAccessibility instances are
// deleted.
- delete manager;
- ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
+ manager.reset();
+ ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
}
TEST_F(BrowserAccessibilityTest, TestSimpleHypertext) {
@@ -390,24 +424,22 @@
root.child_ids.push_back(11);
root.child_ids.push_back(12);
- CountedBrowserAccessibility::global_obj_count_ = 0;
- BrowserAccessibilityManager* manager = BrowserAccessibilityManager::Create(
- root, NULL,
- new CountedBrowserAccessibilityFactory());
+ CountedBrowserAccessibility::reset();
+ scoped_ptr<BrowserAccessibilityManager> manager(
+ BrowserAccessibilityManager::Create(
+ root, NULL, new CountedBrowserAccessibilityFactory()));
manager->UpdateNodesForTesting(root, text1, text2);
- ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_);
+ ASSERT_EQ(3, CountedBrowserAccessibility::num_instances());
BrowserAccessibilityWin* root_obj =
manager->GetRoot()->ToBrowserAccessibilityWin();
- BSTR text;
-
long text_len;
ASSERT_EQ(S_OK, root_obj->get_nCharacters(&text_len));
- ASSERT_EQ(S_OK, root_obj->get_text(0, text_len, &text));
- EXPECT_EQ(text, text1.name + text2.name);
- SysFreeString(text);
+ base::win::ScopedBstr text;
+ ASSERT_EQ(S_OK, root_obj->get_text(0, text_len, text.Receive()));
+ EXPECT_EQ(text1.name + text2.name, string16(text));
long hyperlink_count;
ASSERT_EQ(S_OK, root_obj->get_nHyperlinks(&hyperlink_count));
@@ -431,8 +463,8 @@
// Delete the manager and test that all BrowserAccessibility instances are
// deleted.
- delete manager;
- ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
+ manager.reset();
+ ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
}
TEST_F(BrowserAccessibilityTest, TestComplexHypertext) {
@@ -477,28 +509,27 @@
root.child_ids.push_back(12);
root.child_ids.push_back(14);
- CountedBrowserAccessibility::global_obj_count_ = 0;
- BrowserAccessibilityManager* manager = BrowserAccessibilityManager::Create(
- root, NULL,
- new CountedBrowserAccessibilityFactory());
+ CountedBrowserAccessibility::reset();
+ scoped_ptr<BrowserAccessibilityManager> manager(
+ BrowserAccessibilityManager::Create(
+ root, NULL, new CountedBrowserAccessibilityFactory()));
manager->UpdateNodesForTesting(root,
text1, button1, button1_text,
text2, link1, link1_text);
- ASSERT_EQ(7, CountedBrowserAccessibility::global_obj_count_);
+ ASSERT_EQ(7, CountedBrowserAccessibility::num_instances());
BrowserAccessibilityWin* root_obj =
manager->GetRoot()->ToBrowserAccessibilityWin();
- BSTR text;
-
long text_len;
ASSERT_EQ(S_OK, root_obj->get_nCharacters(&text_len));
- ASSERT_EQ(S_OK, root_obj->get_text(0, text_len, &text));
+ base::win::ScopedBstr text;
+ ASSERT_EQ(S_OK, root_obj->get_text(0, text_len, text.Receive()));
const string16 embed = BrowserAccessibilityWin::kEmbeddedCharacter;
- EXPECT_EQ(text, text1.name + embed + text2.name + embed);
- SysFreeString(text);
+ EXPECT_EQ(text1.name + embed + text2.name + embed, string16(text));
+ text.Reset();
long hyperlink_count;
ASSERT_EQ(S_OK, root_obj->get_nHyperlinks(&hyperlink_count));
@@ -513,18 +544,18 @@
EXPECT_EQ(S_OK, root_obj->get_hyperlink(0, hyperlink.Receive()));
EXPECT_EQ(S_OK,
hyperlink.QueryInterface<IAccessibleText>(hypertext.Receive()));
- EXPECT_EQ(S_OK, hypertext->get_text(0, 3, &text));
- EXPECT_EQ(text, string16(L"red"));
- SysFreeString(text);
+ EXPECT_EQ(S_OK, hypertext->get_text(0, 3, text.Receive()));
+ EXPECT_STREQ(L"red", text);
+ text.Reset();
hyperlink.Release();
hypertext.Release();
EXPECT_EQ(S_OK, root_obj->get_hyperlink(1, hyperlink.Receive()));
EXPECT_EQ(S_OK,
hyperlink.QueryInterface<IAccessibleText>(hypertext.Receive()));
- EXPECT_EQ(S_OK, hypertext->get_text(0, 4, &text));
- EXPECT_EQ(text, string16(L"blue"));
- SysFreeString(text);
+ EXPECT_EQ(S_OK, hypertext->get_text(0, 4, text.Receive()));
+ EXPECT_STREQ(L"blue", text);
+ text.Reset();
hyperlink.Release();
hypertext.Release();
@@ -540,22 +571,23 @@
// Delete the manager and test that all BrowserAccessibility instances are
// deleted.
- delete manager;
- ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
+ manager.reset();
+ ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
}
TEST_F(BrowserAccessibilityTest, TestCreateEmptyDocument) {
// Try creating an empty document with busy state. Readonly is
// set automatically.
+ CountedBrowserAccessibility::reset();
const int32 busy_state = 1 << AccessibilityNodeData::STATE_BUSY;
const int32 readonly_state = 1 << AccessibilityNodeData::STATE_READONLY;
- scoped_ptr<BrowserAccessibilityManager> manager;
- manager.reset(new BrowserAccessibilityManagerWin(
- GetDesktopWindow(),
- NULL,
- BrowserAccessibilityManagerWin::GetEmptyDocument(),
- NULL,
- new CountedBrowserAccessibilityFactory()));
+ scoped_ptr<BrowserAccessibilityManager> manager(
+ new BrowserAccessibilityManagerWin(
+ GetDesktopWindow(),
+ NULL,
+ BrowserAccessibilityManagerWin::GetEmptyDocument(),
+ NULL,
+ new CountedBrowserAccessibilityFactory()));
// Verify the root is as we expect by default.
BrowserAccessibility* root = manager->GetRoot();
@@ -622,7 +654,7 @@
// Ensure we properly cleaned up.
manager.reset();
- ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
+ ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
}
} // namespace content
diff --git a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
index 9fe99c4..ff5789a 100644
--- a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
+++ b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
@@ -107,7 +107,7 @@
if (iter != node.string_attributes.end())
return UTF16ToUTF8(iter->second);
else
- return "";
+ return std::string();
}
// Convenience method to get the value of a particular AccessibilityNodeData
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index f5f05a9..08635d2 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -372,8 +372,9 @@
RunTest(FILE_PATH_LITERAL("hr.html"));
}
+// crbug.com/179717 and crbug.com/224659
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
- MAYBE(AccessibilityIframeCoordinates)) {
+ DISABLED_AccessibilityIframeCoordinates) {
RunTest(FILE_PATH_LITERAL("iframe-coordinates.html"));
}
@@ -436,6 +437,14 @@
RunTest(FILE_PATH_LITERAL("tab.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityTableSimple) {
+ RunTest(FILE_PATH_LITERAL("table-simple.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityTableSpans) {
+ RunTest(FILE_PATH_LITERAL("table-spans.html"));
+}
+
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
AccessibilityToggleButton) {
RunTest(FILE_PATH_LITERAL("togglebutton.html"));
diff --git a/content/browser/android/browser_jni_registrar.cc b/content/browser/android/browser_jni_registrar.cc
index 1915337..4aa5c86 100644
--- a/content/browser/android/browser_jni_registrar.cc
+++ b/content/browser/android/browser_jni_registrar.cc
@@ -17,6 +17,7 @@
#include "content/browser/android/download_controller_android_impl.h"
#include "content/browser/android/interstitial_page_delegate_android.h"
#include "content/browser/android/load_url_params.h"
+#include "content/browser/android/media_resource_getter_impl.h"
#include "content/browser/android/surface_texture_peer_browser_impl.h"
#include "content/browser/android/touch_point.h"
#include "content/browser/android/tracing_intent_handler.h"
@@ -44,6 +45,8 @@
{ "InterstitialPageDelegateAndroid",
content::InterstitialPageDelegateAndroid
::RegisterInterstitialPageDelegateAndroid },
+ { "MediaResourceGetterImpl",
+ content::MediaResourceGetterImpl::RegisterMediaResourceGetter },
{ "LoadUrlParams", content::RegisterLoadUrlParams },
{ "RegisterImeAdapter", content::RegisterImeAdapter },
{ "TouchPoint", content::RegisterTouchPoint },
diff --git a/content/browser/android/child_process_launcher_android.cc b/content/browser/android/child_process_launcher_android.cc
index 3a954dc..b3fb563 100644
--- a/content/browser/android/child_process_launcher_android.cc
+++ b/content/browser/android/child_process_launcher_android.cc
@@ -8,14 +8,14 @@
#include "base/android/jni_array.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "content/browser/android/media_player_manager_android.h"
+#include "content/browser/android/media_player_manager_impl.h"
#include "content/browser/renderer_host/compositor_impl_android.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/common/android/scoped_java_surface.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "jni/ChildProcessLauncher_jni.h"
#include "media/base/android/media_player_bridge.h"
+#include "ui/gl/android/scoped_java_surface.h"
using base::android::AttachCurrentThread;
using base::android::ToJavaArrayOfStrings;
@@ -52,7 +52,7 @@
host->media_player_manager()->GetPlayer(player_id);
if (player &&
player != host->media_player_manager()->GetFullscreenPlayer()) {
- ScopedJavaSurface scoped_surface(surface);
+ gfx::ScopedJavaSurface scoped_surface(surface);
player->SetVideoSurface(scoped_surface.j_surface().obj());
}
}
diff --git a/content/browser/android/content_settings.cc b/content/browser/android/content_settings.cc
index 60a6e23..15600fb 100644
--- a/content/browser/android/content_settings.cc
+++ b/content/browser/android/content_settings.cc
@@ -5,128 +5,19 @@
#include "content/browser/android/content_settings.h"
#include "base/android/jni_android.h"
-#include "base/android/jni_string.h"
#include "content/browser/android/content_view_core_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/public/browser/web_contents.h"
-#include "content/public/common/content_client.h"
#include "jni/ContentSettings_jni.h"
-#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webpreferences.h"
-#include "webkit/user_agent/user_agent.h"
-
-using base::android::CheckException;
-using base::android::ConvertJavaStringToUTF16;
-using base::android::ConvertUTF16ToJavaString;
-using base::android::ConvertUTF8ToJavaString;
-using base::android::GetClass;
-using base::android::GetFieldID;
-using base::android::GetMethodIDFromClassName;
-using base::android::ScopedJavaLocalRef;
-using webkit_glue::WebPreferences;
namespace content {
-struct ContentSettings::FieldIds {
- // Note on speed. One may think that an approach that reads field values via
- // JNI is ineffective and should not be used. Please keep in mind that in the
- // legacy WebView the whole Sync method took <1ms on Xoom, and no one is
- // expected to modify settings in performance-critical code.
- FieldIds() { }
-
- FieldIds(JNIEnv* env) {
- const char* kStringClassName = "Ljava/lang/String;";
-
- // FIXME: we should be using a new GetFieldIDFromClassName() with caching.
- ScopedJavaLocalRef<jclass> clazz(
- GetClass(env, "org/chromium/content/browser/ContentSettings"));
- text_size_percent = GetFieldID(env, clazz, "mTextSizePercent", "I");
- standard_fond_family =
- GetFieldID(env, clazz, "mStandardFontFamily", kStringClassName);
- fixed_font_family =
- GetFieldID(env, clazz, "mFixedFontFamily", kStringClassName);
- sans_serif_font_family =
- GetFieldID(env, clazz, "mSansSerifFontFamily", kStringClassName);
- serif_font_family =
- GetFieldID(env, clazz, "mSerifFontFamily", kStringClassName);
- cursive_font_family =
- GetFieldID(env, clazz, "mCursiveFontFamily", kStringClassName);
- fantasy_font_family =
- GetFieldID(env, clazz, "mFantasyFontFamily", kStringClassName);
- default_text_encoding =
- GetFieldID(env, clazz, "mDefaultTextEncoding", kStringClassName);
- user_agent =
- GetFieldID(env, clazz, "mUserAgent", kStringClassName);
- minimum_font_size = GetFieldID(env, clazz, "mMinimumFontSize", "I");
- minimum_logical_font_size =
- GetFieldID(env, clazz, "mMinimumLogicalFontSize", "I");
- default_font_size = GetFieldID(env, clazz, "mDefaultFontSize", "I");
- default_fixed_font_size =
- GetFieldID(env, clazz, "mDefaultFixedFontSize", "I");
- load_images_automatically =
- GetFieldID(env, clazz, "mLoadsImagesAutomatically", "Z");
- images_enabled =
- GetFieldID(env, clazz, "mImagesEnabled", "Z");
- java_script_enabled =
- GetFieldID(env, clazz, "mJavaScriptEnabled", "Z");
- allow_universal_access_from_file_urls =
- GetFieldID(env, clazz, "mAllowUniversalAccessFromFileURLs", "Z");
- allow_file_access_from_file_urls =
- GetFieldID(env, clazz, "mAllowFileAccessFromFileURLs", "Z");
- java_script_can_open_windows_automatically =
- GetFieldID(env, clazz, "mJavaScriptCanOpenWindowsAutomatically", "Z");
- support_multiple_windows =
- GetFieldID(env, clazz, "mSupportMultipleWindows", "Z");
- dom_storage_enabled =
- GetFieldID(env, clazz, "mDomStorageEnabled", "Z");
- database_enabled =
- GetFieldID(env, clazz, "mDatabaseEnabled", "Z");
- use_wide_viewport =
- GetFieldID(env, clazz, "mUseWideViewport", "Z");
- load_with_overview_mode =
- GetFieldID(env, clazz, "mLoadWithOverviewMode", "Z");
- media_playback_requires_user_gesture =
- GetFieldID(env, clazz, "mMediaPlaybackRequiresUserGesture", "Z");
- default_video_poster_url =
- GetFieldID(env, clazz, "mDefaultVideoPosterURL", kStringClassName);
- }
-
- // Field ids
- jfieldID text_size_percent;
- jfieldID standard_fond_family;
- jfieldID fixed_font_family;
- jfieldID sans_serif_font_family;
- jfieldID serif_font_family;
- jfieldID cursive_font_family;
- jfieldID fantasy_font_family;
- jfieldID default_text_encoding;
- jfieldID user_agent;
- jfieldID minimum_font_size;
- jfieldID minimum_logical_font_size;
- jfieldID default_font_size;
- jfieldID default_fixed_font_size;
- jfieldID load_images_automatically;
- jfieldID images_enabled;
- jfieldID java_script_enabled;
- jfieldID allow_universal_access_from_file_urls;
- jfieldID allow_file_access_from_file_urls;
- jfieldID java_script_can_open_windows_automatically;
- jfieldID support_multiple_windows;
- jfieldID dom_storage_enabled;
- jfieldID database_enabled;
- jfieldID use_wide_viewport;
- jfieldID load_with_overview_mode;
- jfieldID media_playback_requires_user_gesture;
- jfieldID default_video_poster_url;
-};
-
ContentSettings::ContentSettings(JNIEnv* env,
jobject obj,
- WebContents* contents,
- bool is_master_mode)
+ WebContents* contents)
: WebContentsObserver(contents),
- is_master_mode_(is_master_mode),
content_settings_(env, obj) {
}
@@ -144,323 +35,24 @@
return RegisterNativesImpl(env);
}
-void ContentSettings::SyncFromNativeImpl() {
- JNIEnv* env = base::android::AttachCurrentThread();
- CHECK(env);
- if (!field_ids_.get())
- field_ids_.reset(new FieldIds(env));
-
- ScopedJavaLocalRef<jobject> scoped_obj = content_settings_.get(env);
- jobject obj = scoped_obj.obj();
- if (!obj)
- return;
+bool ContentSettings::GetJavaScriptEnabled(JNIEnv* env, jobject obj) {
RenderViewHost* render_view_host = web_contents()->GetRenderViewHost();
- WebPreferences prefs = render_view_host->GetDelegate()->GetWebkitPrefs();
-
- Java_ContentSettings_setTextAutosizingEnabled(
- env, obj, prefs.text_autosizing_enabled);
- CheckException(env);
-
- env->SetIntField(
- obj,
- field_ids_->text_size_percent,
- prefs.font_scale_factor * 100.0f);
- CheckException(env);
-
- ScopedJavaLocalRef<jstring> str =
- ConvertUTF16ToJavaString(env,
- prefs.standard_font_family_map[WebPreferences::kCommonScript]);
- env->SetObjectField(obj, field_ids_->standard_fond_family, str.obj());
- CheckException(env);
-
- str.Reset(ConvertUTF16ToJavaString(env,
- prefs.fixed_font_family_map[WebPreferences::kCommonScript]));
- env->SetObjectField(obj, field_ids_->fixed_font_family, str.obj());
- CheckException(env);
-
- str.Reset(ConvertUTF16ToJavaString(env,
- prefs.sans_serif_font_family_map[WebPreferences::kCommonScript]));
- env->SetObjectField(obj, field_ids_->sans_serif_font_family, str.obj());
- CheckException(env);
-
- str.Reset(ConvertUTF16ToJavaString(env,
- prefs.serif_font_family_map[WebPreferences::kCommonScript]));
- env->SetObjectField(obj, field_ids_->serif_font_family, str.obj());
- CheckException(env);
-
- str.Reset(ConvertUTF16ToJavaString(env,
- prefs.cursive_font_family_map[WebPreferences::kCommonScript]));
- env->SetObjectField(obj, field_ids_->cursive_font_family, str.obj());
- CheckException(env);
-
- str.Reset(ConvertUTF16ToJavaString(env,
- prefs.fantasy_font_family_map[WebPreferences::kCommonScript]));
- env->SetObjectField(obj, field_ids_->fantasy_font_family, str.obj());
- CheckException(env);
-
- str.Reset(ConvertUTF8ToJavaString(env, prefs.default_encoding));
- env->SetObjectField(obj, field_ids_->default_text_encoding, str.obj());
- CheckException(env);
-
- str.Reset(ConvertUTF8ToJavaString(env, webkit_glue::GetUserAgent(GURL(""))));
- env->SetObjectField(obj, field_ids_->user_agent, str.obj());
- CheckException(env);
-
- env->SetIntField(obj, field_ids_->minimum_font_size,
- prefs.minimum_font_size);
- CheckException(env);
-
- env->SetIntField(
- obj,
- field_ids_->minimum_logical_font_size, prefs.minimum_logical_font_size);
- CheckException(env);
-
- env->SetIntField(obj, field_ids_->default_font_size,
- prefs.default_font_size);
- CheckException(env);
-
- env->SetIntField(
- obj, field_ids_->default_fixed_font_size, prefs.default_fixed_font_size);
- CheckException(env);
-
- env->SetBooleanField(
- obj,
- field_ids_->load_images_automatically, prefs.loads_images_automatically);
- CheckException(env);
-
- env->SetBooleanField(
- obj,
- field_ids_->images_enabled, prefs.images_enabled);
- CheckException(env);
-
- env->SetBooleanField(
- obj, field_ids_->java_script_enabled, prefs.javascript_enabled);
- CheckException(env);
-
- env->SetBooleanField(
- obj,
- field_ids_->allow_universal_access_from_file_urls,
- prefs.allow_universal_access_from_file_urls);
- CheckException(env);
-
- env->SetBooleanField(
- obj,
- field_ids_->allow_file_access_from_file_urls,
- prefs.allow_file_access_from_file_urls);
- CheckException(env);
-
- env->SetBooleanField(
- obj,
- field_ids_->java_script_can_open_windows_automatically,
- prefs.javascript_can_open_windows_automatically);
- CheckException(env);
-
- env->SetBooleanField(
- obj,
- field_ids_->support_multiple_windows,
- prefs.supports_multiple_windows);
- CheckException(env);
-
- Java_ContentSettings_setPluginsDisabled(env, obj, !prefs.plugins_enabled);
- CheckException(env);
-
- // We don't need to sync AppCache settings to Java, because there are
- // no getters for them in the API.
-
- env->SetBooleanField(
- obj,
- field_ids_->dom_storage_enabled,
- prefs.local_storage_enabled);
- CheckException(env);
-
- env->SetBooleanField(
- obj,
- field_ids_->database_enabled,
- prefs.databases_enabled);
- CheckException(env);
-
- env->SetBooleanField(
- obj,
- field_ids_->use_wide_viewport,
- prefs.viewport_enabled);
- CheckException(env);
-
- env->SetBooleanField(
- obj,
- field_ids_->load_with_overview_mode,
- prefs.initialize_at_minimum_page_scale);
- CheckException(env);
-
- env->SetBooleanField(
- obj,
- field_ids_->media_playback_requires_user_gesture,
- prefs.user_gesture_required_for_media_playback);
- CheckException(env);
-
- str.Reset(
- ConvertUTF8ToJavaString(env, prefs.default_video_poster_url.spec()));
- env->SetObjectField(obj, field_ids_->default_video_poster_url, str.obj());
- CheckException(env);
-}
-
-void ContentSettings::SyncToNativeImpl() {
- JNIEnv* env = base::android::AttachCurrentThread();
- CHECK(env);
- if (!field_ids_.get())
- field_ids_.reset(new FieldIds(env));
-
- ScopedJavaLocalRef<jobject> scoped_obj = content_settings_.get(env);
- jobject obj = scoped_obj.obj();
- if (!obj)
- return;
- RenderViewHost* render_view_host = web_contents()->GetRenderViewHost();
- WebPreferences prefs = render_view_host->GetDelegate()->GetWebkitPrefs();
-
- prefs.text_autosizing_enabled =
- Java_ContentSettings_getTextAutosizingEnabled(env, obj);
-
- int text_size_percent = env->GetIntField(obj, field_ids_->text_size_percent);
- if (prefs.text_autosizing_enabled) {
- prefs.font_scale_factor = text_size_percent / 100.0f;
- prefs.force_enable_zoom = text_size_percent >= 130;
- } else {
- prefs.force_enable_zoom = false;
- }
-
- ScopedJavaLocalRef<jstring> str(
- env, static_cast<jstring>(
- env->GetObjectField(obj, field_ids_->standard_fond_family)));
- prefs.standard_font_family_map[WebPreferences::kCommonScript] =
- ConvertJavaStringToUTF16(str);
-
- str.Reset(
- env, static_cast<jstring>(
- env->GetObjectField(obj, field_ids_->fixed_font_family)));
- prefs.fixed_font_family_map[WebPreferences::kCommonScript] =
- ConvertJavaStringToUTF16(str);
-
- str.Reset(
- env, static_cast<jstring>(
- env->GetObjectField(obj, field_ids_->sans_serif_font_family)));
- prefs.sans_serif_font_family_map[WebPreferences::kCommonScript] =
- ConvertJavaStringToUTF16(str);
-
- str.Reset(
- env, static_cast<jstring>(
- env->GetObjectField(obj, field_ids_->serif_font_family)));
- prefs.serif_font_family_map[WebPreferences::kCommonScript] =
- ConvertJavaStringToUTF16(str);
-
- str.Reset(
- env, static_cast<jstring>(
- env->GetObjectField(obj, field_ids_->cursive_font_family)));
- prefs.cursive_font_family_map[WebPreferences::kCommonScript] =
- ConvertJavaStringToUTF16(str);
-
- str.Reset(
- env, static_cast<jstring>(
- env->GetObjectField(obj, field_ids_->fantasy_font_family)));
- prefs.fantasy_font_family_map[WebPreferences::kCommonScript] =
- ConvertJavaStringToUTF16(str);
-
- str.Reset(
- env, static_cast<jstring>(
- env->GetObjectField(obj, field_ids_->default_text_encoding)));
- prefs.default_encoding = ConvertJavaStringToUTF8(str);
-
- prefs.minimum_font_size =
- env->GetIntField(obj, field_ids_->minimum_font_size);
-
- prefs.minimum_logical_font_size =
- env->GetIntField(obj, field_ids_->minimum_logical_font_size);
-
- prefs.default_font_size =
- env->GetIntField(obj, field_ids_->default_font_size);
-
- prefs.default_fixed_font_size =
- env->GetIntField(obj, field_ids_->default_fixed_font_size);
-
- prefs.loads_images_automatically =
- env->GetBooleanField(obj, field_ids_->load_images_automatically);
-
- prefs.images_enabled =
- env->GetBooleanField(obj, field_ids_->images_enabled);
-
- prefs.javascript_enabled =
- env->GetBooleanField(obj, field_ids_->java_script_enabled);
-
- prefs.allow_universal_access_from_file_urls = env->GetBooleanField(
- obj, field_ids_->allow_universal_access_from_file_urls);
-
- prefs.allow_file_access_from_file_urls = env->GetBooleanField(
- obj, field_ids_->allow_file_access_from_file_urls);
-
- prefs.javascript_can_open_windows_automatically = env->GetBooleanField(
- obj, field_ids_->java_script_can_open_windows_automatically);
-
- prefs.supports_multiple_windows = env->GetBooleanField(
- obj, field_ids_->support_multiple_windows);
-
- prefs.plugins_enabled = !Java_ContentSettings_getPluginsDisabled(env, obj);
-
- prefs.application_cache_enabled =
- Java_ContentSettings_getAppCacheEnabled(env, obj);
-
- prefs.local_storage_enabled = env->GetBooleanField(
- obj, field_ids_->dom_storage_enabled);
-
- prefs.databases_enabled = env->GetBooleanField(
- obj, field_ids_->database_enabled);
-
- prefs.viewport_enabled = env->GetBooleanField(
- obj, field_ids_->use_wide_viewport);
- prefs.double_tap_to_zoom_enabled = prefs.viewport_enabled;
-
- prefs.initialize_at_minimum_page_scale = env->GetBooleanField(
- obj, field_ids_->load_with_overview_mode);
-
- prefs.user_gesture_required_for_media_playback = env->GetBooleanField(
- obj, field_ids_->media_playback_requires_user_gesture);
-
- str.Reset(
- env, static_cast<jstring>(
- env->GetObjectField(obj, field_ids_->default_video_poster_url)));
- prefs.default_video_poster_url = str.obj() ?
- GURL(ConvertJavaStringToUTF8(str)) : GURL();
-
- render_view_host->UpdateWebkitPreferences(prefs);
-}
-
-void ContentSettings::SyncFromNative(JNIEnv* env, jobject obj) {
- SyncFromNativeImpl();
-}
-
-void ContentSettings::SyncToNative(JNIEnv* env, jobject obj) {
- SyncToNativeImpl();
-}
-
-void ContentSettings::RenderViewCreated(RenderViewHost* render_view_host) {
- if (is_master_mode_)
- SyncToNativeImpl();
+ if (!render_view_host)
+ return false;
+ return render_view_host->GetDelegate()->GetWebkitPrefs().javascript_enabled;
}
void ContentSettings::WebContentsDestroyed(WebContents* web_contents) {
delete this;
}
-static jint Init(JNIEnv* env, jobject obj, jint nativeContentViewCore,
- jboolean is_master_mode) {
+static jint Init(JNIEnv* env, jobject obj, jint nativeContentViewCore) {
WebContents* web_contents =
reinterpret_cast<ContentViewCoreImpl*>(nativeContentViewCore)
->GetWebContents();
ContentSettings* content_settings =
- new ContentSettings(env, obj, web_contents, is_master_mode);
+ new ContentSettings(env, obj, web_contents);
return reinterpret_cast<jint>(content_settings);
}
-static jstring GetDefaultUserAgent(JNIEnv* env, jclass clazz) {
- return base::android::ConvertUTF8ToJavaString(
- env, GetContentClient()->GetUserAgent()).Release();
-}
-
} // namespace content
diff --git a/content/browser/android/content_settings.h b/content/browser/android/content_settings.h
index 3a9128e..5c0f9a0 100644
--- a/content/browser/android/content_settings.h
+++ b/content/browser/android/content_settings.h
@@ -8,7 +8,6 @@
#include <jni.h>
#include "base/android/jni_helper.h"
-#include "base/memory/scoped_ptr.h"
#include "content/public/browser/web_contents_observer.h"
namespace content {
@@ -16,35 +15,19 @@
class ContentSettings : public WebContentsObserver {
public:
ContentSettings(JNIEnv* env, jobject obj,
- WebContents* contents,
- bool is_master_mode);
+ WebContents* contents);
static bool RegisterContentSettings(JNIEnv* env);
- // Synchronizes the Java settings from native settings.
- void SyncFromNative(JNIEnv* env, jobject obj);
- // Synchronizes the native settings from Java settings.
- void SyncToNative(JNIEnv* env, jobject obj);
+ bool GetJavaScriptEnabled(JNIEnv* env, jobject obj);
private:
- struct FieldIds;
// Self-deletes when the underlying WebContents is destroyed.
virtual ~ContentSettings();
- void SyncFromNativeImpl();
- void SyncToNativeImpl();
-
// WebContentsObserver overrides:
- virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE;
virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
- // Determines whether a sync to native should be triggered when a new render
- // view is created.
- bool is_master_mode_;
-
- // Java field references for accessing the values in the Java object.
- scoped_ptr<FieldIds> field_ids_;
-
// The Java counterpart to this class.
JavaObjectWeakGlobalRef content_settings_;
};
diff --git a/content/browser/android/content_video_view.cc b/content/browser/android/content_video_view.cc
index 158749b..242134b 100644
--- a/content/browser/android/content_video_view.cc
+++ b/content/browser/android/content_video_view.cc
@@ -7,7 +7,7 @@
#include "base/android/jni_android.h"
#include "base/command_line.h"
#include "base/logging.h"
-#include "content/browser/android/media_player_manager_android.h"
+#include "content/browser/android/media_player_manager_impl.h"
#include "content/common/android/surface_texture_peer.h"
#include "content/public/common/content_switches.h"
#include "jni/ContentVideoView_jni.h"
@@ -22,7 +22,7 @@
return RegisterNativesImpl(env);
}
-ContentVideoView::ContentVideoView(MediaPlayerManagerAndroid* manager)
+ContentVideoView::ContentVideoView(MediaPlayerManagerImpl* manager)
: manager_(manager) {
}
diff --git a/content/browser/android/content_video_view.h b/content/browser/android/content_video_view.h
index deb5ffc..49b8d05 100644
--- a/content/browser/android/content_video_view.h
+++ b/content/browser/android/content_video_view.h
@@ -15,17 +15,17 @@
namespace content {
-class MediaPlayerManagerAndroid;
+class MediaPlayerManagerImpl;
// Native mirror of ContentVideoView.java. This class is responsible for
// creating the Java video view and pass all the player status change to
// it. It accepts media control from Java class, and forwards it to
-// MediaPlayerManagerAndroid.
+// MediaPlayerManagerImpl.
class ContentVideoView {
public:
// Construct a ContentVideoView object. The |manager| will handle all the
// playback controls from the Java class.
- explicit ContentVideoView(MediaPlayerManagerAndroid* manager);
+ explicit ContentVideoView(MediaPlayerManagerImpl* manager);
~ContentVideoView();
static bool RegisterContentVideoView(JNIEnv* env);
@@ -66,7 +66,7 @@
private:
// Object that manages the fullscreen media player. It is responsible for
// handling all the playback controls.
- MediaPlayerManagerAndroid* manager_;
+ MediaPlayerManagerImpl* manager_;
// Reference to the Java object.
base::android::ScopedJavaGlobalRef<jobject> j_content_video_view_;
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 68cf0c5..41487dd 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -16,7 +16,6 @@
#include "cc/layers/layer.h"
#include "content/browser/android/interstitial_page_delegate_android.h"
#include "content/browser/android/load_url_params.h"
-#include "content/browser/android/media_player_manager_android.h"
#include "content/browser/android/sync_input_event_filter.h"
#include "content/browser/android/touch_point.h"
#include "content/browser/renderer_host/compositor_impl_android.h"
@@ -30,6 +29,7 @@
#include "content/browser/web_contents/navigation_controller_impl.h"
#include "content/browser/web_contents/navigation_entry_impl.h"
#include "content/browser/web_contents/web_contents_view_android.h"
+#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/favicon_status.h"
@@ -45,8 +45,9 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/android/WebInputEventFactory.h"
+#include "ui/android/view_android.h"
+#include "ui/android/window_android.h"
#include "ui/gfx/android/java_bitmap.h"
-#include "ui/gfx/android/window_android.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/size_conversions.h"
#include "ui/gfx/size_f.h"
@@ -150,15 +151,14 @@
ContentViewCoreImpl::ContentViewCoreImpl(JNIEnv* env, jobject obj,
bool hardware_accelerated,
- bool input_events_delivered_at_vsync,
WebContents* web_contents,
+ ui::ViewAndroid* view_android,
ui::WindowAndroid* window_android)
: java_ref_(env, obj),
web_contents_(static_cast<WebContentsImpl*>(web_contents)),
root_layer_(cc::Layer::Create()),
tab_crashed_(false),
- input_events_delivered_at_vsync_(input_events_delivered_at_vsync),
- renderer_frame_pending_(false),
+ view_android_(view_android),
window_android_(window_android) {
CHECK(web_contents) <<
"A ContentViewCoreImpl should be created with a valid WebContents.";
@@ -219,6 +219,9 @@
notification_registrar_.Add(
this, NOTIFICATION_WEB_CONTENTS_CONNECTED,
Source<WebContents>(web_contents_));
+ notification_registrar_.Add(
+ this, NOTIFICATION_WEB_CONTENTS_SWAPPED,
+ Source<WebContents>(web_contents_));
static_cast<WebContentsViewAndroid*>(web_contents_->GetView())->
SetContentViewCore(this);
@@ -278,6 +281,13 @@
}
break;
}
+ case NOTIFICATION_WEB_CONTENTS_SWAPPED: {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (!obj.is_null()) {
+ Java_ContentViewCore_onWebContentsSwapped(env, obj.obj());
+ }
+ }
}
}
@@ -300,21 +310,6 @@
return java_ref_.get(env);
}
-ScopedJavaLocalRef<jobject> ContentViewCoreImpl::GetContainerViewDelegate() {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (obj.is_null())
- return ScopedJavaLocalRef<jobject>();
- return Java_ContentViewCore_getContainerViewDelegate(env, obj.obj());
-}
-
-void ContentViewCoreImpl::OnWebPreferencesUpdated() {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj.is_null())
- Java_ContentViewCore_onWebPreferencesUpdated(env, obj.obj());
-}
-
jint ContentViewCoreImpl::GetBackgroundColor(JNIEnv* env, jobject obj) {
RenderWidgetHostViewAndroid* rwhva = GetRenderWidgetHostViewAndroid();
if (!rwhva)
@@ -348,6 +343,12 @@
}
void ContentViewCoreImpl::OnTabCrashed() {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return;
+ Java_ContentViewCore_resetVSyncNotification(env, obj.obj());
+
// if tab_crashed_ is already true, just return. e.g. if two tabs share the
// render process, this will be called for each tab when the render process
// crashed. If user reload one tab, a new render process is created. It can be
@@ -358,10 +359,6 @@
if (tab_crashed_)
return;
tab_crashed_ = true;
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (obj.is_null())
- return;
Java_ContentViewCore_onTabCrash(env, obj.obj());
}
@@ -375,7 +372,8 @@
const gfx::SizeF& content_size,
const gfx::SizeF& viewport_size,
const gfx::Vector2dF& controls_offset,
- const gfx::Vector2dF& content_offset) {
+ const gfx::Vector2dF& content_offset,
+ float overdraw_bottom_height) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
if (obj.is_null())
@@ -393,7 +391,8 @@
viewport_size.width(),
viewport_size.height(),
controls_offset.y(),
- content_offset.y());
+ content_offset.y(),
+ overdraw_bottom_height);
for (size_t i = 0; i < update_frame_info_callbacks_.size(); ++i) {
update_frame_info_callbacks_[i].Run(
@@ -431,7 +430,7 @@
// given |selected_item| as is.
ScopedJavaLocalRef<jintArray> selected_array;
if (multiple) {
- scoped_array<jint> native_selected_array(new jint[items.size()]);
+ scoped_ptr<jint[]> native_selected_array(new jint[items.size()]);
size_t selected_count = 0;
for (size_t i = 0; i < items.size(); ++i) {
if (items[i].checked)
@@ -600,6 +599,23 @@
env, obj.obj(), static_cast<jint>(player_id));
}
+void ContentViewCoreImpl::NotifyGeometryChange(int player_id,
+ const gfx::RectF& rect) {
+ JNIEnv* env = AttachCurrentThread();
+
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return;
+
+ Java_ContentViewCore_notifyGeometryChange(env,
+ obj.obj(),
+ static_cast<jint>(player_id),
+ static_cast<jfloat>(rect.x()),
+ static_cast<jfloat>(rect.y()),
+ static_cast<jfloat>(rect.width()),
+ static_cast<jfloat>(rect.height()));
+}
+
gfx::Size ContentViewCoreImpl::GetPhysicalBackingSize() const {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
@@ -615,8 +631,19 @@
ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
if (j_obj.is_null())
return gfx::Size();
- return gfx::Size(Java_ContentViewCore_getViewportWidthPix(env, j_obj.obj()),
- Java_ContentViewCore_getViewportHeightPix(env, j_obj.obj()));
+ return gfx::Size(
+ Java_ContentViewCore_getViewportWidthPix(env, j_obj.obj()),
+ Java_ContentViewCore_getViewportHeightPix(env, j_obj.obj()));
+}
+
+gfx::Size ContentViewCoreImpl::GetViewportSizeOffsetPix() const {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
+ if (j_obj.is_null())
+ return gfx::Size();
+ return gfx::Size(
+ Java_ContentViewCore_getViewportSizeOffsetWidthPix(env, j_obj.obj()),
+ Java_ContentViewCore_getViewportSizeOffsetHeightPix(env, j_obj.obj()));
}
gfx::Size ContentViewCoreImpl::GetViewportSizeDip() const {
@@ -624,6 +651,11 @@
gfx::ScaleSize(GetViewportSizePix(), 1.0f / GetDpiScale()));
}
+gfx::Size ContentViewCoreImpl::GetViewportSizeOffsetDip() const {
+ return gfx::ToCeiledSize(
+ gfx::ScaleSize(GetViewportSizeOffsetPix(), 1.0f / GetDpiScale()));
+}
+
float ContentViewCoreImpl::GetOverdrawBottomHeightDip() const {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
@@ -649,17 +681,30 @@
layer->RemoveFromParent();
}
-void ContentViewCoreImpl::DidProduceRendererFrame() {
- renderer_frame_pending_ = true;
-}
-
void ContentViewCoreImpl::LoadUrl(
NavigationController::LoadURLParams& params) {
GetWebContents()->GetController().LoadURLWithParams(params);
tab_crashed_ = false;
}
+void ContentViewCoreImpl::SetVSyncNotificationEnabled(bool enabled) {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return;
+ Java_ContentViewCore_setVSyncNotificationEnabled(
+ env, obj.obj(), static_cast<jboolean>(enabled));
+}
+
+ui::ViewAndroid* ContentViewCoreImpl::GetViewAndroid() const {
+ // view_android_ should never be null for Chrome.
+ DCHECK(view_android_);
+ return view_android_;
+}
+
ui::WindowAndroid* ContentViewCoreImpl::GetWindowAndroid() const {
+ // This should never be NULL for Chrome, but will be NULL for WebView.
+ DCHECK(window_android_);
return window_android_;
}
@@ -742,22 +787,6 @@
web_contents_->GetRenderViewHost());
}
-void ContentViewCoreImpl::SetAllUserAgentOverridesInHistory(
- JNIEnv* env,
- jobject,
- jstring user_agent_override) {
- bool override_used = user_agent_override != NULL;
- if (override_used) {
- std::string override =
- base::android::ConvertJavaStringToUTF8(env, user_agent_override);
- web_contents_->SetUserAgentOverride(override);
- }
-
- const NavigationController& controller = web_contents_->GetController();
- for (int i = 0; i < controller.GetEntryCount(); ++i)
- controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(override_used);
-}
-
ScopedJavaLocalRef<jstring> ContentViewCoreImpl::GetURL(
JNIEnv* env, jobject) const {
return ConvertUTF8ToJavaString(env, GetWebContents()->GetURL().spec());
@@ -809,7 +838,6 @@
WebKit::WebTouchEvent event;
TouchPoint::BuildWebTouchEvent(env, type, time_ms, GetDpiScale(), pts,
event);
- UpdateVSyncFlagOnInputEvent(&event);
rwhv->SendTouchEvent(event);
return true;
}
@@ -832,6 +860,14 @@
input_event_filter_->SetInputHandler(input_handler);
}
+void ContentViewCoreImpl::RequestContentClipping(
+ const gfx::Rect& clipping,
+ const gfx::Size& content_size) {
+ RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
+ if (rwhv)
+ rwhv->RequestContentClipping(clipping, content_size);
+}
+
jboolean ContentViewCoreImpl::SendMouseMoveEvent(JNIEnv* env,
jobject obj,
jlong time_ms,
@@ -876,27 +912,19 @@
}
WebGestureEvent ContentViewCoreImpl::MakeGestureEvent(
- WebInputEvent::Type type, long time_ms, float x, float y) const {
+ WebInputEvent::Type type, long time_ms, float x, float y,
+ InputEventVSyncStatus vsync_status) const {
WebGestureEvent event;
event.type = type;
event.x = x / GetDpiScale();
event.y = y / GetDpiScale();
event.timeStampSeconds = time_ms / 1000.0;
event.sourceDevice = WebGestureEvent::Touchscreen;
- UpdateVSyncFlagOnInputEvent(&event);
+ if (vsync_status == LAST_INPUT_EVENT_FOR_VSYNC)
+ event.modifiers |= WebInputEvent::IsLastInputEventForCurrentVSync;
return event;
}
-void ContentViewCoreImpl::UpdateVSyncFlagOnInputEvent(
- WebKit::WebInputEvent* event) const {
- if (!input_events_delivered_at_vsync_)
- return;
- if (event->type == WebInputEvent::GestureScrollUpdate ||
- event->type == WebInputEvent::GesturePinchUpdate ||
- event->type == WebInputEvent::TouchMove)
- event->modifiers |= WebInputEvent::IsLastInputEventForCurrentVSync;
-}
-
void ContentViewCoreImpl::SendGestureEvent(
const WebKit::WebGestureEvent& event) {
RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
@@ -907,20 +935,26 @@
void ContentViewCoreImpl::ScrollBegin(JNIEnv* env, jobject obj, jlong time_ms,
jfloat x, jfloat y) {
WebGestureEvent event = MakeGestureEvent(
- WebInputEvent::GestureScrollBegin, time_ms, x, y);
+ WebInputEvent::GestureScrollBegin, time_ms, x, y,
+ NOT_LAST_INPUT_EVENT_FOR_VSYNC);
SendGestureEvent(event);
}
void ContentViewCoreImpl::ScrollEnd(JNIEnv* env, jobject obj, jlong time_ms) {
WebGestureEvent event = MakeGestureEvent(
- WebInputEvent::GestureScrollEnd, time_ms, 0, 0);
+ WebInputEvent::GestureScrollEnd, time_ms, 0, 0,
+ NOT_LAST_INPUT_EVENT_FOR_VSYNC);
SendGestureEvent(event);
}
void ContentViewCoreImpl::ScrollBy(JNIEnv* env, jobject obj, jlong time_ms,
- jfloat x, jfloat y, jfloat dx, jfloat dy) {
+ jfloat x, jfloat y, jfloat dx, jfloat dy,
+ jboolean last_input_event_for_vsync) {
+ InputEventVSyncStatus vsync_status =
+ last_input_event_for_vsync ? LAST_INPUT_EVENT_FOR_VSYNC
+ : NOT_LAST_INPUT_EVENT_FOR_VSYNC;
WebGestureEvent event = MakeGestureEvent(
- WebInputEvent::GestureScrollUpdate, time_ms, x, y);
+ WebInputEvent::GestureScrollUpdate, time_ms, x, y, vsync_status);
event.data.scrollUpdate.deltaX = -dx / GetDpiScale();
event.data.scrollUpdate.deltaY = -dy / GetDpiScale();
@@ -930,7 +964,8 @@
void ContentViewCoreImpl::FlingStart(JNIEnv* env, jobject obj, jlong time_ms,
jfloat x, jfloat y, jfloat vx, jfloat vy) {
WebGestureEvent event = MakeGestureEvent(
- WebInputEvent::GestureFlingStart, time_ms, x, y);
+ WebInputEvent::GestureFlingStart, time_ms, x, y,
+ NOT_LAST_INPUT_EVENT_FOR_VSYNC);
// Velocity should not be scaled by DIP since that interacts poorly with the
// deceleration constants. The DIP scaling is done on the renderer.
@@ -942,7 +977,8 @@
void ContentViewCoreImpl::FlingCancel(JNIEnv* env, jobject obj, jlong time_ms) {
WebGestureEvent event = MakeGestureEvent(
- WebInputEvent::GestureFlingCancel, time_ms, 0, 0);
+ WebInputEvent::GestureFlingCancel, time_ms, 0, 0,
+ NOT_LAST_INPUT_EVENT_FOR_VSYNC);
SendGestureEvent(event);
}
@@ -950,7 +986,8 @@
jfloat x, jfloat y,
jboolean disambiguation_popup_tap) {
WebGestureEvent event = MakeGestureEvent(
- WebInputEvent::GestureTap, time_ms, x, y);
+ WebInputEvent::GestureTap, time_ms, x, y,
+ NOT_LAST_INPUT_EVENT_FOR_VSYNC);
event.data.tap.tapCount = 1;
if (!disambiguation_popup_tap) {
@@ -966,7 +1003,8 @@
jlong time_ms,
jfloat x, jfloat y) {
WebGestureEvent event = MakeGestureEvent(
- WebInputEvent::GestureTapDown, time_ms, x, y);
+ WebInputEvent::GestureTapDown, time_ms, x, y,
+ NOT_LAST_INPUT_EVENT_FOR_VSYNC);
SendGestureEvent(event);
}
@@ -976,14 +1014,16 @@
jfloat x,
jfloat y) {
WebGestureEvent event = MakeGestureEvent(
- WebInputEvent::GestureTapCancel, time_ms, x, y);
+ WebInputEvent::GestureTapCancel, time_ms, x, y,
+ NOT_LAST_INPUT_EVENT_FOR_VSYNC);
SendGestureEvent(event);
}
void ContentViewCoreImpl::DoubleTap(JNIEnv* env, jobject obj, jlong time_ms,
jfloat x, jfloat y) {
WebGestureEvent event = MakeGestureEvent(
- WebInputEvent::GestureDoubleTap, time_ms, x, y);
+ WebInputEvent::GestureDoubleTap, time_ms, x, y,
+ NOT_LAST_INPUT_EVENT_FOR_VSYNC);
SendGestureEvent(event);
}
@@ -991,7 +1031,8 @@
jfloat x, jfloat y,
jboolean disambiguation_popup_tap) {
WebGestureEvent event = MakeGestureEvent(
- WebInputEvent::GestureLongPress, time_ms, x, y);
+ WebInputEvent::GestureLongPress, time_ms, x, y,
+ NOT_LAST_INPUT_EVENT_FOR_VSYNC);
if (!disambiguation_popup_tap) {
const float touch_padding_dip = GetTouchPaddingDip();
@@ -1006,7 +1047,8 @@
jfloat x, jfloat y,
jboolean disambiguation_popup_tap) {
WebGestureEvent event = MakeGestureEvent(
- WebInputEvent::GestureLongTap, time_ms, x, y);
+ WebInputEvent::GestureLongTap, time_ms, x, y,
+ NOT_LAST_INPUT_EVENT_FOR_VSYNC);
if (!disambiguation_popup_tap) {
const float touch_padding_dip = GetTouchPaddingDip();
@@ -1020,21 +1062,28 @@
void ContentViewCoreImpl::PinchBegin(JNIEnv* env, jobject obj, jlong time_ms,
jfloat x, jfloat y) {
WebGestureEvent event = MakeGestureEvent(
- WebInputEvent::GesturePinchBegin, time_ms, x, y);
+ WebInputEvent::GesturePinchBegin, time_ms, x, y,
+ NOT_LAST_INPUT_EVENT_FOR_VSYNC);
SendGestureEvent(event);
}
void ContentViewCoreImpl::PinchEnd(JNIEnv* env, jobject obj, jlong time_ms) {
WebGestureEvent event = MakeGestureEvent(
- WebInputEvent::GesturePinchEnd, time_ms, 0, 0);
+ WebInputEvent::GesturePinchEnd, time_ms, 0, 0,
+ NOT_LAST_INPUT_EVENT_FOR_VSYNC);
SendGestureEvent(event);
}
void ContentViewCoreImpl::PinchBy(JNIEnv* env, jobject obj, jlong time_ms,
jfloat anchor_x, jfloat anchor_y,
- jfloat delta) {
+ jfloat delta,
+ jboolean last_input_event_for_vsync) {
+ InputEventVSyncStatus vsync_status =
+ last_input_event_for_vsync ? LAST_INPUT_EVENT_FOR_VSYNC
+ : NOT_LAST_INPUT_EVENT_FOR_VSYNC;
WebGestureEvent event = MakeGestureEvent(
- WebInputEvent::GesturePinchUpdate, time_ms, anchor_x, anchor_y);
+ WebInputEvent::GesturePinchUpdate, time_ms, anchor_x, anchor_y,
+ vsync_status);
event.data.pinchUpdate.scale = delta;
SendGestureEvent(event);
@@ -1162,6 +1211,15 @@
base::TimeDelta::FromMicroseconds(interval_micros));
}
+void ContentViewCoreImpl::OnVSync(JNIEnv* env, jobject /* obj */,
+ jlong frame_time_micros) {
+ RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid();
+ if (!view)
+ return;
+
+ view->SendVSync(base::TimeTicks::FromInternalValue(frame_time_micros));
+}
+
jboolean ContentViewCoreImpl::PopulateBitmapFromCompositor(JNIEnv* env,
jobject obj,
jobject jbitmap) {
@@ -1194,34 +1252,31 @@
return web_contents_->ShowingInterstitialPage();
}
-jboolean ContentViewCoreImpl::ConsumePendingRendererFrame(JNIEnv* env,
- jobject obj) {
- bool had_pending_frame = renderer_frame_pending_;
- renderer_frame_pending_ = false;
- return had_pending_frame;
-}
-
void ContentViewCoreImpl::AttachExternalVideoSurface(JNIEnv* env,
jobject obj,
jint player_id,
jobject jsurface) {
+#if defined(GOOGLE_TV)
RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>(
web_contents_->GetRenderViewHost());
if (rvhi && rvhi->media_player_manager()) {
rvhi->media_player_manager()->AttachExternalVideoSurface(
static_cast<int>(player_id), jsurface);
}
+#endif
}
void ContentViewCoreImpl::DetachExternalVideoSurface(JNIEnv* env,
jobject obj,
jint player_id) {
+#if defined(GOOGLE_TV)
RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>(
web_contents_->GetRenderViewHost());
if (rvhi && rvhi->media_player_manager()) {
rvhi->media_player_manager()->DetachExternalVideoSurface(
static_cast<int>(player_id));
}
+#endif
}
jboolean ContentViewCoreImpl::IsRenderWidgetHostViewReady(JNIEnv* env,
@@ -1235,10 +1290,16 @@
host->ExitFullscreen();
}
-void ContentViewCoreImpl::EnableHidingTopControls(JNIEnv* env, jobject obj,
- bool enable) {
+void ContentViewCoreImpl::UpdateTopControlsState(JNIEnv* env,
+ jobject obj,
+ bool enable_hiding,
+ bool enable_showing,
+ bool animate) {
RenderViewHost* host = web_contents_->GetRenderViewHost();
- host->Send(new ViewMsg_EnableHidingTopControls(host->GetRoutingID(), enable));
+ host->Send(new ViewMsg_UpdateTopControlsState(host->GetRoutingID(),
+ enable_hiding,
+ enable_showing,
+ animate));
}
void ContentViewCoreImpl::ShowImeIfNeeded(JNIEnv* env, jobject obj) {
@@ -1249,8 +1310,8 @@
void ContentViewCoreImpl::ScrollFocusedEditableNodeIntoView(JNIEnv* env,
jobject obj) {
RenderViewHost* host = web_contents_->GetRenderViewHost();
- host->Send(new ViewMsg_ScrollFocusedEditableNodeIntoRect(host->GetRoutingID(),
- gfx::Rect()));
+ host->Send(new InputMsg_ScrollFocusedEditableNodeIntoRect(
+ host->GetRoutingID(), gfx::Rect()));
}
namespace {
@@ -1283,13 +1344,13 @@
int ContentViewCoreImpl::GetNavigationHistory(JNIEnv* env,
jobject obj,
- jobject context) {
+ jobject history) {
// Iterate through navigation entries to populate the list
const NavigationController& controller = web_contents_->GetController();
int count = controller.GetEntryCount();
for (int i = 0; i < count; ++i) {
AddNavigationEntryToHistory(
- env, obj, context, controller.GetEntryAtIndex(i), i);
+ env, obj, history, controller.GetEntryAtIndex(i), i);
}
return controller.GetCurrentEntryIndex();
@@ -1297,7 +1358,7 @@
void ContentViewCoreImpl::GetDirectedNavigationHistory(JNIEnv* env,
jobject obj,
- jobject context,
+ jobject history,
jboolean is_forward,
jint max_entries) {
// Iterate through navigation entries to populate the list
@@ -1312,11 +1373,20 @@
break;
AddNavigationEntryToHistory(
- env, obj, context, controller.GetEntryAtIndex(i), i);
+ env, obj, history, controller.GetEntryAtIndex(i), i);
num_added++;
}
}
+ScopedJavaLocalRef<jstring>
+ContentViewCoreImpl::GetOriginalUrlForActiveNavigationEntry(JNIEnv* env,
+ jobject obj) {
+ NavigationEntry* entry = web_contents_->GetController().GetActiveEntry();
+ if (entry == NULL)
+ return ScopedJavaLocalRef<jstring>(env, NULL);
+ return ConvertUTF8ToJavaString(env, entry->GetOriginalRequestURL().spec());
+}
+
int ContentViewCoreImpl::GetNativeImeAdapter(JNIEnv* env, jobject obj) {
RenderWidgetHostViewAndroid* rwhva = GetRenderWidgetHostViewAndroid();
if (!rwhva)
@@ -1446,14 +1516,15 @@
// This is called for each ContentView.
jint Init(JNIEnv* env, jobject obj,
- jboolean input_events_delivered_at_vsync,
jboolean hardware_accelerated,
jint native_web_contents,
- jint native_window) {
+ jint view_android,
+ jint window_android) {
ContentViewCoreImpl* view = new ContentViewCoreImpl(
- env, obj, input_events_delivered_at_vsync, hardware_accelerated,
+ env, obj, hardware_accelerated,
reinterpret_cast<WebContents*>(native_web_contents),
- reinterpret_cast<ui::WindowAndroid*>(native_window));
+ reinterpret_cast<ui::ViewAndroid*>(view_android),
+ reinterpret_cast<ui::WindowAndroid*>(window_android));
return reinterpret_cast<jint>(view);
}
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index ba17590..414f5cc 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -21,10 +21,12 @@
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
#include "ui/gfx/rect.h"
+#include "ui/gfx/rect_f.h"
struct WebMenuItem;
namespace ui {
+class ViewAndroid;
class WindowAndroid;
}
@@ -40,19 +42,17 @@
ContentViewCoreImpl(JNIEnv* env,
jobject obj,
bool hardware_accelerated,
- bool input_events_delivered_at_vsync,
WebContents* web_contents,
+ ui::ViewAndroid* view_android,
ui::WindowAndroid* window_android);
// ContentViewCore implementation.
virtual base::android::ScopedJavaLocalRef<jobject> GetJavaObject() OVERRIDE;
- virtual base::android::ScopedJavaLocalRef<jobject> GetContainerViewDelegate()
- OVERRIDE;
virtual WebContents* GetWebContents() const OVERRIDE;
+ virtual ui::ViewAndroid* GetViewAndroid() const OVERRIDE;
virtual ui::WindowAndroid* GetWindowAndroid() const OVERRIDE;
virtual scoped_refptr<cc::Layer> GetLayer() const OVERRIDE;
virtual void LoadUrl(NavigationController::LoadURLParams& params) OVERRIDE;
- virtual void OnWebPreferencesUpdated() OVERRIDE;
virtual jint GetCurrentRenderProcessId(JNIEnv* env, jobject obj) OVERRIDE;
virtual void ShowPastePopup(int x, int y) OVERRIDE;
virtual unsigned int GetScaledContentTexture(
@@ -61,6 +61,8 @@
virtual float GetDpiScale() const OVERRIDE;
virtual void SetInputHandler(
WebKit::WebCompositorInputHandler* input_handler) OVERRIDE;
+ virtual void RequestContentClipping(const gfx::Rect& clipping,
+ const gfx::Size& content_size) OVERRIDE;
virtual void AddFrameInfoCallback(
const UpdateFrameInfoCallback& callback) OVERRIDE;
virtual void RemoveFrameInfoCallback(
@@ -87,10 +89,6 @@
jstring base_url_for_data_url,
jstring virtual_url_for_data_url,
jboolean can_load_local_resources);
- void SetAllUserAgentOverridesInHistory(
- JNIEnv* env,
- jobject obj,
- jstring user_agent_override);
base::android::ScopedJavaLocalRef<jstring> GetURL(JNIEnv* env, jobject) const;
base::android::ScopedJavaLocalRef<jstring> GetTitle(
JNIEnv* env, jobject obj) const;
@@ -116,7 +114,8 @@
void ScrollBegin(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y);
void ScrollEnd(JNIEnv* env, jobject obj, jlong time_ms);
void ScrollBy(JNIEnv* env, jobject obj, jlong time_ms,
- jfloat x, jfloat y, jfloat dx, jfloat dy);
+ jfloat x, jfloat y, jfloat dx, jfloat dy,
+ jboolean last_input_event_for_vsync);
void FlingStart(JNIEnv* env, jobject obj, jlong time_ms,
jfloat x, jfloat y, jfloat vx, jfloat vy);
void FlingCancel(JNIEnv* env, jobject obj, jlong time_ms);
@@ -138,8 +137,8 @@
void PinchBegin(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y);
void PinchEnd(JNIEnv* env, jobject obj, jlong time_ms);
void PinchBy(JNIEnv* env, jobject obj, jlong time_ms,
- jfloat x, jfloat y,
- jfloat delta);
+ jfloat x, jfloat y, jfloat delta,
+ jboolean last_input_event_for_vsync);
void SelectBetweenCoordinates(JNIEnv* env, jobject obj,
jfloat x1, jfloat y1,
jfloat x2, jfloat y2);
@@ -186,21 +185,28 @@
jclass safe_annotation_clazz,
jobject retained_object_set);
void RemoveJavascriptInterface(JNIEnv* env, jobject obj, jstring name);
- int GetNavigationHistory(JNIEnv* env, jobject obj, jobject context);
+ int GetNavigationHistory(JNIEnv* env, jobject obj, jobject history);
void GetDirectedNavigationHistory(JNIEnv* env,
jobject obj,
- jobject context,
+ jobject history,
jboolean is_forward,
jint max_entries);
+ base::android::ScopedJavaLocalRef<jstring>
+ GetOriginalUrlForActiveNavigationEntry(JNIEnv* env, jobject obj);
void UpdateVSyncParameters(JNIEnv* env, jobject obj, jlong timebase_micros,
jlong interval_micros);
+ void OnVSync(JNIEnv* env, jobject /* obj */, jlong frame_time_micros);
jboolean PopulateBitmapFromCompositor(JNIEnv* env,
jobject obj,
jobject jbitmap);
void WasResized(JNIEnv* env, jobject obj);
jboolean IsRenderWidgetHostViewReady(JNIEnv* env, jobject obj);
void ExitFullscreen(JNIEnv* env, jobject obj);
- void EnableHidingTopControls(JNIEnv* env, jobject obj, bool enable);
+ void UpdateTopControlsState(JNIEnv* env,
+ jobject obj,
+ bool enable_hiding,
+ bool enable_showing,
+ bool animate);
void ShowImeIfNeeded(JNIEnv* env, jobject obj);
void ShowInterstitialPage(JNIEnv* env,
@@ -209,8 +215,6 @@
jint delegate);
jboolean IsShowingInterstitialPage(JNIEnv* env, jobject obj);
- jboolean ConsumePendingRendererFrame(JNIEnv* env, jobject obj);
-
void AttachExternalVideoSurface(JNIEnv* env,
jobject obj,
jint player_id,
@@ -238,7 +242,8 @@
const gfx::SizeF& content_size,
const gfx::SizeF& viewport_size,
const gfx::Vector2dF& controls_offset,
- const gfx::Vector2dF& content_offset);
+ const gfx::Vector2dF& content_offset,
+ float overdraw_bottom_height);
void UpdateImeAdapter(int native_ime_adapter, int text_input_type,
const std::string& text,
@@ -265,6 +270,7 @@
const gfx::Rect& target_rect, const SkBitmap& zoomed_bitmap);
void RequestExternalVideoSurface(int player_id);
+ void NotifyGeometryChange(int player_id, const gfx::RectF& rect);
// --------------------------------------------------------------------------
// Methods called from native code
@@ -272,15 +278,21 @@
gfx::Size GetPhysicalBackingSize() const;
gfx::Size GetViewportSizeDip() const;
+ gfx::Size GetViewportSizeOffsetDip() const;
float GetOverdrawBottomHeightDip() const;
InputEventAckState FilterInputEvent(const WebKit::WebInputEvent& input_event);
void AttachLayer(scoped_refptr<cc::Layer> layer);
void RemoveLayer(scoped_refptr<cc::Layer> layer);
- void DidProduceRendererFrame();
+ void SetVSyncNotificationEnabled(bool enabled);
private:
+ enum InputEventVSyncStatus {
+ NOT_LAST_INPUT_EVENT_FOR_VSYNC,
+ LAST_INPUT_EVENT_FOR_VSYNC
+ };
+
class ContentViewUserData;
friend class ContentViewUserData;
@@ -303,11 +315,10 @@
WebKit::WebGestureEvent MakeGestureEvent(
WebKit::WebInputEvent::Type type, long time_ms,
- float xPix, float yPix) const;
+ float x, float y, InputEventVSyncStatus vsync_status) const;
gfx::Size GetViewportSizePix() const;
-
- void UpdateVSyncFlagOnInputEvent(WebKit::WebInputEvent* event) const;
+ gfx::Size GetViewportSizeOffsetPix() const;
void DeleteScaledSnapshotTexture();
@@ -328,16 +339,13 @@
// Whether the renderer backing this ContentViewCore has crashed.
bool tab_crashed_;
- // Whether input events will be consistently delivered at vsync time.
- bool input_events_delivered_at_vsync_;
-
- // Whether a new frame from the renderer is waiting to be displayed by the
- // browser compositor.
- bool renderer_frame_pending_;
-
// Device scale factor.
float dpi_scale_;
+ // The Android view that can be used to add and remove decoration layers
+ // like AutofillPopup.
+ ui::ViewAndroid* view_android_;
+
// The owning window that has a hold of main application activity.
ui::WindowAndroid* window_android_;
diff --git a/content/browser/android/content_view_render_view.cc b/content/browser/android/content_view_render_view.cc
index 8e38e08..635ff80 100644
--- a/content/browser/android/content_view_render_view.cc
+++ b/content/browser/android/content_view_render_view.cc
@@ -31,7 +31,7 @@
ContentViewRenderView::ContentViewRenderView()
: scheduled_composite_(false),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ weak_factory_(this) {
}
ContentViewRenderView::~ContentViewRenderView() {
@@ -77,19 +77,19 @@
return;
scheduled_composite_ = true;
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&ContentViewRenderView::Composite,
weak_factory_.GetWeakPtr()));
}
void ContentViewRenderView::InitCompositor() {
- if (!compositor_.get())
+ if (!compositor_)
compositor_.reset(Compositor::Create(this));
}
void ContentViewRenderView::Composite() {
- if (!compositor_.get())
+ if (!compositor_)
return;
scheduled_composite_ = false;
diff --git a/content/browser/android/content_view_statics.cc b/content/browser/android/content_view_statics.cc
index 0fb0896..66af865 100644
--- a/content/browser/android/content_view_statics.cc
+++ b/content/browser/android/content_view_statics.cc
@@ -3,25 +3,64 @@
// found in the LICENSE file.
#include <jni.h>
+#include <vector>
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/basictypes.h"
+#include "base/lazy_instance.h"
#include "base/logging.h"
#include "content/browser/android/content_view_statics.h"
#include "content/common/android/address_parser.h"
#include "content/common/view_messages.h"
#include "content/public/browser/render_process_host.h"
-
#include "jni/ContentViewStatics_jni.h"
using base::android::ConvertJavaStringToUTF16;
using base::android::ConvertUTF16ToJavaString;
-using base::android::ScopedJavaLocalRef;
+namespace {
-// Return the first substring consisting of the address of a physical location.
+// TODO(pliard): http://crbug.com/235909. Move WebKit shared timer toggling
+// functionality out of ContentViewStatistics and not be build on top of
+// WebKit::Platform::SuspendSharedTimer.
+// TODO(pliard): http://crbug.com/235912. Add unit tests for WebKit shared timer
+// toggling.
+
+// This tracks the renderer processes that received a suspend request. It's
+// important on resume to only resume the renderer processes that were actually
+// suspended as opposed to all the current renderer processes because the
+// suspend calls are refcounted within WebKitPlatformSupport and it expects a
+// perfectly matched number of resume calls.
+// Note that this vector is only accessed from the UI thread.
+base::LazyInstance<std::vector<int /* process id */> > g_suspended_processes =
+ LAZY_INSTANCE_INITIALIZER;
+
+// Suspends timers in all current render processes.
+void SuspendWebKitSharedTimers(std::vector<int>* suspended_processes) {
+ for (content::RenderProcessHost::iterator i(
+ content::RenderProcessHost::AllHostsIterator());
+ !i.IsAtEnd(); i.Advance()) {
+ content::RenderProcessHost* host = i.GetCurrentValue();
+ suspended_processes->push_back(host->GetID());
+ host->Send(new ViewMsg_SetWebKitSharedTimersSuspended(true));
+ }
+}
+
+// Resumes timers in processes that were previously stopped.
+void ResumeWebkitSharedTimers(const std::vector<int>& suspended_processes) {
+ for (std::vector<int>::const_iterator it = suspended_processes.begin();
+ it != suspended_processes.end(); ++it) {
+ content::RenderProcessHost* host = content::RenderProcessHost::FromID(*it);
+ if (host) // The process might have been killed since it was suspended.
+ host->Send(new ViewMsg_SetWebKitSharedTimersSuspended(false));
+ }
+}
+
+} // namespace
+
+// Returns the first substring consisting of the address of a physical location.
static jstring FindAddress(JNIEnv* env, jclass clazz, jstring addr) {
string16 content_16 = ConvertJavaStringToUTF16(env, addr);
string16 result_16;
@@ -33,12 +72,13 @@
static void SetWebKitSharedTimersSuspended(JNIEnv* env,
jclass obj,
jboolean suspend) {
- for (content::RenderProcessHost::iterator i =
- content::RenderProcessHost::AllHostsIterator();
- !i.IsAtEnd();
- i.Advance()) {
- content::RenderProcessHost* host = i.GetCurrentValue();
- host->Send(new ViewMsg_SetWebKitSharedTimersSuspended(suspend));
+ std::vector<int>* suspended_processes = g_suspended_processes.Pointer();
+ if (suspend) {
+ DCHECK(suspended_processes->empty());
+ SuspendWebKitSharedTimers(suspended_processes);
+ } else {
+ ResumeWebkitSharedTimers(*suspended_processes);
+ suspended_processes->clear();
}
}
diff --git a/content/browser/android/date_time_chooser_android.cc b/content/browser/android/date_time_chooser_android.cc
index 95bf2f3..0a9a1e2 100644
--- a/content/browser/android/date_time_chooser_android.cc
+++ b/content/browser/android/date_time_chooser_android.cc
@@ -55,7 +55,8 @@
}
// DateTimeChooserAndroid implementation
-DateTimeChooserAndroid::DateTimeChooserAndroid() {
+DateTimeChooserAndroid::DateTimeChooserAndroid()
+ : sender_(NULL) {
}
DateTimeChooserAndroid::~DateTimeChooserAndroid() {
@@ -89,7 +90,10 @@
ContentViewCore* content, RenderViewHost* sender,
int type, int year, int month, int day,
int hour, int minute, int second) {
- sender_.reset(new DateTimeIPCSender(sender));
+ if (sender_)
+ delete sender_;
+ sender_ = new DateTimeIPCSender(sender);
+
JNIEnv* env = AttachCurrentThread();
j_date_time_chooser_.Reset(Java_DateTimeChooserAndroid_createDateTimeChooser(
env, content->GetJavaObject().obj(),
diff --git a/content/browser/android/date_time_chooser_android.h b/content/browser/android/date_time_chooser_android.h
index c33c5c4..6709c38 100644
--- a/content/browser/android/date_time_chooser_android.h
+++ b/content/browser/android/date_time_chooser_android.h
@@ -45,7 +45,10 @@
private:
class DateTimeIPCSender;
- scoped_ptr<DateTimeIPCSender> sender_;
+ // The DateTimeIPCSender class is a render view observer, so it will take care
+ // of its own deletion.
+ DateTimeIPCSender* sender_;
+
base::android::ScopedJavaGlobalRef<jobject> j_date_time_chooser_;
DISALLOW_COPY_AND_ASSIGN(DateTimeChooserAndroid);
diff --git a/content/browser/android/download_controller_android_impl.cc b/content/browser/android/download_controller_android_impl.cc
index 2ade0d0..cc8d640 100644
--- a/content/browser/android/download_controller_android_impl.cc
+++ b/content/browser/android/download_controller_android_impl.cc
@@ -11,14 +11,18 @@
#include "base/memory/scoped_ptr.h"
#include "content/browser/android/content_view_core_impl.h"
#include "content/browser/download/download_item_impl.h"
+#include "content/browser/download/download_manager_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.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_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/download_url_parameters.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/web_contents_view.h"
+#include "content/public/common/referrer.h"
#include "jni/DownloadController_jni.h"
#include "net/cookies/cookie_options.h"
#include "net/cookies/cookie_store.h"
@@ -79,10 +83,8 @@
}
void DownloadControllerAndroidImpl::CreateGETDownload(
- RenderViewHost* render_view_host,
- int request_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- int render_process_id = render_view_host->GetProcess()->GetID();
+ int render_process_id, int render_view_id, int request_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
GlobalRequestID global_id(render_process_id, request_id);
// We are yielding the UI thread and render_view_host may go away by
@@ -91,14 +93,12 @@
GetDownloadInfoCB cb = base::Bind(
&DownloadControllerAndroidImpl::StartAndroidDownload,
base::Unretained(this), render_process_id,
- render_view_host->GetRoutingID());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(
- &DownloadControllerAndroidImpl::PrepareDownloadInfo,
- base::Unretained(this), global_id,
- base::Bind(&DownloadControllerAndroidImpl::StartDownloadOnUIThread,
- base::Unretained(this), cb)));
+ render_view_id);
+
+ PrepareDownloadInfo(
+ global_id,
+ base::Bind(&DownloadControllerAndroidImpl::StartDownloadOnUIThread,
+ base::Unretained(this), cb));
}
void DownloadControllerAndroidImpl::PrepareDownloadInfo(
@@ -226,7 +226,7 @@
jcookie.obj(), jreferer.obj(), info.total_bytes);
}
-void DownloadControllerAndroidImpl::OnPostDownloadStarted(
+void DownloadControllerAndroidImpl::OnDownloadStarted(
DownloadItem* download_item) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!download_item->GetWebContents())
@@ -243,12 +243,14 @@
if (view.is_null())
return;
- Java_DownloadController_onHttpPostDownloadStarted(
+ Java_DownloadController_onDownloadStarted(
env, GetJavaObject()->Controller(env).obj(), view.obj());
}
void DownloadControllerAndroidImpl::OnDownloadUpdated(DownloadItem* item) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (item->IsDangerous() && !item->IsCancelled())
+ OnDangerousDownload(item);
if (!item->IsComplete())
return;
@@ -275,12 +277,25 @@
return;
}
- Java_DownloadController_onHttpPostDownloadCompleted(env,
+ Java_DownloadController_onDownloadCompleted(env,
GetJavaObject()->Controller(env).obj(), view_core.obj(), jurl.obj(),
jcontent_disposition.obj(), jmime_type.obj(), jpath.obj(),
item->GetReceivedBytes(), true);
}
+void DownloadControllerAndroidImpl::OnDangerousDownload(DownloadItem* item) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> jfilename = ConvertUTF8ToJavaString(
+ env, item->GetTargetFilePath().BaseName().value());
+ ScopedJavaLocalRef<jobject> view_core = GetContentViewCoreFromWebContents(
+ item->GetWebContents());
+ if (!view_core.is_null()) {
+ Java_DownloadController_onDangerousDownload(
+ env, GetJavaObject()->Controller(env).obj(), view_core.obj(),
+ jfilename.obj(), item->GetId());
+ }
+}
+
ScopedJavaLocalRef<jobject> DownloadControllerAndroidImpl::GetContentView(
int render_process_id, int render_view_id) {
RenderViewHost* render_view_host =
@@ -301,10 +316,7 @@
ScopedJavaLocalRef<jobject>
DownloadControllerAndroidImpl::GetContentViewCoreFromWebContents(
WebContents* web_contents) {
- if (!web_contents)
- return ScopedJavaLocalRef<jobject>();
-
- ContentViewCore* view_core = web_contents->GetView()->GetContentNativeView();
+ ContentViewCore* view_core = ContentViewCore::FromWebContents(web_contents);
return view_core ? view_core->GetJavaObject() :
ScopedJavaLocalRef<jobject>();
}
@@ -323,6 +335,40 @@
return java_object_;
}
+void DownloadControllerAndroidImpl::StartContextMenuDownload(
+ const ContextMenuParams& params, WebContents* web_contents, bool is_link) {
+ const GURL& url = is_link ? params.link_url : params.src_url;
+ const GURL& referrer = params.frame_url.is_empty() ?
+ params.page_url : params.frame_url;
+ DownloadManagerImpl* dlm = static_cast<DownloadManagerImpl*>(
+ BrowserContext::GetDownloadManager(web_contents->GetBrowserContext()));
+ scoped_ptr<DownloadUrlParameters> dl_params(
+ DownloadUrlParameters::FromWebContents(web_contents, url));
+ dl_params->set_referrer(
+ Referrer(referrer, params.referrer_policy));
+ if (is_link)
+ dl_params->set_referrer_encoding(params.frame_charset);
+ else
+ dl_params->set_prefer_cache(true);
+ dl_params->set_prompt(false);
+ dlm->DownloadUrl(dl_params.Pass());
+}
+
+void DownloadControllerAndroidImpl::DangerousDownloadValidated(
+ WebContents* web_contents, int download_id, bool accept) {
+ if (!web_contents)
+ return;
+ DownloadManagerImpl* dlm = static_cast<DownloadManagerImpl*>(
+ BrowserContext::GetDownloadManager(web_contents->GetBrowserContext()));
+ DownloadItem* item = dlm->GetDownload(download_id);
+ if (!item)
+ return;
+ if (accept)
+ item->DangerousDownloadValidated();
+ else
+ item->Delete(content::DownloadItem::DELETE_DUE_TO_USER_DISCARD);
+}
+
DownloadControllerAndroidImpl::DownloadInfoAndroid::DownloadInfoAndroid(
net::URLRequest* request) {
request->GetResponseHeaderByName("content-disposition", &content_disposition);
@@ -332,7 +378,7 @@
request->extra_request_headers().GetHeader(
net::HttpRequestHeaders::kUserAgent, &user_agent);
- GURL referer_url(request->GetSanitizedReferrer());
+ GURL referer_url(request->referrer());
if (referer_url.is_valid())
referer = referer_url.spec();
if (!request->url_chain().empty()) {
diff --git a/content/browser/android/download_controller_android_impl.h b/content/browser/android/download_controller_android_impl.h
index 6dc87e2..c8a0ea2 100644
--- a/content/browser/android/download_controller_android_impl.h
+++ b/content/browser/android/download_controller_android_impl.h
@@ -75,9 +75,14 @@
virtual ~DownloadControllerAndroidImpl();
// DownloadControllerAndroid implementation.
- virtual void CreateGETDownload(RenderViewHost* source,
+ virtual void CreateGETDownload(int render_process_id, int render_view_id,
int request_id) OVERRIDE;
- virtual void OnPostDownloadStarted(DownloadItem* download_item) OVERRIDE;
+ virtual void OnDownloadStarted(DownloadItem* download_item) OVERRIDE;
+ virtual void StartContextMenuDownload(
+ const ContextMenuParams& params, WebContents* web_contents,
+ bool is_link) OVERRIDE;
+ virtual void DangerousDownloadValidated(
+ WebContents* web_contents, int download_id, bool accept) OVERRIDE;
// DownloadItem::Observer interface.
virtual void OnDownloadUpdated(DownloadItem* item) OVERRIDE;
@@ -102,6 +107,9 @@
int render_view_id,
const DownloadInfoAndroid& info);
+ // The download item contains dangerous file types.
+ void OnDangerousDownload(DownloadItem *item);
+
base::android::ScopedJavaLocalRef<jobject> GetContentViewCoreFromWebContents(
WebContents* web_contents);
diff --git a/content/browser/android/media_player_manager_android.cc b/content/browser/android/media_player_manager_android.cc
deleted file mode 100644
index 7375ff7..0000000
--- a/content/browser/android/media_player_manager_android.cc
+++ /dev/null
@@ -1,331 +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/android/media_player_manager_android.h"
-
-#include "base/bind.h"
-#include "content/browser/android/media_resource_getter_impl.h"
-#include "content/browser/web_contents/web_contents_view_android.h"
-#include "content/common/media/media_player_messages.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/storage_partition.h"
-
-using media::MediaPlayerBridge;
-
-// Threshold on the number of media players per renderer before we start
-// attempting to release inactive media players.
-static const int kMediaPlayerThreshold = 1;
-
-namespace content {
-
-MediaPlayerManagerAndroid::MediaPlayerManagerAndroid(
- RenderViewHost* render_view_host)
- : RenderViewHostObserver(render_view_host),
- ALLOW_THIS_IN_INITIALIZER_LIST(video_view_(this)),
- fullscreen_player_id_(-1),
- web_contents_(WebContents::FromRenderViewHost(render_view_host)) {
-}
-
-MediaPlayerManagerAndroid::~MediaPlayerManagerAndroid() {}
-
-bool MediaPlayerManagerAndroid::OnMessageReceived(const IPC::Message& msg) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(MediaPlayerManagerAndroid, 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_DestroyMediaPlayer, OnDestroyPlayer)
- IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyAllMediaPlayers,
- DestroyAllMediaPlayers)
- IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_RequestExternalSurface,
- OnRequestExternalSurface)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-void MediaPlayerManagerAndroid::FullscreenPlayerPlay() {
- MediaPlayerBridge* player = GetFullscreenPlayer();
- if (player) {
- player->Start();
- Send(new MediaPlayerMsg_DidMediaPlayerPlay(
- routing_id(), fullscreen_player_id_));
- }
-}
-
-void MediaPlayerManagerAndroid::FullscreenPlayerPause() {
- MediaPlayerBridge* player = GetFullscreenPlayer();
- if (player) {
- player->Pause();
- Send(new MediaPlayerMsg_DidMediaPlayerPause(
- routing_id(), fullscreen_player_id_));
- }
-}
-
-void MediaPlayerManagerAndroid::FullscreenPlayerSeek(int msec) {
- MediaPlayerBridge* player = GetFullscreenPlayer();
- if (player)
- player->SeekTo(base::TimeDelta::FromMilliseconds(msec));
-}
-
-void MediaPlayerManagerAndroid::ExitFullscreen(bool release_media_player) {
- Send(new MediaPlayerMsg_DidExitFullscreen(
- routing_id(), fullscreen_player_id_));
- MediaPlayerBridge* player = GetFullscreenPlayer();
- fullscreen_player_id_ = -1;
- if (!player)
- return;
- if (release_media_player)
- player->Release();
- else
- player->SetVideoSurface(NULL);
-}
-
-void MediaPlayerManagerAndroid::SetVideoSurface(jobject surface) {
- MediaPlayerBridge* player = GetFullscreenPlayer();
- if (player) {
- player->SetVideoSurface(surface);
- Send(new MediaPlayerMsg_DidEnterFullscreen(
- routing_id(), player->player_id()));
- }
-}
-
-void MediaPlayerManagerAndroid::OnInitialize(
- int player_id, const GURL& url, const GURL& first_party_for_cookies) {
- for (ScopedVector<MediaPlayerBridge>::iterator it = players_.begin();
- it != players_.end(); ++it) {
- if ((*it)->player_id() == player_id) {
- players_.erase(it);
- break;
- }
- }
-
- RenderProcessHost* host = render_view_host()->GetProcess();
- BrowserContext* context = host->GetBrowserContext();
- StoragePartition* partition = host->GetStoragePartition();
- fileapi::FileSystemContext* file_system_context =
- partition ? partition->GetFileSystemContext() : NULL;
- players_.push_back(new MediaPlayerBridge(
- player_id, url, first_party_for_cookies,
- new MediaResourceGetterImpl(context, file_system_context, host->GetID(),
- routing_id()),
- context->IsOffTheRecord(), this,
- base::Bind(&MediaPlayerManagerAndroid::OnError, base::Unretained(this)),
- base::Bind(&MediaPlayerManagerAndroid::OnVideoSizeChanged,
- base::Unretained(this)),
- base::Bind(&MediaPlayerManagerAndroid::OnBufferingUpdate,
- base::Unretained(this)),
- base::Bind(&MediaPlayerManagerAndroid::OnPrepared,
- base::Unretained(this)),
- base::Bind(&MediaPlayerManagerAndroid::OnPlaybackComplete,
- base::Unretained(this)),
- base::Bind(&MediaPlayerManagerAndroid::OnSeekComplete,
- base::Unretained(this)),
- base::Bind(&MediaPlayerManagerAndroid::OnTimeUpdate,
- base::Unretained(this)),
- base::Bind(&MediaPlayerManagerAndroid::OnMediaInterrupted,
- base::Unretained(this))));
-
- // Send a MediaPrepared message to webkit so that Load() can finish.
- Send(new MediaPlayerMsg_MediaPrepared(
- routing_id(), player_id, GetPlayer(player_id)->GetDuration()));
-}
-
-void MediaPlayerManagerAndroid::OnStart(int player_id) {
- MediaPlayerBridge* player = GetPlayer(player_id);
- if (player)
- player->Start();
-}
-
-void MediaPlayerManagerAndroid::OnSeek(int player_id, base::TimeDelta time) {
- MediaPlayerBridge* player = GetPlayer(player_id);
- if (player)
- player->SeekTo(time);
-}
-
-void MediaPlayerManagerAndroid::OnPause(int player_id) {
- MediaPlayerBridge* player = GetPlayer(player_id);
- if (player)
- player->Pause();
-}
-
-void MediaPlayerManagerAndroid::OnEnterFullscreen(int player_id) {
- DCHECK_EQ(fullscreen_player_id_, -1);
-
- fullscreen_player_id_ = player_id;
- video_view_.CreateContentVideoView();
-}
-
-void MediaPlayerManagerAndroid::OnExitFullscreen(int player_id) {
- if (fullscreen_player_id_ == player_id) {
- MediaPlayerBridge* player = GetPlayer(player_id);
- if (player)
- player->SetVideoSurface(NULL);
- video_view_.DestroyContentVideoView();
- fullscreen_player_id_ = -1;
- }
-}
-
-void MediaPlayerManagerAndroid::OnReleaseResources(int player_id) {
- MediaPlayerBridge* player = GetPlayer(player_id);
- // Don't release the fullscreen player when tab visibility changes,
- // it will be released when user hit the back/home button or when
- // OnDestroyPlayer is called.
- if (player && player_id != fullscreen_player_id_)
- player->Release();
-}
-
-void MediaPlayerManagerAndroid::OnDestroyPlayer(int player_id) {
- for (ScopedVector<MediaPlayerBridge>::iterator it = players_.begin();
- it != players_.end(); ++it) {
- if ((*it)->player_id() == player_id) {
- players_.erase(it);
- break;
- }
- }
- if (fullscreen_player_id_ == player_id)
- fullscreen_player_id_ = -1;
-}
-
-void MediaPlayerManagerAndroid::DestroyAllMediaPlayers() {
- players_.clear();
- if (fullscreen_player_id_ != -1) {
- video_view_.DestroyContentVideoView();
- fullscreen_player_id_ = -1;
- }
-}
-
-void MediaPlayerManagerAndroid::AttachExternalVideoSurface(int player_id,
- jobject surface) {
- MediaPlayerBridge* player = GetPlayer(player_id);
- if (player)
- player->SetVideoSurface(surface);
-}
-
-void MediaPlayerManagerAndroid::DetachExternalVideoSurface(int player_id) {
- MediaPlayerBridge* player = GetPlayer(player_id);
- if (player)
- player->SetVideoSurface(NULL);
-}
-
-void MediaPlayerManagerAndroid::OnRequestExternalSurface(int player_id) {
- if (web_contents_) {
- WebContentsViewAndroid* view =
- static_cast<WebContentsViewAndroid*>(web_contents_->GetView());
- if (view)
- view->RequestExternalVideoSurface(player_id);
- }
-}
-
-MediaPlayerBridge* MediaPlayerManagerAndroid::GetPlayer(int player_id) {
- for (ScopedVector<MediaPlayerBridge>::iterator it = players_.begin();
- it != players_.end(); ++it) {
- if ((*it)->player_id() == player_id)
- return *it;
- }
- return NULL;
-}
-
-MediaPlayerBridge* MediaPlayerManagerAndroid::GetFullscreenPlayer() {
- return GetPlayer(fullscreen_player_id_);
-}
-
-void MediaPlayerManagerAndroid::OnPrepared(int player_id,
- base::TimeDelta duration) {
- Send(new MediaPlayerMsg_MediaPrepared(routing_id(), player_id, duration));
- if (fullscreen_player_id_ != -1)
- video_view_.UpdateMediaMetadata();
-}
-
-void MediaPlayerManagerAndroid::OnPlaybackComplete(int player_id) {
- Send(new MediaPlayerMsg_MediaPlaybackCompleted(routing_id(), player_id));
- if (fullscreen_player_id_ != -1)
- video_view_.OnPlaybackComplete();
-}
-
-void MediaPlayerManagerAndroid::OnMediaInterrupted(int player_id) {
- // Tell WebKit that the audio should be paused, then release all resources
- Send(new MediaPlayerMsg_DidMediaPlayerPause(routing_id(), player_id));
- OnReleaseResources(player_id);
-}
-
-void MediaPlayerManagerAndroid::OnBufferingUpdate(
- int player_id, int percentage) {
- Send(new MediaPlayerMsg_MediaBufferingUpdate(
- routing_id(), player_id, percentage));
- if (fullscreen_player_id_ != -1)
- video_view_.OnBufferingUpdate(percentage);
-}
-
-void MediaPlayerManagerAndroid::OnSeekComplete(int player_id,
- base::TimeDelta current_time) {
- Send(new MediaPlayerMsg_MediaSeekCompleted(
- routing_id(), player_id, current_time));
-}
-
-void MediaPlayerManagerAndroid::OnError(int player_id, int error) {
- Send(new MediaPlayerMsg_MediaError(routing_id(), player_id, error));
- if (fullscreen_player_id_ != -1)
- video_view_.OnMediaPlayerError(error);
-}
-
-void MediaPlayerManagerAndroid::OnVideoSizeChanged(
- int player_id, int width, int height) {
- Send(new MediaPlayerMsg_MediaVideoSizeChanged(routing_id(), player_id,
- width, height));
- if (fullscreen_player_id_ != -1)
- video_view_.OnVideoSizeChanged(width, height);
-}
-
-void MediaPlayerManagerAndroid::OnTimeUpdate(int player_id,
- base::TimeDelta current_time) {
- Send(new MediaPlayerMsg_MediaTimeUpdate(
- routing_id(), player_id, current_time));
-}
-
-void MediaPlayerManagerAndroid::RequestMediaResources(
- MediaPlayerBridge* player) {
- if (player == NULL)
- return;
-
- int num_active_player = 0;
- ScopedVector<MediaPlayerBridge>::iterator it;
- for (it = players_.begin(); it != players_.end(); ++it) {
- if (!(*it)->prepared())
- continue;
-
- // The player is already active, ignore it.
- if ((*it) == player)
- return;
- else
- num_active_player++;
- }
-
- // Number of active players are less than the threshold, do nothing.
- if (num_active_player < kMediaPlayerThreshold)
- return;
-
- for (it = players_.begin(); it != players_.end(); ++it) {
- if ((*it)->prepared() && !(*it)->IsPlaying() &&
- fullscreen_player_id_ != (*it)->player_id()) {
- (*it)->Release();
- Send(new MediaPlayerMsg_MediaPlayerReleased(
- routing_id(), (*it)->player_id()));
- }
- }
-}
-
-void MediaPlayerManagerAndroid::ReleaseMediaResources(
- MediaPlayerBridge* player) {
- // Nothing needs to be done.
-}
-
-} // namespace content
diff --git a/content/browser/android/media_player_manager_impl.cc b/content/browser/android/media_player_manager_impl.cc
new file mode 100644
index 0000000..ba799a6
--- /dev/null
+++ b/content/browser/android/media_player_manager_impl.cc
@@ -0,0 +1,388 @@
+// 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/android/media_player_manager_impl.h"
+
+#include "base/bind.h"
+#include "content/browser/android/media_resource_getter_impl.h"
+#include "content/browser/web_contents/web_contents_view_android.h"
+#include "content/common/media/media_player_messages.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/storage_partition.h"
+
+using media::MediaPlayerBridge;
+
+// Threshold on the number of media players per renderer before we start
+// attempting to release inactive media players.
+static const int kMediaPlayerThreshold = 1;
+
+namespace content {
+
+MediaPlayerManagerImpl::MediaPlayerManagerImpl(
+ RenderViewHost* render_view_host)
+ : RenderViewHostObserver(render_view_host),
+ video_view_(this),
+ fullscreen_player_id_(-1),
+ web_contents_(WebContents::FromRenderViewHost(render_view_host)) {
+}
+
+MediaPlayerManagerImpl::~MediaPlayerManagerImpl() {}
+
+bool MediaPlayerManagerImpl::OnMessageReceived(const IPC::Message& msg) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(MediaPlayerManagerImpl, 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_DestroyMediaPlayer, OnDestroyPlayer)
+ IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyAllMediaPlayers,
+ DestroyAllMediaPlayers)
+#if defined(GOOGLE_TV)
+ IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_RequestExternalSurface,
+ OnRequestExternalSurface)
+ IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_NotifyGeometryChange,
+ OnNotifyGeometryChange)
+ IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DemuxerReady,
+ OnDemuxerReady)
+ IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_ReadFromDemuxerAck,
+ OnReadFromDemuxerAck)
+#endif
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void MediaPlayerManagerImpl::FullscreenPlayerPlay() {
+ MediaPlayerBridge* player = GetFullscreenPlayer();
+ if (player) {
+ player->Start();
+ Send(new MediaPlayerMsg_DidMediaPlayerPlay(
+ routing_id(), fullscreen_player_id_));
+ }
+}
+
+void MediaPlayerManagerImpl::FullscreenPlayerPause() {
+ MediaPlayerBridge* player = GetFullscreenPlayer();
+ if (player) {
+ player->Pause();
+ Send(new MediaPlayerMsg_DidMediaPlayerPause(
+ routing_id(), fullscreen_player_id_));
+ }
+}
+
+void MediaPlayerManagerImpl::FullscreenPlayerSeek(int msec) {
+ MediaPlayerBridge* player = GetFullscreenPlayer();
+ if (player)
+ player->SeekTo(base::TimeDelta::FromMilliseconds(msec));
+}
+
+void MediaPlayerManagerImpl::ExitFullscreen(bool release_media_player) {
+ Send(new MediaPlayerMsg_DidExitFullscreen(
+ routing_id(), fullscreen_player_id_));
+ MediaPlayerBridge* player = GetFullscreenPlayer();
+ fullscreen_player_id_ = -1;
+ if (!player)
+ return;
+ if (release_media_player)
+ player->Release();
+ else
+ player->SetVideoSurface(NULL);
+}
+
+void MediaPlayerManagerImpl::SetVideoSurface(jobject surface) {
+ MediaPlayerBridge* player = GetFullscreenPlayer();
+ if (player) {
+ player->SetVideoSurface(surface);
+ Send(new MediaPlayerMsg_DidEnterFullscreen(
+ routing_id(), player->player_id()));
+ }
+}
+
+void MediaPlayerManagerImpl::OnInitialize(
+ int player_id, const GURL& url,
+ bool is_media_source,
+ const GURL& first_party_for_cookies) {
+ for (ScopedVector<MediaPlayerBridge>::iterator it = players_.begin();
+ it != players_.end(); ++it) {
+ if ((*it)->player_id() == player_id) {
+ players_.erase(it);
+ break;
+ }
+ }
+
+ RenderProcessHost* host = render_view_host()->GetProcess();
+ players_.push_back(media::MediaPlayerBridge::Create(
+ player_id, url, is_media_source, first_party_for_cookies,
+ host->GetBrowserContext()->IsOffTheRecord(), this,
+#if defined(GOOGLE_TV)
+ base::Bind(&MediaPlayerManagerImpl::OnReadFromDemuxer,
+ base::Unretained(this)),
+#endif
+ base::Bind(&MediaPlayerManagerImpl::OnError, base::Unretained(this)),
+ base::Bind(&MediaPlayerManagerImpl::OnVideoSizeChanged,
+ base::Unretained(this)),
+ base::Bind(&MediaPlayerManagerImpl::OnBufferingUpdate,
+ base::Unretained(this)),
+ base::Bind(&MediaPlayerManagerImpl::OnMediaMetadataChanged,
+ base::Unretained(this)),
+ base::Bind(&MediaPlayerManagerImpl::OnPlaybackComplete,
+ base::Unretained(this)),
+ base::Bind(&MediaPlayerManagerImpl::OnSeekComplete,
+ base::Unretained(this)),
+ base::Bind(&MediaPlayerManagerImpl::OnTimeUpdate,
+ base::Unretained(this)),
+ base::Bind(&MediaPlayerManagerImpl::OnMediaInterrupted,
+ base::Unretained(this))));
+}
+
+media::MediaResourceGetter* MediaPlayerManagerImpl::GetMediaResourceGetter() {
+ if (!media_resource_getter_.get()) {
+ RenderProcessHost* host = render_view_host()->GetProcess();
+ BrowserContext* context = host->GetBrowserContext();
+ StoragePartition* partition = host->GetStoragePartition();
+ fileapi::FileSystemContext* file_system_context =
+ partition ? partition->GetFileSystemContext() : NULL;
+ media_resource_getter_.reset(new MediaResourceGetterImpl(
+ context, file_system_context, host->GetID(), routing_id()));
+ }
+ return media_resource_getter_.get();
+}
+
+void MediaPlayerManagerImpl::OnStart(int player_id) {
+ MediaPlayerBridge* player = GetPlayer(player_id);
+ if (player)
+ player->Start();
+}
+
+void MediaPlayerManagerImpl::OnSeek(int player_id, base::TimeDelta time) {
+ MediaPlayerBridge* player = GetPlayer(player_id);
+ if (player)
+ player->SeekTo(time);
+}
+
+void MediaPlayerManagerImpl::OnPause(int player_id) {
+ MediaPlayerBridge* player = GetPlayer(player_id);
+ if (player)
+ player->Pause();
+}
+
+void MediaPlayerManagerImpl::OnEnterFullscreen(int player_id) {
+ DCHECK_EQ(fullscreen_player_id_, -1);
+
+ fullscreen_player_id_ = player_id;
+ video_view_.CreateContentVideoView();
+}
+
+void MediaPlayerManagerImpl::OnExitFullscreen(int player_id) {
+ if (fullscreen_player_id_ == player_id) {
+ MediaPlayerBridge* player = GetPlayer(player_id);
+ if (player)
+ player->SetVideoSurface(NULL);
+ video_view_.DestroyContentVideoView();
+ fullscreen_player_id_ = -1;
+ }
+}
+
+void MediaPlayerManagerImpl::OnReleaseResources(int player_id) {
+ MediaPlayerBridge* player = GetPlayer(player_id);
+ // Don't release the fullscreen player when tab visibility changes,
+ // it will be released when user hit the back/home button or when
+ // OnDestroyPlayer is called.
+ if (player && player_id != fullscreen_player_id_)
+ player->Release();
+}
+
+void MediaPlayerManagerImpl::OnDestroyPlayer(int player_id) {
+ for (ScopedVector<MediaPlayerBridge>::iterator it = players_.begin();
+ it != players_.end(); ++it) {
+ if ((*it)->player_id() == player_id) {
+ players_.erase(it);
+ break;
+ }
+ }
+ if (fullscreen_player_id_ == player_id)
+ fullscreen_player_id_ = -1;
+}
+
+void MediaPlayerManagerImpl::DestroyAllMediaPlayers() {
+ players_.clear();
+ if (fullscreen_player_id_ != -1) {
+ video_view_.DestroyContentVideoView();
+ fullscreen_player_id_ = -1;
+ }
+}
+
+#if defined(GOOGLE_TV)
+void MediaPlayerManagerImpl::AttachExternalVideoSurface(int player_id,
+ jobject surface) {
+ MediaPlayerBridge* player = GetPlayer(player_id);
+ if (player)
+ player->SetVideoSurface(surface);
+}
+
+void MediaPlayerManagerImpl::DetachExternalVideoSurface(int player_id) {
+ MediaPlayerBridge* player = GetPlayer(player_id);
+ if (player)
+ player->SetVideoSurface(NULL);
+}
+
+void MediaPlayerManagerImpl::OnRequestExternalSurface(int player_id) {
+ if (!web_contents_)
+ return;
+
+ WebContentsViewAndroid* view =
+ static_cast<WebContentsViewAndroid*>(web_contents_->GetView());
+ if (view)
+ view->RequestExternalVideoSurface(player_id);
+}
+
+void MediaPlayerManagerImpl::OnNotifyGeometryChange(int player_id,
+ const gfx::RectF& rect) {
+ if (!web_contents_)
+ return;
+
+ WebContentsViewAndroid* view =
+ static_cast<WebContentsViewAndroid*>(web_contents_->GetView());
+ if (view)
+ view->NotifyGeometryChange(player_id, rect);
+}
+
+void MediaPlayerManagerImpl::OnDemuxerReady(
+ int player_id,
+ const media::MediaPlayerHostMsg_DemuxerReady_Params& params) {
+ MediaPlayerBridge* player = GetPlayer(player_id);
+ if (player)
+ player->DemuxerReady(params);
+}
+
+void MediaPlayerManagerImpl::OnReadFromDemuxerAck(
+ int player_id,
+ const media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params& params) {
+ MediaPlayerBridge* player = GetPlayer(player_id);
+ if (player)
+ player->ReadFromDemuxerAck(params);
+}
+#endif
+
+MediaPlayerBridge* MediaPlayerManagerImpl::GetPlayer(int player_id) {
+ for (ScopedVector<MediaPlayerBridge>::iterator it = players_.begin();
+ it != players_.end(); ++it) {
+ if ((*it)->player_id() == player_id)
+ return *it;
+ }
+ return NULL;
+}
+
+MediaPlayerBridge* MediaPlayerManagerImpl::GetFullscreenPlayer() {
+ return GetPlayer(fullscreen_player_id_);
+}
+
+void MediaPlayerManagerImpl::OnMediaMetadataChanged(
+ int player_id, base::TimeDelta duration, int width, int height,
+ bool success) {
+ Send(new MediaPlayerMsg_MediaMetadataChanged(
+ routing_id(), player_id, duration, width, height, success));
+ if (fullscreen_player_id_ != -1)
+ video_view_.UpdateMediaMetadata();
+}
+
+void MediaPlayerManagerImpl::OnPlaybackComplete(int player_id) {
+ Send(new MediaPlayerMsg_MediaPlaybackCompleted(routing_id(), player_id));
+ if (fullscreen_player_id_ != -1)
+ video_view_.OnPlaybackComplete();
+}
+
+void MediaPlayerManagerImpl::OnMediaInterrupted(int player_id) {
+ // Tell WebKit that the audio should be paused, then release all resources
+ Send(new MediaPlayerMsg_DidMediaPlayerPause(routing_id(), player_id));
+ OnReleaseResources(player_id);
+}
+
+void MediaPlayerManagerImpl::OnBufferingUpdate(
+ int player_id, int percentage) {
+ Send(new MediaPlayerMsg_MediaBufferingUpdate(
+ routing_id(), player_id, percentage));
+ if (fullscreen_player_id_ != -1)
+ video_view_.OnBufferingUpdate(percentage);
+}
+
+void MediaPlayerManagerImpl::OnSeekComplete(int player_id,
+ base::TimeDelta current_time) {
+ Send(new MediaPlayerMsg_MediaSeekCompleted(
+ routing_id(), player_id, current_time));
+}
+
+void MediaPlayerManagerImpl::OnError(int player_id, int error) {
+ Send(new MediaPlayerMsg_MediaError(routing_id(), player_id, error));
+ if (fullscreen_player_id_ != -1)
+ video_view_.OnMediaPlayerError(error);
+}
+
+void MediaPlayerManagerImpl::OnVideoSizeChanged(
+ int player_id, int width, int height) {
+ Send(new MediaPlayerMsg_MediaVideoSizeChanged(routing_id(), player_id,
+ width, height));
+ if (fullscreen_player_id_ != -1)
+ video_view_.OnVideoSizeChanged(width, height);
+}
+
+void MediaPlayerManagerImpl::OnTimeUpdate(int player_id,
+ base::TimeDelta current_time) {
+ Send(new MediaPlayerMsg_MediaTimeUpdate(
+ routing_id(), player_id, current_time));
+}
+
+#if defined(GOOGLE_TV)
+void MediaPlayerManagerImpl::OnReadFromDemuxer(
+ int player_id, media::DemuxerStream::Type type, bool seek_done) {
+ Send(new MediaPlayerMsg_ReadFromDemuxer(
+ routing_id(), player_id, type, seek_done));
+}
+#endif
+
+void MediaPlayerManagerImpl::RequestMediaResources(
+ MediaPlayerBridge* player) {
+ if (player == NULL)
+ return;
+
+ int num_active_player = 0;
+ ScopedVector<MediaPlayerBridge>::iterator it;
+ for (it = players_.begin(); it != players_.end(); ++it) {
+ if (!(*it)->prepared())
+ continue;
+
+ // The player is already active, ignore it.
+ if ((*it) == player)
+ return;
+ else
+ num_active_player++;
+ }
+
+ // Number of active players are less than the threshold, do nothing.
+ if (num_active_player < kMediaPlayerThreshold)
+ return;
+
+ for (it = players_.begin(); it != players_.end(); ++it) {
+ if ((*it)->prepared() && !(*it)->IsPlaying() &&
+ fullscreen_player_id_ != (*it)->player_id()) {
+ (*it)->Release();
+ Send(new MediaPlayerMsg_MediaPlayerReleased(
+ routing_id(), (*it)->player_id()));
+ }
+ }
+}
+
+void MediaPlayerManagerImpl::ReleaseMediaResources(
+ MediaPlayerBridge* player) {
+ // Nothing needs to be done.
+}
+
+} // namespace content
diff --git a/content/browser/android/media_player_manager_android.h b/content/browser/android/media_player_manager_impl.h
similarity index 65%
rename from content/browser/android/media_player_manager_android.h
rename to content/browser/android/media_player_manager_impl.h
index 2500086..34905df 100644
--- a/content/browser/android/media_player_manager_android.h
+++ b/content/browser/android/media_player_manager_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_BROWSER_ANDROID_MEDIA_PLAYER_MANAGER_ANDROID_H_
-#define CONTENT_BROWSER_ANDROID_MEDIA_PLAYER_MANAGER_ANDROID_H_
+#ifndef CONTENT_BROWSER_ANDROID_MEDIA_PLAYER_MANAGER_IMPL_H_
+#define CONTENT_BROWSER_ANDROID_MEDIA_PLAYER_MANAGER_IMPL_H_
#include <map>
@@ -14,8 +14,12 @@
#include "content/browser/android/content_video_view.h"
#include "content/public/browser/render_view_host_observer.h"
#include "googleurl/src/gurl.h"
+#if defined(GOOGLE_TV)
+#include "media/base/android/demuxer_stream_player_params.h"
+#endif
#include "media/base/android/media_player_bridge.h"
-#include "media/base/android/media_player_bridge_manager.h"
+#include "media/base/android/media_player_manager.h"
+#include "ui/gfx/rect_f.h"
namespace content {
@@ -26,13 +30,13 @@
// them to corresponding MediaPlayerBridge object. Callbacks from
// MediaPlayerBridge objects are converted to IPCs and then sent to the
// render process.
-class MediaPlayerManagerAndroid
+class MediaPlayerManagerImpl
: public RenderViewHostObserver,
- public media::MediaPlayerBridgeManager {
+ public media::MediaPlayerManager {
public:
- // Create a MediaPlayerManagerAndroid object for the |render_view_host|.
- explicit MediaPlayerManagerAndroid(RenderViewHost* render_view_host);
- virtual ~MediaPlayerManagerAndroid();
+ // Create a MediaPlayerManagerImpl object for the |render_view_host|.
+ explicit MediaPlayerManagerImpl(RenderViewHost* render_view_host);
+ virtual ~MediaPlayerManagerImpl();
// RenderViewHostObserver overrides.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
@@ -49,7 +53,8 @@
void OnTimeUpdate(int player_id, base::TimeDelta current_time);
// Callbacks needed by media::MediaPlayerBridge.
- void OnPrepared(int player_id, base::TimeDelta duration);
+ void OnMediaMetadataChanged(int player_id, base::TimeDelta duration,
+ int width, int height, bool success);
void OnPlaybackComplete(int player_id);
void OnMediaInterrupted(int player_id);
void OnBufferingUpdate(int player_id, int percentage);
@@ -57,15 +62,24 @@
void OnError(int player_id, int error);
void OnVideoSizeChanged(int player_id, int width, int height);
+#if defined(GOOGLE_TV)
+ // Callbacks needed by media::DemuxerStreamPlayer.
+ void OnReadFromDemuxer(
+ int player_id, media::DemuxerStream::Type type, bool seek_done);
+#endif
+
// media::MediaPlayerBridgeManager overrides.
virtual void RequestMediaResources(media::MediaPlayerBridge* player) OVERRIDE;
virtual void ReleaseMediaResources(media::MediaPlayerBridge* player) OVERRIDE;
+ virtual media::MediaResourceGetter* GetMediaResourceGetter() OVERRIDE;
// Release all the players managed by this object.
void DestroyAllMediaPlayers();
+#if defined(GOOGLE_TV)
void AttachExternalVideoSurface(int player_id, jobject surface);
void DetachExternalVideoSurface(int player_id);
+#endif
media::MediaPlayerBridge* GetFullscreenPlayer();
media::MediaPlayerBridge* GetPlayer(int player_id);
@@ -75,13 +89,23 @@
void OnEnterFullscreen(int player_id);
void OnExitFullscreen(int player_id);
void OnInitialize(int player_id, const GURL& url,
+ bool is_media_source,
const GURL& first_party_for_cookies);
void OnStart(int player_id);
void OnSeek(int player_id, base::TimeDelta time);
void OnPause(int player_id);
void OnReleaseResources(int player_id);
void OnDestroyPlayer(int player_id);
+#if defined(GOOGLE_TV)
void OnRequestExternalSurface(int player_id);
+ void OnNotifyGeometryChange(int player_id, const gfx::RectF& rect);
+ void OnDemuxerReady(
+ int player_id,
+ const media::MediaPlayerHostMsg_DemuxerReady_Params& params);
+ void OnReadFromDemuxerAck(
+ int player_id,
+ const media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params& params);
+#endif
// An array of managed players.
ScopedVector<media::MediaPlayerBridge> players_;
@@ -94,9 +118,12 @@
WebContents* web_contents_;
- DISALLOW_COPY_AND_ASSIGN(MediaPlayerManagerAndroid);
+ // Object for retrieving resources media players.
+ scoped_ptr<media::MediaResourceGetter> media_resource_getter_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaPlayerManagerImpl);
};
} // namespace content
-#endif // CONTENT_BROWSER_ANDROID_MEDIA_PLAYER_MANAGER_ANDROID_H_
+#endif // CONTENT_BROWSER_ANDROID_MEDIA_PLAYER_MANAGER_IMPL_H_
diff --git a/content/browser/android/media_resource_getter_impl.cc b/content/browser/android/media_resource_getter_impl.cc
index 2f5d4ee..00f92d6 100644
--- a/content/browser/android/media_resource_getter_impl.cc
+++ b/content/browser/android/media_resource_getter_impl.cc
@@ -4,8 +4,11 @@
#include "content/browser/android/media_resource_getter_impl.h"
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
#include "base/bind.h"
#include "base/path_service.h"
+#include "base/threading/sequenced_worker_pool.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/fileapi/browser_file_system_helper.h"
#include "content/public/browser/browser_context.h"
@@ -13,6 +16,7 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
#include "googleurl/src/gurl.h"
+#include "jni/MediaResourceGetter_jni.h"
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_store.h"
#include "net/url_request/url_request_context.h"
@@ -27,6 +31,31 @@
BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
}
+// Get the metadata from a media URL. When finished, a task is posted to the UI
+// thread to run the callback function.
+static void GetMediaMetadata(
+ const std::string& url, const std::string& cookies,
+ const media::MediaResourceGetter::ExtractMediaMetadataCB& callback) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ base::android::ScopedJavaLocalRef<jstring> j_url_string =
+ base::android::ConvertUTF8ToJavaString(env, url);
+ base::android::ScopedJavaLocalRef<jstring> j_cookies =
+ base::android::ConvertUTF8ToJavaString(env, cookies);
+ jobject j_context = base::android::GetApplicationContext();
+ base::android::ScopedJavaLocalRef<jobject> j_metadata =
+ Java_MediaResourceGetter_extractMediaMetadata(
+ env, j_context, j_url_string.obj(), j_cookies.obj());
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(callback, base::TimeDelta::FromMilliseconds(
+ Java_MediaMetadata_getDurationInMilliseconds(
+ env, j_metadata.obj())),
+ Java_MediaMetadata_getWidth(env, j_metadata.obj()),
+ Java_MediaMetadata_getHeight(env, j_metadata.obj()),
+ Java_MediaMetadata_isSuccess(env, j_metadata.obj())));
+}
+
// The task object that retrieves cookie on the IO thread.
// TODO(qinmin): refactor this class to make the code reusable by others as
// there are lots of duplicated functionalities elsewhere.
@@ -177,16 +206,16 @@
int renderer_id, int routing_id)
: browser_context_(browser_context),
file_system_context_(file_system_context),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_this_(this)),
+ weak_this_(this),
renderer_id_(renderer_id),
routing_id_(routing_id) {
}
MediaResourceGetterImpl::~MediaResourceGetterImpl() {}
-void MediaResourceGetterImpl::GetCookies(const GURL& url,
- const GURL& first_party_for_cookies,
- const GetCookieCB& callback) {
+void MediaResourceGetterImpl::GetCookies(
+ const GURL& url, const GURL& first_party_for_cookies,
+ const GetCookieCB& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
scoped_refptr<CookieGetterTask> task = new CookieGetterTask(
browser_context_, renderer_id_, routing_id_);
@@ -230,4 +259,18 @@
callback.Run(platform_path);
}
+void MediaResourceGetterImpl::ExtractMediaMetadata(
+ const std::string& url, const std::string& cookies,
+ const ExtractMediaMetadataCB& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
+ pool->PostWorkerTask(
+ FROM_HERE, base::Bind(&GetMediaMetadata, url, cookies, callback));
+}
+
+// static
+bool MediaResourceGetterImpl::RegisterMediaResourceGetter(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
} // namespace content
diff --git a/content/browser/android/media_resource_getter_impl.h b/content/browser/android/media_resource_getter_impl.h
index 20ba44f..1d15244 100644
--- a/content/browser/android/media_resource_getter_impl.h
+++ b/content/browser/android/media_resource_getter_impl.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_ANDROID_MEDIA_RESOURCE_GETTER_IMPL_H_
#define CONTENT_BROWSER_ANDROID_MEDIA_RESOURCE_GETTER_IMPL_H_
+#include <jni.h>
#include <string>
#include "base/memory/ref_counted.h"
@@ -46,6 +47,11 @@
virtual void GetPlatformPathFromFileSystemURL(
const GURL& url,
const GetPlatformPathCB& callback) OVERRIDE;
+ virtual void ExtractMediaMetadata(
+ const std::string& url, const std::string& cookies,
+ const ExtractMediaMetadataCB& callback) OVERRIDE;
+
+ static bool RegisterMediaResourceGetter(JNIEnv* env);
private:
// Called when GetCookies() finishes.
diff --git a/content/browser/android/surface_texture_peer_browser_impl.cc b/content/browser/android/surface_texture_peer_browser_impl.cc
index afd999b..1cba847 100644
--- a/content/browser/android/surface_texture_peer_browser_impl.cc
+++ b/content/browser/android/surface_texture_peer_browser_impl.cc
@@ -4,12 +4,12 @@
#include "content/browser/android/surface_texture_peer_browser_impl.h"
-#include "content/browser/android/media_player_manager_android.h"
+#include "content/browser/android/media_player_manager_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/common/android/scoped_java_surface.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "media/base/android/media_player_bridge.h"
+#include "ui/gl/android/scoped_java_surface.h"
namespace content {
@@ -18,7 +18,7 @@
// Pass a java surface object to the MediaPlayerBridge object
// identified by render process handle, render view ID and player ID.
static void SetSurfacePeer(
- scoped_refptr<SurfaceTextureBridge> surface_texture_bridge,
+ scoped_refptr<gfx::SurfaceTextureBridge> surface_texture_bridge,
base::ProcessHandle render_process_handle,
int render_view_id,
int player_id) {
@@ -40,7 +40,7 @@
host->media_player_manager()->GetPlayer(player_id);
if (player &&
player != host->media_player_manager()->GetFullscreenPlayer()) {
- ScopedJavaSurface surface(surface_texture_bridge.get());
+ gfx::ScopedJavaSurface surface(surface_texture_bridge.get());
player->SetVideoSurface(surface.j_surface().obj());
}
}
@@ -57,7 +57,7 @@
void SurfaceTexturePeerBrowserImpl::EstablishSurfaceTexturePeer(
base::ProcessHandle render_process_handle,
- scoped_refptr<SurfaceTextureBridge> surface_texture_bridge,
+ scoped_refptr<gfx::SurfaceTextureBridge> surface_texture_bridge,
int render_view_id,
int player_id) {
if (!surface_texture_bridge)
diff --git a/content/browser/android/surface_texture_peer_browser_impl.h b/content/browser/android/surface_texture_peer_browser_impl.h
index 5ebe141..644bf2c 100644
--- a/content/browser/android/surface_texture_peer_browser_impl.h
+++ b/content/browser/android/surface_texture_peer_browser_impl.h
@@ -24,7 +24,7 @@
// SurfaceTexturePeer implementation.
virtual void EstablishSurfaceTexturePeer(
base::ProcessHandle render_process_handle,
- scoped_refptr<SurfaceTextureBridge> surface_texture_bridge,
+ scoped_refptr<gfx::SurfaceTextureBridge> surface_texture_bridge,
int render_view_id,
int player_id) OVERRIDE;
diff --git a/content/browser/appcache/appcache_dispatcher_host.cc b/content/browser/appcache/appcache_dispatcher_host.cc
index ac4564c..90a5dc7 100644
--- a/content/browser/appcache/appcache_dispatcher_host.cc
+++ b/content/browser/appcache/appcache_dispatcher_host.cc
@@ -16,13 +16,13 @@
ChromeAppCacheService* appcache_service,
int process_id)
: appcache_service_(appcache_service),
- ALLOW_THIS_IN_INITIALIZER_LIST(frontend_proxy_(this)),
+ frontend_proxy_(this),
process_id_(process_id) {
}
void AppCacheDispatcherHost::OnChannelConnected(int32 peer_pid) {
BrowserMessageFilter::OnChannelConnected(peer_pid);
- if (appcache_service_.get()) {
+ if (appcache_service_) {
backend_impl_.Initialize(
appcache_service_.get(), &frontend_proxy_, process_id_);
get_status_callback_ =
@@ -69,7 +69,7 @@
}
void AppCacheDispatcherHost::OnRegisterHost(int host_id) {
- if (appcache_service_.get()) {
+ if (appcache_service_) {
if (!backend_impl_.RegisterHost(host_id)) {
BadMessageReceived();
}
@@ -77,7 +77,7 @@
}
void AppCacheDispatcherHost::OnUnregisterHost(int host_id) {
- if (appcache_service_.get()) {
+ if (appcache_service_) {
if (!backend_impl_.UnregisterHost(host_id)) {
BadMessageReceived();
}
@@ -86,7 +86,7 @@
void AppCacheDispatcherHost::OnSetSpawningHostId(
int host_id, int spawning_host_id) {
- if (appcache_service_.get()) {
+ if (appcache_service_) {
if (!backend_impl_.SetSpawningHostId(host_id, spawning_host_id))
BadMessageReceived();
}
@@ -96,7 +96,7 @@
int host_id, const GURL& document_url,
int64 cache_document_was_loaded_from,
const GURL& opt_manifest_url) {
- if (appcache_service_.get()) {
+ if (appcache_service_) {
if (!backend_impl_.SelectCache(host_id, document_url,
cache_document_was_loaded_from,
opt_manifest_url)) {
@@ -109,7 +109,7 @@
void AppCacheDispatcherHost::OnSelectCacheForWorker(
int host_id, int parent_process_id, int parent_host_id) {
- if (appcache_service_.get()) {
+ if (appcache_service_) {
if (!backend_impl_.SelectCacheForWorker(
host_id, parent_process_id, parent_host_id)) {
BadMessageReceived();
@@ -121,7 +121,7 @@
void AppCacheDispatcherHost::OnSelectCacheForSharedWorker(
int host_id, int64 appcache_id) {
- if (appcache_service_.get()) {
+ if (appcache_service_) {
if (!backend_impl_.SelectCacheForSharedWorker(host_id, appcache_id))
BadMessageReceived();
} else {
@@ -132,7 +132,7 @@
void AppCacheDispatcherHost::OnMarkAsForeignEntry(
int host_id, const GURL& document_url,
int64 cache_document_was_loaded_from) {
- if (appcache_service_.get()) {
+ if (appcache_service_) {
if (!backend_impl_.MarkAsForeignEntry(host_id, document_url,
cache_document_was_loaded_from)) {
BadMessageReceived();
@@ -142,19 +142,19 @@
void AppCacheDispatcherHost::OnGetResourceList(
int host_id, std::vector<appcache::AppCacheResourceInfo>* params) {
- if (appcache_service_.get())
+ if (appcache_service_)
backend_impl_.GetResourceList(host_id, params);
}
void AppCacheDispatcherHost::OnGetStatus(int host_id, IPC::Message* reply_msg) {
- if (pending_reply_msg_.get()) {
+ if (pending_reply_msg_) {
BadMessageReceived();
delete reply_msg;
return;
}
pending_reply_msg_.reset(reply_msg);
- if (appcache_service_.get()) {
+ if (appcache_service_) {
if (!backend_impl_.GetStatusWithCallback(host_id, get_status_callback_,
reply_msg)) {
BadMessageReceived();
@@ -167,14 +167,14 @@
void AppCacheDispatcherHost::OnStartUpdate(int host_id,
IPC::Message* reply_msg) {
- if (pending_reply_msg_.get()) {
+ if (pending_reply_msg_) {
BadMessageReceived();
delete reply_msg;
return;
}
pending_reply_msg_.reset(reply_msg);
- if (appcache_service_.get()) {
+ if (appcache_service_) {
if (!backend_impl_.StartUpdateWithCallback(host_id, start_update_callback_,
reply_msg)) {
BadMessageReceived();
@@ -186,14 +186,14 @@
}
void AppCacheDispatcherHost::OnSwapCache(int host_id, IPC::Message* reply_msg) {
- if (pending_reply_msg_.get()) {
+ if (pending_reply_msg_) {
BadMessageReceived();
delete reply_msg;
return;
}
pending_reply_msg_.reset(reply_msg);
- if (appcache_service_.get()) {
+ if (appcache_service_) {
if (!backend_impl_.SwapCacheWithCallback(host_id, swap_cache_callback_,
reply_msg)) {
BadMessageReceived();
diff --git a/content/browser/appcache/chrome_appcache_service_unittest.cc b/content/browser/appcache/chrome_appcache_service_unittest.cc
index 0c8a7f4..d925104 100644
--- a/content/browser/appcache/chrome_appcache_service_unittest.cc
+++ b/content/browser/appcache/chrome_appcache_service_unittest.cc
@@ -63,16 +63,15 @@
class ChromeAppCacheServiceTest : public testing::Test {
public:
ChromeAppCacheServiceTest()
- : message_loop_(MessageLoop::TYPE_IO),
+ : message_loop_(base::MessageLoop::TYPE_IO),
kProtectedManifestURL(kProtectedManifest),
kNormalManifestURL(kNormalManifest),
kSessionOnlyManifestURL(kSessionOnlyManifest),
file_thread_(BrowserThread::FILE, &message_loop_),
- file_user_blocking_thread_(
- BrowserThread::FILE_USER_BLOCKING, &message_loop_),
+ file_user_blocking_thread_(BrowserThread::FILE_USER_BLOCKING,
+ &message_loop_),
cache_thread_(BrowserThread::CACHE, &message_loop_),
- io_thread_(BrowserThread::IO, &message_loop_) {
- }
+ io_thread_(BrowserThread::IO, &message_loop_) {}
protected:
scoped_refptr<ChromeAppCacheService> CreateAppCacheService(
@@ -80,7 +79,7 @@
bool init_storage);
void InsertDataIntoAppCache(ChromeAppCacheService* appcache_service);
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
base::ScopedTempDir temp_dir_;
const GURL kProtectedManifestURL;
const GURL kNormalManifestURL;
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc
index 7979c36..6a2218f 100644
--- a/content/browser/browser_child_process_host_impl.cc
+++ b/content/browser/browser_child_process_host_impl.cc
@@ -221,7 +221,7 @@
base::TerminationStatus BrowserChildProcessHostImpl::GetTerminationStatus(
int* exit_code) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (!child_process_.get()) // If the delegate doesn't use Launch() helper.
+ if (!child_process_) // If the delegate doesn't use Launch() helper.
return base::GetTerminationStatus(data_.handle, exit_code);
return child_process_->GetChildTerminationStatus(false /* known_dead */,
exit_code);
@@ -300,7 +300,8 @@
}
void BrowserChildProcessHostImpl::OnProcessLaunched() {
- if (!child_process_->GetHandle()) {
+ base::ProcessHandle handle = child_process_->GetHandle();
+ if (!handle) {
delete delegate_; // Will delete us
return;
}
@@ -312,12 +313,12 @@
// IPC channel thereafter.
DCHECK(!early_exit_watcher_.GetWatchedEvent());
early_exit_watcher_.StartWatching(
- new base::WaitableEvent(child_process_->GetHandle()),
+ new base::WaitableEvent(handle),
base::Bind(&BrowserChildProcessHostImpl::OnProcessExitedEarly,
base::Unretained(this)));
#endif
- data_.handle = child_process_->GetHandle();
+ data_.handle = handle;
delegate_->OnProcessLaunched();
}
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc
index cac0e2c..b32b58a 100644
--- a/content/browser/browser_context.cc
+++ b/content/browser/browser_context.cc
@@ -9,7 +9,7 @@
#include "content/browser/appcache/chrome_appcache_service.h"
#include "content/browser/dom_storage/dom_storage_context_impl.h"
#include "content/browser/download/download_manager_impl.h"
-#include "content/browser/in_process_webkit/indexed_db_context_impl.h"
+#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/storage_partition_impl_map.h"
@@ -106,25 +106,16 @@
ExamineClipboard(clipboard, ui::Clipboard::BUFFER_SELECTION);
}
- ui::Clipboard::SourceTag GetAsSourceTag() {
- return ui::Clipboard::SourceTag(this);
+ ui::SourceTag GetAsSourceTag() {
+ return ui::SourceTag(this);
}
private:
void ExamineClipboard(ui::Clipboard* clipboard,
ui::Clipboard::Buffer buffer) {
- ui::Clipboard::SourceTag source_tag = clipboard->ReadSourceTag(buffer);
- if (source_tag == ui::Clipboard::SourceTag(this)) {
- if (buffer == ui::Clipboard::BUFFER_STANDARD) {
- // We want to leave invalid SourceTag in the clipboard in order to
- // collect statistics later.
- clipboard->WriteObjects(buffer,
- ui::Clipboard::ObjectMap(),
- ui::Clipboard::kInvalidSourceTag);
- } else {
- clipboard->Clear(buffer);
- }
- }
+ ui::SourceTag source_tag = clipboard->ReadSourceTag(buffer);
+ if (source_tag == ui::SourceTag(this))
+ clipboard->Clear(buffer);
}
};
@@ -167,13 +158,12 @@
DCHECK(rdh);
scoped_refptr<DownloadManager> download_manager =
new DownloadManagerImpl(
- GetContentClient()->browser()->GetNetLog());
+ GetContentClient()->browser()->GetNetLog(), context);
context->SetUserData(
kDownloadManagerKeyName,
new UserDataAdapter<DownloadManager>(download_manager));
download_manager->SetDelegate(context->GetDownloadManagerDelegate());
- download_manager->Init(context);
}
return UserDataAdapter<DownloadManager>::Get(
@@ -321,7 +311,7 @@
base::Bind(&PurgeDOMStorageContextInPartition));
}
-ui::Clipboard::SourceTag BrowserContext::GetMarkerForOffTheRecordContext(
+ui::SourceTag BrowserContext::GetMarkerForOffTheRecordContext(
BrowserContext* context) {
if (context && context->IsOffTheRecord()) {
OffTheRecordClipboardDestroyer* clipboard_destroyer =
@@ -329,7 +319,7 @@
return clipboard_destroyer->GetAsSourceTag();
}
- return ui::Clipboard::SourceTag();
+ return ui::SourceTag();
}
#endif // !OS_IOS
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 4b7feb6..31f9f17 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -13,6 +13,8 @@
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/pending_task.h"
+#include "base/power_monitor/power_monitor.h"
+#include "base/system_monitor/system_monitor.h"
#include "base/run_loop.h"
#include "base/string_number_conversions.h"
#include "base/threading/thread_restrictions.h"
@@ -46,7 +48,6 @@
#include "media/audio/audio_manager.h"
#include "net/base/network_change_notifier.h"
#include "net/socket/client_socket_factory.h"
-#include "net/socket/tcp_client_socket.h"
#include "net/ssl/ssl_config_service.h"
#include "ui/base/clipboard/clipboard.h"
@@ -232,7 +233,7 @@
}
// For measuring memory usage after each task. Behind a command line flag.
-class BrowserMainLoop::MemoryObserver : public MessageLoop::TaskObserver {
+class BrowserMainLoop::MemoryObserver : public base::MessageLoop::TaskObserver {
public:
MemoryObserver() {}
virtual ~MemoryObserver() {}
@@ -292,6 +293,7 @@
}
void BrowserMainLoop::Init() {
+ TRACE_EVENT0("startup", "BrowserMainLoop::Init")
parts_.reset(
GetContentClient()->browser()->CreateBrowserMainParts(parameters_));
}
@@ -299,6 +301,7 @@
// BrowserMainLoop stages ==================================================
void BrowserMainLoop::EarlyInitialization() {
+ TRACE_EVENT0("startup", "BrowserMainLoop::EarlyInitialization")
#if defined(USE_X11)
if (parsed_command_line_.HasSwitch(switches::kSingleProcess) ||
parsed_command_line_.HasSwitch(switches::kInProcessGPU)) {
@@ -308,7 +311,7 @@
}
#endif
- if (parts_.get())
+ if (parts_)
parts_->PreEarlyInitialization();
#if defined(OS_WIN)
@@ -327,11 +330,6 @@
if (parsed_command_line_.HasSwitch(switches::kEnableSSLCachedInfo))
net::SSLConfigService::EnableCachedInfo();
- // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't
- // seem dependent on SSL initialization().
- if (parsed_command_line_.HasSwitch(switches::kEnableTcpFastOpen))
- net::SetTCPFastOpenEnabled(true);
-
#if !defined(OS_IOS)
if (parsed_command_line_.HasSwitch(switches::kRendererProcessLimit)) {
std::string limit_string = parsed_command_line_.GetSwitchValueASCII(
@@ -343,13 +341,17 @@
}
#endif // !defined(OS_IOS)
- if (parts_.get())
+ if (parts_)
parts_->PostEarlyInitialization();
}
void BrowserMainLoop::MainMessageLoopStart() {
- if (parts_.get())
+ TRACE_EVENT0("startup", "BrowserMainLoop::MainMessageLoopStart")
+ if (parts_) {
+ TRACE_EVENT0("startup",
+ "BrowserMainLoop::MainMessageLoopStart:PreMainMessageLoopStart");
parts_->PreMainMessageLoopStart();
+ }
#if defined(OS_WIN)
// If we're running tests (ui_task is non-null), then the ResourceBundle
@@ -361,12 +363,13 @@
#endif
// Create a MessageLoop if one does not already exist for the current thread.
- if (!MessageLoop::current())
- main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI));
+ if (!base::MessageLoop::current())
+ main_message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_UI));
InitializeMainThread();
system_monitor_.reset(new base::SystemMonitor);
+ power_monitor_.reset(new base::PowerMonitor);
hi_res_timer_manager_.reset(new HighResolutionTimerManager);
network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
audio_manager_.reset(media::AudioManager::Create());
@@ -398,7 +401,7 @@
system_message_window_.reset(new SystemMessageWindowWin);
#endif
- if (parts_.get())
+ if (parts_)
parts_->PostMainMessageLoopStart();
#if defined(OS_ANDROID)
@@ -408,13 +411,18 @@
if (parsed_command_line_.HasSwitch(switches::kMemoryMetrics)) {
memory_observer_.reset(new MemoryObserver());
- MessageLoop::current()->AddTaskObserver(memory_observer_.get());
+ base::MessageLoop::current()->AddTaskObserver(memory_observer_.get());
}
}
void BrowserMainLoop::CreateThreads() {
- if (parts_.get())
+ TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads")
+
+ if (parts_) {
+ TRACE_EVENT0("startup",
+ "BrowserMainLoop::MainMessageLoopStart:PreCreateThreads");
result_code_ = parts_->PreCreateThreads();
+ }
#if !defined(OS_IOS) && (!defined(GOOGLE_CHROME_BUILD) || defined(OS_ANDROID))
// Single-process is an unsupported and not fully tested mode, so
@@ -428,9 +436,9 @@
base::Thread::Options default_options;
base::Thread::Options io_message_loop_options;
- io_message_loop_options.message_loop_type = MessageLoop::TYPE_IO;
+ io_message_loop_options.message_loop_type = base::MessageLoop::TYPE_IO;
base::Thread::Options ui_message_loop_options;
- ui_message_loop_options.message_loop_type = MessageLoop::TYPE_UI;
+ ui_message_loop_options.message_loop_type = base::MessageLoop::TYPE_UI;
// Start threads in the order they occur in the BrowserThread::ID
// enumeration, except for BrowserThread::UI which is the main
@@ -445,16 +453,28 @@
switch (thread_id) {
case BrowserThread::DB:
+ TRACE_EVENT_BEGIN1("startup",
+ "BrowserMainLoop::CreateThreads:start",
+ "Thread", "BrowserThread::DB");
thread_to_start = &db_thread_;
break;
case BrowserThread::WEBKIT_DEPRECATED:
// Special case as WebKitThread is a separate
// type. |thread_to_start| is not used in this case.
+ TRACE_EVENT_BEGIN1("startup",
+ "BrowserMainLoop::CreateThreads:start",
+ "Thread", "BrowserThread::WEBKIT_DEPRECATED");
break;
case BrowserThread::FILE_USER_BLOCKING:
+ TRACE_EVENT_BEGIN1("startup",
+ "BrowserMainLoop::CreateThreads:start",
+ "Thread", "BrowserThread::FILE_USER_BLOCKING");
thread_to_start = &file_user_blocking_thread_;
break;
case BrowserThread::FILE:
+ TRACE_EVENT_BEGIN1("startup",
+ "BrowserMainLoop::CreateThreads:start",
+ "Thread", "BrowserThread::FILE");
thread_to_start = &file_thread_;
#if defined(OS_WIN)
// On Windows, the FILE thread needs to be have a UI message loop
@@ -466,13 +486,22 @@
#endif
break;
case BrowserThread::PROCESS_LAUNCHER:
+ TRACE_EVENT_BEGIN1("startup",
+ "BrowserMainLoop::CreateThreads:start",
+ "Thread", "BrowserThread::PROCESS_LAUNCHER");
thread_to_start = &process_launcher_thread_;
break;
case BrowserThread::CACHE:
+ TRACE_EVENT_BEGIN1("startup",
+ "BrowserMainLoop::CreateThreads:start",
+ "Thread", "BrowserThread::CACHE");
thread_to_start = &cache_thread_;
options = &io_message_loop_options;
break;
case BrowserThread::IO:
+ TRACE_EVENT_BEGIN1("startup",
+ "BrowserMainLoop::CreateThreads:start",
+ "Thread", "BrowserThread::IO");
thread_to_start = &io_thread_;
options = &io_message_loop_options;
break;
@@ -496,12 +525,18 @@
} else {
NOTREACHED();
}
+
+ TRACE_EVENT_END0("startup", "BrowserMainLoop::CreateThreads:start");
+
}
BrowserThreadsStarted();
- if (parts_.get())
+ if (parts_) {
+ TRACE_EVENT0("startup",
+ "BrowserMainLoop::CreateThreads:PreMainMessageLoopRun");
parts_->PreMainMessageLoopRun();
+ }
// If the UI thread blocks, the whole UI is unresponsive.
// Do not allow disk IO from the UI thread.
@@ -513,7 +548,7 @@
TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
bool ran_main_loop = false;
- if (parts_.get())
+ if (parts_)
ran_main_loop = parts_->MainMessageLoopRun(&result_code_);
if (!ran_main_loop)
@@ -531,7 +566,7 @@
base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed),
true));
- if (parts_.get())
+ if (parts_)
parts_->PostMainMessageLoopRun();
#if !defined(OS_IOS)
@@ -542,7 +577,7 @@
GpuProcessHostUIShim::DestroyAll();
// Cancel pending requests and prevent new requests.
- if (resource_dispatcher_host_.get())
+ if (resource_dispatcher_host_)
resource_dispatcher_host_.get()->Shutdown();
#if defined(USE_AURA)
@@ -610,7 +645,7 @@
#if !defined(OS_IOS)
// Clean up state that lives on or uses the file_thread_ before
// it goes away.
- if (resource_dispatcher_host_.get())
+ if (resource_dispatcher_host_)
resource_dispatcher_host_.get()->save_file_manager()->Shutdown();
#endif // !defined(OS_IOS)
break;
@@ -663,19 +698,19 @@
URLDataManager::DeleteDataSources();
#endif // !defined(OS_IOS)
- if (parts_.get())
+ if (parts_)
parts_->PostDestroyThreads();
}
void BrowserMainLoop::InitializeMainThread() {
const char* kThreadName = "CrBrowserMain";
base::PlatformThread::SetName(kThreadName);
- if (main_message_loop_.get())
+ if (main_message_loop_)
main_message_loop_->set_thread_name(kThreadName);
// Register the main thread by instantiating it, but don't call any methods.
- main_thread_.reset(new BrowserThreadImpl(BrowserThread::UI,
- MessageLoop::current()));
+ main_thread_.reset(
+ new BrowserThreadImpl(BrowserThread::UI, base::MessageLoop::current()));
}
#if defined(OS_ANDROID)
@@ -689,6 +724,7 @@
#endif
void BrowserMainLoop::BrowserThreadsStarted() {
+ TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted")
#if defined(OS_ANDROID)
// TODO(epenner): Move thread priorities to base. (crbug.com/170549)
BrowserThread::PostTask(BrowserThread::UI,
@@ -713,11 +749,19 @@
device_monitor_mac_.reset(new DeviceMonitorMac());
#endif
- // RDH needs the IO thread to be created.
- resource_dispatcher_host_.reset(new ResourceDispatcherHostImpl());
+ // RDH needs the IO thread to be created
+ {
+ TRACE_EVENT0("startup",
+ "BrowserMainLoop::BrowserThreadsStarted:InitResourceDispatcherHost");
+ resource_dispatcher_host_.reset(new ResourceDispatcherHostImpl());
+ }
// MediaStreamManager needs the IO thread to be created.
- media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
+ {
+ TRACE_EVENT0("startup",
+ "BrowserMainLoop::BrowserThreadsStarted:InitMediaStreamManager");
+ media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
+ }
// Initialize the GpuDataManager before we set up the MessageLoops because
// otherwise we'll trigger the assertion about doing IO on the UI thread.
@@ -725,7 +769,11 @@
#endif // !OS_IOS
#if defined(ENABLE_INPUT_SPEECH)
- speech_recognition_manager_.reset(new SpeechRecognitionManagerImpl());
+ {
+ TRACE_EVENT0("startup",
+ "BrowserMainLoop::BrowserThreadsStarted:InitSpeechRecognition");
+ speech_recognition_manager_.reset(new SpeechRecognitionManagerImpl());
+ }
#endif
#if !defined(OS_IOS)
@@ -744,12 +792,13 @@
// When running the GPU thread in-process, avoid optimistically starting it
// since creating the GPU thread races against creation of the one-and-only
// ChildProcess instance which is created by the renderer thread.
- if (GpuDataManagerImpl::GetInstance()->GpuAccessAllowed() &&
+ if (GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL) &&
IsForceCompositingModeEnabled() &&
!parsed_command_line_.HasSwitch(switches::kDisableGpuProcessPrelaunch) &&
!parsed_command_line_.HasSwitch(switches::kSingleProcess) &&
!parsed_command_line_.HasSwitch(switches::kInProcessGPU)) {
- TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process");
+ TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process",
+ TRACE_EVENT_SCOPE_THREAD);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE, base::Bind(
base::IgnoreResult(&GpuProcessHost::Get),
@@ -760,6 +809,7 @@
}
void BrowserMainLoop::InitializeToolkit() {
+ TRACE_EVENT0("startup", "BrowserMainLoop::InitializeToolkit")
// TODO(evan): this function is rather subtle, due to the variety
// of intersecting ifdefs we have. To keep it easy to follow, there
// are no #else branches on any #ifs.
@@ -800,7 +850,7 @@
LOG_GETLASTERROR(FATAL);
#endif
- if (parts_.get())
+ if (parts_)
parts_->ToolkitInitialized();
}
@@ -809,9 +859,10 @@
// Android's main message loop is the Java message loop.
NOTREACHED();
#else
- DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type());
+ DCHECK_EQ(base::MessageLoop::TYPE_UI, base::MessageLoop::current()->type());
if (parameters_.ui_task)
- MessageLoopForUI::current()->PostTask(FROM_HERE, *parameters_.ui_task);
+ base::MessageLoopForUI::current()->PostTask(FROM_HERE,
+ *parameters_.ui_task);
base::RunLoop run_loop;
run_loop.Run();
diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h
index 25e15a0..30442a6 100644
--- a/content/browser/browser_main_loop.h
+++ b/content/browser/browser_main_loop.h
@@ -11,9 +11,10 @@
class CommandLine;
class HighResolutionTimerManager;
-class MessageLoop;
namespace base {
+class MessageLoop;
+class PowerMonitor;
class SystemMonitor;
}
@@ -93,8 +94,9 @@
int result_code_;
// Members initialized in |MainMessageLoopStart()| ---------------------------
- scoped_ptr<MessageLoop> main_message_loop_;
+ scoped_ptr<base::MessageLoop> main_message_loop_;
scoped_ptr<base::SystemMonitor> system_monitor_;
+ scoped_ptr<base::PowerMonitor> power_monitor_;
scoped_ptr<HighResolutionTimerManager> hi_res_timer_manager_;
scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_;
scoped_ptr<media::AudioManager> audio_manager_;
diff --git a/content/browser/browser_main_runner.cc b/content/browser/browser_main_runner.cc
index c283db9..175b62f 100644
--- a/content/browser/browser_main_runner.cc
+++ b/content/browser/browser_main_runner.cc
@@ -43,6 +43,7 @@
virtual int Initialize(const MainFunctionParams& parameters)
OVERRIDE {
+ TRACE_EVENT0("startup", "BrowserMainRunnerImpl::Initialize")
is_initialized_ = true;
#if !defined(OS_IOS)
diff --git a/content/browser/browser_plugin/browser_plugin_embedder.cc b/content/browser/browser_plugin/browser_plugin_embedder.cc
index 10df740..12de8ef 100644
--- a/content/browser/browser_plugin/browser_plugin_embedder.cc
+++ b/content/browser/browser_plugin/browser_plugin_embedder.cc
@@ -10,6 +10,7 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/browser_plugin/browser_plugin_constants.h"
#include "content/common/browser_plugin/browser_plugin_messages.h"
+#include "content/common/drag_messages.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/user_metrics.h"
@@ -40,6 +41,28 @@
return new BrowserPluginEmbedder(web_contents);
}
+void BrowserPluginEmbedder::DragEnteredGuest(BrowserPluginGuest* guest) {
+ guest_dragging_over_ = guest->AsWeakPtr();
+}
+
+void BrowserPluginEmbedder::DragLeftGuest(BrowserPluginGuest* guest) {
+ // Avoid race conditions in switching between guests being hovered over by
+ // only un-setting if the caller is marked as the guest being dragged over.
+ if (guest_dragging_over_ == guest) {
+ guest_dragging_over_.reset();
+ }
+}
+
+void BrowserPluginEmbedder::StartDrag(BrowserPluginGuest* guest) {
+ guest_started_drag_ = guest->AsWeakPtr();
+}
+
+void BrowserPluginEmbedder::StopDrag(BrowserPluginGuest* guest) {
+ if (guest_started_drag_ == guest) {
+ guest_started_drag_.reset();
+ }
+}
+
void BrowserPluginEmbedder::GetRenderViewHostAtPosition(
int x, int y, const WebContents::GetRenderViewHostCallback& callback) {
// Store the callback so we can call it later when we have the response.
@@ -62,14 +85,46 @@
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_AllocateInstanceID,
OnAllocateInstanceID)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_Attach, OnAttach)
- IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CreateGuest, OnCreateGuest)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_PluginAtPositionResponse,
OnPluginAtPositionResponse)
+ IPC_MESSAGE_HANDLER_GENERIC(DragHostMsg_UpdateDragCursor,
+ OnUpdateDragCursor(&handled));
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
+void BrowserPluginEmbedder::DragSourceEndedAt(int client_x, int client_y,
+ int screen_x, int screen_y, WebKit::WebDragOperation operation) {
+ if (guest_started_drag_) {
+ gfx::Point guest_offset =
+ guest_started_drag_->GetScreenCoordinates(gfx::Point());
+ guest_started_drag_->DragSourceEndedAt(client_x - guest_offset.x(),
+ client_y - guest_offset.y(), screen_x, screen_y, operation);
+ }
+}
+
+void BrowserPluginEmbedder::DragSourceMovedTo(int client_x, int client_y,
+ int screen_x, int screen_y) {
+ if (guest_started_drag_) {
+ gfx::Point guest_offset =
+ guest_started_drag_->GetScreenCoordinates(gfx::Point());
+ guest_started_drag_->DragSourceMovedTo(client_x - guest_offset.x(),
+ client_y - guest_offset.y(), screen_x, screen_y);
+ }
+}
+
+void BrowserPluginEmbedder::SystemDragEnded() {
+ if (guest_started_drag_ && (guest_started_drag_ != guest_dragging_over_))
+ guest_started_drag_->EndSystemDrag();
+ guest_started_drag_.reset();
+ guest_dragging_over_.reset();
+}
+
+void BrowserPluginEmbedder::OnUpdateDragCursor(bool* handled) {
+ *handled = (guest_dragging_over_ != NULL);
+}
+
void BrowserPluginEmbedder::CleanUp() {
// CleanUp gets called when BrowserPluginEmbedder's WebContents goes away
// or the associated RenderViewHost is destroyed or swapped out. Therefore we
@@ -97,18 +152,21 @@
void BrowserPluginEmbedder::OnAttach(
int instance_id,
- const BrowserPluginHostMsg_CreateGuest_Params& params) {
+ const BrowserPluginHostMsg_Attach_Params& params) {
+ if (!GetBrowserPluginGuestManager()->CanEmbedderAccessInstanceIDMaybeKill(
+ web_contents()->GetRenderProcessHost()->GetID(), instance_id))
+ return;
+
BrowserPluginGuest* guest =
GetBrowserPluginGuestManager()->GetGuestByInstanceID(
instance_id, web_contents()->GetRenderProcessHost()->GetID());
- if (guest)
- guest->Attach(static_cast<WebContentsImpl*>(web_contents()), params);
-}
-void BrowserPluginEmbedder::OnCreateGuest(
- int instance_id,
- const BrowserPluginHostMsg_CreateGuest_Params& params) {
- BrowserPluginGuest* guest = GetBrowserPluginGuestManager()->CreateGuest(
+ if (guest) {
+ guest->Attach(static_cast<WebContentsImpl*>(web_contents()), params);
+ return;
+ }
+
+ guest = GetBrowserPluginGuestManager()->CreateGuest(
web_contents()->GetSiteInstance(), instance_id, params);
if (guest)
guest->Initialize(static_cast<WebContentsImpl*>(web_contents()), params);
@@ -122,9 +180,12 @@
return;
RenderViewHost* render_view_host;
- BrowserPluginGuest* guest =
- GetBrowserPluginGuestManager()->GetGuestByInstanceID(
- instance_id, web_contents()->GetRenderProcessHost()->GetID());
+ BrowserPluginGuest* guest = NULL;
+ if (instance_id != browser_plugin::kInstanceIDNone) {
+ guest = GetBrowserPluginGuestManager()->GetGuestByInstanceID(
+ instance_id, web_contents()->GetRenderProcessHost()->GetID());
+ }
+
if (guest)
render_view_host = guest->GetWebContents()->GetRenderViewHost();
else // No plugin, use embedder's RenderViewHost.
diff --git a/content/browser/browser_plugin/browser_plugin_embedder.h b/content/browser/browser_plugin/browser_plugin_embedder.h
index ddcf6f1..1b6c8b2 100644
--- a/content/browser/browser_plugin/browser_plugin_embedder.h
+++ b/content/browser/browser_plugin/browser_plugin_embedder.h
@@ -16,10 +16,12 @@
#include <map>
+#include "base/memory/weak_ptr.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDragOperation.h"
-struct BrowserPluginHostMsg_CreateGuest_Params;
+struct BrowserPluginHostMsg_Attach_Params;
struct BrowserPluginHostMsg_ResizeGuest_Params;
namespace gfx {
@@ -28,6 +30,7 @@
namespace content {
+class BrowserPluginGuest;
class BrowserPluginGuestManager;
class BrowserPluginHostFactory;
class WebContentsImpl;
@@ -56,6 +59,24 @@
virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+ void DragSourceEndedAt(int client_x, int client_y, int screen_x,
+ int screen_y, WebKit::WebDragOperation operation);
+
+ void DragSourceMovedTo(int client_x, int client_y,
+ int screen_x, int screen_y);
+
+ void OnUpdateDragCursor(bool* handled);
+
+ void DragEnteredGuest(BrowserPluginGuest* guest);
+
+ void DragLeftGuest(BrowserPluginGuest* guest);
+
+ void StartDrag(BrowserPluginGuest* guest);
+
+ void StopDrag(BrowserPluginGuest* guest);
+
+ void SystemDragEnded();
+
private:
friend class TestBrowserPluginEmbedder;
@@ -69,9 +90,7 @@
void OnAllocateInstanceID(int request_id);
void OnAttach(int instance_id,
- const BrowserPluginHostMsg_CreateGuest_Params& params);
- void OnCreateGuest(int instance_id,
- const BrowserPluginHostMsg_CreateGuest_Params& params);
+ const BrowserPluginHostMsg_Attach_Params& params);
void OnPluginAtPositionResponse(int instance_id,
int request_id,
const gfx::Point& position);
@@ -88,6 +107,17 @@
// Next request id for BrowserPluginMsg_PluginAtPositionRequest query.
int next_get_render_view_request_id_;
+ // Used to correctly update the cursor when dragging over a guest, and to
+ // handle a race condition when dropping onto the guest that started the drag
+ // (the race is that the dragend message arrives before the drop message so
+ // the drop never takes place).
+ // crbug.com/233571
+ base::WeakPtr<BrowserPluginGuest> guest_dragging_over_;
+
+ // Pointer to the guest that started the drag, used to forward necessary drag
+ // status messages to the correct guest.
+ base::WeakPtr<BrowserPluginGuest> guest_started_drag_;
+
DISALLOW_COPY_AND_ASSIGN(BrowserPluginEmbedder);
};
diff --git a/content/browser/browser_plugin/browser_plugin_geolocation_permission_context.cc b/content/browser/browser_plugin/browser_plugin_geolocation_permission_context.cc
index 59a23b5..8a803c4 100644
--- a/content/browser/browser_plugin/browser_plugin_geolocation_permission_context.cc
+++ b/content/browser/browser_plugin/browser_plugin_geolocation_permission_context.cc
@@ -49,7 +49,6 @@
// have geolocation access.
RenderViewHost* rvh = RenderViewHost::FromID(render_process_id,
render_view_id);
- DCHECK(rvh);
if (rvh) {
DCHECK(rvh->GetProcess()->IsGuest());
WebContentsImpl* guest_web_contents =
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc
index 973408f..cffa56c 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -6,6 +6,7 @@
#include <algorithm>
+#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
@@ -13,6 +14,8 @@
#include "content/browser/browser_plugin/browser_plugin_guest_helper.h"
#include "content/browser/browser_plugin/browser_plugin_guest_manager.h"
#include "content/browser/browser_plugin/browser_plugin_host_factory.h"
+#include "content/browser/browser_thread_impl.h"
+#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -22,6 +25,7 @@
#include "content/common/content_constants_internal.h"
#include "content/common/drag_messages.h"
#include "content/common/gpu/gpu_messages.h"
+#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/port/browser/render_view_host_delegate_view.h"
#include "content/public/browser/browser_context.h"
@@ -34,10 +38,13 @@
#include "content/public/browser/resource_request_details.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents_view.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/media_stream_request.h"
#include "content/public/common/result_codes.h"
#include "net/base/net_errors.h"
+#include "net/url_request/url_request.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h"
+#include "ui/base/keycodes/keyboard_codes.h"
#include "ui/surface/transport_dib.h"
#include "webkit/glue/resource_type.h"
#include "webkit/glue/webdropdata.h"
@@ -51,6 +58,133 @@
// static
BrowserPluginHostFactory* BrowserPluginGuest::factory_ = NULL;
+// Parent class for the various types of permission requests, each of which
+// should be able to handle the response to their permission request.
+class BrowserPluginGuest::PermissionRequest {
+ public:
+ virtual void Respond(bool should_allow) = 0;
+ virtual ~PermissionRequest() {}
+ protected:
+ PermissionRequest() {}
+};
+
+class BrowserPluginGuest::DownloadRequest : public PermissionRequest {
+ public:
+ explicit DownloadRequest(base::Callback<void(bool)> callback)
+ : callback_(callback) {}
+ virtual void Respond(bool should_allow) OVERRIDE {
+ callback_.Run(should_allow);
+ }
+ virtual ~DownloadRequest() {}
+ private:
+ base::Callback<void(bool)> callback_;
+};
+
+class BrowserPluginGuest::GeolocationRequest : public PermissionRequest {
+ public:
+ GeolocationRequest(GeolocationCallback callback,
+ int bridge_id,
+ BrowserPluginGuest* guest,
+ base::WeakPtrFactory<BrowserPluginGuest>* weak_ptr_factory)
+ : callback_(callback),
+ bridge_id_(bridge_id),
+ guest_(guest),
+ weak_ptr_factory_(weak_ptr_factory) {}
+
+ virtual void Respond(bool should_allow) OVERRIDE {
+ WebContents* web_contents = guest_->embedder_web_contents();
+ if (should_allow && web_contents) {
+ // If renderer side embedder decides to allow gelocation, we need to check
+ // if the app/embedder itself has geolocation access.
+ BrowserContext* browser_context = web_contents->GetBrowserContext();
+ if (browser_context) {
+ GeolocationPermissionContext* geolocation_context =
+ browser_context->GetGeolocationPermissionContext();
+ if (geolocation_context) {
+ base::Callback<void(bool)> geolocation_callback = base::Bind(
+ &BrowserPluginGuest::SetGeolocationPermission,
+ weak_ptr_factory_->GetWeakPtr(),
+ callback_,
+ bridge_id_);
+ geolocation_context->RequestGeolocationPermission(
+ web_contents->GetRenderProcessHost()->GetID(),
+ web_contents->GetRoutingID(),
+ // The geolocation permission request here is not initiated
+ // through WebGeolocationPermissionRequest. We are only interested
+ // in the fact whether the embedder/app has geolocation
+ // permission. Therefore we use an invalid |bridge_id|.
+ -1 /* bridge_id */,
+ web_contents->GetURL(),
+ geolocation_callback);
+ return;
+ }
+ }
+ }
+ guest_->SetGeolocationPermission(callback_, bridge_id_, false);
+ }
+ virtual ~GeolocationRequest() {}
+ private:
+ base::Callback<void(bool)> callback_;
+ int bridge_id_;
+ BrowserPluginGuest* guest_;
+ base::WeakPtrFactory<BrowserPluginGuest>* weak_ptr_factory_;
+};
+
+class BrowserPluginGuest::MediaRequest : public PermissionRequest {
+ public:
+ MediaRequest(const MediaStreamRequest& request,
+ const MediaResponseCallback& callback,
+ BrowserPluginGuest* guest)
+ : request_(request),
+ callback_(callback),
+ guest_(guest) {}
+
+ virtual void Respond(bool should_allow) OVERRIDE {
+ WebContentsImpl* web_contents = guest_->embedder_web_contents();
+ if (should_allow && web_contents) {
+ // Re-route the request to the embedder's WebContents; the guest gets the
+ // permission this way.
+ web_contents->RequestMediaAccessPermission(request_, callback_);
+ } else {
+ // Deny the request.
+ callback_.Run(MediaStreamDevices(), scoped_ptr<MediaStreamUI>());
+ }
+
+ }
+ virtual ~MediaRequest() {}
+ private:
+ MediaStreamRequest request_;
+ MediaResponseCallback callback_;
+ BrowserPluginGuest* guest_;
+};
+
+class BrowserPluginGuest::NewWindowRequest : public PermissionRequest {
+ public:
+ NewWindowRequest(int instance_id, BrowserPluginGuest* guest)
+ : instance_id_(instance_id),
+ guest_(guest) {}
+
+ virtual void Respond(bool should_allow) OVERRIDE {
+ int embedder_render_process_id =
+ guest_->embedder_web_contents()->GetRenderProcessHost()->GetID();
+ BrowserPluginGuest* guest =
+ guest_->GetWebContents()->GetBrowserPluginGuestManager()->
+ GetGuestByInstanceID(instance_id_, embedder_render_process_id);
+ if (!guest) {
+ LOG(INFO) << "Guest not found. Instance ID: " << instance_id_;
+ return;
+ }
+
+ // If we do not destroy the guest then we allow the new window.
+ if (!should_allow)
+ guest->Destroy();
+ }
+ virtual ~NewWindowRequest() {}
+ private:
+ int instance_id_;
+ BrowserPluginGuest* guest_;
+};
+
namespace {
const size_t kNumMaxOutstandingPermissionRequests = 1024;
@@ -77,8 +211,23 @@
}
}
+// Called on IO thread.
+static std::string RetrieveDownloadURLFromRequestId(
+ RenderViewHost* render_view_host,
+ int url_request_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ int render_process_id = render_view_host->GetProcess()->GetID();
+ GlobalRequestID global_id(render_process_id, url_request_id);
+ net::URLRequest* url_request =
+ ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id);
+ if (url_request)
+ return url_request->url().possibly_invalid_spec();
+ return std::string();
}
+} // namespace
+
class BrowserPluginGuest::EmbedderRenderViewHostObserver
: public RenderViewHostObserver {
public:
@@ -94,6 +243,7 @@
// RenderViewHostObserver:
virtual void RenderViewHostDestroyed(
RenderViewHost* render_view_host) OVERRIDE {
+ browser_plugin_guest_->embedder_web_contents_ = NULL;
browser_plugin_guest_->Destroy();
}
@@ -105,28 +255,53 @@
BrowserPluginGuest::BrowserPluginGuest(
int instance_id,
- WebContentsImpl* web_contents)
+ WebContentsImpl* web_contents,
+ BrowserPluginGuest* opener,
+ bool has_render_view)
: WebContentsObserver(web_contents),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
+ weak_ptr_factory_(this),
embedder_web_contents_(NULL),
instance_id_(instance_id),
damage_buffer_sequence_id_(0),
damage_buffer_size_(0),
damage_buffer_scale_factor_(1.0f),
+ guest_device_scale_factor_(1.0f),
guest_hang_timeout_(
base::TimeDelta::FromMilliseconds(kHungRendererDelayMs)),
focused_(false),
mouse_locked_(false),
pending_lock_request_(false),
embedder_visible_(true),
- opener_(NULL),
- next_permission_request_id_(0) {
+ next_permission_request_id_(0),
+ has_render_view_(has_render_view) {
DCHECK(web_contents);
web_contents->SetDelegate(this);
+ if (opener)
+ opener_ = opener->AsWeakPtr();
GetWebContents()->GetBrowserPluginGuestManager()->AddGuest(instance_id_,
GetWebContents());
}
+bool BrowserPluginGuest::AddMessageToConsole(WebContents* source,
+ int32 level,
+ const string16& message,
+ int32 line_no,
+ const string16& source_id) {
+ base::DictionaryValue message_info;
+ // Log levels are from base/logging.h: LogSeverity.
+ message_info.Set(browser_plugin::kLevel,
+ base::Value::CreateIntegerValue(level));
+ message_info.Set(browser_plugin::kMessage,
+ base::Value::CreateStringValue(message));
+ message_info.Set(browser_plugin::kLine,
+ base::Value::CreateIntegerValue(line_no));
+ message_info.Set(browser_plugin::kSourceId,
+ base::Value::CreateStringValue(source_id));
+ SendMessageToEmbedder(
+ new BrowserPluginMsg_AddMessageToConsole(instance_id_, message_info));
+ return false;
+}
+
void BrowserPluginGuest::DestroyUnattachedWindows() {
// Destroy() reaches in and removes the BrowserPluginGuest from its opener's
// pending_new_windows_ set. To avoid mutating the set while iterating, we
@@ -156,8 +331,12 @@
IPC_BEGIN_MESSAGE_MAP(BrowserPluginGuest, message)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_BuffersSwappedACK,
OnSwapBuffersACK)
+ IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CompositorFrameACK,
+ OnCompositorFrameACK)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_DragStatusUpdate,
OnDragStatusUpdate)
+ IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ExecuteEditCommand,
+ OnExecuteEditCommand)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_Go, OnGo)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_HandleInputEvent,
OnHandleInputEvent)
@@ -183,7 +362,7 @@
void BrowserPluginGuest::Initialize(
WebContentsImpl* embedder_web_contents,
- const BrowserPluginHostMsg_CreateGuest_Params& params) {
+ const BrowserPluginHostMsg_Attach_Params& params) {
focused_ = params.focused;
guest_visible_ = params.visible;
if (!params.name.empty())
@@ -244,6 +423,8 @@
if (!params.src.empty())
OnNavigateGuest(instance_id_, params.src);
+ has_render_view_ = true;
+
GetContentClient()->browser()->GuestWebContentsCreated(
GetWebContents(), embedder_web_contents_);
}
@@ -258,7 +439,19 @@
RecordAction(UserMetricsAction("BrowserPlugin.Guest.Create"));
if (factory_)
return factory_->CreateBrowserPluginGuest(instance_id, web_contents);
- return new BrowserPluginGuest(instance_id, web_contents);
+ return new BrowserPluginGuest(instance_id, web_contents, NULL, false);
+}
+
+// static
+BrowserPluginGuest* BrowserPluginGuest::CreateWithOpener(
+ int instance_id,
+ WebContentsImpl* web_contents,
+ BrowserPluginGuest* opener,
+ bool has_render_view) {
+ return new BrowserPluginGuest(instance_id,
+ web_contents,
+ opener,
+ has_render_view);
}
RenderWidgetHostView* BrowserPluginGuest::GetEmbedderRenderWidgetHostView() {
@@ -302,19 +495,39 @@
const gfx::Rect& initial_pos,
bool user_gesture,
bool* was_blocked) {
- *was_blocked = false;
+ if (was_blocked)
+ *was_blocked = false;
RequestNewWindowPermission(static_cast<WebContentsImpl*>(new_contents),
disposition, initial_pos, user_gesture);
}
-bool BrowserPluginGuest::CanDownload(RenderViewHost* render_view_host,
- int request_id,
- const std::string& request_method) {
- // TODO(fsamuel): We disable downloads in guests for now, but we will later
- // expose API to allow embedders to handle them.
- // Note: it seems content_shell ignores this. This should be fixed
- // for debugging and test purposes.
- return false;
+void BrowserPluginGuest::CanDownload(
+ RenderViewHost* render_view_host,
+ int request_id,
+ const std::string& request_method,
+ const base::Callback<void(bool)>& callback) {
+ if (permission_request_map_.size() >= kNumMaxOutstandingPermissionRequests) {
+ // Deny the download request.
+ callback.Run(false);
+ return;
+ }
+
+ int permission_request_id = next_permission_request_id_++;
+ permission_request_map_[permission_request_id] =
+ new DownloadRequest(callback);
+
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&RetrieveDownloadURLFromRequestId,
+ render_view_host, request_id),
+ base::Bind(&BrowserPluginGuest::DidRetrieveDownloadURLFromRequestId,
+ weak_ptr_factory_.GetWeakPtr(),
+ request_method,
+ permission_request_id));
+}
+
+void BrowserPluginGuest::CloseContents(WebContents* source) {
+ SendMessageToEmbedder(new BrowserPluginMsg_Close(instance_id_));
}
bool BrowserPluginGuest::HandleContextMenu(
@@ -325,6 +538,45 @@
return true;
}
+void BrowserPluginGuest::HandleKeyboardEvent(
+ WebContents* source,
+ const NativeWebKeyboardEvent& event) {
+ if (!attached())
+ return;
+
+ // Send the unhandled keyboard events back to the embedder to reprocess them.
+ // TODO(fsamuel): This introduces the possibility of out-of-order keyboard
+ // events because the guest may be arbitrarily delayed when responding to
+ // keyboard events. In that time, the embedder may have received and processed
+ // additional key events. This needs to be fixed as soon as possible.
+ // See http://crbug.com/229882.
+ embedder_web_contents_->GetDelegate()->HandleKeyboardEvent(
+ web_contents(), event);
+}
+
+WebContents* BrowserPluginGuest::OpenURLFromTab(WebContents* source,
+ const OpenURLParams& params) {
+ // If the guest wishes to navigate away prior to attachment then we save the
+ // navigation to perform upon attachment. Navigation initializes a lot of
+ // state that assumes an embedder exists, such as RenderWidgetHostViewGuest.
+ // Navigation also resumes resource loading which we don't want to allow
+ // until attachment.
+ if (!attached()) {
+ PendingWindowMap::iterator it = opener()->pending_new_windows_.find(this);
+ if (it == opener()->pending_new_windows_.end())
+ return NULL;
+ const TargetURL& old_target_url = it->second;
+ TargetURL new_target_url(params.url);
+ new_target_url.changed = new_target_url.url != old_target_url.url;
+ it->second = new_target_url;
+ return NULL;
+ }
+ // This can happen for cross-site redirects.
+ source->GetController().LoadURL(
+ params.url, params.referrer, params.transition, std::string());
+ return source;
+}
+
void BrowserPluginGuest::WebContentsCreated(WebContents* source_contents,
int64 source_frame_id,
const string16& frame_name,
@@ -333,12 +585,12 @@
WebContentsImpl* new_contents_impl =
static_cast<WebContentsImpl*>(new_contents);
BrowserPluginGuest* guest = new_contents_impl->GetBrowserPluginGuest();
- guest->opener_ = this;
+ guest->opener_ = AsWeakPtr();
guest->name_ = UTF16ToUTF8(frame_name);
// Take ownership of the new guest until it is attached to the embedder's DOM
// tree to avoid leaking a guest if this guest is destroyed before attaching
// the new guest.
- pending_new_windows_.insert(make_pair(guest, target_url.spec()));
+ pending_new_windows_.insert(std::make_pair(guest, TargetURL(target_url)));
}
void BrowserPluginGuest::RendererUnresponsive(WebContents* source) {
@@ -423,21 +675,22 @@
PendingWindowMap::iterator it = pending_new_windows_.find(guest);
if (it == pending_new_windows_.end())
return;
- const std::string& target_url = it->second;
+ const TargetURL& target_url = it->second;
base::DictionaryValue request_info;
request_info.Set(browser_plugin::kInitialHeight,
base::Value::CreateIntegerValue(initial_bounds.height()));
request_info.Set(browser_plugin::kInitialWidth,
base::Value::CreateIntegerValue(initial_bounds.width()));
request_info.Set(browser_plugin::kTargetURL,
- base::Value::CreateStringValue(target_url));
+ base::Value::CreateStringValue(target_url.url.spec()));
request_info.Set(browser_plugin::kWindowID,
base::Value::CreateIntegerValue(guest->instance_id()));
request_info.Set(browser_plugin::kWindowOpenDisposition,
base::Value::CreateStringValue(
WindowOpenDispositionToString(disposition)));
int request_id = next_permission_request_id_++;
- new_window_request_map_[request_id] = guest->instance_id();
+ permission_request_map_[request_id] =
+ new NewWindowRequest(guest->instance_id(), this);
SendMessageToEmbedder(new BrowserPluginMsg_RequestPermission(
instance_id(), BrowserPluginPermissionTypeNewWindow,
request_id, request_info));
@@ -485,6 +738,29 @@
embedder_web_contents_->Send(msg);
}
+void BrowserPluginGuest::DragSourceEndedAt(int client_x, int client_y,
+ int screen_x, int screen_y, WebKit::WebDragOperation operation) {
+ web_contents()->GetRenderViewHost()->DragSourceEndedAt(client_x, client_y,
+ screen_x, screen_y, operation);
+}
+
+void BrowserPluginGuest::DragSourceMovedTo(int client_x, int client_y,
+ int screen_x, int screen_y) {
+ web_contents()->GetRenderViewHost()->DragSourceMovedTo(client_x, client_y,
+ screen_x, screen_y);
+}
+
+void BrowserPluginGuest::EndSystemDrag() {
+ RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
+ GetWebContents()->GetRenderViewHost());
+ guest_rvh->DragSourceSystemDragEnded();
+ // Issue a MouseUp event to get out of a selection state.
+ WebKit::WebMouseEvent mouse_event;
+ mouse_event.type = WebKit::WebInputEvent::MouseUp;
+ mouse_event.button = WebKit::WebMouseEvent::ButtonLeft;
+ guest_rvh->ForwardMouseEvent(mouse_event);
+}
+
void BrowserPluginGuest::LoadRedirect(
const GURL& old_url,
const GURL& new_url,
@@ -500,14 +776,17 @@
int bridge_id,
const GURL& requesting_frame,
const GeolocationCallback& callback) {
- if (geolocation_request_callback_map_.size() >=
- kNumMaxOutstandingPermissionRequests) {
+ if (permission_request_map_.size() >= kNumMaxOutstandingPermissionRequests) {
// Deny the geolocation request.
callback.Run(false);
return;
}
int request_id = next_permission_request_id_++;
- geolocation_request_callback_map_[request_id] = callback;
+ permission_request_map_[request_id] = new GeolocationRequest(
+ callback, bridge_id, this, &weak_ptr_factory_);
+ DCHECK(bridge_id_to_request_id_map_.find(bridge_id) ==
+ bridge_id_to_request_id_map_.end());
+ bridge_id_to_request_id_map_[bridge_id] = request_id;
base::DictionaryValue request_info;
request_info.Set(browser_plugin::kURL,
@@ -519,20 +798,25 @@
}
void BrowserPluginGuest::CancelGeolocationRequest(int bridge_id) {
- GeolocationRequestsMap::iterator callback_iter =
- geolocation_request_callback_map_.find(bridge_id);
- if (callback_iter != geolocation_request_callback_map_.end())
- geolocation_request_callback_map_.erase(callback_iter);
+ std::map<int, int>::iterator bridge_itr =
+ bridge_id_to_request_id_map_.find(bridge_id);
+ if (bridge_itr == bridge_id_to_request_id_map_.end())
+ return;
+
+ int request_id = bridge_itr->second;
+ bridge_id_to_request_id_map_.erase(bridge_itr);
+ RequestMap::iterator request_itr = permission_request_map_.find(request_id);
+ if (request_itr == permission_request_map_.end())
+ return;
+ delete request_itr->second;
+ permission_request_map_.erase(request_itr);
}
-void BrowserPluginGuest::SetGeolocationPermission(int request_id,
+void BrowserPluginGuest::SetGeolocationPermission(GeolocationCallback callback,
+ int bridge_id,
bool allowed) {
- GeolocationRequestsMap::iterator callback_iter =
- geolocation_request_callback_map_.find(request_id);
- if (callback_iter != geolocation_request_callback_map_.end()) {
- callback_iter->second.Run(allowed);
- geolocation_request_callback_map_.erase(callback_iter);
- }
+ callback.Run(allowed);
+ CancelGeolocationRequest(bridge_id);
}
void BrowserPluginGuest::DidCommitProvisionalLoadForFrame(
@@ -557,20 +841,29 @@
}
void BrowserPluginGuest::DidStopLoading(RenderViewHost* render_view_host) {
- // Initiating a drag from inside a guest is currently not supported. So inject
- // some JS to disable it. http://crbug.com/161112
- const char script[] = "window.addEventListener('dragstart', function() { "
- " window.event.preventDefault(); "
- "});";
- render_view_host->ExecuteJavascriptInWebFrame(string16(),
- ASCIIToUTF16(script));
+ bool disable_dragdrop = true;
+#if defined(OS_LINUX) || defined(OS_MACOSX)
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserPluginDragDrop))
+ disable_dragdrop = false;
+#endif // defined(OS_LINUX) || defined(OS_MACOSX)
+ if (disable_dragdrop) {
+ // Initiating a drag from inside a guest is currently not supported without
+ // the kEnableBrowserPluginDragDrop flag on a linux platform. So inject some
+ // JS to disable it. http://crbug.com/161112
+ const char script[] = "window.addEventListener('dragstart', function() { "
+ " window.event.preventDefault(); "
+ "});";
+ render_view_host->ExecuteJavascriptInWebFrame(string16(),
+ ASCIIToUTF16(script));
+ }
SendMessageToEmbedder(new BrowserPluginMsg_LoadStop(instance_id()));
}
void BrowserPluginGuest::RenderViewReady() {
// TODO(fsamuel): Investigate whether it's possible to update state earlier
// here (see http://crbug.com/158151).
- Send(new ViewMsg_SetFocus(routing_id(), focused_));
+ Send(new InputMsg_SetFocus(routing_id(), focused_));
UpdateVisibility();
RenderViewHost* rvh = GetWebContents()->GetRenderViewHost();
if (auto_size_enabled_)
@@ -622,7 +915,9 @@
const IPC::Message& message) {
switch (message.type()) {
case BrowserPluginHostMsg_BuffersSwappedACK::ID:
+ case BrowserPluginHostMsg_CompositorFrameACK::ID:
case BrowserPluginHostMsg_DragStatusUpdate::ID:
+ case BrowserPluginHostMsg_ExecuteEditCommand::ID:
case BrowserPluginHostMsg_Go::ID:
case BrowserPluginHostMsg_HandleInputEvent::ID:
case BrowserPluginHostMsg_LockMouse_ACK::ID:
@@ -659,11 +954,9 @@
// renderer process paints inside.
IPC_MESSAGE_HANDLER(ViewHostMsg_ShowPopup, OnShowPopup)
#endif
- IPC_MESSAGE_HANDLER(ViewHostMsg_ShowView, OnShowView)
IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget)
IPC_MESSAGE_HANDLER(ViewHostMsg_TakeFocus, OnTakeFocus)
IPC_MESSAGE_HANDLER(ViewHostMsg_UnlockMouse, OnUnlockMouse)
- IPC_MESSAGE_HANDLER(DragHostMsg_UpdateDragCursor, OnUpdateDragCursor)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFrameName, OnUpdateFrameName)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnUpdateRect)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -673,26 +966,39 @@
void BrowserPluginGuest::Attach(
WebContentsImpl* embedder_web_contents,
- BrowserPluginHostMsg_CreateGuest_Params params) {
- const std::string target_url = opener()->pending_new_windows_[this];
- if (!GetWebContents()->opener()) {
- // For guests that have a suppressed opener, we navigate now.
- // Navigation triggers the creation of a RenderWidgetHostViewGuest so
- // we don't need to create one manually.
- params.src = target_url;
- } else {
- // Ensure that the newly attached guest gets a RenderWidgetHostViewGuest.
+ BrowserPluginHostMsg_Attach_Params params) {
+ if (attached())
+ return;
+
+ // Clear parameters that get inherited from the opener.
+ params.storage_partition_id.clear();
+ params.persist_storage = false;
+ params.src.clear();
+
+ // If a RenderView has already been created for this new window, then we need
+ // to initialize the browser-side state now so that the RenderViewHostManager
+ // does not create a new RenderView on navigation.
+ if (has_render_view_) {
+ static_cast<RenderViewHostImpl*>(
+ GetWebContents()->GetRenderViewHost())->Init();
WebContentsViewGuest* new_view =
static_cast<WebContentsViewGuest*>(GetWebContents()->GetView());
new_view->CreateViewForWidget(web_contents()->GetRenderViewHost());
-
- // Reply to ViewHostMsg_ShowView to inform the renderer that the browser has
- // processed the move. The browser may have ignored the move, but it
- // finished processing. This is used because the renderer keeps a temporary
- // cache of the widget position while these asynchronous operations are in
- // progress.
- Send(new ViewMsg_Move_ACK(web_contents()->GetRoutingID()));
}
+
+ // We need to do a navigation here if the target URL has changed between
+ // the time the WebContents was created and the time it was attached.
+ // We also need to do an initial navigation if a RenderView was never
+ // created for the new window in cases where there is no referrer.
+ PendingWindowMap::iterator it = opener()->pending_new_windows_.find(this);
+ if (it != opener()->pending_new_windows_.end()) {
+ const TargetURL& target_url = it->second;
+ if (target_url.changed || !has_render_view_)
+ params.src = it->second.url.spec();
+ } else {
+ NOTREACHED();
+ }
+
// Once a new guest is attached to the DOM of the embedder page, then the
// lifetime of the new guest is no longer managed by the opener guest.
opener()->pending_new_windows_.erase(this);
@@ -705,19 +1011,27 @@
Initialize(embedder_web_contents, params);
- // We initialize the RenderViewHost after a BrowserPlugin has been attached
- // to it and is ready to receive pixels. Until a RenderViewHost is
- // initialized, it will not allow any resize requests.
- if (!GetWebContents()->GetRenderViewHost()->IsRenderViewLive()) {
- static_cast<RenderViewHostImpl*>(
- GetWebContents()->GetRenderViewHost())->Init();
- }
+ // Inform the embedder of the guest's information.
+ // We pull the partition information from the site's URL, which is of the form
+ // guest://site/{persist}?{partition_name}.
+ const GURL& site_url = GetWebContents()->GetSiteInstance()->GetSiteURL();
+ BrowserPluginMsg_Attach_ACK_Params ack_params;
+ ack_params.storage_partition_id = site_url.query();
+ ack_params.persist_storage =
+ site_url.path().find("persist") != std::string::npos;
+ ack_params.name = name_;
+ SendMessageToEmbedder(
+ new BrowserPluginMsg_Attach_ACK(instance_id_, ack_params));
+}
- // Inform the embedder BrowserPlugin of the attached guest.
- if (!name_.empty()) {
- SendMessageToEmbedder(
- new BrowserPluginMsg_UpdatedName(instance_id_, name_));
- }
+void BrowserPluginGuest::OnCompositorFrameACK(
+ int instance_id,
+ int route_id,
+ int renderer_host_id,
+ const cc::CompositorFrameAck& ack) {
+ RenderWidgetHostImpl::SendSwapCompositorFrameAck(route_id,
+ renderer_host_id,
+ ack);
}
void BrowserPluginGuest::OnDragStatusUpdate(int instance_id,
@@ -728,22 +1042,31 @@
RenderViewHost* host = GetWebContents()->GetRenderViewHost();
switch (drag_status) {
case WebKit::WebDragStatusEnter:
+ embedder_web_contents_->GetBrowserPluginEmbedder()->DragEnteredGuest(
+ this);
host->DragTargetDragEnter(drop_data, location, location, mask, 0);
break;
case WebKit::WebDragStatusOver:
host->DragTargetDragOver(location, location, mask, 0);
break;
case WebKit::WebDragStatusLeave:
+ embedder_web_contents_->GetBrowserPluginEmbedder()->DragLeftGuest(this);
host->DragTargetDragLeave();
break;
case WebKit::WebDragStatusDrop:
host->DragTargetDrop(location, location, 0);
+ EndSystemDrag();
break;
case WebKit::WebDragStatusUnknown:
NOTREACHED();
}
}
+void BrowserPluginGuest::OnExecuteEditCommand(int instance_id,
+ const std::string& name) {
+ Send(new InputMsg_ExecuteEditCommand(routing_id(), name, std::string()));
+}
+
void BrowserPluginGuest::OnGo(int instance_id, int relative_index) {
GetWebContents()->GetController().GoToOffset(relative_index);
}
@@ -753,10 +1076,16 @@
const gfx::Rect& guest_window_rect,
const WebKit::WebInputEvent* event) {
guest_window_rect_ = guest_window_rect;
- guest_screen_rect_ = guest_window_rect;
- guest_screen_rect_.Offset(
- embedder_web_contents_->GetRenderViewHost()->GetView()->
- GetViewBounds().OffsetFromOrigin());
+ // If the embedder's RWHV is destroyed then that means that the embedder's
+ // window has been closed but the embedder's WebContents has not yet been
+ // destroyed. Computing screen coordinates of a BrowserPlugin only makes sense
+ // if there is a visible embedder.
+ if (embedder_web_contents_->GetRenderWidgetHostView()) {
+ guest_screen_rect_ = guest_window_rect;
+ guest_screen_rect_.Offset(
+ embedder_web_contents_->GetRenderWidgetHostView()->
+ GetViewBounds().OffsetFromOrigin());
+ }
RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
GetWebContents()->GetRenderViewHost());
@@ -773,12 +1102,12 @@
}
if (WebKit::WebInputEvent::isKeyboardEventType(event->type)) {
- NativeWebKeyboardEvent keyboard_event;
- const WebKit::WebKeyboardEvent* original_event =
- static_cast<const WebKit::WebKeyboardEvent*>(event);
- memcpy(&keyboard_event, original_event, sizeof(WebKit::WebKeyboardEvent));
- if (keyboard_event.type == WebKit::WebInputEvent::KeyDown)
- keyboard_event.type = WebKit::WebInputEvent::RawKeyDown;
+ RenderViewHostImpl* embedder_rvh = static_cast<RenderViewHostImpl*>(
+ embedder_web_contents_->GetRenderViewHost());
+ if (!embedder_rvh->GetLastKeyboardEvent())
+ return;
+ NativeWebKeyboardEvent keyboard_event(
+ *embedder_rvh->GetLastKeyboardEvent());
guest_rvh->ForwardKeyboardEvent(keyboard_event);
return;
}
@@ -870,11 +1199,19 @@
RenderWidgetHostImpl* render_widget_host =
RenderWidgetHostImpl::From(GetWebContents()->GetRenderViewHost());
render_widget_host->ResetSizeAndRepaintPendingFlags();
+
+ if (guest_device_scale_factor_ != params.scale_factor) {
+ guest_device_scale_factor_ = params.scale_factor;
+ render_widget_host->NotifyScreenInfoChanged();
+ }
}
+ // Invalid damage buffer means we are in HW compositing mode,
+ // so just resize the WebContents and repaint if needed.
if (!base::SharedMemory::IsHandleValid(params.damage_buffer_handle)) {
- // Invalid damage buffer, so just resize the WebContents.
if (!params.view_size.IsEmpty())
GetWebContents()->GetView()->SizeContents(params.view_size);
+ if (params.repaint)
+ Send(new ViewMsg_Repaint(routing_id(), params.view_size));
return;
}
SetDamageBuffer(params);
@@ -887,7 +1224,9 @@
if (focused_ == focused)
return;
focused_ = focused;
- Send(new ViewMsg_SetFocus(routing_id(), focused));
+ Send(new InputMsg_SetFocus(routing_id(), focused));
+ if (!focused && mouse_locked_)
+ OnUnlockMouse();
}
void BrowserPluginGuest::OnSetName(int instance_id, const std::string& name) {
@@ -944,19 +1283,18 @@
BrowserPluginPermissionType permission_type,
int request_id,
bool should_allow) {
- switch (permission_type) {
- case BrowserPluginPermissionTypeGeolocation:
- OnRespondPermissionGeolocation(request_id, should_allow);
- break;
- case BrowserPluginPermissionTypeMedia:
- OnRespondPermissionMedia(request_id, should_allow);
- break;
- case BrowserPluginPermissionTypeNewWindow:
- OnRespondPermissionNewWindow(request_id, should_allow);
- break;
- default:
- NOTREACHED();
- break;
+ RequestMap::iterator request_itr = permission_request_map_.find(request_id);
+ if (request_itr == permission_request_map_.end()) {
+ LOG(INFO) << "Not a valid request ID.";
+ return;
+ }
+ request_itr->second->Respond(should_allow);
+
+ // Geolocation requests have to hang around for a while, so we don't delete
+ // them here.
+ if (permission_type != BrowserPluginPermissionTypeGeolocation) {
+ delete request_itr->second;
+ permission_request_map_.erase(request_itr);
}
}
@@ -1032,18 +1370,6 @@
}
#endif
-void BrowserPluginGuest::OnShowView(int route_id,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_bounds,
- bool user_gesture) {
- RenderViewHostImpl* rvh = RenderViewHostImpl::FromID(
- web_contents()->GetRenderProcessHost()->GetID(), route_id);
- WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
- WebContents::FromRenderViewHost(rvh));
- RequestNewWindowPermission(
- web_contents, disposition, initial_bounds, user_gesture);
-}
-
void BrowserPluginGuest::OnShowWidget(int route_id,
const gfx::Rect& initial_pos) {
gfx::Rect screen_pos(initial_pos);
@@ -1056,18 +1382,6 @@
new BrowserPluginMsg_AdvanceFocus(instance_id(), reverse));
}
-void BrowserPluginGuest::OnUpdateDragCursor(
- WebKit::WebDragOperation operation) {
- RenderViewHostImpl* embedder_render_view_host =
- static_cast<RenderViewHostImpl*>(
- embedder_web_contents_->GetRenderViewHost());
- CHECK(embedder_render_view_host);
- RenderViewHostDelegateView* view =
- embedder_render_view_host->GetDelegate()->GetDelegateView();
- if (view)
- view->UpdateDragCursor(operation);
-}
-
void BrowserPluginGuest::OnUpdateFrameName(int frame_id,
bool is_top_level,
const std::string& name) {
@@ -1082,15 +1396,14 @@
WebContents* web_contents,
const MediaStreamRequest& request,
const MediaResponseCallback& callback) {
- if (media_requests_map_.size() >= kNumMaxOutstandingPermissionRequests) {
+ if (permission_request_map_.size() >= kNumMaxOutstandingPermissionRequests) {
// Deny the media request.
- callback.Run(MediaStreamDevices());
+ callback.Run(MediaStreamDevices(), scoped_ptr<MediaStreamUI>());
return;
}
int request_id = next_permission_request_id_++;
- media_requests_map_.insert(
- std::make_pair(request_id,
- std::make_pair(request, callback)));
+ permission_request_map_[request_id] =
+ new MediaRequest(request, callback, this);
base::DictionaryValue request_info;
request_info.Set(
@@ -1157,83 +1470,25 @@
new BrowserPluginMsg_UpdateRect(instance_id(), relay_params));
}
-void BrowserPluginGuest::OnRespondPermissionGeolocation(
- int request_id, bool should_allow) {
- if (should_allow && embedder_web_contents_) {
- // If renderer side embedder decides to allow gelocation, we need to check
- // if the app/embedder itself has geolocation access.
- BrowserContext* browser_context =
- embedder_web_contents_->GetBrowserContext();
- if (browser_context) {
- GeolocationPermissionContext* geolocation_context =
- browser_context->GetGeolocationPermissionContext();
- if (geolocation_context) {
- base::Callback<void(bool)> geolocation_callback = base::Bind(
- &BrowserPluginGuest::SetGeolocationPermission,
- weak_ptr_factory_.GetWeakPtr(),
- request_id);
- geolocation_context->RequestGeolocationPermission(
- embedder_web_contents_->GetRenderProcessHost()->GetID(),
- embedder_web_contents_->GetRoutingID(),
- // The geolocation permission request here is not initiated through
- // WebGeolocationPermissionRequest. We are only interested in the
- // fact whether the embedder/app has geolocation permission.
- // Therefore we use an invalid |bridge_id|.
- -1 /* bridge_id */,
- embedder_web_contents_->GetURL(),
- geolocation_callback);
- return;
- }
- }
- }
- SetGeolocationPermission(request_id, false);
-}
-
-void BrowserPluginGuest::OnRespondPermissionMedia(
- int request_id, bool should_allow) {
- MediaStreamRequestsMap::iterator media_request_iter =
- media_requests_map_.find(request_id);
- if (media_request_iter == media_requests_map_.end()) {
- LOG(INFO) << "Not a valid request ID.";
+void BrowserPluginGuest::DidRetrieveDownloadURLFromRequestId(
+ const std::string& request_method,
+ int permission_request_id,
+ const std::string& url) {
+ if (url.empty()) {
+ OnRespondPermission(instance_id(), BrowserPluginPermissionTypeDownload,
+ permission_request_id, false);
return;
}
- const MediaStreamRequest& request = media_request_iter->second.first;
- const MediaResponseCallback& callback =
- media_request_iter->second.second;
- if (should_allow && embedder_web_contents_) {
- // Re-route the request to the embedder's WebContents; the guest gets the
- // permission this way.
- embedder_web_contents_->RequestMediaAccessPermission(request, callback);
- } else {
- // Deny the request.
- callback.Run(MediaStreamDevices());
- }
- media_requests_map_.erase(media_request_iter);
-}
+ base::DictionaryValue request_info;
+ request_info.Set(browser_plugin::kRequestMethod,
+ base::Value::CreateStringValue(request_method));
+ request_info.Set(browser_plugin::kURL, base::Value::CreateStringValue(url));
-void BrowserPluginGuest::OnRespondPermissionNewWindow(
- int request_id, bool should_allow) {
- NewWindowRequestMap::iterator new_window_request_iter =
- new_window_request_map_.find(request_id);
- if (new_window_request_iter == new_window_request_map_.end()) {
- LOG(INFO) << "Not a valid request ID.";
- return;
- }
- int instance_id = new_window_request_iter->second;
- int embedder_render_process_id =
- embedder_web_contents_->GetRenderProcessHost()->GetID();
- BrowserPluginGuest* guest =
- GetWebContents()->GetBrowserPluginGuestManager()->
- GetGuestByInstanceID(instance_id, embedder_render_process_id);
- if (!guest) {
- LOG(INFO) << "Guest not found. Instance ID: " << instance_id;
- return;
- }
- if (!should_allow)
- guest->Destroy();
- // If we do not destroy the guest then we allow the new window.
- new_window_request_map_.erase(new_window_request_iter);
+ SendMessageToEmbedder(
+ new BrowserPluginMsg_RequestPermission(instance_id(),
+ BrowserPluginPermissionTypeDownload, permission_request_id,
+ request_info));
}
} // namespace content
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h
index 1b480e6..8b406da 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.h
+++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -42,7 +42,7 @@
#include "ui/surface/transport_dib.h"
struct BrowserPluginHostMsg_AutoSize_Params;
-struct BrowserPluginHostMsg_CreateGuest_Params;
+struct BrowserPluginHostMsg_Attach_Params;
struct BrowserPluginHostMsg_ResizeGuest_Params;
struct ViewHostMsg_CreateWindow_Params;
#if defined(OS_MACOSX)
@@ -52,6 +52,10 @@
class WebCursor;
struct WebDropData;
+namespace cc {
+class CompositorFrameAck;
+}
+
namespace WebKit {
class WebInputEvent;
}
@@ -75,9 +79,11 @@
// A BrowserPluginGuest can also create a new unattached guest via
// CreateNewWindow. The newly created guest will live in the same partition,
// which means it can share storage and can script this guest.
-class CONTENT_EXPORT BrowserPluginGuest : public NotificationObserver,
- public WebContentsDelegate,
- public WebContentsObserver {
+class CONTENT_EXPORT BrowserPluginGuest
+ : public NotificationObserver,
+ public WebContentsDelegate,
+ public WebContentsObserver,
+ public base::SupportsWeakPtr<BrowserPluginGuest> {
public:
typedef base::Callback<void(bool)> GeolocationCallback;
virtual ~BrowserPluginGuest();
@@ -86,6 +92,12 @@
int instance_id,
WebContentsImpl* web_contents);
+ static BrowserPluginGuest* CreateWithOpener(
+ int instance_id,
+ WebContentsImpl* web_contents,
+ BrowserPluginGuest* opener,
+ bool has_render_view);
+
// Destroys the guest WebContents and all its associated state, including
// this BrowserPluginGuest, and its new unattached windows.
void Destroy();
@@ -103,7 +115,7 @@
bool OnMessageReceivedFromEmbedder(const IPC::Message& message);
void Initialize(WebContentsImpl* embedder_web_contents,
- const BrowserPluginHostMsg_CreateGuest_Params& params);
+ const BrowserPluginHostMsg_Attach_Params& params);
void set_guest_hang_timeout_for_testing(const base::TimeDelta& timeout) {
guest_hang_timeout_ = timeout;
@@ -159,6 +171,11 @@
// WebContentsDelegate implementation.
+ virtual bool AddMessageToConsole(WebContents* source,
+ int32 level,
+ const string16& message,
+ int32 line_no,
+ const string16& source_id) OVERRIDE;
// If a new window is created with target="_blank" and rel="noreferrer", then
// this method is called, indicating that the new WebContents is ready to be
// attached.
@@ -168,10 +185,17 @@
const gfx::Rect& initial_pos,
bool user_gesture,
bool* was_blocked) OVERRIDE;
- virtual bool CanDownload(RenderViewHost* render_view_host,
+ virtual void CanDownload(RenderViewHost* render_view_host,
int request_id,
- const std::string& request_method) OVERRIDE;
+ const std::string& request_method,
+ const base::Callback<void(bool)>& callback) OVERRIDE;
+ virtual void CloseContents(WebContents* source) OVERRIDE;
virtual bool HandleContextMenu(const ContextMenuParams& params) OVERRIDE;
+ virtual void HandleKeyboardEvent(
+ WebContents* source,
+ const NativeWebKeyboardEvent& event) OVERRIDE;
+ virtual WebContents* OpenURLFromTab(WebContents* source,
+ const OpenURLParams& params) OVERRIDE;
virtual void WebContentsCreated(WebContents* source_contents,
int64 source_frame_id,
const string16& frame_name,
@@ -190,9 +214,6 @@
// Exposes the protected web_contents() from WebContentsObserver.
WebContentsImpl* GetWebContents();
- // Kill the guest process.
- void Terminate();
-
// Overridden in tests.
virtual void SetDamageBuffer(
const BrowserPluginHostMsg_ResizeGuest_Params& params);
@@ -213,16 +234,14 @@
// to an embedder implies that this guest's lifetime is no longer managed
// by its opener, and it can begin loading resources.
void Attach(WebContentsImpl* embedder_web_contents,
- BrowserPluginHostMsg_CreateGuest_Params params);
+ BrowserPluginHostMsg_Attach_Params params);
- // Requests geolocation permission through embedder js api.
+ // Requests geolocation permission through Embedder JavaScript API.
void AskEmbedderForGeolocationPermission(int bridge_id,
const GURL& requesting_frame,
const GeolocationCallback& callback);
// Cancels pending geolocation request.
void CancelGeolocationRequest(int bridge_id);
- // Embedder sets permission to allow or deny geolocation request.
- void SetGeolocationPermission(int request_id, bool allowed);
// Allow the embedder to call this for unhandled messages when
// BrowserPluginGuest is already destroyed.
@@ -235,17 +254,30 @@
// |message|.
static bool ShouldForwardToBrowserPluginGuest(const IPC::Message& message);
- private:
- typedef std::pair<MediaStreamRequest, MediaResponseCallback>
- MediaStreamRequestAndCallbackPair;
- typedef std::map<int, MediaStreamRequestAndCallbackPair>
- MediaStreamRequestsMap;
+ void DragSourceEndedAt(int client_x, int client_y, int screen_x,
+ int screen_y, WebKit::WebDragOperation operation);
+ void DragSourceMovedTo(int client_x, int client_y,
+ int screen_x, int screen_y);
+
+ // Called when the drag started by this guest ends at an OS-level.
+ void EndSystemDrag();
+
+ private:
class EmbedderRenderViewHostObserver;
friend class TestBrowserPluginGuest;
+ class DownloadRequest;
+ class GeolocationRequest;
+ // MediaRequest because of naming conflicts with MediaStreamRequest.
+ class MediaRequest;
+ class NewWindowRequest;
+ class PermissionRequest;
+
BrowserPluginGuest(int instance_id,
- WebContentsImpl* web_contents);
+ WebContentsImpl* web_contents,
+ BrowserPluginGuest* opener,
+ bool has_render_view);
// Destroy unattached new windows that have been opened by this
// BrowserPluginGuest.
@@ -274,6 +306,11 @@
// Message handlers for messages from embedder.
+ void OnCompositorFrameACK(int instance_id,
+ int route_id,
+ int renderer_host_id,
+ const cc::CompositorFrameAck& ack);
+
// Allows or denies a permission request access, after the embedder has had a
// chance to decide.
void OnRespondPermission(int instance_id,
@@ -290,6 +327,9 @@
const WebDropData& drop_data,
WebKit::WebDragOperationsMask drag_mask,
const gfx::Point& location);
+ // Instructs the guest to execute an edit command decoded in the embedder.
+ void OnExecuteEditCommand(int instance_id,
+ const std::string& command);
// If possible, navigate the guest to |relative_index| entries away from the
// current navigation entry.
virtual void OnGo(int instance_id, int relative_index);
@@ -355,6 +395,7 @@
// Message handlers for messages from guest.
+ void OnDragStopped();
void OnHandleInputEventAck(
WebKit::WebInputEvent::Type event_type,
InputEventAckState ack_result);
@@ -365,23 +406,23 @@
#if defined(OS_MACOSX)
void OnShowPopup(const ViewHostMsg_ShowPopup_Params& params);
#endif
- void OnShowView(int route_id,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_bounds,
- bool user_gesture);
void OnShowWidget(int route_id, const gfx::Rect& initial_pos);
// Overriden in tests.
virtual void OnTakeFocus(bool reverse);
- void OnUpdateDragCursor(WebKit::WebDragOperation operation);
void OnUpdateFrameName(int frame_id,
bool is_top_level,
const std::string& name);
void OnUpdateRect(const ViewHostMsg_UpdateRect_Params& params);
- // Helpers for |OnRespondPermission|.
- void OnRespondPermissionGeolocation(int request_id, bool should_allow);
- void OnRespondPermissionMedia(int request_id, bool should_allow);
- void OnRespondPermissionNewWindow(int request_id, bool should_allow);
+ // Requests download permission through embedder JavaScript API after
+ // retrieving url information from IO thread.
+ void DidRetrieveDownloadURLFromRequestId(const std::string& request_method,
+ int permission_request_id,
+ const std::string& url);
+
+ // Embedder sets permission to allow or deny geolocation request.
+ void SetGeolocationPermission(
+ GeolocationCallback callback, int bridge_id, bool allowed);
// Weak pointer used to ask GeolocationPermissionContext about geolocation
// permission.
@@ -393,8 +434,9 @@
NotificationRegistrar notification_registrar_;
scoped_ptr<EmbedderRenderViewHostObserver> embedder_rvh_observer_;
WebContentsImpl* embedder_web_contents_;
- typedef std::map<int, GeolocationCallback> GeolocationRequestsMap;
- GeolocationRequestsMap geolocation_request_callback_map_;
+
+ std::map<int, int> bridge_id_to_request_id_map_;
+
// An identifier that uniquely identifies a browser plugin guest within an
// embedder.
int instance_id_;
@@ -404,6 +446,7 @@
size_t damage_buffer_size_;
gfx::Size damage_view_size_;
float damage_buffer_scale_factor_;
+ float guest_device_scale_factor_;
gfx::Rect guest_window_rect_;
gfx::Rect guest_screen_rect_;
base::TimeDelta guest_hang_timeout_;
@@ -417,20 +460,32 @@
gfx::Size max_auto_size_;
gfx::Size min_auto_size_;
- typedef std::map<BrowserPluginGuest*, std::string> PendingWindowMap;
+ // Tracks the target URL of the new window and whether or not it has changed
+ // since the WebContents has been created and before the new window has been
+ // attached to a BrowserPlugin. Once the first navigation commits, we no
+ // longer track this URL.
+ struct TargetURL {
+ bool changed;
+ GURL url;
+ explicit TargetURL(const GURL& url) :
+ changed(false),
+ url(url) {}
+ };
+ typedef std::map<BrowserPluginGuest*, TargetURL> PendingWindowMap;
PendingWindowMap pending_new_windows_;
- BrowserPluginGuest* opener_;
+ base::WeakPtr<BrowserPluginGuest> opener_;
// A counter to generate a unique request id for a permission request.
// We only need the ids to be unique for a given BrowserPluginGuest.
int next_permission_request_id_;
- // A map to store WebContents's media request object and callback.
- // We need to store these because we need a roundtrip to the embedder to know
- // if we allow or disallow the request. The key of the map is unique only for
- // a given BrowserPluginGuest.
- MediaStreamRequestsMap media_requests_map_;
- // A map from request ID to instance ID for use by the New Window API.
- typedef std::map<int, int> NewWindowRequestMap;
- NewWindowRequestMap new_window_request_map_;
+
+ // A map to store relevant info for a request keyed by the request's id.
+ typedef std::map<int, PermissionRequest*> RequestMap;
+ RequestMap permission_request_map_;
+
+ // Indicates that this BrowserPluginGuest has associated renderer-side state.
+ // This is used to determine whether or not to create a new RenderView when
+ // this guest is attached.
+ bool has_render_view_;
DISALLOW_COPY_AND_ASSIGN(BrowserPluginGuest);
};
diff --git a/content/browser/browser_plugin/browser_plugin_guest_helper.cc b/content/browser/browser_plugin/browser_plugin_guest_helper.cc
index e255dc8..ee18b6e 100644
--- a/content/browser/browser_plugin/browser_plugin_guest_helper.cc
+++ b/content/browser/browser_plugin/browser_plugin_guest_helper.cc
@@ -32,7 +32,8 @@
bool BrowserPluginGuestHelper::ShouldForwardToBrowserPluginGuest(
const IPC::Message& message) {
switch (message.type()) {
- case DragHostMsg_UpdateDragCursor::ID:
+ case DragHostMsg_StartDragging::ID:
+ case DragHostMsg_TargetDrop_ACK::ID:
case ViewHostMsg_HasTouchEventHandlers::ID:
case ViewHostMsg_SetCursor::ID:
#if defined(OS_MACOSX)
diff --git a/content/browser/browser_plugin/browser_plugin_guest_manager.cc b/content/browser/browser_plugin/browser_plugin_guest_manager.cc
index 6a41b50..081f332 100644
--- a/content/browser/browser_plugin/browser_plugin_guest_manager.cc
+++ b/content/browser/browser_plugin/browser_plugin_guest_manager.cc
@@ -40,14 +40,8 @@
BrowserPluginGuest* BrowserPluginGuestManager::CreateGuest(
SiteInstance* embedder_site_instance,
int instance_id,
- const BrowserPluginHostMsg_CreateGuest_Params& params) {
+ const BrowserPluginHostMsg_Attach_Params& params) {
SiteInstance* guest_site_instance = NULL;
- int embedder_render_process_id =
- embedder_site_instance->GetProcess()->GetID();
- BrowserPluginGuest* guest =
- GetGuestByInstanceID(instance_id, embedder_render_process_id);
- CHECK(!guest);
-
// Validate that the partition id coming from the renderer is valid UTF-8,
// since we depend on this in other parts of the code, such as FilePath
// creation. If the validation fails, treat it as a bad message and kill the
@@ -110,22 +104,15 @@
BrowserPluginGuest* BrowserPluginGuestManager::GetGuestByInstanceID(
int instance_id,
int embedder_render_process_id) const {
+ if (!CanEmbedderAccessInstanceIDMaybeKill(embedder_render_process_id,
+ instance_id)) {
+ return NULL;
+ }
GuestInstanceMap::const_iterator it =
guest_web_contents_by_instance_id_.find(instance_id);
if (it == guest_web_contents_by_instance_id_.end())
return NULL;
-
- BrowserPluginGuest* guest =
- static_cast<WebContentsImpl*>(it->second)->GetBrowserPluginGuest();
- if (!CanEmbedderAccessGuest(embedder_render_process_id, guest)) {
- // The embedder process is trying to access a guest it does not own.
- content::RecordAction(UserMetricsAction("BadMessageTerminate_BPGM"));
- base::KillProcess(
- RenderProcessHost::FromID(embedder_render_process_id)->GetHandle(),
- content::RESULT_CODE_KILLED_BAD_MESSAGE, false);
- return NULL;
- }
- return guest;
+ return static_cast<WebContentsImpl*>(it->second)->GetBrowserPluginGuest();
}
void BrowserPluginGuestManager::AddGuest(int instance_id,
@@ -141,6 +128,20 @@
guest_web_contents_by_instance_id_.erase(instance_id);
}
+bool BrowserPluginGuestManager::CanEmbedderAccessInstanceIDMaybeKill(
+ int embedder_render_process_id,
+ int instance_id) const {
+ if (!CanEmbedderAccessInstanceID(embedder_render_process_id, instance_id)) {
+ // The embedder process is trying to access a guest it does not own.
+ content::RecordAction(UserMetricsAction("BadMessageTerminate_BPGM"));
+ base::KillProcess(
+ RenderProcessHost::FromID(embedder_render_process_id)->GetHandle(),
+ content::RESULT_CODE_KILLED_BAD_MESSAGE, false);
+ return false;
+ }
+ return true;
+}
+
void BrowserPluginGuestManager::OnMessageReceived(const IPC::Message& message,
int render_process_id) {
if (BrowserPluginGuest::ShouldForwardToBrowserPluginGuest(message)) {
@@ -160,11 +161,11 @@
IPC_END_MESSAGE_MAP()
}
-//static
+// static
bool BrowserPluginGuestManager::CanEmbedderAccessGuest(
int embedder_render_process_id,
BrowserPluginGuest* guest) {
- // An embedder can access |guest| if the guest has not been attached and its
+ // The embedder can access the guest if it has not been attached and its
// opener's embedder lives in the same process as the given embedder.
if (!guest->attached()) {
if (!guest->opener())
@@ -179,6 +180,31 @@
guest->embedder_web_contents()->GetRenderProcessHost()->GetID();
}
+bool BrowserPluginGuestManager::CanEmbedderAccessInstanceID(
+ int embedder_render_process_id,
+ int instance_id) const {
+ // The embedder is trying to access a guest with a negative or zero
+ // instance ID.
+ if (instance_id <= browser_plugin::kInstanceIDNone)
+ return false;
+
+ // The embedder is trying to access an instance ID that has not yet been
+ // allocated by BrowserPluginGuestManager. This could cause instance ID
+ // collisions in the future, and potentially give one embedder access to a
+ // guest it does not own.
+ if (instance_id > next_instance_id_)
+ return false;
+
+ GuestInstanceMap::const_iterator it =
+ guest_web_contents_by_instance_id_.find(instance_id);
+ if (it == guest_web_contents_by_instance_id_.end())
+ return true;
+ BrowserPluginGuest* guest =
+ static_cast<WebContentsImpl*>(it->second)->GetBrowserPluginGuest();
+
+ return CanEmbedderAccessGuest(embedder_render_process_id, guest);
+}
+
SiteInstance* BrowserPluginGuestManager::GetGuestSiteInstance(
const GURL& guest_site) {
for (GuestInstanceMap::const_iterator it =
diff --git a/content/browser/browser_plugin/browser_plugin_guest_manager.h b/content/browser/browser_plugin/browser_plugin_guest_manager.h
index 4f5bb9b..4e1ba28 100644
--- a/content/browser/browser_plugin/browser_plugin_guest_manager.h
+++ b/content/browser/browser_plugin/browser_plugin_guest_manager.h
@@ -14,7 +14,7 @@
#include "content/common/content_export.h"
#include "ipc/ipc_message.h"
-struct BrowserPluginHostMsg_CreateGuest_Params;
+struct BrowserPluginHostMsg_Attach_Params;
struct BrowserPluginHostMsg_ResizeGuest_Params;
class GURL;
@@ -58,19 +58,27 @@
BrowserPluginGuest* CreateGuest(
SiteInstance* embedder_site_instance,
int instance_id,
- const BrowserPluginHostMsg_CreateGuest_Params& params);
+ const BrowserPluginHostMsg_Attach_Params& params);
- // Returns a BrowserPluginGuest given an instance ID. Returns NULL if the
- // guest wasn't found. If the guest doesn't belong to the given embedder,
- // then NULL is returned and the embedder is killed.
+ // Returns a BrowserPluginGuest given an |instance_id|. Returns NULL if the
+ // guest wasn't found. If the embedder is not permitted to access the given
+ // |instance_id|, the embedder is killed, and NULL is returned.
BrowserPluginGuest* GetGuestByInstanceID(
int instance_id,
int embedder_render_process_id) const;
// Adds a new |guest_web_contents| to the embedder (overridable in test).
virtual void AddGuest(int instance_id, WebContentsImpl* guest_web_contents);
+
+ // Removes the guest with the given |instance_id| from this
+ // BrowserPluginGuestManager.
void RemoveGuest(int instance_id);
+ // Returns whether the specified embedder is permitted to access the given
+ // |instance_id|, and kills the embedder if not.
+ bool CanEmbedderAccessInstanceIDMaybeKill(int embedder_render_process_id,
+ int instance_id) const;
+
void OnMessageReceived(const IPC::Message& message, int render_process_id);
private:
@@ -78,10 +86,20 @@
BrowserPluginGuestManager();
- // Returns whether the given embedder process is allowed to access |guest|.
+ // Returns whether the given embedder process is allowed to access the
+ // provided |guest|.
static bool CanEmbedderAccessGuest(int embedder_render_process_id,
BrowserPluginGuest* guest);
+ // Returns whether the given embedder process is allowed to use the provided
+ // |instance_id| or access the guest associated with the |instance_id|. If the
+ // embedder can, the method returns true. If the guest does not exist but the
+ // embedder can use that |instance_id|, then it returns true. If the embedder
+ // is not permitted to use that instance ID or access the associated guest,
+ // then it returns false.
+ bool CanEmbedderAccessInstanceID(int embedder_render_process_id,
+ int instance_id) const;
+
// Returns an existing SiteInstance if the current profile has a guest of the
// given |guest_site|.
SiteInstance* GetGuestSiteInstance(const GURL& guest_site);
diff --git a/content/browser/browser_plugin/browser_plugin_host_browsertest.cc b/content/browser/browser_plugin/browser_plugin_host_browsertest.cc
index abbf63b..26b783c 100644
--- a/content/browser/browser_plugin/browser_plugin_host_browsertest.cc
+++ b/content/browser/browser_plugin/browser_plugin_host_browsertest.cc
@@ -28,7 +28,7 @@
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"
#include "net/base/net_util.h"
-#include "net/test/test_server.h"
+#include "net/test/spawned_test_server.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
#include "webkit/glue/webdropdata.h"
@@ -375,13 +375,21 @@
// guest.
//
// Disabled on Windows and Linux since it is flaky. crbug.com/164812
-IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, GuestUnresponsive) {
+// THIS TEST IS ALWAYS FLAKY. DO NOT ENABLE AGAIN WITHOUT REWRITING.
+#if defined(OS_WIN) || defined(OS_LINUX)
+#define MAYBE_GuestUnresponsive DISABLED_GuestUnresponsive
+#else
+#define MAYBE_GuestUnresponsive GuestUnresponsive
+#endif
+IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest,
+ MAYBE_GuestUnresponsive) {
// Override the hang timeout for guest to be very small.
content::BrowserPluginGuest::set_factory_for_testing(
TestShortHangTimeoutGuestFactory::GetInstance());
const char kEmbedderURL[] =
"files/browser_plugin_embedder_guest_unresponsive.html";
- StartBrowserPluginTest(kEmbedderURL, kHTMLForGuestBusyLoop, true, "");
+ StartBrowserPluginTest(
+ kEmbedderURL, kHTMLForGuestBusyLoop, true, std::string());
// Wait until the busy loop starts.
{
const string16 expected_title = ASCIIToUTF16("start");
@@ -446,7 +454,7 @@
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AdvanceFocus) {
const char kEmbedderURL[] = "files/browser_plugin_focus.html";
const char* kGuestURL = "files/browser_plugin_focus_child.html";
- StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, "");
+ StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, std::string());
SimulateMouseClick(test_embedder()->web_contents(), 0,
WebKit::WebMouseEvent::ButtonLeft);
@@ -469,15 +477,15 @@
// a RenderViewHost swap in the web_contents. We verify that the embedder in the
// web_contents gets cleared properly.
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderChangedAfterSwap) {
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
// 1. Load an embedder page with one guest in it.
const char kEmbedderURL[] = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, "");
+ StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string());
// 2. Navigate to a URL in https, so we trigger a RenderViewHost swap.
GURL test_https_url(https_server.GetURL(
@@ -503,7 +511,7 @@
// web_contents.
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderSameAfterNav) {
const char kEmbedderURL[] = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, "");
+ StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string());
WebContentsImpl* embedder_web_contents = test_embedder()->web_contents();
// Navigate to another page in same host and port, so RenderViewHost swap
@@ -528,7 +536,7 @@
// This test verifies that hiding the embedder also hides the guest.
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, BrowserPluginVisibilityChanged) {
const char kEmbedderURL[] = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, "");
+ StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string());
// Hide the Browser Plugin.
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
@@ -542,7 +550,7 @@
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderVisibilityChanged) {
const char kEmbedderURL[] = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, "");
+ StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string());
// Hide the embedder.
test_embedder()->web_contents()->WasHidden();
@@ -554,7 +562,7 @@
// This test verifies that calling the reload method reloads the guest.
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, ReloadGuest) {
const char kEmbedderURL[] = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, "");
+ StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string());
test_guest()->ResetUpdateRectCount();
@@ -568,7 +576,7 @@
// to the guest's WebContents.
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, StopGuest) {
const char kEmbedderURL[] = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, "");
+ StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string());
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
@@ -580,7 +588,8 @@
// plugin correctly updates the touch-event handling state in the embedder.
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AcceptTouchEvents) {
const char kEmbedderURL[] = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, kHTMLForGuestTouchHandler, true, "");
+ StartBrowserPluginTest(
+ kEmbedderURL, kHTMLForGuestTouchHandler, true, std::string());
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
@@ -608,7 +617,7 @@
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, Renavigate) {
const char kEmbedderURL[] = "files/browser_plugin_embedder.html";
StartBrowserPluginTest(
- kEmbedderURL, GetHTMLForGuestWithTitle("P1"), true, "");
+ kEmbedderURL, GetHTMLForGuestWithTitle("P1"), true, std::string());
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
@@ -703,7 +712,7 @@
// and that the guest is reset.
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, ReloadEmbedder) {
const char kEmbedderURL[] = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, "");
+ StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string());
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
@@ -754,7 +763,7 @@
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, TerminateGuest) {
const char kEmbedderURL[] = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, "");
+ StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string());
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
@@ -769,7 +778,7 @@
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, BackAfterTerminateGuest) {
const char* kEmbedderURL = "files/browser_plugin_embedder.html";
StartBrowserPluginTest(
- kEmbedderURL, GetHTMLForGuestWithTitle("P1"), true, "");
+ kEmbedderURL, GetHTMLForGuestWithTitle("P1"), true, std::string());
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
@@ -811,7 +820,7 @@
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadStart) {
const char kEmbedderURL[] = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, "about:blank", true, "");
+ StartBrowserPluginTest(kEmbedderURL, "about:blank", true, std::string());
const string16 expected_title = ASCIIToUTF16(kHTMLForGuest);
content::TitleWatcher title_watcher(test_embedder()->web_contents(),
@@ -828,7 +837,7 @@
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadAbort) {
const char kEmbedderURL[] = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, "about:blank", true, "");
+ StartBrowserPluginTest(kEmbedderURL, "about:blank", true, std::string());
{
// Navigate the guest to "close-socket".
@@ -875,7 +884,7 @@
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadRedirect) {
const char kEmbedderURL[] = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, "about:blank", true, "");
+ StartBrowserPluginTest(kEmbedderURL, "about:blank", true, std::string());
const string16 expected_title = ASCIIToUTF16("redirected");
content::TitleWatcher title_watcher(test_embedder()->web_contents(),
@@ -915,7 +924,8 @@
// correctly.
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, MAYBE_AcceptDragEvents) {
const char kEmbedderURL[] = "files/browser_plugin_dragging.html";
- StartBrowserPluginTest(kEmbedderURL, kHTMLForGuestAcceptDrag, true, "");
+ StartBrowserPluginTest(
+ kEmbedderURL, kHTMLForGuestAcceptDrag, true, std::string());
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
@@ -971,7 +981,7 @@
const char* kTesting = "testing123";
const char* kEmbedderURL = "files/browser_plugin_embedder.html";
const char* kGuestURL = "files/browser_plugin_post_message_guest.html";
- StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, "");
+ StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, std::string());
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
{
@@ -999,7 +1009,7 @@
const char* kTesting = "testing123";
const char* kEmbedderURL = "files/browser_plugin_embedder.html";
const char* kGuestURL = "files/browser_plugin_post_message_guest.html";
- StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, "");
+ StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, std::string());
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
{
@@ -1045,7 +1055,7 @@
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadStop) {
const char* kEmbedderURL = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, "about:blank", true, "");
+ StartBrowserPluginTest(kEmbedderURL, "about:blank", true, std::string());
const string16 expected_title = ASCIIToUTF16("loadStop");
content::TitleWatcher title_watcher(
@@ -1062,7 +1072,7 @@
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadCommit) {
const char* kEmbedderURL = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, "about:blank", true, "");
+ StartBrowserPluginTest(kEmbedderURL, "about:blank", true, std::string());
const string16 expected_title = ASCIIToUTF16(
base::StringPrintf("loadCommit:%s", kHTMLForGuest));
@@ -1098,7 +1108,7 @@
// the new guest will inherit the visibility state of the old guest.
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, VisibilityPreservation) {
const char* kEmbedderURL = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, "");
+ StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string());
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
// Hide the BrowserPlugin.
@@ -1138,7 +1148,7 @@
// crbug.com/170249
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DISABLED_FocusPreservation) {
const char* kEmbedderURL = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, "");
+ StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string());
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
@@ -1177,7 +1187,7 @@
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, FocusTracksEmbedder) {
const char* kEmbedderURL = "files/browser_plugin_embedder.html";
- StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, "");
+ StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string());
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
@@ -1222,7 +1232,7 @@
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AutoSizeAfterNavigation) {
const char* kEmbedderURL = "files/browser_plugin_embedder.html";
StartBrowserPluginTest(
- kEmbedderURL, kHTMLForGuestWithSize, true, "");
+ kEmbedderURL, kHTMLForGuestWithSize, true, std::string());
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
@@ -1273,10 +1283,17 @@
test_embedder()->last_rvh_at_position_response());
}
-IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, ChangeWindowName) {
+// Flaky on Win Aura Tests (1) bot. See http://crbug.com/233087.
+#if defined(OS_WIN) && defined(USE_AURA)
+#define MAYBE_ChangeWindowName DISABLED_ChangeWindowName
+#else
+#define MAYBE_ChangeWindowName ChangeWindowName
+#endif
+
+IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, MAYBE_ChangeWindowName) {
const char kEmbedderURL[] = "files/browser_plugin_naming_embedder.html";
const char* kGuestURL = "files/browser_plugin_naming_guest.html";
- StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, "");
+ StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, std::string());
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
diff --git a/content/browser/browser_plugin/browser_plugin_message_filter.h b/content/browser/browser_plugin/browser_plugin_message_filter.h
index 327d2f8..829c1ba 100644
--- a/content/browser/browser_plugin/browser_plugin_message_filter.h
+++ b/content/browser/browser_plugin/browser_plugin_message_filter.h
@@ -7,8 +7,6 @@
#include "content/public/browser/browser_message_filter.h"
-struct ViewHostMsg_CreateWindow_Params;
-
namespace content {
class BrowserContext;
diff --git a/content/browser/browser_plugin/test_browser_plugin_guest.cc b/content/browser/browser_plugin/test_browser_plugin_guest.cc
index 3ca0697..083ea5a 100644
--- a/content/browser/browser_plugin/test_browser_plugin_guest.cc
+++ b/content/browser/browser_plugin/test_browser_plugin_guest.cc
@@ -17,7 +17,7 @@
TestBrowserPluginGuest::TestBrowserPluginGuest(
int instance_id,
WebContentsImpl* web_contents)
- : BrowserPluginGuest(instance_id, web_contents),
+ : BrowserPluginGuest(instance_id, web_contents, NULL, false),
update_rect_count_(0),
damage_buffer_call_count_(0),
exit_observed_(false),
@@ -106,7 +106,9 @@
void TestBrowserPluginGuest::RenderViewGone(base::TerminationStatus status) {
exit_observed_ = true;
- LOG(INFO) << "Guest crashed";
+ if (status != base::TERMINATION_STATUS_NORMAL_TERMINATION &&
+ status != base::TERMINATION_STATUS_STILL_RUNNING)
+ LOG(INFO) << "Guest crashed status: " << status;
if (crash_message_loop_runner_)
crash_message_loop_runner_->Quit();
BrowserPluginGuest::RenderViewGone(status);
diff --git a/content/browser/browser_thread_impl.cc b/content/browser/browser_thread_impl.cc
index e2867c3..37f67bc 100644
--- a/content/browser/browser_thread_impl.cc
+++ b/content/browser/browser_thread_impl.cc
@@ -69,9 +69,8 @@
}
BrowserThreadImpl::BrowserThreadImpl(ID identifier,
- MessageLoop* message_loop)
- : Thread(message_loop->thread_name().c_str()),
- identifier_(identifier) {
+ base::MessageLoop* message_loop)
+ : Thread(message_loop->thread_name().c_str()), identifier_(identifier) {
set_message_loop(message_loop);
Initialize();
}
@@ -113,51 +112,54 @@
MSVC_DISABLE_OPTIMIZE()
MSVC_PUSH_DISABLE_WARNING(4748)
-NOINLINE void BrowserThreadImpl::UIThreadRun(MessageLoop* message_loop) {
+NOINLINE void BrowserThreadImpl::UIThreadRun(base::MessageLoop* message_loop) {
volatile int line_number = __LINE__;
Thread::Run(message_loop);
CHECK_GT(line_number, 0);
}
-NOINLINE void BrowserThreadImpl::DBThreadRun(MessageLoop* message_loop) {
+NOINLINE void BrowserThreadImpl::DBThreadRun(base::MessageLoop* message_loop) {
volatile int line_number = __LINE__;
Thread::Run(message_loop);
CHECK_GT(line_number, 0);
}
-NOINLINE void BrowserThreadImpl::WebKitThreadRun(MessageLoop* message_loop) {
+NOINLINE void BrowserThreadImpl::WebKitThreadRun(
+ base::MessageLoop* message_loop) {
volatile int line_number = __LINE__;
Thread::Run(message_loop);
CHECK_GT(line_number, 0);
}
-NOINLINE void BrowserThreadImpl::FileThreadRun(MessageLoop* message_loop) {
+NOINLINE void BrowserThreadImpl::FileThreadRun(
+ base::MessageLoop* message_loop) {
volatile int line_number = __LINE__;
Thread::Run(message_loop);
CHECK_GT(line_number, 0);
}
NOINLINE void BrowserThreadImpl::FileUserBlockingThreadRun(
- MessageLoop* message_loop) {
+ base::MessageLoop* message_loop) {
volatile int line_number = __LINE__;
Thread::Run(message_loop);
CHECK_GT(line_number, 0);
}
NOINLINE void BrowserThreadImpl::ProcessLauncherThreadRun(
- MessageLoop* message_loop) {
+ base::MessageLoop* message_loop) {
volatile int line_number = __LINE__;
Thread::Run(message_loop);
CHECK_GT(line_number, 0);
}
-NOINLINE void BrowserThreadImpl::CacheThreadRun(MessageLoop* message_loop) {
+NOINLINE void BrowserThreadImpl::CacheThreadRun(
+ base::MessageLoop* message_loop) {
volatile int line_number = __LINE__;
Thread::Run(message_loop);
CHECK_GT(line_number, 0);
}
-NOINLINE void BrowserThreadImpl::IOThreadRun(MessageLoop* message_loop) {
+NOINLINE void BrowserThreadImpl::IOThreadRun(base::MessageLoop* message_loop) {
volatile int line_number = __LINE__;
Thread::Run(message_loop);
CHECK_GT(line_number, 0);
@@ -166,7 +168,7 @@
MSVC_POP_WARNING()
MSVC_ENABLE_OPTIMIZE();
-void BrowserThreadImpl::Run(MessageLoop* message_loop) {
+void BrowserThreadImpl::Run(base::MessageLoop* message_loop) {
BrowserThread::ID thread_id;
if (!GetCurrentThreadIdentifier(&thread_id))
return Thread::Run(message_loop);
@@ -259,8 +261,9 @@
if (!target_thread_outlives_current)
globals.lock.Acquire();
- MessageLoop* message_loop = globals.threads[identifier] ?
- globals.threads[identifier]->message_loop() : NULL;
+ base::MessageLoop* message_loop =
+ globals.threads[identifier] ? globals.threads[identifier]->message_loop()
+ : NULL;
if (message_loop) {
if (nestable) {
message_loop->PostDelayedTask(from_here, task, delay);
@@ -362,7 +365,7 @@
DCHECK(identifier >= 0 && identifier < ID_COUNT);
return globals.threads[identifier] &&
globals.threads[identifier]->message_loop() ==
- MessageLoop::current();
+ base::MessageLoop::current();
}
// static
@@ -434,7 +437,7 @@
// function.
// http://crbug.com/63678
base::ThreadRestrictions::ScopedAllowSingleton allow_singleton;
- MessageLoop* cur_message_loop = MessageLoop::current();
+ base::MessageLoop* cur_message_loop = base::MessageLoop::current();
BrowserThreadGlobals& globals = g_globals.Get();
for (int i = 0; i < ID_COUNT; ++i) {
if (globals.threads[i] &&
@@ -450,9 +453,7 @@
// static
scoped_refptr<base::MessageLoopProxy>
BrowserThread::GetMessageLoopProxyForThread(ID identifier) {
- scoped_refptr<base::MessageLoopProxy> proxy(
- new BrowserThreadMessageLoopProxy(identifier));
- return proxy;
+ return make_scoped_refptr(new BrowserThreadMessageLoopProxy(identifier));
}
// static
@@ -464,7 +465,7 @@
base::AutoLock lock(globals.lock);
base::Thread* thread = globals.threads[identifier];
DCHECK(thread);
- MessageLoop* loop = thread->message_loop();
+ base::MessageLoop* loop = thread->message_loop();
return loop;
}
diff --git a/content/browser/browser_thread_impl.h b/content/browser/browser_thread_impl.h
index 7375420..b4ca49b 100644
--- a/content/browser/browser_thread_impl.h
+++ b/content/browser/browser_thread_impl.h
@@ -20,14 +20,15 @@
// Special constructor for the main (UI) thread and unittests. We use a dummy
// thread here since the main thread already exists.
- BrowserThreadImpl(BrowserThread::ID identifier, MessageLoop* message_loop);
+ BrowserThreadImpl(BrowserThread::ID identifier,
+ base::MessageLoop* message_loop);
virtual ~BrowserThreadImpl();
static void ShutdownThreadPool();
protected:
virtual void Init() OVERRIDE;
- virtual void Run(MessageLoop* message_loop) OVERRIDE;
+ virtual void Run(base::MessageLoop* message_loop) OVERRIDE;
virtual void CleanUp() OVERRIDE;
private:
@@ -38,14 +39,14 @@
// The following are unique function names that makes it possible to tell
// the thread id from the callstack alone in crash dumps.
- void UIThreadRun(MessageLoop* message_loop);
- void DBThreadRun(MessageLoop* message_loop);
- void WebKitThreadRun(MessageLoop* message_loop);
- void FileThreadRun(MessageLoop* message_loop);
- void FileUserBlockingThreadRun(MessageLoop* message_loop);
- void ProcessLauncherThreadRun(MessageLoop* message_loop);
- void CacheThreadRun(MessageLoop* message_loop);
- void IOThreadRun(MessageLoop* message_loop);
+ void UIThreadRun(base::MessageLoop* message_loop);
+ void DBThreadRun(base::MessageLoop* message_loop);
+ void WebKitThreadRun(base::MessageLoop* message_loop);
+ void FileThreadRun(base::MessageLoop* message_loop);
+ void FileUserBlockingThreadRun(base::MessageLoop* message_loop);
+ void ProcessLauncherThreadRun(base::MessageLoop* message_loop);
+ void CacheThreadRun(base::MessageLoop* message_loop);
+ void IOThreadRun(base::MessageLoop* message_loop);
static bool PostTaskHelper(
BrowserThread::ID identifier,
diff --git a/content/browser/browser_thread_unittest.cc b/content/browser/browser_thread_unittest.cc
index 3dbfcf2..ec4b7cc 100644
--- a/content/browser/browser_thread_unittest.cc
+++ b/content/browser/browser_thread_unittest.cc
@@ -19,7 +19,7 @@
public:
void Release() const {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- loop_.PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
}
protected:
@@ -35,17 +35,17 @@
file_thread_->Stop();
}
- static void BasicFunction(MessageLoop* message_loop) {
+ static void BasicFunction(base::MessageLoop* message_loop) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
}
class DeletedOnFile
: public base::RefCountedThreadSafe<
DeletedOnFile, BrowserThread::DeleteOnFileThread> {
public:
- explicit DeletedOnFile(MessageLoop* message_loop)
- : message_loop_(message_loop) { }
+ explicit DeletedOnFile(base::MessageLoop* message_loop)
+ : message_loop_(message_loop) {}
private:
friend struct BrowserThread::DeleteOnThread<BrowserThread::FILE>;
@@ -53,25 +53,10 @@
~DeletedOnFile() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ message_loop_->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
}
- MessageLoop* message_loop_;
- };
-
- class NeverDeleted
- : public base::RefCountedThreadSafe<
- NeverDeleted, BrowserThread::DeleteOnWebKitThread> {
- public:
-
- private:
- friend struct BrowserThread::DeleteOnThread<
- BrowserThread::WEBKIT_DEPRECATED>;
- friend class base::DeleteHelper<NeverDeleted>;
-
- ~NeverDeleted() {
- CHECK(false);
- }
+ base::MessageLoop* message_loop_;
};
private:
@@ -79,46 +64,43 @@
scoped_ptr<BrowserThreadImpl> file_thread_;
// It's kind of ugly to make this mutable - solely so we can post the Quit
// Task from Release(). This should be fixed.
- mutable MessageLoop loop_;
+ mutable base::MessageLoop loop_;
};
TEST_F(BrowserThreadTest, PostTask) {
BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&BasicFunction, MessageLoop::current()));
- MessageLoop::current()->Run();
+ BrowserThread::FILE,
+ FROM_HERE,
+ base::Bind(&BasicFunction, base::MessageLoop::current()));
+ base::MessageLoop::current()->Run();
}
TEST_F(BrowserThreadTest, Release) {
BrowserThread::ReleaseSoon(BrowserThread::UI, FROM_HERE, this);
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
}
TEST_F(BrowserThreadTest, ReleasedOnCorrectThread) {
{
scoped_refptr<DeletedOnFile> test(
- new DeletedOnFile(MessageLoop::current()));
+ new DeletedOnFile(base::MessageLoop::current()));
}
- MessageLoop::current()->Run();
-}
-
-TEST_F(BrowserThreadTest, NotReleasedIfTargetThreadNonExistent) {
- scoped_refptr<NeverDeleted> test(new NeverDeleted());
+ base::MessageLoop::current()->Run();
}
TEST_F(BrowserThreadTest, PostTaskViaMessageLoopProxy) {
scoped_refptr<base::MessageLoopProxy> message_loop_proxy =
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE);
message_loop_proxy->PostTask(
- FROM_HERE, base::Bind(&BasicFunction, MessageLoop::current()));
- MessageLoop::current()->Run();
+ FROM_HERE, base::Bind(&BasicFunction, base::MessageLoop::current()));
+ base::MessageLoop::current()->Run();
}
TEST_F(BrowserThreadTest, ReleaseViaMessageLoopProxy) {
scoped_refptr<base::MessageLoopProxy> message_loop_proxy =
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
message_loop_proxy->ReleaseSoon(FROM_HERE, this);
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
}
TEST_F(BrowserThreadTest, PostTaskAndReply) {
@@ -128,9 +110,9 @@
BrowserThread::FILE,
FROM_HERE,
base::Bind(&base::DoNothing),
- base::Bind(&MessageLoop::Quit,
- base::Unretained(MessageLoop::current()->current()))));
- MessageLoop::current()->Run();
+ base::Bind(&base::MessageLoop::Quit,
+ base::Unretained(base::MessageLoop::current()->current()))));
+ base::MessageLoop::current()->Run();
}
-}
+} // namespace content
diff --git a/content/browser/byte_stream.cc b/content/browser/byte_stream.cc
index 44f5ce3..f83e8c3 100644
--- a/content/browser/byte_stream.cc
+++ b/content/browser/byte_stream.cc
@@ -363,7 +363,7 @@
bool was_empty = available_contents_.empty();
- if (transfer_buffer.get()) {
+ if (transfer_buffer) {
available_contents_.insert(available_contents_.end(),
transfer_buffer->begin(),
transfer_buffer->end());
diff --git a/content/browser/byte_stream_unittest.cc b/content/browser/byte_stream_unittest.cc
index 9ef45a3..aac6905 100644
--- a/content/browser/byte_stream_unittest.cc
+++ b/content/browser/byte_stream_unittest.cc
@@ -85,7 +85,7 @@
}
protected:
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
private:
int producing_seed_key_;
diff --git a/content/browser/cert_store_impl.h b/content/browser/cert_store_impl.h
index 5c13fa3..8a326e9 100644
--- a/content/browser/cert_store_impl.h
+++ b/content/browser/cert_store_impl.h
@@ -12,7 +12,7 @@
#include "content/public/browser/cert_store.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
-#include "net/base/x509_certificate.h"
+#include "net/cert/x509_certificate.h"
namespace content {
diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc
index 66e7c83..bde7f93 100644
--- a/content/browser/child_process_launcher.cc
+++ b/content/browser/child_process_launcher.cc
@@ -266,30 +266,30 @@
options.fds_to_remap = &fds_to_map;
#if defined(OS_MACOSX)
- // Use synchronization to make sure that the MachBroker is ready to
- // receive a check-in from the new process before the new process
- // actually tries to check in.
- base::LaunchSynchronizationHandle synchronization_handle;
- options.synchronize = &synchronization_handle;
+ // Hold the MachBroker lock for the duration of LaunchProcess. The child
+ // will send its task port to the parent almost immediately after startup.
+ // The Mach message will be delivered to the parent, but updating the
+ // record of the launch will wait until after the placeholder PID is
+ // inserted below. This ensures that while the child process may send its
+ // port to the parent prior to the parent leaving LaunchProcess, the
+ // order in which the record in MachBroker is updated is correct.
+ MachBroker* broker = MachBroker::GetInstance();
+ broker->GetLock().Acquire();
+
+ // Make sure the MachBroker is running, and inform it to expect a
+ // check-in from the new process.
+ broker->EnsureRunning();
#endif // defined(OS_MACOSX)
bool launched = base::LaunchProcess(*cmd_line, options, &handle);
#if defined(OS_MACOSX)
- if (launched) {
- MachBroker* broker = MachBroker::GetInstance();
- {
- base::AutoLock lock(broker->GetLock());
+ if (launched)
+ broker->AddPlaceholderForPid(handle);
- // Make sure the MachBroker is running, and inform it to expect a
- // check-in from the new process.
- broker->EnsureRunning();
- broker->AddPlaceholderForPid(handle);
- }
-
- // Now that the MachBroker is ready, the child may continue.
- base::LaunchSynchronize(synchronization_handle);
- }
+ // After updating the broker, release the lock and let the child's
+ // messasge be processed on the broker's thread.
+ broker->GetLock().Release();
#endif // defined(OS_MACOSX)
if (!launched)
diff --git a/content/browser/child_process_security_policy_unittest.cc b/content/browser/child_process_security_policy_unittest.cc
index a2eed34..6aad9d9 100644
--- a/content/browser/child_process_security_policy_unittest.cc
+++ b/content/browser/child_process_security_policy_unittest.cc
@@ -55,8 +55,7 @@
}
virtual void SetUp() {
- old_browser_client_ = GetContentClient()->browser();
- GetContentClient()->set_browser_for_testing(&test_browser_client_);
+ old_browser_client_ = SetBrowserClientForTesting(&test_browser_client_);
// Claim to always handle chrome:// URLs because the CPSP's notion of
// allowing WebUI bindings is hard-wired to this particular scheme.
@@ -65,7 +64,7 @@
virtual void TearDown() {
test_browser_client_.ClearSchemes();
- GetContentClient()->set_browser_for_testing(old_browser_client_);
+ SetBrowserClientForTesting(old_browser_client_);
}
protected:
diff --git a/content/browser/database_browsertest.cc b/content/browser/database_browsertest.cc
index 48f7304..29030ad 100644
--- a/content/browser/database_browsertest.cc
+++ b/content/browser/database_browsertest.cc
@@ -102,7 +102,7 @@
CreateTable(shell());
InsertRecord(shell(), "text");
DeleteRecord(shell(), 0);
- CompareRecords(shell(), "");
+ CompareRecords(shell(), std::string());
InsertRecord(shell(), "0");
InsertRecord(shell(), "1");
@@ -151,12 +151,12 @@
for (int i = 0; i < 10; ++i)
DeleteRecord(shell(), 0);
- CompareRecords(shell(), "");
+ CompareRecords(shell(), std::string());
RunScriptAndCheckResult(
shell(), "deleteRecord(1)", "could not find row with index: 1");
- CompareRecords(shell(), "");
+ CompareRecords(shell(), std::string());
}
// Create records in the database and verify they persist after reload.
@@ -186,7 +186,7 @@
ASSERT_FALSE(HasTable(otr));
CreateTable(otr);
- CompareRecords(otr, "");
+ CompareRecords(otr, std::string());
}
// Attempt to read a database created in an off the record browser from a
@@ -200,7 +200,7 @@
Navigate(shell());
ASSERT_FALSE(HasTable(shell()));
CreateTable(shell());
- CompareRecords(shell(), "");
+ CompareRecords(shell(), std::string());
}
// Verify DB changes within first window are present in the second window.
diff --git a/content/browser/device_monitor_linux.cc b/content/browser/device_monitor_linux.cc
index 8a734b9..61aad7c 100644
--- a/content/browser/device_monitor_linux.cc
+++ b/content/browser/device_monitor_linux.cc
@@ -49,7 +49,7 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
// We want to be notified of IO message loop destruction to delete |udev_|.
- MessageLoop::current()->AddDestructionObserver(this);
+ base::MessageLoop::current()->AddDestructionObserver(this);
std::vector<UdevLinux::UdevMonitorFilter> filters;
for (size_t i = 0; i < arraysize(kSubsystemMap); ++i) {
diff --git a/content/browser/device_monitor_linux.h b/content/browser/device_monitor_linux.h
index 60044c0..71f0924 100644
--- a/content/browser/device_monitor_linux.h
+++ b/content/browser/device_monitor_linux.h
@@ -20,7 +20,7 @@
class UdevLinux;
-class DeviceMonitorLinux : public MessageLoop::DestructionObserver {
+class DeviceMonitorLinux : public base::MessageLoop::DestructionObserver {
public:
DeviceMonitorLinux();
virtual ~DeviceMonitorLinux();
diff --git a/content/browser/device_orientation/data_fetcher_impl_android.cc b/content/browser/device_orientation/data_fetcher_impl_android.cc
index 287b63a..c7a066f 100644
--- a/content/browser/device_orientation/data_fetcher_impl_android.cc
+++ b/content/browser/device_orientation/data_fetcher_impl_android.cc
@@ -7,7 +7,7 @@
#include "base/android/jni_android.h"
#include "base/logging.h"
#include "content/browser/device_orientation/orientation.h"
-#include "jni/DeviceOrientation_jni.h"
+#include "jni/DeviceMotionAndOrientation_jni.h"
using base::android::AttachCurrentThread;
@@ -23,7 +23,7 @@
DataFetcherImplAndroid::DataFetcherImplAndroid() {
device_orientation_.Reset(
- Java_DeviceOrientation_getInstance(AttachCurrentThread()));
+ Java_DeviceMotionAndOrientation_getInstance(AttachCurrentThread()));
}
void DataFetcherImplAndroid::Init(JNIEnv* env) {
@@ -31,9 +31,11 @@
DCHECK(result);
}
+// TODO(timvolodine): Modify this method to be able to distinguish
+// device motion from orientation.
DataFetcher* DataFetcherImplAndroid::Create() {
scoped_ptr<DataFetcherImplAndroid> fetcher(new DataFetcherImplAndroid);
- if (fetcher->Start(kPeriodInMilliseconds))
+ if (fetcher->Start(DeviceData::kTypeOrientation, kPeriodInMilliseconds))
return fetcher.release();
LOG(ERROR) << "DataFetcherImplAndroid::Start failed!";
@@ -41,7 +43,9 @@
}
DataFetcherImplAndroid::~DataFetcherImplAndroid() {
- Stop();
+ // TODO(timvolodine): Support device motion as well. Only stop
+ // the active event type(s).
+ Stop(DeviceData::kTypeOrientation);
}
const DeviceData* DataFetcherImplAndroid::GetDeviceData(
@@ -55,11 +59,11 @@
// Do we have a new orientation value? (It's safe to do this outside the lock
// because we only skip the lock if the value is null. We always enter the
// lock if we're going to make use of the new value.)
- if (next_orientation_.get()) {
+ if (next_orientation_) {
base::AutoLock autolock(next_orientation_lock_);
next_orientation_.swap(current_orientation_);
}
- if (!current_orientation_.get())
+ if (!current_orientation_)
return new Orientation();
return current_orientation_.get();
}
@@ -76,17 +80,35 @@
next_orientation_ = orientation;
}
-bool DataFetcherImplAndroid::Start(int rate_in_milliseconds) {
- DCHECK(!device_orientation_.is_null());
- return Java_DeviceOrientation_start(AttachCurrentThread(),
- device_orientation_.obj(),
- reinterpret_cast<jint>(this),
- rate_in_milliseconds);
+void DataFetcherImplAndroid::GotAcceleration(
+ JNIEnv*, jobject, double x, double y, double z) {
+ NOTIMPLEMENTED();
}
-void DataFetcherImplAndroid::Stop() {
+void DataFetcherImplAndroid::GotAccelerationIncludingGravity(
+ JNIEnv*, jobject, double x, double y, double z) {
+ NOTIMPLEMENTED();
+}
+
+void DataFetcherImplAndroid::GotRotationRate(
+ JNIEnv*, jobject, double alpha, double beta, double gamma) {
+ NOTIMPLEMENTED();
+}
+
+bool DataFetcherImplAndroid::Start(
+ DeviceData::Type event_type, int rate_in_milliseconds) {
DCHECK(!device_orientation_.is_null());
- Java_DeviceOrientation_stop(AttachCurrentThread(), device_orientation_.obj());
+ return Java_DeviceMotionAndOrientation_start(
+ AttachCurrentThread(), device_orientation_.obj(),
+ reinterpret_cast<jint>(this), static_cast<jint>(event_type),
+ rate_in_milliseconds);
+}
+
+void DataFetcherImplAndroid::Stop(DeviceData::Type event_type) {
+ DCHECK(!device_orientation_.is_null());
+ Java_DeviceMotionAndOrientation_stop(
+ AttachCurrentThread(), device_orientation_.obj(),
+ static_cast<jint>(event_type));
}
} // namespace content
diff --git a/content/browser/device_orientation/data_fetcher_impl_android.h b/content/browser/device_orientation/data_fetcher_impl_android.h
index cbcb363..568fe55 100644
--- a/content/browser/device_orientation/data_fetcher_impl_android.h
+++ b/content/browser/device_orientation/data_fetcher_impl_android.h
@@ -37,6 +37,12 @@
// Called from Java via JNI.
void GotOrientation(JNIEnv*, jobject,
double alpha, double beta, double gamma);
+ void GotAcceleration(JNIEnv*, jobject,
+ double x, double y, double z);
+ void GotAccelerationIncludingGravity(JNIEnv*, jobject,
+ double x, double y, double z);
+ void GotRotationRate(JNIEnv*, jobject,
+ double alpha, double beta, double gamma);
// Implementation of DataFetcher.
virtual const DeviceData* GetDeviceData(DeviceData::Type type) OVERRIDE;
@@ -46,8 +52,10 @@
const Orientation* GetOrientation();
// Wrappers for JNI methods.
- bool Start(int rate_in_milliseconds);
- void Stop();
+ // TODO(timvolodine): move the DeviceData::Type enum to the service class
+ // once it is implemented.
+ bool Start(DeviceData::Type event_type, int rate_in_milliseconds);
+ void Stop(DeviceData::Type event_type);
// Value returned by GetDeviceData.
scoped_refptr<Orientation> current_orientation_;
diff --git a/content/browser/device_orientation/data_fetcher_impl_win.cc b/content/browser/device_orientation/data_fetcher_impl_win.cc
new file mode 100644
index 0000000..d08ed44
--- /dev/null
+++ b/content/browser/device_orientation/data_fetcher_impl_win.cc
@@ -0,0 +1,193 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/device_orientation/data_fetcher_impl_win.h"
+
+#include <InitGuid.h>
+#include <PortableDeviceTypes.h>
+#include <Sensors.h>
+
+#include "base/logging.h"
+#include "base/win/iunknown_impl.h"
+#include "base/win/windows_version.h"
+#include "content/browser/device_orientation/orientation.h"
+
+namespace {
+
+// This should match ProviderImpl::kDesiredSamplingIntervalMs.
+const int kPeriodInMilliseconds = 100;
+
+} // namespace
+
+namespace content {
+
+class DataFetcherImplWin::SensorEventSink : public ISensorEvents,
+ public base::win::IUnknownImpl {
+ public:
+ explicit SensorEventSink(DataFetcherImplWin* const fetcher)
+ : fetcher_(fetcher) {}
+
+ virtual ~SensorEventSink() {}
+
+ // IUnknown interface
+ virtual ULONG STDMETHODCALLTYPE AddRef() OVERRIDE {
+ return IUnknownImpl::AddRef();
+ }
+
+ virtual ULONG STDMETHODCALLTYPE Release() OVERRIDE {
+ return IUnknownImpl::Release();
+ }
+
+ virtual STDMETHODIMP QueryInterface(REFIID riid, void** ppv) OVERRIDE {
+ if (riid == __uuidof(ISensorEvents)) {
+ *ppv = static_cast<ISensorEvents*>(this);
+ AddRef();
+ return S_OK;
+ }
+ return IUnknownImpl::QueryInterface(riid, ppv);
+ }
+
+ // ISensorEvents interface
+ STDMETHODIMP OnEvent(ISensor* sensor,
+ REFGUID event_id,
+ IPortableDeviceValues* event_data) OVERRIDE {
+ return S_OK;
+ }
+
+ STDMETHODIMP OnDataUpdated(ISensor* sensor,
+ ISensorDataReport* new_data) OVERRIDE {
+ if (NULL == new_data || NULL == sensor)
+ return E_INVALIDARG;
+
+ PROPVARIANT value = {};
+ scoped_refptr<Orientation> orientation = new Orientation();
+
+ if (SUCCEEDED(new_data->GetSensorValue(
+ SENSOR_DATA_TYPE_TILT_X_DEGREES, &value))) {
+ orientation->set_beta(value.fltVal);
+ }
+ PropVariantClear(&value);
+
+ if (SUCCEEDED(new_data->GetSensorValue(
+ SENSOR_DATA_TYPE_TILT_Y_DEGREES, &value))) {
+ orientation->set_gamma(value.fltVal);
+ }
+ PropVariantClear(&value);
+
+ if (SUCCEEDED(new_data->GetSensorValue(
+ SENSOR_DATA_TYPE_TILT_Z_DEGREES, &value))) {
+ orientation->set_alpha(value.fltVal);
+ }
+ PropVariantClear(&value);
+
+ orientation->set_absolute(true);
+ fetcher_->OnOrientationData(orientation.get());
+
+ return S_OK;
+ }
+
+ STDMETHODIMP OnLeave(REFSENSOR_ID sensor_id) OVERRIDE {
+ return S_OK;
+ }
+
+ STDMETHODIMP OnStateChanged(ISensor* sensor, SensorState state) OVERRIDE {
+ return S_OK;
+ }
+
+ private:
+ DataFetcherImplWin* const fetcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(SensorEventSink);
+};
+
+// Create a DataFetcherImplWin object and return NULL if no valid sensor found.
+// static
+DataFetcher* DataFetcherImplWin::Create() {
+ scoped_ptr<DataFetcherImplWin> fetcher(new DataFetcherImplWin);
+ if (fetcher->Initialize())
+ return fetcher.release();
+
+ LOG(ERROR) << "DataFetcherImplWin::Initialize failed!";
+ return NULL;
+}
+
+DataFetcherImplWin::~DataFetcherImplWin() {
+ if (sensor_)
+ sensor_->SetEventSink(NULL);
+}
+
+DataFetcherImplWin::DataFetcherImplWin() {
+}
+
+void DataFetcherImplWin::OnOrientationData(Orientation* orientation) {
+ // This method is called on Windows sensor thread.
+ base::AutoLock autolock(next_orientation_lock_);
+ next_orientation_ = orientation;
+}
+
+const DeviceData* DataFetcherImplWin::GetDeviceData(DeviceData::Type type) {
+ if (type != DeviceData::kTypeOrientation)
+ return NULL;
+ return GetOrientation();
+}
+
+const Orientation* DataFetcherImplWin::GetOrientation() {
+ if (next_orientation_.get()) {
+ base::AutoLock autolock(next_orientation_lock_);
+ next_orientation_.swap(current_orientation_);
+ }
+ if (!current_orientation_.get())
+ return new Orientation();
+ return current_orientation_.get();
+}
+
+bool DataFetcherImplWin::Initialize() {
+ if (base::win::GetVersion() < base::win::VERSION_WIN7)
+ return false;
+
+ base::win::ScopedComPtr<ISensorManager> sensor_manager;
+ HRESULT hr = sensor_manager.CreateInstance(CLSID_SensorManager);
+ if (FAILED(hr) || !sensor_manager)
+ return false;
+
+ base::win::ScopedComPtr<ISensorCollection> sensor_collection;
+ hr = sensor_manager->GetSensorsByType(
+ SENSOR_TYPE_INCLINOMETER_3D, sensor_collection.Receive());
+
+ if (FAILED(hr) || !sensor_collection)
+ return false;
+
+ ULONG count = 0;
+ hr = sensor_collection->GetCount(&count);
+ if (FAILED(hr) || !count)
+ return false;
+
+ hr = sensor_collection->GetAt(0, sensor_.Receive());
+ if (FAILED(hr) || !sensor_)
+ return false;
+
+ base::win::ScopedComPtr<IPortableDeviceValues> device_values;
+ if (SUCCEEDED(device_values.CreateInstance(CLSID_PortableDeviceValues))) {
+ if (SUCCEEDED(device_values->SetUnsignedIntegerValue(
+ SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, kPeriodInMilliseconds))) {
+ base::win::ScopedComPtr<IPortableDeviceValues> return_values;
+ sensor_->SetProperties(device_values.get(), return_values.Receive());
+ }
+ }
+
+ scoped_refptr<SensorEventSink> sensor_event_impl(new SensorEventSink(this));
+ base::win::ScopedComPtr<ISensorEvents> sensor_events;
+ hr = sensor_event_impl->QueryInterface(
+ __uuidof(ISensorEvents), sensor_events.ReceiveVoid());
+ if (FAILED(hr) || !sensor_events)
+ return false;
+
+ hr = sensor_->SetEventSink(sensor_events);
+ if (FAILED(hr))
+ return false;
+
+ return true;
+}
+
+} // namespace content
diff --git a/content/browser/device_orientation/data_fetcher_impl_win.h b/content/browser/device_orientation/data_fetcher_impl_win.h
new file mode 100644
index 0000000..9a06506
--- /dev/null
+++ b/content/browser/device_orientation/data_fetcher_impl_win.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DEVICE_ORIENTATION_DATA_FETCHER_IMPL_WIN_H_
+#define CONTENT_BROWSER_DEVICE_ORIENTATION_DATA_FETCHER_IMPL_WIN_H_
+
+#include <SensorsApi.h>
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/synchronization/lock.h"
+#include "base/win/scoped_comptr.h"
+#include "content/browser/device_orientation/data_fetcher.h"
+#include "content/browser/device_orientation/device_data.h"
+
+namespace content {
+
+class Orientation;
+
+// Windows implementation of DeviceOrientation API.
+// The SensorEventSink is installed to Windows sensor thread to listen for
+// sensor's data. Upon each notification, DataFetcherImplWin buffers the data.
+// Then Chrome sensor polling thread pulls the buffered data via GetDeviceData.
+// The Inclinometer 3D sensor (SENSOR_TYPE_INCLINOMETER_3D) is used to get the
+// orientation data.
+
+class DataFetcherImplWin : public DataFetcher {
+ public:
+ virtual ~DataFetcherImplWin();
+
+ // Factory function. It returns NULL on error.
+ // The created object listens for events for the whole lifetime.
+ static DataFetcher* Create();
+
+ // Implement DataFetcher.
+ virtual const DeviceData* GetDeviceData(DeviceData::Type type) OVERRIDE;
+
+ private:
+ class SensorEventSink;
+ friend SensorEventSink;
+
+ DataFetcherImplWin();
+ bool Initialize();
+ void OnOrientationData(Orientation* orientation);
+ const Orientation* GetOrientation();
+
+ base::win::ScopedComPtr<ISensor> sensor_;
+
+ // Value returned by GetDeviceData.
+ scoped_refptr<Orientation> current_orientation_;
+
+ // The 1-element buffer follows DataFetcherImplAndroid implementation.
+ // It is written by OnOrientationData and read by GetDeviceData.
+ base::Lock next_orientation_lock_;
+ scoped_refptr<Orientation> next_orientation_;
+
+ DISALLOW_COPY_AND_ASSIGN(DataFetcherImplWin);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DEVICE_ORIENTATION_DATA_FETCHER_IMPL_WIN_H_
diff --git a/content/browser/device_orientation/device_data.h b/content/browser/device_orientation/device_data.h
index ae65618..e8c79ad 100644
--- a/content/browser/device_orientation/device_data.h
+++ b/content/browser/device_orientation/device_data.h
@@ -17,10 +17,12 @@
class CONTENT_EXPORT DeviceData :
public base::RefCountedThreadSafe<DeviceData> {
public:
+ // TODO(timvolodine): move the DeviceData::Type enum to the service class
+ // once it is implemented.
enum Type {
- kTypeMotion,
- kTypeOrientation,
- kTypeTest
+ kTypeOrientation = 0,
+ kTypeMotion = 1,
+ kTypeTest = 100
};
virtual IPC::Message* CreateIPCMessage(int render_view_id) const = 0;
diff --git a/content/browser/device_orientation/observer_delegate.cc b/content/browser/device_orientation/observer_delegate.cc
index 1ffe07a..fc4273f 100644
--- a/content/browser/device_orientation/observer_delegate.cc
+++ b/content/browser/device_orientation/observer_delegate.cc
@@ -29,7 +29,7 @@
void ObserverDelegate::OnDeviceDataUpdate(
const DeviceData* device_data, DeviceData::Type device_data_type) {
scoped_refptr<const DeviceData> new_device_data(device_data);
- if (!new_device_data.get())
+ if (!new_device_data)
new_device_data = EmptyDeviceData(device_data_type);
sender_->Send(new_device_data->CreateIPCMessage(render_view_id_));
diff --git a/content/browser/device_orientation/provider.cc b/content/browser/device_orientation/provider.cc
index ead9b14..b7aa52f 100644
--- a/content/browser/device_orientation/provider.cc
+++ b/content/browser/device_orientation/provider.cc
@@ -13,6 +13,8 @@
#include "content/browser/device_orientation/accelerometer_mac.h"
#elif defined(OS_ANDROID)
#include "content/browser/device_orientation/data_fetcher_impl_android.h"
+#elif defined(OS_WIN)
+#include "content/browser/device_orientation/data_fetcher_impl_win.h"
#endif
namespace content {
@@ -26,6 +28,8 @@
default_factory = AccelerometerMac::Create;
#elif defined(OS_ANDROID)
default_factory = DataFetcherImplAndroid::Create;
+#elif defined(OS_WIN)
+ default_factory = DataFetcherImplWin::Create;
#endif
instance_ = new ProviderImpl(default_factory);
diff --git a/content/browser/device_orientation/provider_impl.cc b/content/browser/device_orientation/provider_impl.cc
index c490514..59bdebf 100644
--- a/content/browser/device_orientation/provider_impl.cc
+++ b/content/browser/device_orientation/provider_impl.cc
@@ -27,7 +27,7 @@
public:
PollingThread(const char* name,
base::WeakPtr<ProviderImpl> provider,
- MessageLoop* creator_loop);
+ base::MessageLoop* creator_loop);
virtual ~PollingThread();
// Method for creating a DataFetcher and starting the polling, if the fetcher
@@ -52,7 +52,7 @@
// The Message Loop on which this object was created.
// Typically the I/O loop, but may be something else during testing.
- MessageLoop* creator_loop_;
+ base::MessageLoop* creator_loop_;
scoped_ptr<DataFetcher> data_fetcher_;
std::map<DeviceData::Type, scoped_refptr<const DeviceData> >
@@ -62,28 +62,24 @@
base::WeakPtr<ProviderImpl> provider_;
};
-ProviderImpl::PollingThread::PollingThread(
- const char* name,
- base::WeakPtr<ProviderImpl> provider,
- MessageLoop* creator_loop)
- : base::Thread(name),
- creator_loop_(creator_loop),
- provider_(provider) {
-}
+ProviderImpl::PollingThread::PollingThread(const char* name,
+ base::WeakPtr<ProviderImpl> provider,
+ base::MessageLoop* creator_loop)
+ : base::Thread(name), creator_loop_(creator_loop), provider_(provider) {}
ProviderImpl::PollingThread::~PollingThread() {
Stop();
}
void ProviderImpl::PollingThread::DoAddPollingDataType(DeviceData::Type type) {
- DCHECK(MessageLoop::current() == message_loop());
+ DCHECK(base::MessageLoop::current() == message_loop());
polling_data_types_.insert(type);
}
void ProviderImpl::PollingThread::Initialize(DataFetcherFactory factory,
DeviceData::Type type) {
- DCHECK(MessageLoop::current() == message_loop());
+ DCHECK(base::MessageLoop::current() == message_loop());
if (factory != NULL) {
// Try to use factory to create a fetcher that can provide this type of
@@ -91,7 +87,7 @@
// start polling.
scoped_ptr<DataFetcher> fetcher(factory());
- if (fetcher.get()) {
+ if (fetcher) {
scoped_refptr<const DeviceData> device_data(fetcher->GetDeviceData(type));
if (device_data != NULL) {
// Pass ownership of fetcher to provider_.
@@ -115,7 +111,7 @@
void ProviderImpl::PollingThread::ScheduleDoNotify(
const scoped_refptr<const DeviceData>& device_data,
DeviceData::Type device_data_type) {
- DCHECK(MessageLoop::current() == message_loop());
+ DCHECK(base::MessageLoop::current() == message_loop());
creator_loop_->PostTask(FROM_HERE,
base::Bind(&ProviderImpl::DoNotify, provider_,
@@ -123,7 +119,7 @@
}
void ProviderImpl::PollingThread::DoPoll() {
- DCHECK(MessageLoop::current() == message_loop());
+ DCHECK(base::MessageLoop::current() == message_loop());
// Poll the fetcher for each type of data.
typedef std::set<DeviceData::Type>::const_iterator SetIterator;
@@ -152,7 +148,7 @@
}
void ProviderImpl::PollingThread::ScheduleDoPoll() {
- DCHECK(MessageLoop::current() == message_loop());
+ DCHECK(base::MessageLoop::current() == message_loop());
message_loop()->PostDelayedTask(
FROM_HERE,
@@ -161,7 +157,7 @@
}
base::TimeDelta ProviderImpl::PollingThread::SamplingInterval() const {
- DCHECK(MessageLoop::current() == message_loop());
+ DCHECK(base::MessageLoop::current() == message_loop());
DCHECK(data_fetcher_.get());
// TODO(erg): There used to be unused code here, that called a default
@@ -171,9 +167,9 @@
}
ProviderImpl::ProviderImpl(DataFetcherFactory factory)
- : creator_loop_(MessageLoop::current()),
+ : creator_loop_(base::MessageLoop::current()),
factory_(factory),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+ weak_factory_(this),
polling_thread_(NULL) {
}
@@ -182,9 +178,9 @@
}
void ProviderImpl::ScheduleDoAddPollingDataType(DeviceData::Type type) {
- DCHECK(MessageLoop::current() == creator_loop_);
+ DCHECK(base::MessageLoop::current() == creator_loop_);
- MessageLoop* polling_loop = polling_thread_->message_loop();
+ base::MessageLoop* polling_loop = polling_thread_->message_loop();
polling_loop->PostTask(FROM_HERE,
base::Bind(&PollingThread::DoAddPollingDataType,
base::Unretained(polling_thread_),
@@ -192,7 +188,7 @@
}
void ProviderImpl::AddObserver(Observer* observer) {
- DCHECK(MessageLoop::current() == creator_loop_);
+ DCHECK(base::MessageLoop::current() == creator_loop_);
DeviceData::Type type = observer->device_data_type();
@@ -210,7 +206,7 @@
}
void ProviderImpl::RemoveObserver(Observer* observer) {
- DCHECK(MessageLoop::current() == creator_loop_);
+ DCHECK(base::MessageLoop::current() == creator_loop_);
observers_.erase(observer);
if (observers_.empty())
@@ -218,12 +214,15 @@
}
void ProviderImpl::Start(DeviceData::Type type) {
- DCHECK(MessageLoop::current() == creator_loop_);
+ DCHECK(base::MessageLoop::current() == creator_loop_);
DCHECK(!polling_thread_);
polling_thread_ = new PollingThread("Device data polling thread",
weak_factory_.GetWeakPtr(),
creator_loop_);
+#if defined(OS_WIN)
+ polling_thread_->init_com_with_mta(true);
+#endif
if (!polling_thread_->Start()) {
LOG(ERROR) << "Failed to start device data polling thread";
delete polling_thread_;
@@ -234,7 +233,7 @@
}
void ProviderImpl::Stop() {
- DCHECK(MessageLoop::current() == creator_loop_);
+ DCHECK(base::MessageLoop::current() == creator_loop_);
weak_factory_.InvalidateWeakPtrs();
if (polling_thread_) {
@@ -250,9 +249,9 @@
void ProviderImpl::ScheduleInitializePollingThread(
DeviceData::Type device_data_type) {
- DCHECK(MessageLoop::current() == creator_loop_);
+ DCHECK(base::MessageLoop::current() == creator_loop_);
- MessageLoop* polling_loop = polling_thread_->message_loop();
+ base::MessageLoop* polling_loop = polling_thread_->message_loop();
polling_loop->PostTask(FROM_HERE,
base::Bind(&PollingThread::Initialize,
base::Unretained(polling_thread_),
@@ -262,7 +261,7 @@
void ProviderImpl::DoNotify(const scoped_refptr<const DeviceData>& data,
DeviceData::Type device_data_type) {
- DCHECK(MessageLoop::current() == creator_loop_);
+ DCHECK(base::MessageLoop::current() == creator_loop_);
// Update last notification of this type.
last_notifications_map_[device_data_type] = data;
diff --git a/content/browser/device_orientation/provider_impl.h b/content/browser/device_orientation/provider_impl.h
index 6706f06..be7cf3b 100644
--- a/content/browser/device_orientation/provider_impl.h
+++ b/content/browser/device_orientation/provider_impl.h
@@ -16,7 +16,9 @@
#include "content/browser/device_orientation/provider.h"
#include "content/common/content_export.h"
+namespace base {
class MessageLoop;
+}
namespace content {
@@ -55,7 +57,7 @@
// The Message Loop on which this object was created.
// Typically the I/O loop, but may be something else during testing.
- MessageLoop* creator_loop_;
+ base::MessageLoop* creator_loop_;
// Members below are only to be used from the creator_loop_.
DataFetcherFactory factory_;
diff --git a/content/browser/device_orientation/provider_unittest.cc b/content/browser/device_orientation/provider_unittest.cc
index 4358c7f..ee2beed 100644
--- a/content/browser/device_orientation/provider_unittest.cc
+++ b/content/browser/device_orientation/provider_unittest.cc
@@ -150,7 +150,8 @@
--(*expectations_count_ptr_);
if (*expectations_count_ptr_ == 0) {
- MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ base::MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::QuitClosure());
}
}
};
@@ -196,7 +197,8 @@
--(*expectations_count_ptr_);
if (*expectations_count_ptr_ == 0) {
- MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ base::MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::QuitClosure());
}
}
};
@@ -228,7 +230,8 @@
--(*expectations_count_ptr_);
if (*expectations_count_ptr_ == 0) {
- MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ base::MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::QuitClosure());
}
}
};
@@ -330,7 +333,7 @@
scoped_refptr<Provider> provider_;
// Message loop for the test thread.
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
};
TEST_F(DeviceOrientationProviderTest, FailingTest) {
@@ -346,11 +349,11 @@
checker_a->AddExpectation(new Orientation());
provider_->AddObserver(checker_a.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
checker_b->AddExpectation(new Orientation());
provider_->AddObserver(checker_b.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
MockDeviceDataFactory::SetCurInstance(NULL);
}
@@ -385,7 +388,7 @@
device_data_factory->SetDeviceData(test_orientation,
DeviceData::kTypeOrientation);
provider_->AddObserver(checker.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
provider_->RemoveObserver(checker.get());
MockDeviceDataFactory::SetCurInstance(NULL);
@@ -426,7 +429,7 @@
device_data_factory->SetDeviceData(test_orientations[0],
DeviceData::kTypeOrientation);
provider_->AddObserver(checker_a.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
checker_a->AddExpectation(test_orientations[1]);
checker_b->AddExpectation(test_orientations[0]);
@@ -434,7 +437,7 @@
device_data_factory->SetDeviceData(test_orientations[1],
DeviceData::kTypeOrientation);
provider_->AddObserver(checker_b.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
provider_->RemoveObserver(checker_a.get());
checker_b->AddExpectation(test_orientations[2]);
@@ -443,7 +446,7 @@
device_data_factory->SetDeviceData(test_orientations[2],
DeviceData::kTypeOrientation);
provider_->AddObserver(checker_c.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
provider_->RemoveObserver(checker_b.get());
provider_->RemoveObserver(checker_c.get());
@@ -472,13 +475,13 @@
test_data_checker->AddExpectation(new TestData());
provider_->AddObserver(test_data_checker.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
orientation_checker->AddExpectation(test_orientation);
device_data_factory->SetDeviceData(test_orientation,
DeviceData::kTypeOrientation);
provider_->AddObserver(orientation_checker.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
provider_->RemoveObserver(test_data_checker.get());
provider_->RemoveObserver(orientation_checker.get());
@@ -515,12 +518,12 @@
device_data_factory->SetDeviceData(test_orientation,
DeviceData::kTypeOrientation);
provider_->AddObserver(checker.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
checker->AddExpectation(test_orientation2);
device_data_factory->SetDeviceData(test_orientation2,
DeviceData::kTypeOrientation);
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
MockDeviceDataFactory::SetCurInstance(NULL);
@@ -553,15 +556,15 @@
DeviceData::kTypeOrientation);
checker_a->AddExpectation(test_orientation);
provider_->AddObserver(checker_a.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
checker_a->AddExpectation(new Orientation());
device_data_factory->SetFailing(true);
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
checker_b->AddExpectation(new Orientation());
provider_->AddObserver(checker_b.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
provider_->RemoveObserver(checker_a.get());
provider_->RemoveObserver(checker_b.get());
@@ -595,7 +598,7 @@
device_data_factory->SetDeviceData(test_orientation,
DeviceData::kTypeOrientation);
provider_->AddObserver(checker_a.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
provider_->RemoveObserver(checker_a.get()); // This stops the Provider.
@@ -603,7 +606,7 @@
device_data_factory->SetDeviceData(test_orientation2,
DeviceData::kTypeOrientation);
provider_->AddObserver(checker_b.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
provider_->RemoveObserver(checker_b.get());
MockDeviceDataFactory::SetCurInstance(NULL);
@@ -634,12 +637,12 @@
device_data_factory->SetDeviceData(test_motion, DeviceData::kTypeMotion);
checker->AddExpectation(test_motion);
provider_->AddObserver(checker.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
// The observer should receive the same motion again.
device_data_factory->SetDeviceData(test_motion, DeviceData::kTypeMotion);
checker->AddExpectation(test_motion);
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
provider_->RemoveObserver(checker.get());
MockDeviceDataFactory::SetCurInstance(NULL);
@@ -685,20 +688,20 @@
DeviceData::kTypeOrientation);
checker_a->AddExpectation(first_orientation);
provider_->AddObserver(checker_a.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
// The observers should not see this insignificantly different orientation.
device_data_factory->SetDeviceData(second_orientation,
DeviceData::kTypeOrientation);
checker_b->AddExpectation(first_orientation);
provider_->AddObserver(checker_b.get());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
device_data_factory->SetDeviceData(third_orientation,
DeviceData::kTypeOrientation);
checker_a->AddExpectation(third_orientation);
checker_b->AddExpectation(third_orientation);
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
provider_->RemoveObserver(checker_a.get());
provider_->RemoveObserver(checker_b.get());
diff --git a/content/browser/devtools/devtools_agent_host_impl.cc b/content/browser/devtools/devtools_agent_host_impl.cc
index a4c9449..881e4bfc 100644
--- a/content/browser/devtools/devtools_agent_host_impl.cc
+++ b/content/browser/devtools/devtools_agent_host_impl.cc
@@ -9,7 +9,7 @@
#include "base/basictypes.h"
#include "base/guid.h"
#include "base/lazy_instance.h"
-#include "content/common/devtools_messages.h"
+#include "content/browser/devtools/devtools_manager_impl.h"
namespace content {
@@ -38,32 +38,11 @@
return it->second;
}
-void DevToolsAgentHostImpl::Attach() {
- SendMessageToAgent(new DevToolsAgentMsg_Attach(MSG_ROUTING_NONE));
- NotifyClientAttaching();
-}
-
-void DevToolsAgentHostImpl::Reattach(const std::string& saved_agent_state) {
- SendMessageToAgent(new DevToolsAgentMsg_Reattach(
- MSG_ROUTING_NONE,
- saved_agent_state));
- NotifyClientAttaching();
-}
-
-void DevToolsAgentHostImpl::Detach() {
- SendMessageToAgent(new DevToolsAgentMsg_Detach(MSG_ROUTING_NONE));
- NotifyClientDetaching();
-}
-
-void DevToolsAgentHostImpl::DispatchOnInspectorBackend(
- const std::string& message) {
- SendMessageToAgent(new DevToolsAgentMsg_DispatchOnInspectorBackend(
- MSG_ROUTING_NONE, message));
+bool DevToolsAgentHostImpl::IsAttached() {
+ return !!DevToolsManagerImpl::GetInstance()->GetDevToolsClientHostFor(this);
}
void DevToolsAgentHostImpl::InspectElement(int x, int y) {
- SendMessageToAgent(new DevToolsAgentMsg_InspectElement(MSG_ROUTING_NONE,
- x, y));
}
std::string DevToolsAgentHostImpl::GetId() {
diff --git a/content/browser/devtools/devtools_agent_host_impl.h b/content/browser/devtools/devtools_agent_host_impl.h
index 6e1f481..9c21650 100644
--- a/content/browser/devtools/devtools_agent_host_impl.h
+++ b/content/browser/devtools/devtools_agent_host_impl.h
@@ -27,17 +27,22 @@
virtual ~CloseListener() {}
};
- // Sends the message to the devtools agent hosted by this object.
- void Attach();
- void Reattach(const std::string& saved_agent_state);
- void Detach();
- virtual void DispatchOnInspectorBackend(const std::string& message);
+ // Informs the hosted agent that a client host has attached.
+ virtual void Attach() = 0;
+
+ // Informs the hosted agent that a client host has detached.
+ virtual void Detach() = 0;
+
+ // Sends a message to the agent hosted by this object.
+ virtual void DispatchOnInspectorBackend(const std::string& message) = 0;
void set_close_listener(CloseListener* listener) {
close_listener_ = listener;
}
// DevToolsAgentHost implementation.
+ virtual bool IsAttached() OVERRIDE;
+
virtual void InspectElement(int x, int y) OVERRIDE;
virtual std::string GetId() OVERRIDE;
@@ -48,10 +53,6 @@
DevToolsAgentHostImpl();
virtual ~DevToolsAgentHostImpl();
- virtual void SendMessageToAgent(IPC::Message* msg) = 0;
- virtual void NotifyClientAttaching() = 0;
- virtual void NotifyClientDetaching() = 0;
-
void NotifyCloseListener();
private:
diff --git a/content/browser/devtools/devtools_browser_target.cc b/content/browser/devtools/devtools_browser_target.cc
index aa5e1ac..fc563fb 100644
--- a/content/browser/devtools/devtools_browser_target.cc
+++ b/content/browser/devtools/devtools_browser_target.cc
@@ -22,7 +22,7 @@
http_server_(http_server),
connection_id_(connection_id),
handlers_deleter_(&handlers_),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ weak_factory_(this) {
}
DevToolsBrowserTarget::~DevToolsBrowserTarget() {
diff --git a/content/browser/devtools/devtools_external_agent_proxy_impl.cc b/content/browser/devtools/devtools_external_agent_proxy_impl.cc
new file mode 100644
index 0000000..5ecaa57
--- /dev/null
+++ b/content/browser/devtools/devtools_external_agent_proxy_impl.cc
@@ -0,0 +1,73 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/devtools/devtools_external_agent_proxy_impl.h"
+
+#include "content/browser/devtools/devtools_agent_host_impl.h"
+#include "content/browser/devtools/devtools_manager_impl.h"
+#include "content/public/browser/devtools_external_agent_proxy_delegate.h"
+
+namespace content {
+
+class DevToolsExternalAgentProxyImpl::ForwardingAgentHost
+ : public DevToolsAgentHostImpl {
+ public:
+ ForwardingAgentHost(DevToolsExternalAgentProxyDelegate* delegate)
+ : delegate_(delegate) {
+ }
+
+ void ConnectionClosed() {
+ NotifyCloseListener();
+ }
+
+ private:
+ virtual ~ForwardingAgentHost() {
+ }
+
+ // DevToolsAgentHostImpl implementation.
+ virtual void Attach() OVERRIDE {
+ delegate_->Attach();
+ };
+
+ virtual void Detach() OVERRIDE {
+ delegate_->Detach();
+ };
+
+ virtual void DispatchOnInspectorBackend(const std::string& message) OVERRIDE {
+ delegate_->SendMessageToBackend(message);
+ }
+
+ DevToolsExternalAgentProxyDelegate* delegate_;
+};
+
+//static
+DevToolsExternalAgentProxy* DevToolsExternalAgentProxy::Create(
+ DevToolsExternalAgentProxyDelegate* delegate) {
+ return new DevToolsExternalAgentProxyImpl(delegate);
+}
+
+DevToolsExternalAgentProxyImpl::DevToolsExternalAgentProxyImpl(
+ DevToolsExternalAgentProxyDelegate* delegate)
+ : agent_host_(new ForwardingAgentHost(delegate)) {
+}
+
+DevToolsExternalAgentProxyImpl::~DevToolsExternalAgentProxyImpl() {
+}
+
+scoped_refptr<DevToolsAgentHost> DevToolsExternalAgentProxyImpl::
+ GetAgentHost() {
+ return agent_host_;
+}
+
+void DevToolsExternalAgentProxyImpl::DispatchOnClientHost(
+ const std::string& message) {
+ DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(
+ agent_host_, message);
+}
+
+void DevToolsExternalAgentProxyImpl::ConnectionClosed() {
+ agent_host_->ConnectionClosed();
+}
+
+} // content
diff --git a/content/browser/devtools/devtools_external_agent_proxy_impl.h b/content/browser/devtools/devtools_external_agent_proxy_impl.h
new file mode 100644
index 0000000..cf025ec
--- /dev/null
+++ b/content/browser/devtools/devtools_external_agent_proxy_impl.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_EXTERNAL_AGENT_PROXY_IMPL_H
+#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_EXTERNAL_AGENT_PROXY_IMPL_H
+
+#include "base/memory/ref_counted.h"
+#include "content/public/browser/devtools_external_agent_proxy.h"
+
+namespace content {
+
+class DevToolsExternalAgentProxyImpl
+ : public DevToolsExternalAgentProxy {
+ public:
+ explicit DevToolsExternalAgentProxyImpl(
+ DevToolsExternalAgentProxyDelegate* delegate);
+ virtual ~DevToolsExternalAgentProxyImpl();
+
+ // DevToolsExternalAgentProxy implementation.
+ virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() OVERRIDE;
+ virtual void DispatchOnClientHost(const std::string& message) OVERRIDE;
+ virtual void ConnectionClosed() OVERRIDE;
+
+ private:
+ class ForwardingAgentHost;
+
+ scoped_refptr<ForwardingAgentHost> agent_host_;
+
+ DISALLOW_COPY_AND_ASSIGN(DevToolsExternalAgentProxyImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_EXTERNAL_AGENT_PROXY_IMPL_H
diff --git a/content/browser/devtools/devtools_http_handler_impl.cc b/content/browser/devtools/devtools_http_handler_impl.cc
index cc43682..cea2156 100644
--- a/content/browser/devtools/devtools_http_handler_impl.cc
+++ b/content/browser/devtools/devtools_http_handler_impl.cc
@@ -14,12 +14,16 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
+#include "base/stl_util.h"
#include "base/string_number_conversions.h"
#include "base/threading/thread.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "content/browser/devtools/devtools_browser_target.h"
+#include "content/browser/devtools/devtools_protocol.h"
+#include "content/browser/devtools/devtools_protocol_constants.h"
#include "content/browser/devtools/devtools_tracing_handler.h"
+#include "content/browser/devtools/tethering_handler.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/devtools_messages.h"
#include "content/public/browser/browser_thread.h"
@@ -89,16 +93,14 @@
// messages sent for DevToolsClient to a DebuggerShell instance.
class DevToolsClientHostImpl : public DevToolsClientHost {
public:
- DevToolsClientHostImpl(
- MessageLoop* message_loop,
- net::HttpServer* server,
- int connection_id)
+ DevToolsClientHostImpl(base::MessageLoop* message_loop,
+ net::HttpServer* server,
+ int connection_id)
: message_loop_(message_loop),
server_(server),
connection_id_(connection_id),
is_closed_(false),
- detach_reason_("target_closed") {
- }
+ detach_reason_("target_closed") {}
virtual ~DevToolsClientHostImpl() {}
@@ -108,9 +110,8 @@
return;
is_closed_ = true;
- std::string response =
- WebKit::WebDevToolsAgent::inspectorDetachedEvent(
- WebKit::WebString::fromUTF8(detach_reason_)).utf8();
+ std::string response = DevToolsProtocol::CreateNotification(
+ devtools::Inspector::detached::kName, NULL)->Serialize();
message_loop_->PostTask(
FROM_HERE,
base::Bind(&net::HttpServer::SendOverWebSocket,
@@ -137,7 +138,7 @@
}
private:
- MessageLoop* message_loop_;
+ base::MessageLoop* message_loop_;
net::HttpServer* server_;
int connection_id_;
bool is_closed_;
@@ -190,7 +191,7 @@
}
void DevToolsHttpHandlerImpl::Start() {
- if (thread_.get())
+ if (thread_)
return;
thread_.reset(new base::Thread(kDevToolsHandlerThreadName));
BrowserThread::PostTask(
@@ -201,7 +202,7 @@
// Runs on FILE thread.
void DevToolsHttpHandlerImpl::StartHandlerThread() {
base::Thread::Options options;
- options.message_loop_type = MessageLoop::TYPE_IO;
+ options.message_loop_type = base::MessageLoop::TYPE_IO;
if (!thread_->StartWithOptions(options)) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
@@ -224,7 +225,7 @@
}
void DevToolsHttpHandlerImpl::Stop() {
- if (!thread_.get())
+ if (!thread_)
return;
BrowserThread::PostTaskAndReply(
BrowserThread::FILE, FROM_HERE,
@@ -367,6 +368,30 @@
void DevToolsHttpHandlerImpl::OnWebSocketMessage(
int connection_id,
const std::string& data) {
+ std::string error_response;
+ scoped_ptr<DevToolsProtocol::Command> command(
+ DevToolsProtocol::ParseCommand(data, &error_response));
+ if (command && command->domain() == TetheringHandler::kDomain) {
+ TetheringHandlers::iterator it = tethering_handlers_.find(connection_id);
+ TetheringHandler* tethering_handler;
+ if (it == tethering_handlers_.end()) {
+ tethering_handler = new TetheringHandler(delegate_.get());
+ tethering_handlers_[connection_id] = tethering_handler;
+ tethering_handler->SetNotifier(
+ base::Bind(&net::HttpServer::SendOverWebSocket,
+ server_,
+ connection_id));
+ } else {
+ tethering_handler = it->second;
+ }
+ scoped_ptr<DevToolsProtocol::Response> response(
+ tethering_handler->HandleCommand(command.get()));
+ if (!response)
+ response = command->NoSuchMethodErrorResponse();
+ server_->SendOverWebSocket(connection_id, response->Serialize());
+ return;
+ }
+
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
@@ -378,6 +403,12 @@
}
void DevToolsHttpHandlerImpl::OnClose(int connection_id) {
+ TetheringHandlers::iterator it = tethering_handlers_.find(connection_id);
+ if (it != tethering_handlers_.end()) {
+ delete it->second;
+ tethering_handlers_.erase(connection_id);
+ }
+
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
@@ -459,7 +490,7 @@
content::GetContentClient()->GetProduct());
version.SetString("User-Agent",
webkit_glue::GetUserAgent(GURL(chrome::kAboutBlankURL)));
- SendJson(connection_id, net::HTTP_OK, &version, "");
+ SendJson(connection_id, net::HTTP_OK, &version, std::string());
return;
}
@@ -506,7 +537,7 @@
}
std::string host = info.headers["Host"];
scoped_ptr<base::DictionaryValue> dictionary(SerializePageInfo(rvh, host));
- SendJson(connection_id, net::HTTP_OK, dictionary.get(), "");
+ SendJson(connection_id, net::HTTP_OK, dictionary.get(), std::string());
return;
}
@@ -552,7 +583,7 @@
void DevToolsHttpHandlerImpl::SendTargetList(int connection_id,
ListValue* target_list) {
- SendJson(connection_id, net::HTTP_OK, target_list, "");
+ SendJson(connection_id, net::HTTP_OK, target_list, std::string());
delete target_list;
Release(); // Balanced OnJsonRequestUI.
}
@@ -574,7 +605,7 @@
void DevToolsHttpHandlerImpl::OnWebSocketRequestUI(
int connection_id,
const net::HttpServerRequestInfo& request) {
- if (!thread_.get())
+ if (!thread_)
return;
std::string browser_prefix = "/devtools/browser";
size_t browser_pos = request.path.find(browser_prefix);
@@ -604,8 +635,7 @@
return;
}
- DevToolsManager* manager = DevToolsManager::GetInstance();
- if (manager->GetDevToolsClientHostFor(agent)) {
+ if (agent->IsAttached()) {
Send500(connection_id,
"Target with given id is being inspected: " + page_id);
return;
@@ -617,7 +647,8 @@
connection_id);
connection_to_client_host_ui_[connection_id] = client_host;
- manager->RegisterDevToolsClientHostFor(agent, client_host);
+ DevToolsManager::GetInstance()->
+ RegisterDevToolsClientHostFor(agent, client_host);
AcceptWebSocket(connection_id, request);
}
@@ -686,6 +717,8 @@
// Runs on the handler thread
void DevToolsHttpHandlerImpl::Teardown() {
+ STLDeleteContainerPairSecondPointers(tethering_handlers_.begin(),
+ tethering_handlers_.end());
server_ = NULL;
}
@@ -705,7 +738,7 @@
net::HttpStatusCode status_code,
base::Value* value,
const std::string& message) {
- if (!thread_.get())
+ if (!thread_)
return;
// Serialize value and message.
@@ -737,7 +770,7 @@
void DevToolsHttpHandlerImpl::Send200(int connection_id,
const std::string& data,
const std::string& mime_type) {
- if (!thread_.get())
+ if (!thread_)
return;
thread_->message_loop()->PostTask(
FROM_HERE,
@@ -749,7 +782,7 @@
}
void DevToolsHttpHandlerImpl::Send404(int connection_id) {
- if (!thread_.get())
+ if (!thread_)
return;
thread_->message_loop()->PostTask(
FROM_HERE,
@@ -758,7 +791,7 @@
void DevToolsHttpHandlerImpl::Send500(int connection_id,
const std::string& message) {
- if (!thread_.get())
+ if (!thread_)
return;
thread_->message_loop()->PostTask(
FROM_HERE,
@@ -769,7 +802,7 @@
void DevToolsHttpHandlerImpl::AcceptWebSocket(
int connection_id,
const net::HttpServerRequestInfo& request) {
- if (!thread_.get())
+ if (!thread_)
return;
thread_->message_loop()->PostTask(
FROM_HERE,
@@ -814,7 +847,7 @@
dictionary->SetString(kTargetDescriptionField,
delegate_->GetViewDescription(rvh));
- if (!DevToolsManager::GetInstance()->GetDevToolsClientHostFor(agent))
+ if (!agent->IsAttached())
SerializeDebuggerURLs(dictionary, id, host);
return dictionary;
}
@@ -837,7 +870,7 @@
dictionary->SetString(kTargetDescriptionField,
base::StringPrintf("Worker pid:%d", base::GetProcId(worker.handle)));
- if (!DevToolsManager::GetInstance()->GetDevToolsClientHostFor(agent))
+ if (!agent->IsAttached())
SerializeDebuggerURLs(dictionary, id, host);
return dictionary;
}
diff --git a/content/browser/devtools/devtools_http_handler_impl.h b/content/browser/devtools/devtools_http_handler_impl.h
index ce2688b..76820e8 100644
--- a/content/browser/devtools/devtools_http_handler_impl.h
+++ b/content/browser/devtools/devtools_http_handler_impl.h
@@ -34,6 +34,7 @@
class DevToolsBrowserTarget;
class DevToolsClientHost;
+class TetheringHandler;
class DevToolsHttpHandlerImpl
: public DevToolsHttpHandler,
@@ -128,6 +129,8 @@
DevToolsAgentHostBinding* binding_;
scoped_ptr<DevToolsAgentHostBinding> default_binding_;
scoped_ptr<DevToolsBrowserTarget> browser_target_;
+ typedef std::map<int, TetheringHandler*> TetheringHandlers;
+ TetheringHandlers tethering_handlers_;
DISALLOW_COPY_AND_ASSIGN(DevToolsHttpHandlerImpl);
};
diff --git a/content/browser/devtools/devtools_http_handler_unittest.cc b/content/browser/devtools/devtools_http_handler_unittest.cc
index 56f3277..9441c83 100644
--- a/content/browser/devtools/devtools_http_handler_unittest.cc
+++ b/content/browser/devtools/devtools_http_handler_unittest.cc
@@ -7,7 +7,7 @@
#include "content/browser/browser_thread_impl.h"
#include "content/public/browser/devtools_http_handler.h"
#include "content/public/browser/devtools_http_handler_delegate.h"
-#include "net/base/stream_listen_socket.h"
+#include "net/socket/stream_listen_socket.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
@@ -19,7 +19,7 @@
public StreamListenSocket::Delegate {
public:
DummyListenSocket()
- : ALLOW_THIS_IN_INITIALIZER_LIST(StreamListenSocket(0, this)) {}
+ : StreamListenSocket(0, this) {}
// StreamListenSocket::Delegate "implementation"
virtual void DidAccept(StreamListenSocket* server,
@@ -56,20 +56,25 @@
class DummyDelegate : public DevToolsHttpHandlerDelegate {
public:
- virtual std::string GetDiscoveryPageHTML() OVERRIDE { return ""; }
+ virtual std::string GetDiscoveryPageHTML() OVERRIDE { return std::string(); }
virtual bool BundlesFrontendResources() OVERRIDE { return true; }
virtual base::FilePath GetDebugFrontendDir() OVERRIDE {
return base::FilePath();
}
virtual std::string GetPageThumbnailData(const GURL& url) OVERRIDE {
- return "";
+ return std::string();
}
virtual RenderViewHost* CreateNewTarget() OVERRIDE { return NULL; }
virtual TargetType GetTargetType(RenderViewHost*) OVERRIDE {
return kTargetTypeTab;
}
virtual std::string GetViewDescription(content::RenderViewHost*) OVERRIDE {
- return "";
+ return std::string();
+ }
+ virtual scoped_refptr<net::StreamListenSocket> CreateSocketForTethering(
+ net::StreamListenSocket::Delegate* delegate,
+ std::string* name) OVERRIDE {
+ return NULL;
}
};
@@ -89,7 +94,7 @@
file_thread_->Stop();
}
private:
- MessageLoopForIO message_loop_;
+ base::MessageLoopForIO message_loop_;
BrowserThreadImpl ui_thread_;
scoped_ptr<BrowserThreadImpl> file_thread_;
};
@@ -98,9 +103,9 @@
base::RunLoop run_loop, run_loop_2;
content::DevToolsHttpHandler* devtools_http_handler_ =
content::DevToolsHttpHandler::Start(
- new DummyListenSocketFactory(
- run_loop.QuitClosure(), run_loop_2.QuitClosure()),
- "",
+ new DummyListenSocketFactory(run_loop.QuitClosure(),
+ run_loop_2.QuitClosure()),
+ std::string(),
new DummyDelegate());
// Our dummy socket factory will post a quit message once the server will
// become ready.
diff --git a/content/browser/devtools/devtools_manager_impl.cc b/content/browser/devtools/devtools_manager_impl.cc
index 4ae34da..753340b 100644
--- a/content/browser/devtools/devtools_manager_impl.cc
+++ b/content/browser/devtools/devtools_manager_impl.cc
@@ -37,9 +37,7 @@
}
DevToolsClientHost* DevToolsManagerImpl::GetDevToolsClientHostFor(
- DevToolsAgentHost* agent_host) {
- DevToolsAgentHostImpl* agent_host_impl =
- static_cast<DevToolsAgentHostImpl*>(agent_host);
+ DevToolsAgentHostImpl* agent_host_impl) {
AgentToClientHostMap::iterator it =
agent_to_client_host_.find(agent_host_impl);
if (it != agent_to_client_host_.end())
@@ -60,6 +58,12 @@
DevToolsClientHost* client_host) {
DevToolsAgentHostImpl* agent_host_impl =
static_cast<DevToolsAgentHostImpl*>(agent_host);
+ DevToolsClientHost* old_client_host =
+ GetDevToolsClientHostFor(agent_host_impl);
+ if (old_client_host) {
+ old_client_host->ReplacedWithAnotherClient();
+ UnregisterDevToolsClientHostFor(agent_host_impl);
+ }
BindClientHost(agent_host_impl, client_host);
agent_host_impl->Attach();
}
@@ -79,7 +83,9 @@
void DevToolsManagerImpl::DispatchOnInspectorFrontend(
DevToolsAgentHost* agent_host,
const std::string& message) {
- DevToolsClientHost* client_host = GetDevToolsClientHostFor(agent_host);
+ DevToolsAgentHostImpl* agent_host_impl =
+ static_cast<DevToolsAgentHostImpl*>(agent_host);
+ DevToolsClientHost* client_host = GetDevToolsClientHostFor(agent_host_impl);
if (!client_host) {
// Client window was closed while there were messages
// being sent to it.
@@ -102,12 +108,10 @@
}
void DevToolsManagerImpl::UnregisterDevToolsClientHostFor(
- DevToolsAgentHost* agent_host) {
- DevToolsClientHost* client_host = GetDevToolsClientHostFor(agent_host);
+ DevToolsAgentHostImpl* agent_host_impl) {
+ DevToolsClientHost* client_host = GetDevToolsClientHostFor(agent_host_impl);
if (!client_host)
return;
- DevToolsAgentHostImpl* agent_host_impl =
- static_cast<DevToolsAgentHostImpl*>(agent_host);
UnbindClientHost(agent_host_impl, client_host);
client_host->InspectedContentsClosing();
}
@@ -129,6 +133,7 @@
agent_to_client_host_[agent_host] = client_host;
client_to_agent_host_[client_host] = agent_host;
agent_host->set_close_listener(this);
+ NotifyObservers(agent_host, true);
}
void DevToolsManagerImpl::UnbindClientHost(DevToolsAgentHostImpl* agent_host,
@@ -150,22 +155,41 @@
FROM_HERE,
base::Bind(&DevToolsNetLogObserver::Detach));
}
+ NotifyObservers(agent_host, false);
// Lazy agent hosts can be deleted from within detach.
// Do not access agent_host below this line.
agent_host->Detach();
}
void DevToolsManagerImpl::CloseAllClientHosts() {
- std::vector<DevToolsAgentHost*> agents;
+ std::vector<DevToolsAgentHostImpl*> agents;
for (AgentToClientHostMap::iterator it =
agent_to_client_host_.begin();
it != agent_to_client_host_.end(); ++it) {
agents.push_back(it->first);
}
- for (std::vector<DevToolsAgentHost*>::iterator it = agents.begin();
+ for (std::vector<DevToolsAgentHostImpl*>::iterator it = agents.begin();
it != agents.end(); ++it) {
UnregisterDevToolsClientHostFor(*it);
}
}
+void DevToolsManagerImpl::AddAgentStateCallback(const Callback& callback) {
+ callbacks_.push_back(&callback);
+}
+
+void DevToolsManagerImpl::RemoveAgentStateCallback(const Callback& callback) {
+ CallbackContainer::iterator it =
+ std::find(callbacks_.begin(), callbacks_.end(), &callback);
+ DCHECK(it != callbacks_.end());
+ callbacks_.erase(it);
+}
+
+void DevToolsManagerImpl::NotifyObservers(DevToolsAgentHost* agent_host,
+ bool attached) {
+ CallbackContainer copy(callbacks_);
+ for (CallbackContainer::iterator it = copy.begin(); it != copy.end(); ++it)
+ (*it)->Run(agent_host, attached);
+}
+
} // namespace content
diff --git a/content/browser/devtools/devtools_manager_impl.h b/content/browser/devtools/devtools_manager_impl.h
index 6e1607c..3232bc1 100644
--- a/content/browser/devtools/devtools_manager_impl.h
+++ b/content/browser/devtools/devtools_manager_impl.h
@@ -7,6 +7,7 @@
#include <map>
#include <string>
+#include <vector>
#include "base/compiler_specific.h"
#include "base/memory/singleton.h"
@@ -49,18 +50,17 @@
virtual bool DispatchOnInspectorBackend(DevToolsClientHost* from,
const std::string& message) OVERRIDE;
virtual void CloseAllClientHosts() OVERRIDE;
- virtual DevToolsClientHost* GetDevToolsClientHostFor(
- DevToolsAgentHost* agent_host) OVERRIDE;
virtual DevToolsAgentHost* GetDevToolsAgentHostFor(
DevToolsClientHost* client_host) OVERRIDE;
virtual void RegisterDevToolsClientHostFor(
DevToolsAgentHost* agent_host,
DevToolsClientHost* client_host) OVERRIDE;
- virtual void UnregisterDevToolsClientHostFor(
- DevToolsAgentHost* agent_host) OVERRIDE;
virtual void ClientHostClosing(DevToolsClientHost* host) OVERRIDE;
+ virtual void AddAgentStateCallback(const Callback& callback) OVERRIDE;
+ virtual void RemoveAgentStateCallback(const Callback& callback) OVERRIDE;
private:
+ friend class DevToolsAgentHostImpl;
friend struct DefaultSingletonTraits<DevToolsManagerImpl>;
// DevToolsAgentHost::CloseListener implementation.
@@ -71,6 +71,13 @@
void UnbindClientHost(DevToolsAgentHostImpl* agent_host,
DevToolsClientHost* client_host);
+ DevToolsClientHost* GetDevToolsClientHostFor(
+ DevToolsAgentHostImpl* agent_host);
+
+ void UnregisterDevToolsClientHostFor(DevToolsAgentHostImpl* agent_host);
+
+ void NotifyObservers(DevToolsAgentHost* agent_host, bool attached);
+
// These two maps are for tracking dependencies between inspected contents and
// their DevToolsClientHosts. They are useful for routing devtools messages
// and allow us to have at most one devtools client host per contents.
@@ -85,6 +92,9 @@
ClientToAgentHostMap;
ClientToAgentHostMap client_to_agent_host_;
+ typedef std::vector<const Callback*> CallbackContainer;
+ CallbackContainer callbacks_;
+
DISALLOW_COPY_AND_ASSIGN(DevToolsManagerImpl);
};
diff --git a/content/browser/devtools/devtools_manager_unittest.cc b/content/browser/devtools/devtools_manager_unittest.cc
index deac3c1..6923a93 100644
--- a/content/browser/devtools/devtools_manager_unittest.cc
+++ b/content/browser/devtools/devtools_manager_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
#include "base/time.h"
#include "content/browser/devtools/devtools_manager_impl.h"
#include "content/browser/devtools/render_view_devtools_agent_host.h"
@@ -11,6 +12,8 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/devtools_client_host.h"
+#include "content/public/browser/devtools_external_agent_proxy.h"
+#include "content/public/browser/devtools_external_agent_proxy_delegate.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_web_contents.h"
@@ -109,8 +112,7 @@
protected:
virtual void SetUp() OVERRIDE {
- original_browser_client_ = GetContentClient()->browser();
- GetContentClient()->set_browser_for_testing(&browser_client_);
+ original_browser_client_ = SetBrowserClientForTesting(&browser_client_);
RenderViewHostImplTestHarness::SetUp();
TestDevToolsClientHost::ResetCounters();
@@ -118,7 +120,7 @@
virtual void TearDown() OVERRIDE {
RenderViewHostImplTestHarness::TearDown();
- GetContentClient()->set_browser_for_testing(original_browser_client_);
+ SetBrowserClientForTesting(original_browser_client_);
}
private:
@@ -127,46 +129,39 @@
};
TEST_F(DevToolsManagerTest, OpenAndManuallyCloseDevToolsClientHost) {
- DevToolsManagerImpl manager;
+ DevToolsManager* manager = DevToolsManager::GetInstance();
scoped_refptr<DevToolsAgentHost> agent(
DevToolsAgentHost::GetOrCreateFor(rvh()));
- DevToolsClientHost* host = manager.GetDevToolsClientHostFor(agent);
- EXPECT_TRUE(NULL == host);
+ EXPECT_FALSE(agent->IsAttached());
TestDevToolsClientHost client_host;
- manager.RegisterDevToolsClientHostFor(agent, &client_host);
- // Test that just registered devtools host is returned.
- host = manager.GetDevToolsClientHostFor(agent);
- EXPECT_TRUE(&client_host == host);
+ manager->RegisterDevToolsClientHostFor(agent, &client_host);
+ // Test that the connection is established.
+ EXPECT_TRUE(agent->IsAttached());
+ EXPECT_EQ(agent, manager->GetDevToolsAgentHostFor(&client_host));
EXPECT_EQ(0, TestDevToolsClientHost::close_counter);
- // Test that the same devtools host is returned.
- host = manager.GetDevToolsClientHostFor(agent);
- EXPECT_TRUE(&client_host == host);
- EXPECT_EQ(0, TestDevToolsClientHost::close_counter);
-
- client_host.Close(&manager);
+ client_host.Close(manager);
EXPECT_EQ(1, TestDevToolsClientHost::close_counter);
- host = manager.GetDevToolsClientHostFor(agent);
- EXPECT_TRUE(NULL == host);
+ EXPECT_FALSE(agent->IsAttached());
}
TEST_F(DevToolsManagerTest, ForwardMessageToClient) {
- DevToolsManagerImpl manager;
+ DevToolsManagerImpl* manager = DevToolsManagerImpl::GetInstance();
TestDevToolsClientHost client_host;
scoped_refptr<DevToolsAgentHost> agent_host(
DevToolsAgentHost::GetOrCreateFor(rvh()));
- manager.RegisterDevToolsClientHostFor(agent_host, &client_host);
+ manager->RegisterDevToolsClientHostFor(agent_host, &client_host);
EXPECT_EQ(0, TestDevToolsClientHost::close_counter);
std::string m = "test message";
agent_host = DevToolsAgentHost::GetOrCreateFor(rvh());
- manager.DispatchOnInspectorFrontend(agent_host, m);
+ manager->DispatchOnInspectorFrontend(agent_host, m);
EXPECT_TRUE(&m == client_host.last_sent_message);
- client_host.Close(&manager);
+ client_host.Close(manager);
EXPECT_EQ(1, TestDevToolsClientHost::close_counter);
}
@@ -186,9 +181,11 @@
// Start with a short timeout.
inspected_rvh->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
// Wait long enough for first timeout and see if it fired.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(10));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(10));
+ base::MessageLoop::current()->Run();
EXPECT_FALSE(delegate.renderer_unresponsive_received());
// Now close devtools and check that the notification is delivered.
@@ -196,9 +193,11 @@
// Start with a short timeout.
inspected_rvh->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
// Wait long enough for first timeout and see if it fired.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(10));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(10));
+ base::MessageLoop::current()->Run();
EXPECT_TRUE(delegate.renderer_unresponsive_received());
contents()->SetDelegate(NULL);
@@ -224,17 +223,73 @@
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_TRUE(contents()->cross_navigation_pending());
- EXPECT_EQ(&client_host, devtools_manager->GetDevToolsClientHostFor(
- DevToolsAgentHost::GetOrCreateFor(pending_rvh())));
+ EXPECT_EQ(devtools_manager->GetDevToolsAgentHostFor(&client_host),
+ DevToolsAgentHost::GetOrCreateFor(pending_rvh()));
// Interrupt pending navigation and navigate back to the original site.
controller().LoadURL(
url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
contents()->TestDidNavigate(rvh(), 1, url, PAGE_TRANSITION_TYPED);
EXPECT_FALSE(contents()->cross_navigation_pending());
- EXPECT_EQ(&client_host, devtools_manager->GetDevToolsClientHostFor(
- DevToolsAgentHost::GetOrCreateFor(rvh())));
+ EXPECT_EQ(devtools_manager->GetDevToolsAgentHostFor(&client_host),
+ DevToolsAgentHost::GetOrCreateFor(rvh()));
client_host.Close(DevToolsManager::GetInstance());
}
+class TestExternalAgentDelegate: public DevToolsExternalAgentProxyDelegate {
+ std::map<std::string,int> event_counter_;
+
+ void recordEvent(const std::string& name) {
+ if (event_counter_.find(name) == event_counter_.end())
+ event_counter_[name] = 0;
+ event_counter_[name] = event_counter_[name] + 1;
+ }
+
+ void expectEvent(int count, const std::string& name) {
+ EXPECT_EQ(count, event_counter_[name]);
+ }
+
+ virtual void Attach() OVERRIDE {
+ recordEvent("Attach");
+ };
+
+ virtual void Detach() OVERRIDE {
+ recordEvent("Detach");
+ };
+
+ virtual void SendMessageToBackend(const std::string& message) OVERRIDE {
+ recordEvent(std::string("SendMessageToBackend.") + message);
+ };
+
+ public :
+ virtual ~TestExternalAgentDelegate() {
+ expectEvent(1, "Attach");
+ expectEvent(1, "Detach");
+ expectEvent(0, "SendMessageToBackend.message0");
+ expectEvent(1, "SendMessageToBackend.message1");
+ expectEvent(2, "SendMessageToBackend.message2");
+ }
+};
+
+TEST_F(DevToolsManagerTest, TestExternalProxy) {
+ TestExternalAgentDelegate delegate;
+
+ scoped_ptr<DevToolsExternalAgentProxy> proxy(
+ DevToolsExternalAgentProxy::Create(&delegate));
+
+ scoped_refptr<DevToolsAgentHost> agent_host = proxy->GetAgentHost();
+ EXPECT_EQ(agent_host, DevToolsAgentHost::GetForId(agent_host->GetId()));
+
+ DevToolsManager* manager = DevToolsManager::GetInstance();
+
+ TestDevToolsClientHost client_host;
+ manager->RegisterDevToolsClientHostFor(agent_host, &client_host);
+
+ manager->DispatchOnInspectorBackend(&client_host, "message1");
+ manager->DispatchOnInspectorBackend(&client_host, "message2");
+ manager->DispatchOnInspectorBackend(&client_host, "message2");
+
+ client_host.Close(manager);
+}
+
} // namespace content
diff --git a/content/browser/devtools/devtools_protocol.cc b/content/browser/devtools/devtools_protocol.cc
index 28d6fe8..1ef3085 100644
--- a/content/browser/devtools/devtools_protocol.cc
+++ b/content/browser/devtools/devtools_protocol.cc
@@ -6,6 +6,7 @@
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
+#include "base/stringprintf.h"
namespace content {
@@ -20,25 +21,65 @@
const char kErrorMessageParam[] = "message";
const int kNoId = -1;
+// JSON RPC 2.0 spec: http://www.jsonrpc.org/specification#error_object
+enum Error {
+ kErrorParseError = -32700,
+ kErrorInvalidRequest = -32600,
+ kErrorNoSuchMethod = -32601,
+ kErrorInvalidParams = -32602,
+ kErrorInternalError = -32603
+};
+
} // namespace
using base::DictionaryValue;
using base::Value;
+DevToolsProtocol::Message::~Message() {
+}
+
+DevToolsProtocol::Message::Message(const std::string& method,
+ DictionaryValue* params)
+ : method_(method),
+ params_(params) {
+ size_t pos = method.find(".");
+ if (pos != std::string::npos && pos > 0)
+ domain_ = method.substr(0, pos);
+}
+
DevToolsProtocol::Command::~Command() {
}
+std::string DevToolsProtocol::Command::Serialize() {
+ DictionaryValue command;
+ command.SetInteger(kIdParam, id_);
+ command.SetString(kMethodParam, method_);
+ if (params_)
+ command.Set(kParamsParam, params_->DeepCopy());
+
+ std::string json_command;
+ base::JSONWriter::Write(&command, &json_command);
+ return json_command;
+}
+
scoped_ptr<DevToolsProtocol::Response>
-DevToolsProtocol::Command::SuccessResponse(base::DictionaryValue* result) {
+DevToolsProtocol::Command::SuccessResponse(DictionaryValue* result) {
return scoped_ptr<DevToolsProtocol::Response>(
new DevToolsProtocol::Response(id_, result));
}
scoped_ptr<DevToolsProtocol::Response>
-DevToolsProtocol::Command::ErrorResponse(int error_code,
- const std::string& error_message) {
+DevToolsProtocol::Command::InternalErrorResponse(const std::string& message) {
return scoped_ptr<DevToolsProtocol::Response>(
- new DevToolsProtocol::Response(id_, error_code, error_message));
+ new DevToolsProtocol::Response(id_, kErrorInternalError, message));
+}
+
+scoped_ptr<DevToolsProtocol::Response>
+DevToolsProtocol::Command::InvalidParamResponse(const std::string& param) {
+ std::string message =
+ base::StringPrintf("Missing or invalid '%s' parameter", param.c_str());
+ return scoped_ptr<DevToolsProtocol::Response>(
+ new DevToolsProtocol::Response(id_, kErrorInvalidParams, message));
}
scoped_ptr<DevToolsProtocol::Response>
@@ -48,13 +89,10 @@
}
DevToolsProtocol::Command::Command(int id,
- const std::string& domain,
const std::string& method,
DictionaryValue* params)
- : id_(id),
- domain_(domain),
- method_(method),
- params_(params) {
+ : Message(method, params),
+ id_(id) {
}
std::string DevToolsProtocol::Response::Serialize() {
@@ -69,7 +107,7 @@
error_object->SetInteger(kErrorCodeParam, error_code_);
if (!error_message_.empty())
error_object->SetString(kErrorMessageParam, error_message_);
- } else if (result_.get()) {
+ } else if (result_) {
response.Set(kResultParam, result_->DeepCopy());
}
@@ -98,19 +136,16 @@
DevToolsProtocol::Notification::Notification(const std::string& method,
DictionaryValue* params)
- : method_(method),
- params_(params) {
+ : Message(method, params) {
}
DevToolsProtocol::Notification::~Notification() {
}
std::string DevToolsProtocol::Notification::Serialize() {
- DictionaryValue response;
-
- base::DictionaryValue notification;
+ DictionaryValue notification;
notification.SetString(kMethodParam, method_);
- if (params_.get())
+ if (params_)
notification.Set(kParamsParam, params_->DeepCopy());
std::string json_notification;
@@ -118,27 +153,6 @@
return json_notification;
}
-DevToolsProtocol::Event::~Event() {
-}
-
-std::string DevToolsProtocol::Event::Serialize() {
- DictionaryValue dictionary;
-
- dictionary.SetString(kMethodParam, method_);
- if (params_)
- dictionary.Set(kParamsParam, params_->DeepCopy());
-
- std::string result;
- base::JSONWriter::Write(&dictionary, &result);
- return result;
-}
-
-DevToolsProtocol::Event::Event(const std::string& method,
- DictionaryValue* params)
- : method_(method),
- params_(params) {
-}
-
DevToolsProtocol::Handler::~Handler() {
}
@@ -166,62 +180,87 @@
void DevToolsProtocol::Handler::SendNotification(
const std::string& method,
- base::DictionaryValue* params) {
+ DictionaryValue* params) {
DevToolsProtocol::Notification notification(method, params);
if (!notifier_.is_null())
notifier_.Run(notification.Serialize());
}
+static bool ParseMethod(DictionaryValue* command,
+ std::string* method) {
+ if (!command->GetString(kMethodParam, method))
+ return false;
+ size_t pos = method->find(".");
+ if (pos == std::string::npos || pos == 0)
+ return false;
+ return true;
+}
+
// static
DevToolsProtocol::Command* DevToolsProtocol::ParseCommand(
const std::string& json,
std::string* error_response) {
- int parse_error_code;
- std::string error_message;
- scoped_ptr<base::Value> command(
- base::JSONReader::ReadAndReturnError(
- json, 0, &parse_error_code, &error_message));
-
- if (!command || !command->IsType(base::Value::TYPE_DICTIONARY)) {
- Response response(0, kErrorParseError, error_message);
- *error_response = response.Serialize();
+ scoped_ptr<DictionaryValue> command_dict(ParseMessage(json, error_response));
+ if (!command_dict)
return NULL;
- }
-
- base::DictionaryValue* command_dict = NULL;
- command->GetAsDictionary(&command_dict);
int id;
std::string method;
- bool ok = true;
- ok &= command_dict->GetInteger(kIdParam, &id);
- ok &= id >= 0;
- ok &= command_dict->GetString(kMethodParam, &method);
+ bool ok = command_dict->GetInteger(kIdParam, &id) && id >= 0;
+ ok = ok && ParseMethod(command_dict.get(), &method);
if (!ok) {
- Response response(kNoId, kErrorInvalidRequest, "Invalid request");
+ Response response(kNoId, kErrorInvalidRequest, "No such method");
*error_response = response.Serialize();
return NULL;
}
- size_t pos = method.find(".");
- if (pos == std::string::npos || pos == 0) {
- Response response(id, kErrorNoSuchMethod, "No such method");
- *error_response = response.Serialize();
- return NULL;
- }
-
- std::string domain = method.substr(0, pos);
-
- base::DictionaryValue* params = NULL;
+ DictionaryValue* params = NULL;
command_dict->GetDictionary(kParamsParam, ¶ms);
- return new Command(id, domain, method, params ? params->DeepCopy() : NULL);
+ return new Command(id, method, params ? params->DeepCopy() : NULL);
+}
+
+// static
+DevToolsProtocol::Notification*
+DevToolsProtocol::ParseNotification(const std::string& json) {
+ scoped_ptr<DictionaryValue> dict(ParseMessage(json, NULL));
+ if (!dict)
+ return NULL;
+
+ std::string method;
+ bool ok = ParseMethod(dict.get(), &method);
+ if (!ok)
+ return NULL;
+
+ DictionaryValue* params = NULL;
+ dict->GetDictionary(kParamsParam, ¶ms);
+ return new Notification(method, params ? params->DeepCopy() : NULL);
}
//static
-DevToolsProtocol::Event* DevToolsProtocol::CreateEvent(
+DevToolsProtocol::Notification* DevToolsProtocol::CreateNotification(
const std::string& method,
- base::DictionaryValue* params) {
- return new Event(method, params);
+ DictionaryValue* params) {
+ return new Notification(method, params);
+}
+
+// static
+DictionaryValue* DevToolsProtocol::ParseMessage(
+ const std::string& json,
+ std::string* error_response) {
+ int parse_error_code;
+ std::string error_message;
+ scoped_ptr<Value> message(
+ base::JSONReader::ReadAndReturnError(
+ json, 0, &parse_error_code, &error_message));
+
+ if (!message || !message->IsType(Value::TYPE_DICTIONARY)) {
+ Response response(0, kErrorParseError, error_message);
+ if (error_response)
+ *error_response = response.Serialize();
+ return NULL;
+ }
+
+ return static_cast<DictionaryValue*>(message.release());
}
} // namespace content
diff --git a/content/browser/devtools/devtools_protocol.h b/content/browser/devtools/devtools_protocol.h
index 9755476..a2ef7db 100644
--- a/content/browser/devtools/devtools_protocol.h
+++ b/content/browser/devtools/devtools_protocol.h
@@ -21,45 +21,55 @@
public:
typedef base::Callback<void(const std::string& message)> Notifier;
- // JSON RPC 2.0 spec: http://www.jsonrpc.org/specification#error_object
- enum Error {
- kErrorParseError = -32700,
- kErrorInvalidRequest = -32600,
- kErrorNoSuchMethod = -32601,
- kErrorInvalidParams = -32602,
- kErrorInternalError = -32603
- };
-
class Response;
- class Command {
+ class Message {
public:
- ~Command();
+ virtual ~Message();
- int id() { return id_; }
std::string domain() { return domain_; }
std::string method() { return method_; }
base::DictionaryValue* params() { return params_.get(); }
+ virtual std::string Serialize() = 0;
+
+ protected:
+ Message(const std::string& method,
+ base::DictionaryValue* params);
+
+ std::string domain_;
+ std::string method_;
+ scoped_ptr<base::DictionaryValue> params_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Message);
+ };
+
+ class Command : public Message {
+ public:
+ virtual ~Command();
+
+ int id() { return id_; }
+
+ virtual std::string Serialize() OVERRIDE;
// Creates success response. Takes ownership of |result|.
scoped_ptr<Response> SuccessResponse(base::DictionaryValue* result);
// Creates error response. Caller takes ownership of the return value.
- scoped_ptr<Response> ErrorResponse(int error_code,
- const std::string& error_message);
+ scoped_ptr<Response> InternalErrorResponse(const std::string& message);
+
+ // Creates error response. Caller takes ownership of the return value.
+ scoped_ptr<Response> InvalidParamResponse(const std::string& param);
// Creates error response. Caller takes ownership of the return value.
scoped_ptr<Response> NoSuchMethodErrorResponse();
private:
friend class DevToolsProtocol;
- Command(int id, const std::string& domain, const std::string& method,
+ Command(int id, const std::string& method,
base::DictionaryValue* params);
int id_;
- std::string domain_;
- std::string method_;
- scoped_ptr<base::DictionaryValue> params_;
DISALLOW_COPY_AND_ASSIGN(Command);
};
@@ -85,37 +95,20 @@
DISALLOW_COPY_AND_ASSIGN(Response);
};
- class Notification {
+ class Notification : public Message {
public:
- // Takes ownership of |params|.
- Notification(const std::string& method, base::DictionaryValue* params);
- ~Notification();
+ virtual ~Notification();
- std::string Serialize();
-
- private:
- std::string method_;
- scoped_ptr<base::DictionaryValue> params_;
-
- DISALLOW_COPY_AND_ASSIGN(Notification);
- };
-
- class Event {
- public:
- ~Event();
-
- std::string Serialize();
+ virtual std::string Serialize() OVERRIDE;
private:
friend class DevToolsProtocol;
- // Takes ownership over |params|.
- Event(const std::string& method, base::DictionaryValue* params);
+ // Takes ownership of |params|.
+ Notification(const std::string& method,
+ base::DictionaryValue* params);
- std::string method_;
- scoped_ptr<base::DictionaryValue> params_;
-
- DISALLOW_COPY_AND_ASSIGN(Event);
+ DISALLOW_COPY_AND_ASSIGN(Notification);
};
class Handler {
@@ -152,10 +145,15 @@
static Command* ParseCommand(const std::string& json,
std::string* error_response);
- static Event* CreateEvent(const std::string& method,
- base::DictionaryValue* params);
+ static Notification* ParseNotification(const std::string& json);
+
+ static Notification* CreateNotification(const std::string& method,
+ base::DictionaryValue* params);
private:
+ static DictionaryValue* ParseMessage(const std::string& json,
+ std::string* error_response);
+
DevToolsProtocol() {}
~DevToolsProtocol() {}
};
diff --git a/content/browser/devtools/devtools_protocol_constants.cc b/content/browser/devtools/devtools_protocol_constants.cc
index 5f7c012..0ac7344 100644
--- a/content/browser/devtools/devtools_protocol_constants.cc
+++ b/content/browser/devtools/devtools_protocol_constants.cc
@@ -8,6 +8,9 @@
namespace devtools {
namespace Inspector {
+namespace detached {
+ const char kName[] = "Inspector.detached";
+} // detached
namespace targetCrashed {
const char kName[] = "Inspector.targetCrashed";
} // targetCrashed
@@ -30,8 +33,18 @@
const char kName[] = "Page.navigate";
const char kParamUrl[] = "url";
} // navigate
+namespace captureScreenshot {
+ const char kName[] = "Page.captureScreenshot";
+ const char kResponseData[] = "data";
+} // captureScreenshot
} // Page
+namespace Worker {
+namespace disconnectedFromWorker {
+ extern const char kName[] = "Worker.disconnectedFromWorker";
+} // disconnectedFromWorker
+} // Worker
+
} // devtools
} // content
diff --git a/content/browser/devtools/devtools_protocol_constants.h b/content/browser/devtools/devtools_protocol_constants.h
index 79d9726..5a37a3f 100644
--- a/content/browser/devtools/devtools_protocol_constants.h
+++ b/content/browser/devtools/devtools_protocol_constants.h
@@ -15,6 +15,9 @@
namespace devtools {
namespace Inspector {
+namespace detached {
+ extern const char kName[];
+} // detached
namespace targetCrashed {
extern const char kName[];
} // targetCrashed
@@ -37,8 +40,18 @@
extern const char kName[];
extern const char kParamUrl[];
} // navigate
+namespace captureScreenshot {
+ extern const char kName[];
+ extern const char kResponseData[];
+} // captureScreenshot
} // Page
+namespace Worker {
+namespace disconnectedFromWorker {
+ extern const char kName[];
+} // disconnectedFromWorker
+} // Worker
+
} // devtools
} // content
diff --git a/content/browser/devtools/devtools_resources.gyp b/content/browser/devtools/devtools_resources.gyp
index 9ee2076..39c09ae 100644
--- a/content/browser/devtools/devtools_resources.gyp
+++ b/content/browser/devtools/devtools_resources.gyp
@@ -17,7 +17,7 @@
'target_name': 'devtools_resources',
'type': 'none',
'dependencies': [
- '<(webkit_src_dir)/Source/WebKit/chromium/WebKit.gyp:generate_devtools_grd',
+ '<(webkit_src_dir)/Source/devtools/devtools.gyp:generate_devtools_grd',
],
'variables': {
'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/webkit',
diff --git a/content/browser/devtools/devtools_resources.target.darwin-arm.mk b/content/browser/devtools/devtools_resources.target.darwin-arm.mk
new file mode 100644
index 0000000..1d4262f
--- /dev/null
+++ b/content/browser/devtools/devtools_resources.target.darwin-arm.mk
@@ -0,0 +1,57 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_browser_devtools_devtools_resources_gyp
+LOCAL_MODULE_STEM := devtools_resources
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_generate_devtools_grd_gyp)/generate_devtools_grd.stamp
+
+### Rules for action "devtools_resources":
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+ @echo "Gyp action: Generating resources from $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd ($@)"
+ $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses
+
+$(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.h: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
+
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h \
+ $(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak \
+ $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc \
+ $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.h
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_browser_devtools_devtools_resources_gyp
+
+# Alias gyp target name.
+.PHONY: devtools_resources
+devtools_resources: content_browser_devtools_devtools_resources_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/browser/devtools/devtools_resources.target.darwin-x86.mk b/content/browser/devtools/devtools_resources.target.darwin-x86.mk
new file mode 100644
index 0000000..1d4262f
--- /dev/null
+++ b/content/browser/devtools/devtools_resources.target.darwin-x86.mk
@@ -0,0 +1,57 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_browser_devtools_devtools_resources_gyp
+LOCAL_MODULE_STEM := devtools_resources
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_generate_devtools_grd_gyp)/generate_devtools_grd.stamp
+
+### Rules for action "devtools_resources":
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+ @echo "Gyp action: Generating resources from $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd ($@)"
+ $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses
+
+$(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.h: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
+
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h \
+ $(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak \
+ $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc \
+ $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.h
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_browser_devtools_devtools_resources_gyp
+
+# Alias gyp target name.
+.PHONY: devtools_resources
+devtools_resources: content_browser_devtools_devtools_resources_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/browser/devtools/devtools_resources.target.linux-arm.mk b/content/browser/devtools/devtools_resources.target.linux-arm.mk
index 8685478..1d4262f 100644
--- a/content/browser/devtools/devtools_resources.target.linux-arm.mk
+++ b/content/browser/devtools/devtools_resources.target.linux-arm.mk
@@ -12,7 +12,7 @@
# Make sure our deps are built first.
GYP_TARGET_DEPENDENCIES := \
- $(call intermediates-dir-for,GYP,third_party_WebKit_Source_WebKit_chromium_generate_devtools_grd_gyp)/generate_devtools_grd.stamp
+ $(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_generate_devtools_grd_gyp)/generate_devtools_grd.stamp
### Rules for action "devtools_resources":
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
@@ -21,7 +21,7 @@
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd ($@)"
- $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android
+ $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses
$(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
diff --git a/content/browser/devtools/devtools_resources.target.linux-x86.mk b/content/browser/devtools/devtools_resources.target.linux-x86.mk
index 8685478..1d4262f 100644
--- a/content/browser/devtools/devtools_resources.target.linux-x86.mk
+++ b/content/browser/devtools/devtools_resources.target.linux-x86.mk
@@ -12,7 +12,7 @@
# Make sure our deps are built first.
GYP_TARGET_DEPENDENCIES := \
- $(call intermediates-dir-for,GYP,third_party_WebKit_Source_WebKit_chromium_generate_devtools_grd_gyp)/generate_devtools_grd.stamp
+ $(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_generate_devtools_grd_gyp)/generate_devtools_grd.stamp
### Rules for action "devtools_resources":
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
@@ -21,7 +21,7 @@
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd ($@)"
- $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android
+ $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses
$(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
diff --git a/content/browser/devtools/devtools_tracing_handler.cc b/content/browser/devtools/devtools_tracing_handler.cc
index 5caa2e3..5605c27 100644
--- a/content/browser/devtools/devtools_tracing_handler.cc
+++ b/content/browser/devtools/devtools_tracing_handler.cc
@@ -6,7 +6,6 @@
#include "base/bind.h"
#include "base/callback.h"
-#include "base/json/json_writer.h"
#include "base/location.h"
#include "base/strings/string_split.h"
#include "base/values.h"
@@ -104,7 +103,6 @@
return command->SuccessResponse(NULL);
}
-
scoped_ptr<DevToolsProtocol::Response>
DevToolsTracingHandler::OnEnd(DevToolsProtocol::Command* command) {
TraceController::GetInstance()->EndTracingAsync(this);
diff --git a/content/browser/devtools/devtools_tracing_handler.h b/content/browser/devtools/devtools_tracing_handler.h
index 86ddf00..64f1af7 100644
--- a/content/browser/devtools/devtools_tracing_handler.h
+++ b/content/browser/devtools/devtools_tracing_handler.h
@@ -11,8 +11,6 @@
namespace content {
-class DevToolsWebSocketSender;
-
// This class bridges DevTools remote debugging server with the trace
// infrastructure.
class DevToolsTracingHandler
diff --git a/content/browser/devtools/ipc_devtools_agent_host.cc b/content/browser/devtools/ipc_devtools_agent_host.cc
new file mode 100644
index 0000000..c7cd3c3
--- /dev/null
+++ b/content/browser/devtools/ipc_devtools_agent_host.cc
@@ -0,0 +1,42 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/devtools/ipc_devtools_agent_host.h"
+
+#include "content/common/devtools_messages.h"
+
+namespace content {
+
+void IPCDevToolsAgentHost::Attach() {
+ SendMessageToAgent(new DevToolsAgentMsg_Attach(MSG_ROUTING_NONE));
+ OnClientAttached();
+}
+
+void IPCDevToolsAgentHost::Detach() {
+ SendMessageToAgent(new DevToolsAgentMsg_Detach(MSG_ROUTING_NONE));
+ OnClientDetached();
+}
+
+void IPCDevToolsAgentHost::DispatchOnInspectorBackend(
+ const std::string& message) {
+ SendMessageToAgent(new DevToolsAgentMsg_DispatchOnInspectorBackend(
+ MSG_ROUTING_NONE, message));
+}
+
+void IPCDevToolsAgentHost::InspectElement(int x, int y) {
+ SendMessageToAgent(new DevToolsAgentMsg_InspectElement(MSG_ROUTING_NONE,
+ x, y));
+}
+
+IPCDevToolsAgentHost::~IPCDevToolsAgentHost() {
+}
+
+void IPCDevToolsAgentHost::Reattach(const std::string& saved_agent_state) {
+ SendMessageToAgent(new DevToolsAgentMsg_Reattach(
+ MSG_ROUTING_NONE,
+ saved_agent_state));
+ OnClientAttached();
+}
+
+} // namespace content
diff --git a/content/browser/devtools/ipc_devtools_agent_host.h b/content/browser/devtools/ipc_devtools_agent_host.h
new file mode 100644
index 0000000..98c2794
--- /dev/null
+++ b/content/browser/devtools/ipc_devtools_agent_host.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DEVTOOLS_IPC_DEVTOOLS_AGENT_HOST_H_
+#define CONTENT_BROWSER_DEVTOOLS_IPC_DEVTOOLS_AGENT_HOST_H_
+
+#include "content/browser/devtools/devtools_agent_host_impl.h"
+
+namespace IPC {
+class Message;
+}
+
+namespace content {
+
+class CONTENT_EXPORT IPCDevToolsAgentHost : public DevToolsAgentHostImpl {
+ public:
+ // DevToolsAgentHostImpl implementation.
+ virtual void Attach() OVERRIDE;
+ virtual void Detach() OVERRIDE;
+ virtual void DispatchOnInspectorBackend(const std::string& message) OVERRIDE;
+ virtual void InspectElement(int x, int y) OVERRIDE;
+
+ protected:
+ virtual ~IPCDevToolsAgentHost();
+
+ void Reattach(const std::string& saved_agent_state);
+
+ virtual void SendMessageToAgent(IPC::Message* msg) = 0;
+ virtual void OnClientAttached() = 0;
+ virtual void OnClientDetached() = 0;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DEVTOOLS_IPC_DEVTOOLS_AGENT_HOST_H_
diff --git a/content/browser/devtools/render_view_devtools_agent_host.cc b/content/browser/devtools/render_view_devtools_agent_host.cc
index 91f17a1..39698d3 100644
--- a/content/browser/devtools/render_view_devtools_agent_host.cc
+++ b/content/browser/devtools/render_view_devtools_agent_host.cc
@@ -4,7 +4,6 @@
#include "content/browser/devtools/render_view_devtools_agent_host.h"
-#include "base/base64.h"
#include "base/basictypes.h"
#include "base/lazy_instance.h"
#include "content/browser/child_process_security_policy_impl.h"
@@ -20,12 +19,6 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
-#include "content/public/browser/render_widget_host_view.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebDevToolsAgent.h"
-#include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/snapshot/snapshot.h"
-
namespace content {
@@ -47,8 +40,6 @@
} // namespace
-using WebKit::WebDevToolsAgent;
-
class RenderViewDevToolsAgentHost::DevToolsAgentHostRvhObserver
: public RenderViewHostObserver {
public:
@@ -99,7 +90,7 @@
RenderViewHost* rvh = (*it)->render_view_host_;
if (rvh && rvh->GetDelegate() != delegate)
continue;
- if (devtools_manager->GetDevToolsClientHostFor(*it))
+ if ((*it)->IsAttached())
return true;
}
return false;
@@ -193,17 +184,16 @@
std::string error_message;
scoped_ptr<DevToolsProtocol::Command> command(
DevToolsProtocol::ParseCommand(message, &error_message));
- if (!command) {
- OnDispatchOnInspectorFrontend(error_message);
- return;
+ if (command) {
+ scoped_ptr<DevToolsProtocol::Response> overridden_response(
+ overrides_handler_->HandleCommand(command.get()));
+ if (overridden_response) {
+ OnDispatchOnInspectorFrontend(overridden_response->Serialize());
+ return;
+ }
}
- scoped_ptr<DevToolsProtocol::Response> overridden_response(
- overrides_handler_->HandleCommand(command.get()));
- if (overridden_response)
- OnDispatchOnInspectorFrontend(overridden_response->Serialize());
- else
- DevToolsAgentHostImpl::DispatchOnInspectorBackend(message);
+ IPCDevToolsAgentHost::DispatchOnInspectorBackend(message);
}
void RenderViewDevToolsAgentHost::SendMessageToAgent(IPC::Message* msg) {
@@ -213,31 +203,23 @@
render_view_host_->Send(msg);
}
-void RenderViewDevToolsAgentHost::NotifyClientAttaching() {
+void RenderViewDevToolsAgentHost::OnClientAttached() {
if (!render_view_host_)
return;
ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadRawCookies(
render_view_host_->GetProcess()->GetID());
-
- NotificationService::current()->Notify(
- NOTIFICATION_DEVTOOLS_AGENT_ATTACHED,
- Source<BrowserContext>(
- render_view_host_->GetSiteInstance()->GetProcess()->
- GetBrowserContext()),
- Details<RenderViewHost>(render_view_host_));
}
-void RenderViewDevToolsAgentHost::NotifyClientDetaching() {
+void RenderViewDevToolsAgentHost::OnClientDetached() {
if (!render_view_host_)
return;
- DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
bool process_has_agents = false;
RenderProcessHost* render_process_host = render_view_host_->GetProcess();
for (Instances::iterator it = g_instances.Get().begin();
it != g_instances.Get().end(); ++it) {
- if (*it == this || !devtools_manager->GetDevToolsClientHostFor(*it))
+ if (*it == this || !(*it)->IsAttached())
continue;
RenderViewHost* rvh = (*it)->render_view_host();
if (rvh && rvh->GetProcess() == render_process_host)
@@ -249,13 +231,6 @@
ChildProcessSecurityPolicyImpl::GetInstance()->RevokeReadRawCookies(
render_process_host->GetID());
}
-
- NotificationService::current()->Notify(
- NOTIFICATION_DEVTOOLS_AGENT_DETACHED,
- Source<BrowserContext>(
- render_view_host_->GetSiteInstance()->GetProcess()->
- GetBrowserContext()),
- Details<RenderViewHost>(render_view_host_));
}
RenderViewDevToolsAgentHost::~RenderViewDevToolsAgentHost() {
@@ -301,7 +276,7 @@
}
void RenderViewDevToolsAgentHost::DisconnectRenderViewHost() {
- NotifyClientDetaching();
+ OnClientDetached();
rvh_observer_.reset();
render_view_host_ = NULL;
}
@@ -316,11 +291,11 @@
}
void RenderViewDevToolsAgentHost::RenderViewCrashed() {
- scoped_ptr<DevToolsProtocol::Event> event(
- DevToolsProtocol::CreateEvent(
+ scoped_ptr<DevToolsProtocol::Notification> notification(
+ DevToolsProtocol::CreateNotification(
devtools::Inspector::targetCrashed::kName, NULL));
DevToolsManagerImpl::GetInstance()->
- DispatchOnInspectorFrontend(this, event->Serialize());
+ DispatchOnInspectorFrontend(this, notification->Serialize());
}
bool RenderViewDevToolsAgentHost::OnRvhMessageReceived(
@@ -350,38 +325,8 @@
const std::string& message) {
if (!render_view_host_)
return;
-
- WebDevToolsAgent::BrowserDataHint dataHint =
- WebDevToolsAgent::shouldPatchWithBrowserData(message.data(),
- message.length());
- if (dataHint == WebDevToolsAgent::BrowserDataHintNone) {
- DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(
- this, message);
- return;
- }
-
- // Prepare the data and patch message with it.
- std::string overriden_message;
- switch (dataHint) {
- case WebDevToolsAgent::BrowserDataHintScreenshot:
- {
- std::string base_64_data;
- if (CaptureScreenshot(&base_64_data)) {
- overriden_message = WebDevToolsAgent::patchWithBrowserData(
- WebKit::WebString::fromUTF8(message),
- dataHint,
- WebKit::WebString::fromUTF8(base_64_data)).utf8();
- }
- break;
- }
- case WebDevToolsAgent::BrowserDataHintNone:
- // Fall through.
- default:
- overriden_message = message;
- }
-
DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(
- this, overriden_message);
+ this, message);
}
void RenderViewDevToolsAgentHost::OnClearBrowserCache() {
@@ -394,21 +339,4 @@
GetContentClient()->browser()->ClearCookies(render_view_host_);
}
-bool RenderViewDevToolsAgentHost::CaptureScreenshot(std::string* base_64_data) {
- DCHECK(render_view_host_);
- gfx::Rect view_bounds = render_view_host_->GetView()->GetViewBounds();
- gfx::Rect snapshot_bounds(view_bounds.size());
- gfx::Size snapshot_size = snapshot_bounds.size();
- std::vector<unsigned char> png;
- if (!ui::GrabViewSnapshot(render_view_host_->GetView()->GetNativeView(),
- &png,
- snapshot_bounds))
- return false;
-
- return base::Base64Encode(base::StringPiece(
- reinterpret_cast<char*>(&*png.begin()),
- png.size()),
- base_64_data);
-}
-
} // namespace content
diff --git a/content/browser/devtools/render_view_devtools_agent_host.h b/content/browser/devtools/render_view_devtools_agent_host.h
index 436776b..bac4064 100644
--- a/content/browser/devtools/render_view_devtools_agent_host.h
+++ b/content/browser/devtools/render_view_devtools_agent_host.h
@@ -10,7 +10,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
-#include "content/browser/devtools/devtools_agent_host_impl.h"
+#include "content/browser/devtools/ipc_devtools_agent_host.h"
#include "content/common/content_export.h"
#include "content/public/browser/render_view_host_observer.h"
#include "content/public/browser/web_contents_observer.h"
@@ -21,7 +21,7 @@
class RenderViewHost;
class CONTENT_EXPORT RenderViewDevToolsAgentHost
- : public DevToolsAgentHostImpl,
+ : public IPCDevToolsAgentHost,
private WebContentsObserver {
public:
static void OnCancelPendingNavigation(RenderViewHost* pending,
@@ -40,11 +40,11 @@
// DevTooolsAgentHost overrides.
virtual RenderViewHost* GetRenderViewHost() OVERRIDE;
- // DevToolsAgentHostImpl overrides.
+ // IPCDevToolsAgentHost overrides.
virtual void DispatchOnInspectorBackend(const std::string& message) OVERRIDE;
virtual void SendMessageToAgent(IPC::Message* msg) OVERRIDE;
- virtual void NotifyClientAttaching() OVERRIDE;
- virtual void NotifyClientDetaching() OVERRIDE;
+ virtual void OnClientAttached() OVERRIDE;
+ virtual void OnClientDetached() OVERRIDE;
// WebContentsObserver overrides.
virtual void AboutToNavigateRenderView(RenderViewHost* dest_rvh) OVERRIDE;
@@ -62,8 +62,6 @@
void OnClearBrowserCache();
void OnClearBrowserCookies();
- bool CaptureScreenshot(std::string* base_64_data);
-
RenderViewHost* render_view_host_;
scoped_ptr<DevToolsAgentHostRvhObserver> rvh_observer_;
scoped_ptr<RendererOverridesHandler> overrides_handler_;
diff --git a/content/browser/devtools/renderer_overrides_handler.cc b/content/browser/devtools/renderer_overrides_handler.cc
index 0531f8b..7b736e3 100644
--- a/content/browser/devtools/renderer_overrides_handler.cc
+++ b/content/browser/devtools/renderer_overrides_handler.cc
@@ -6,11 +6,11 @@
#include <string>
+#include "base/base64.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
#include "base/string16.h"
-#include "base/stringprintf.h"
#include "base/values.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/devtools/devtools_protocol_constants.h"
@@ -20,11 +20,13 @@
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/page_transition_types.h"
#include "content/public/common/referrer.h"
#include "googleurl/src/gurl.h"
+#include "ui/snapshot/snapshot.h"
namespace content {
@@ -45,6 +47,11 @@
base::Bind(
&RendererOverridesHandler::PageNavigate,
base::Unretained(this)));
+ RegisterCommandHandler(
+ devtools::Page::captureScreenshot::kName,
+ base::Bind(
+ &RendererOverridesHandler::PageCaptureScreenshot,
+ base::Unretained(this)));
}
RendererOverridesHandler::~RendererOverridesHandler() {}
@@ -56,22 +63,16 @@
base::ListValue* file_list = NULL;
const char* param =
devtools::DOM::setFileInputFiles::kParamFiles;
- if (!params || !params->GetList(param, &file_list)) {
- return command->ErrorResponse(
- DevToolsProtocol::kErrorInvalidParams,
- base::StringPrintf("Missing or invalid '%s' parameter", param));
- }
+ if (!params || !params->GetList(param, &file_list))
+ return command->InvalidParamResponse(param);
RenderViewHost* host = agent_->GetRenderViewHost();
if (!host)
return scoped_ptr<DevToolsProtocol::Response>();
for (size_t i = 0; i < file_list->GetSize(); ++i) {
base::FilePath::StringType file;
- if (!file_list->GetString(i, &file)) {
- return command->ErrorResponse(
- DevToolsProtocol::kErrorInvalidParams,
- base::StringPrintf("'%s' must be a list of strings", param));
- }
+ if (!file_list->GetString(i, &file))
+ return command->InvalidParamResponse(param);
ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
host->GetProcess()->GetID(), base::FilePath(file));
}
@@ -85,11 +86,8 @@
const char* paramAccept =
devtools::Page::handleJavaScriptDialog::kParamAccept;
bool accept;
- if (!params || !params->GetBoolean(paramAccept, &accept)) {
- return command->ErrorResponse(
- DevToolsProtocol::kErrorInvalidParams,
- base::StringPrintf("Missing or invalid '%s' parameter", paramAccept));
- }
+ if (!params || !params->GetBoolean(paramAccept, &accept))
+ return command->InvalidParamResponse(paramAccept);
string16 prompt_override;
string16* prompt_override_ptr = &prompt_override;
if (!params || !params->GetString(
@@ -110,9 +108,7 @@
}
}
}
- return command->ErrorResponse(
- DevToolsProtocol::kErrorInternalError,
- "No JavaScript dialog to handle");
+ return command->InternalErrorResponse("No JavaScript dialog to handle");
}
scoped_ptr<DevToolsProtocol::Response>
@@ -121,30 +117,52 @@
base::DictionaryValue* params = command->params();
std::string url;
const char* param = devtools::Page::navigate::kParamUrl;
- if (!params || !params->GetString(param, &url)) {
- return command->ErrorResponse(
- DevToolsProtocol::kErrorInvalidParams,
- base::StringPrintf("Missing or invalid '%s' parameter",
- param));
- }
+ if (!params || !params->GetString(param, &url))
+ return command->InvalidParamResponse(param);
GURL gurl(url);
if (!gurl.is_valid()) {
- return command->ErrorResponse(
- DevToolsProtocol::kErrorInternalError,
- "Cannot navigate to invalid URL");
+ return command->InternalErrorResponse("Cannot navigate to invalid URL");
}
RenderViewHost* host = agent_->GetRenderViewHost();
if (host) {
WebContents* web_contents = host->GetDelegate()->GetAsWebContents();
if (web_contents) {
- web_contents->GetController().LoadURL(
- gurl, Referrer(), PAGE_TRANSITION_TYPED, "");
+ web_contents->GetController()
+ .LoadURL(gurl, Referrer(), PAGE_TRANSITION_TYPED, std::string());
return command->SuccessResponse(new base::DictionaryValue());
}
}
- return command->ErrorResponse(
- DevToolsProtocol::kErrorInternalError,
- "No WebContents to navigate");
+ return command->InternalErrorResponse("No WebContents to navigate");
+}
+
+scoped_ptr<DevToolsProtocol::Response>
+RendererOverridesHandler::PageCaptureScreenshot(
+ DevToolsProtocol::Command* command) {
+ std::string base_64_data;
+ if (!CaptureScreenshot(&base_64_data))
+ return command->InternalErrorResponse("Unable to capture a screenshot");
+
+ base::DictionaryValue* response = new base::DictionaryValue();
+ response->SetString(
+ devtools::Page::captureScreenshot::kResponseData, base_64_data);
+ return command->SuccessResponse(response);
+}
+
+bool RendererOverridesHandler::CaptureScreenshot(std::string* base_64_data) {
+ RenderViewHost* host = agent_->GetRenderViewHost();
+ gfx::Rect view_bounds = host->GetView()->GetViewBounds();
+ gfx::Rect snapshot_bounds(view_bounds.size());
+ gfx::Size snapshot_size = snapshot_bounds.size();
+ std::vector<unsigned char> png;
+ if (!ui::GrabViewSnapshot(host->GetView()->GetNativeView(),
+ &png,
+ snapshot_bounds))
+ return false;
+
+ return base::Base64Encode(base::StringPiece(
+ reinterpret_cast<char*>(&*png.begin()),
+ png.size()),
+ base_64_data);
}
} // namespace content
diff --git a/content/browser/devtools/renderer_overrides_handler.h b/content/browser/devtools/renderer_overrides_handler.h
index cf3989d..e175f05 100644
--- a/content/browser/devtools/renderer_overrides_handler.h
+++ b/content/browser/devtools/renderer_overrides_handler.h
@@ -29,6 +29,10 @@
DevToolsProtocol::Command* command);
scoped_ptr<DevToolsProtocol::Response> PageNavigate(
DevToolsProtocol::Command* command);
+ scoped_ptr<DevToolsProtocol::Response> PageCaptureScreenshot(
+ DevToolsProtocol::Command* command);
+
+ bool CaptureScreenshot(std::string* base_64_data);
DevToolsAgentHost* agent_;
diff --git a/content/browser/devtools/tethering_handler.cc b/content/browser/devtools/tethering_handler.cc
new file mode 100644
index 0000000..bad1ded
--- /dev/null
+++ b/content/browser/devtools/tethering_handler.cc
@@ -0,0 +1,306 @@
+// 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/devtools/tethering_handler.h"
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/stl_util.h"
+#include "base/values.h"
+#include "content/browser/devtools/devtools_http_handler_impl.h"
+#include "content/public/browser/devtools_client_host.h"
+#include "content/public/browser/devtools_http_handler_delegate.h"
+#include "net/base/io_buffer.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_log.h"
+#include "net/socket/stream_listen_socket.h"
+#include "net/socket/stream_socket.h"
+#include "net/socket/tcp_server_socket.h"
+
+namespace content {
+
+namespace {
+
+const char kTetheringBind[] = "Tethering.bind";
+const char kTetheringUnbind[] = "Tethering.unbind";
+
+const char kTetheringAccepted[] = "Tethering.accepted";
+
+const char kPortParam[] = "port";
+const char kConnectionIdParam[] = "connectionId";
+
+const char kLocalhost[] = "127.0.0.1";
+
+const int kListenBacklog = 5;
+const int kBufferSize = 16 * 1024;
+
+const int kMinTetheringPort = 5000;
+const int kMaxTetheringPort = 10000;
+
+class SocketPump : public net::StreamListenSocket::Delegate {
+ public:
+ SocketPump(DevToolsHttpHandlerDelegate* delegate,
+ net::StreamSocket* client_socket)
+ : client_socket_(client_socket),
+ delegate_(delegate),
+ wire_buffer_size_(0),
+ pending_destruction_(false) {
+ }
+
+ std::string Init() {
+ std::string channel_name;
+ server_socket_ = delegate_->CreateSocketForTethering(this, &channel_name);
+ if (!server_socket_ || channel_name.empty())
+ SelfDestruct();
+ return channel_name;
+ }
+
+ virtual ~SocketPump() { }
+
+ private:
+ virtual void DidAccept(net::StreamListenSocket* server,
+ net::StreamListenSocket* socket) OVERRIDE {
+ if (accepted_socket_)
+ return;
+
+ buffer_ = new net::IOBuffer(kBufferSize);
+ wire_buffer_ = new net::GrowableIOBuffer();
+ wire_buffer_->SetCapacity(kBufferSize);
+
+ accepted_socket_ = socket;
+ int result = client_socket_->Read(buffer_, kBufferSize,
+ base::Bind(&SocketPump::OnClientRead,
+ base::Unretained(this)));
+ if (result != net::ERR_IO_PENDING)
+ OnClientRead(result);
+ }
+
+ virtual void DidRead(net::StreamListenSocket* socket,
+ const char* data,
+ int len) OVERRIDE {
+ int old_size = wire_buffer_size_;
+ wire_buffer_size_ += len;
+ while (wire_buffer_->capacity() < wire_buffer_size_)
+ wire_buffer_->SetCapacity(wire_buffer_->capacity() * 2);
+ memcpy(wire_buffer_->StartOfBuffer() + old_size, data, len);
+ if (old_size != wire_buffer_->offset())
+ return;
+ OnClientWrite(0);
+ }
+
+ virtual void DidClose(net::StreamListenSocket* socket) OVERRIDE {
+ SelfDestruct();
+ }
+
+ void OnClientRead(int result) {
+ if (result <= 0) {
+ SelfDestruct();
+ return;
+ }
+
+ accepted_socket_->Send(buffer_->data(), result);
+ result = client_socket_->Read(buffer_, kBufferSize,
+ base::Bind(&SocketPump::OnClientRead,
+ base::Unretained(this)));
+ if (result != net::ERR_IO_PENDING)
+ OnClientRead(result);
+ }
+
+ void OnClientWrite(int result) {
+ if (result < 0)
+ SelfDestruct();
+
+ wire_buffer_->set_offset(wire_buffer_->offset() + result);
+
+ int remaining = wire_buffer_size_ - wire_buffer_->offset();
+ if (remaining == 0) {
+ if (pending_destruction_)
+ SelfDestruct();
+ return;
+ }
+
+
+ if (remaining > kBufferSize)
+ remaining = kBufferSize;
+
+ scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(remaining);
+ memcpy(buffer->data(), wire_buffer_->data(), remaining);
+ result = client_socket_->Write(
+ buffer, remaining, base::Bind(&SocketPump::OnClientWrite,
+ base::Unretained(this)));
+
+ // Shrink buffer
+ int offset = wire_buffer_->offset();
+ if (offset > kBufferSize) {
+ memcpy(wire_buffer_->StartOfBuffer(), wire_buffer_->data(),
+ wire_buffer_size_ - offset);
+ wire_buffer_size_ -= offset;
+ wire_buffer_->set_offset(0);
+ }
+
+ if (result != net::ERR_IO_PENDING)
+ OnClientWrite(result);
+ return;
+ }
+
+ void SelfDestruct() {
+ if (wire_buffer_->offset() != wire_buffer_size_) {
+ pending_destruction_ = true;
+ return;
+ }
+ delete this;
+ }
+
+ private:
+ scoped_ptr<net::StreamSocket> client_socket_;
+ scoped_refptr<net::StreamListenSocket> server_socket_;
+ scoped_refptr<net::StreamListenSocket> accepted_socket_;
+ scoped_refptr<net::IOBuffer> buffer_;
+ scoped_refptr<net::GrowableIOBuffer> wire_buffer_;
+ DevToolsHttpHandlerDelegate* delegate_;
+ int wire_buffer_size_;
+ bool pending_destruction_;
+};
+
+} // namespace
+
+const char TetheringHandler::kDomain[] = "Tethering";
+
+class TetheringHandler::BoundSocket {
+ public:
+ BoundSocket(TetheringHandler* handler,
+ DevToolsHttpHandlerDelegate* delegate)
+ : handler_(handler),
+ delegate_(delegate),
+ socket_(new net::TCPServerSocket(NULL, net::NetLog::Source())),
+ port_(0) {
+ }
+
+ virtual ~BoundSocket() {
+ }
+
+ bool Listen(int port) {
+ port_ = port;
+ net::IPAddressNumber ip_number;
+ if (!net::ParseIPLiteralToNumber(kLocalhost, &ip_number))
+ return false;
+
+ net::IPEndPoint end_point(ip_number, port);
+ socket_->AllowAddressReuse();
+ int result = socket_->Listen(end_point, kListenBacklog);
+ if (result < 0)
+ return false;
+
+ net::IPEndPoint local_address;
+ result = socket_->GetLocalAddress(&local_address);
+ if (result < 0)
+ return false;
+
+ DoAccept();
+ return true;
+ }
+
+ private:
+ typedef std::map<net::IPEndPoint, net::StreamSocket*> AcceptedSocketsMap;
+
+ void DoAccept() {
+ while (true) {
+ int result = socket_->Accept(
+ &accept_socket_,
+ base::Bind(&BoundSocket::OnAccepted, base::Unretained(this)));
+ if (result == net::ERR_IO_PENDING)
+ break;
+ else
+ HandleAcceptResult(result);
+ }
+ }
+
+ void OnAccepted(int result) {
+ HandleAcceptResult(result);
+ if (result == net::OK)
+ DoAccept();
+ }
+
+ void HandleAcceptResult(int result) {
+ if (result != net::OK)
+ return;
+
+ SocketPump* pump = new SocketPump(delegate_, accept_socket_.release());
+ std::string name = pump->Init();
+ if (!name.empty())
+ handler_->Accepted(port_, name);
+ }
+
+ TetheringHandler* handler_;
+ DevToolsHttpHandlerDelegate* delegate_;
+ scoped_ptr<net::ServerSocket> socket_;
+ scoped_ptr<net::StreamSocket> accept_socket_;
+ int port_;
+};
+
+TetheringHandler::TetheringHandler(DevToolsHttpHandlerDelegate* delegate)
+ : delegate_(delegate) {
+ RegisterCommandHandler(kTetheringBind,
+ base::Bind(&TetheringHandler::OnBind,
+ base::Unretained(this)));
+ RegisterCommandHandler(kTetheringUnbind,
+ base::Bind(&TetheringHandler::OnUnbind,
+ base::Unretained(this)));
+}
+
+TetheringHandler::~TetheringHandler() {
+ STLDeleteContainerPairSecondPointers(bound_sockets_.begin(),
+ bound_sockets_.end());
+}
+
+void TetheringHandler::Accepted(int port, const std::string& name) {
+ base::DictionaryValue* params = new base::DictionaryValue();
+ params->SetInteger(kPortParam, port);
+ params->SetString(kConnectionIdParam, name);
+ SendNotification(kTetheringAccepted, params);
+}
+
+static int GetPort(DevToolsProtocol::Command* command) {
+ base::DictionaryValue* params = command->params();
+ int port = 0;
+ if (!params || !params->GetInteger(kPortParam, &port) ||
+ port < kMinTetheringPort || port > kMaxTetheringPort)
+ return 0;
+ return port;
+}
+
+scoped_ptr<DevToolsProtocol::Response>
+TetheringHandler::OnBind(DevToolsProtocol::Command* command) {
+ int port = GetPort(command);
+ if (port == 0)
+ return command->InvalidParamResponse(kPortParam);
+
+ if (bound_sockets_.find(port) != bound_sockets_.end())
+ return command->InternalErrorResponse("Port already bound");
+
+ scoped_ptr<BoundSocket> bound_socket(new BoundSocket(this, delegate_));
+ if (!bound_socket->Listen(port))
+ return command->InternalErrorResponse("Could not bind port");
+
+ bound_sockets_[port] = bound_socket.release();
+ return command->SuccessResponse(NULL);
+}
+
+scoped_ptr<DevToolsProtocol::Response>
+TetheringHandler::OnUnbind(DevToolsProtocol::Command* command) {
+ int port = GetPort(command);
+ if (port == 0)
+ return command->InvalidParamResponse(kPortParam);
+
+ BoundSockets::iterator it = bound_sockets_.find(port);
+ if (it == bound_sockets_.end())
+ return command->InternalErrorResponse("Port is not bound");
+
+ delete it->second;
+ bound_sockets_.erase(it);
+ return command->SuccessResponse(NULL);
+}
+
+} // namespace content
diff --git a/content/browser/devtools/tethering_handler.h b/content/browser/devtools/tethering_handler.h
new file mode 100644
index 0000000..a9931cc
--- /dev/null
+++ b/content/browser/devtools/tethering_handler.h
@@ -0,0 +1,41 @@
+// 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_DEVTOOLS_TETHERING_HANDLER_H_
+#define CONTENT_BROWSER_DEVTOOLS_TETHERING_HANDLER_H_
+
+#include <map>
+
+#include "content/browser/devtools/devtools_protocol.h"
+
+namespace content {
+
+class DevToolsHttpHandlerDelegate;
+
+// This class implements reversed tethering handler.
+class TetheringHandler : public DevToolsProtocol::Handler {
+ public:
+ static const char kDomain[];
+
+ TetheringHandler(DevToolsHttpHandlerDelegate* delegate);
+ virtual ~TetheringHandler();
+
+ void Accepted(int port, const std::string& name);
+
+ private:
+ class BoundSocket;
+ scoped_ptr<DevToolsProtocol::Response> OnBind(
+ DevToolsProtocol::Command* command);
+ scoped_ptr<DevToolsProtocol::Response> OnUnbind(
+ DevToolsProtocol::Command* command);
+
+ typedef std::map<int, BoundSocket*> BoundSockets;
+ BoundSockets bound_sockets_;
+ DevToolsHttpHandlerDelegate* delegate_;
+ DISALLOW_COPY_AND_ASSIGN(TetheringHandler);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DEVTOOLS_TETHERING_HANDLER_H_
diff --git a/content/browser/devtools/worker_devtools_manager.cc b/content/browser/devtools/worker_devtools_manager.cc
index ae32629..97bfda7 100644
--- a/content/browser/devtools/worker_devtools_manager.cc
+++ b/content/browser/devtools/worker_devtools_manager.cc
@@ -9,8 +9,10 @@
#include "base/bind.h"
#include "base/lazy_instance.h"
-#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/devtools_manager_impl.h"
+#include "content/browser/devtools/devtools_protocol.h"
+#include "content/browser/devtools/devtools_protocol_constants.h"
+#include "content/browser/devtools/ipc_devtools_agent_host.h"
#include "content/browser/devtools/worker_devtools_message_filter.h"
#include "content/browser/worker_host/worker_service_impl.h"
#include "content/common/devtools_messages.h"
@@ -56,16 +58,17 @@
class WorkerDevToolsManager::WorkerDevToolsAgentHost
- : public DevToolsAgentHostImpl {
+ : public IPCDevToolsAgentHost {
public:
explicit WorkerDevToolsAgentHost(WorkerId worker_id)
: has_worker_id_(false) {
SetWorkerId(worker_id, false);
- AddRef(); // Balanced in ResetWorkerId.
}
void SetWorkerId(WorkerId worker_id, bool reattach) {
worker_id_ = worker_id;
+ if (!has_worker_id_)
+ AddRef(); // Balanced in ResetWorkerId.
has_worker_id_ = true;
g_agent_map.Get()[worker_id_] = this;
@@ -84,7 +87,7 @@
void ResetWorkerId() {
g_agent_map.Get().erase(worker_id_);
has_worker_id_ = false;
- Release();
+ Release(); // Balanced in SetWorkerId.
}
void SaveAgentRuntimeState(const std::string& state) {
@@ -97,10 +100,7 @@
}
private:
- virtual ~WorkerDevToolsAgentHost() {
- g_agent_map.Get().erase(worker_id_);
- g_orphan_map.Get().erase(worker_id_);
- }
+ virtual ~WorkerDevToolsAgentHost();
static void ConnectToWorker(
int worker_process_id,
@@ -117,7 +117,7 @@
worker_process_id, worker_route_id, *message);
}
- // DevToolsAgentHostImpl implementation.
+ // IPCDevToolsAgentHost implementation.
virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE {
if (!has_worker_id_) {
delete message;
@@ -132,8 +132,8 @@
base::Owned(message)));
}
- virtual void NotifyClientAttaching() OVERRIDE {}
- virtual void NotifyClientDetaching() OVERRIDE {}
+ virtual void OnClientAttached() OVERRIDE {}
+ virtual void OnClientDetached() OVERRIDE {}
bool has_worker_id_;
WorkerId worker_id_;
@@ -166,33 +166,30 @@
WorkerDevToolsAgentHost* agent = it->second;
DevToolsManagerImpl* devtools_manager = DevToolsManagerImpl::GetInstance();
- DevToolsClientHost* client_host =
- devtools_manager->GetDevToolsClientHostFor(agent);
-
- if (!client_host) {
+ if (!agent->IsAttached()) {
// Agent has no client hosts -> delete it.
RemovePendingWorkerData(id);
return;
}
// Client host is debugging this worker agent host.
- devtools_manager->DispatchOnInspectorFrontend(
- agent,
- WebDevToolsAgent::workerDisconnectedFromWorkerEvent().utf8());
+ std::string notification = DevToolsProtocol::CreateNotification(
+ devtools::Worker::disconnectedFromWorker::kName, NULL)->Serialize();
+ devtools_manager->DispatchOnInspectorFrontend(agent, notification);
g_orphan_map.Get()[id] = agent;
agent->ResetWorkerId();
}
- private:
- DetachedClientHosts() {}
- ~DetachedClientHosts() {}
-
static void RemovePendingWorkerData(WorkerId id) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&RemoveInspectedWorkerDataOnIOThread, id));
}
+ private:
+ DetachedClientHosts() {}
+ ~DetachedClientHosts() {}
+
static void RemoveInspectedWorkerDataOnIOThread(WorkerId id) {
WorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(id);
}
@@ -444,4 +441,10 @@
process->Send(new DevToolsAgentMsg_ResumeWorkerContext(id.second));
}
+WorkerDevToolsManager::WorkerDevToolsAgentHost::~WorkerDevToolsAgentHost() {
+ DetachedClientHosts::RemovePendingWorkerData(worker_id_);
+ g_agent_map.Get().erase(worker_id_);
+ g_orphan_map.Get().erase(worker_id_);
+}
+
} // namespace content
diff --git a/content/browser/download/base_file.cc b/content/browser/download/base_file.cc
index b5ded45..687c321 100644
--- a/content/browser/download/base_file.cc
+++ b/content/browser/download/base_file.cc
@@ -67,7 +67,7 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
DCHECK(!detached_);
- if (file_stream_.get()) {
+ if (file_stream_) {
file_stream_->SetBoundNetLogSource(bound_net_log_);
file_stream_->EnableErrorStatistics();
}
@@ -103,7 +103,7 @@
if (detached_)
RecordDownloadCount(APPEND_TO_DETACHED_FILE_COUNT);
- if (!file_stream_.get())
+ if (!file_stream_)
return LogInterruptReason("No file stream on append", 0,
DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
@@ -232,11 +232,11 @@
std::string BaseFile::GetHashState() {
if (!calculate_hash_)
- return "";
+ return std::string();
Pickle hash_state;
if (!secure_hash_->Serialize(&hash_state))
- return "";
+ return std::string();
return std::string(reinterpret_cast<const char*>(hash_state.data()),
hash_state.size());
@@ -274,7 +274,7 @@
base::Bind(&FileOpenedNetLogCallback, &full_path_, bytes_so_far_));
// Create a new file stream if it is not provided.
- if (!file_stream_.get()) {
+ if (!file_stream_) {
CreateFileStream();
file_stream_->EnableErrorStatistics();
int open_result = file_stream_->OpenSync(
@@ -322,7 +322,7 @@
bound_net_log_.AddEvent(net::NetLog::TYPE_DOWNLOAD_FILE_CLOSED);
- if (file_stream_.get()) {
+ if (file_stream_) {
#if defined(OS_CHROMEOS)
// Currently we don't really care about the return value, since if it fails
// theres not much we can do. But we might in the future.
diff --git a/content/browser/download/base_file_unittest.cc b/content/browser/download/base_file_unittest.cc
index 799076d..7b53c4d 100644
--- a/content/browser/download/base_file_unittest.cc
+++ b/content/browser/download/base_file_unittest.cc
@@ -54,7 +54,7 @@
GURL(),
0,
false,
- "",
+ std::string(),
scoped_ptr<net::FileStream>(),
net::BoundNetLog()));
}
@@ -105,7 +105,7 @@
GURL(),
0,
true,
- "",
+ std::string(),
scoped_ptr<net::FileStream>(),
net::BoundNetLog()));
}
@@ -145,7 +145,7 @@
GURL(),
0,
false,
- "",
+ std::string(),
scoped_ptr<net::FileStream>(),
net::BoundNetLog());
@@ -171,7 +171,7 @@
GURL(),
0,
false,
- "",
+ std::string(),
scoped_ptr<net::FileStream>(),
net::BoundNetLog());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
@@ -222,7 +222,7 @@
DownloadInterruptReason expected_error_;
// Mock file thread to satisfy debug checks in BaseFile.
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
BrowserThreadImpl file_thread_;
};
@@ -503,7 +503,7 @@
GURL(),
0,
false,
- "",
+ std::string(),
mock_file_stream_scoped_ptr.Pass(),
net::BoundNetLog()));
ASSERT_TRUE(InitializeFile());
@@ -550,7 +550,7 @@
GURL(),
kTestDataLength4,
false,
- "",
+ std::string(),
scoped_ptr<net::FileStream>(),
net::BoundNetLog()));
@@ -584,7 +584,7 @@
GURL(),
0,
false,
- "",
+ std::string(),
scoped_ptr<net::FileStream>(),
net::BoundNetLog()));
@@ -609,7 +609,7 @@
EXPECT_TRUE(BaseFile::IsEmptyHash(empty));
std::string not_empty(BaseFile::kSha256HashLen, '\x01');
EXPECT_FALSE(BaseFile::IsEmptyHash(not_empty));
- EXPECT_FALSE(BaseFile::IsEmptyHash(""));
+ EXPECT_FALSE(BaseFile::IsEmptyHash(std::string()));
}
// Test that calculating speed after no writes.
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc
index 26e951a..f3ed766 100644
--- a/content/browser/download/download_browsertest.cc
+++ b/content/browser/download/download_browsertest.cc
@@ -29,7 +29,7 @@
#include "content/test/net/url_request_mock_http_job.h"
#include "content/test/net/url_request_slow_download_job.h"
#include "googleurl/src/gurl.h"
-#include "net/test/test_server.h"
+#include "net/test/spawned_test_server.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -58,12 +58,28 @@
class MockDownloadManagerObserver : public DownloadManager::Observer {
public:
- MockDownloadManagerObserver() {}
- virtual ~MockDownloadManagerObserver() {}
+ MockDownloadManagerObserver(DownloadManager* manager) {
+ manager_ = manager;
+ manager->AddObserver(this);
+ }
+ virtual ~MockDownloadManagerObserver() {
+ if (manager_)
+ manager_->RemoveObserver(this);
+ }
MOCK_METHOD2(OnDownloadCreated, void(DownloadManager*, DownloadItem*));
MOCK_METHOD1(ModelChanged, void(DownloadManager*));
- MOCK_METHOD1(ManagerGoingDown, void(DownloadManager*));
+ void ManagerGoingDown(DownloadManager* manager) {
+ DCHECK_EQ(manager_, manager);
+ MockManagerGoingDown(manager);
+
+ manager_->RemoveObserver(this);
+ manager_ = NULL;
+ }
+
+ MOCK_METHOD1(MockManagerGoingDown, void(DownloadManager*));
+ private:
+ DownloadManager* manager_;
};
class DownloadFileWithDelayFactory;
@@ -197,7 +213,7 @@
}
DownloadFileWithDelayFactory::DownloadFileWithDelayFactory()
- : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ : weak_ptr_factory_(this),
waiting_(false) {}
DownloadFileWithDelayFactory::~DownloadFileWithDelayFactory() {}
@@ -224,7 +240,7 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
rename_callbacks_.push_back(callback);
if (waiting_)
- MessageLoopForUI::current()->Quit();
+ base::MessageLoopForUI::current()->Quit();
}
void DownloadFileWithDelayFactory::GetAllRenameCallbacks(
@@ -280,10 +296,12 @@
// until data is returned.
static int GetNumberActiveFilesFromFileThread() {
int result = -1;
- BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE,
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::FILE,
+ FROM_HERE,
base::Bind(&CountingDownloadFile::GetNumberActiveFiles, &result),
- MessageLoop::current()->QuitClosure());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->QuitClosure());
+ base::MessageLoop::current()->Run();
DCHECK_NE(-1, result);
return result;
}
@@ -420,25 +438,25 @@
manager_->AddObserver(this);
}
- ~DownloadCreateObserver() {
+ virtual ~DownloadCreateObserver() {
if (manager_)
manager_->RemoveObserver(this);
manager_ = NULL;
}
- virtual void ManagerGoingDown(DownloadManager* manager) {
+ virtual void ManagerGoingDown(DownloadManager* manager) OVERRIDE {
DCHECK_EQ(manager_, manager);
manager_->RemoveObserver(this);
manager_ = NULL;
}
virtual void OnDownloadCreated(DownloadManager* manager,
- DownloadItem* download) {
+ DownloadItem* download) OVERRIDE {
if (!item_)
item_ = download;
if (waiting_)
- MessageLoopForUI::current()->Quit();
+ base::MessageLoopForUI::current()->Quit();
}
DownloadItem* WaitForFinished() {
@@ -552,9 +570,9 @@
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
return result &&
- (CountingDownloadFile::GetNumberActiveFilesFromFileThread() == 0);
+ (CountingDownloadFile::GetNumberActiveFilesFromFileThread() == 0);
}
void DownloadAndWait(Shell* shell, const GURL& url,
@@ -663,7 +681,7 @@
if (URLRequestSlowDownloadJob::NumberOutstandingRequests())
*result = false;
BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure());
+ BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure());
}
// Location of the downloads directory for these tests
@@ -873,15 +891,15 @@
// notifications in the right order.
StrictMock<MockDownloadItemObserver> item_observer;
items[0]->AddObserver(&item_observer);
- MockDownloadManagerObserver manager_observer;
+ MockDownloadManagerObserver manager_observer(
+ DownloadManagerForShell(shell()));
// Don't care about ModelChanged() events.
EXPECT_CALL(manager_observer, ModelChanged(_))
.WillRepeatedly(Return());
- DownloadManagerForShell(shell())->AddObserver(&manager_observer);
{
InSequence notifications;
- EXPECT_CALL(manager_observer, ManagerGoingDown(
+ EXPECT_CALL(manager_observer, MockManagerGoingDown(
DownloadManagerForShell(shell())))
.WillOnce(Return());
EXPECT_CALL(item_observer, OnDownloadUpdated(
@@ -960,8 +978,12 @@
base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
+ MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
+ EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
+
DownloadItem* download(StartDownloadAndReturnItem(url));
WaitForData(download, GetSafeBufferChunk());
+ ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
// Confirm resumption while in progress doesn't do anything.
download->ResumeInterruptedDownload();
@@ -975,12 +997,15 @@
base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
// Resume, confirming received bytes on resumption is correct.
+ // Make sure no creation calls are included.
+ EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(0);
int initial_size = 0;
DownloadUpdatedObserver initial_size_observer(
download, base::Bind(&InitialSizeFilter, &initial_size));
download->ResumeInterruptedDownload();
initial_size_observer.WaitForEvent();
EXPECT_EQ(GetSafeBufferChunk(), initial_size);
+ ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
// and wait for expected data.
WaitForData(download, GetSafeBufferChunk() * 2);
diff --git a/content/browser/download/download_file_impl.cc b/content/browser/download/download_file_impl.cc
index ab95900..9c064d2 100644
--- a/content/browser/download/download_file_impl.cc
+++ b/content/browser/download/download_file_impl.cc
@@ -50,7 +50,7 @@
bytes_seen_(0),
bound_net_log_(bound_net_log),
observer_(observer),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ weak_factory_(this),
power_save_blocker_(power_save_blocker.Pass()) {
}
@@ -108,8 +108,8 @@
base::FilePath new_path(full_path);
- int uniquifier =
- file_util::GetUniquePathNumber(new_path, FILE_PATH_LITERAL(""));
+ int uniquifier = file_util::GetUniquePathNumber(
+ new_path, base::FilePath::StringType());
if (uniquifier > 0) {
new_path = new_path.InsertBeforeExtensionASCII(
base::StringPrintf(" (%d)", uniquifier));
diff --git a/content/browser/download/download_file_unittest.cc b/content/browser/download/download_file_unittest.cc
index 95e3a9c..982692e 100644
--- a/content/browser/download/download_file_unittest.cc
+++ b/content/browser/download/download_file_unittest.cc
@@ -77,7 +77,7 @@
DownloadFileTest() :
observer_(new StrictMock<MockDownloadDestinationObserver>),
- observer_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(observer_.get())),
+ observer_factory_(observer_.get()),
bytes_(-1),
bytes_per_sec_(-1),
hash_state_("xyzzy"),
@@ -302,7 +302,7 @@
int64 bytes_per_sec_;
std::string hash_state_;
- MessageLoop loop_;
+ base::MessageLoop loop_;
private:
void SetRenameResult(bool* called_p,
@@ -592,8 +592,9 @@
AppendDataToFile(chunks1, 2);
// Run the message loops for 750ms and check for results.
- loop_.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
- base::TimeDelta::FromMilliseconds(750));
+ loop_.PostDelayedTask(FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ base::TimeDelta::FromMilliseconds(750));
loop_.Run();
EXPECT_EQ(static_cast<int64>(strlen(kTestData1) + strlen(kTestData2)),
diff --git a/content/browser/download/download_id_unittest.cc b/content/browser/download/download_id_unittest.cc
index 55e6494..ad84c91 100644
--- a/content/browser/download/download_id_unittest.cc
+++ b/content/browser/download/download_id_unittest.cc
@@ -44,7 +44,7 @@
protected:
scoped_refptr<DownloadManager> download_managers_[2];
- MessageLoopForUI message_loop_;
+ base::MessageLoopForUI message_loop_;
// Necessary to delete |DownloadManager|s.
BrowserThreadImpl ui_thread_;
size_t num_managers_;
diff --git a/content/browser/download/download_item_factory.h b/content/browser/download/download_item_factory.h
index 2e42c45..dfc15ec 100644
--- a/content/browser/download/download_item_factory.h
+++ b/content/browser/download/download_item_factory.h
@@ -57,14 +57,15 @@
virtual DownloadItemImpl* CreateActiveItem(
DownloadItemImplDelegate* delegate,
+ DownloadId download_id,
const DownloadCreateInfo& info,
const net::BoundNetLog& bound_net_log) = 0;
virtual DownloadItemImpl* CreateSavePageItem(
DownloadItemImplDelegate* delegate,
+ DownloadId download_id,
const base::FilePath& path,
const GURL& url,
- DownloadId download_id,
const std::string& mime_type,
scoped_ptr<DownloadRequestHandleInterface> request_handle,
const net::BoundNetLog& bound_net_log) = 0;
diff --git a/content/browser/download/download_item_impl.cc b/content/browser/download/download_item_impl.cc
index 1b43462..dfb915e 100644
--- a/content/browser/download/download_item_impl.cc
+++ b/content/browser/download/download_item_impl.cc
@@ -131,22 +131,20 @@
opened_(opened),
delegate_delayed_complete_(false),
bound_net_log_(bound_net_log),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
+ weak_ptr_factory_(this) {
delegate_->Attach();
- if (state_ == IN_PROGRESS_INTERNAL) {
- state_ = INTERRUPTED_INTERNAL;
- last_reason_ = DOWNLOAD_INTERRUPT_REASON_CRASH;
- }
+ DCHECK_NE(IN_PROGRESS_INTERNAL, state_);
Init(false /* not actively downloading */, SRC_HISTORY_IMPORT);
}
// Constructing for a regular download:
DownloadItemImpl::DownloadItemImpl(
DownloadItemImplDelegate* delegate,
+ DownloadId download_id,
const DownloadCreateInfo& info,
const net::BoundNetLog& bound_net_log)
: is_save_package_download_(false),
- download_id_(info.download_id),
+ download_id_(download_id),
target_disposition_(
(info.save_info->prompt_for_save_location) ?
TARGET_DISPOSITION_PROMPT : TARGET_DISPOSITION_OVERWRITE),
@@ -182,7 +180,7 @@
opened_(false),
delegate_delayed_complete_(false),
bound_net_log_(bound_net_log),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
+ weak_ptr_factory_(this) {
delegate_->Attach();
Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD);
@@ -199,9 +197,9 @@
// Constructing for the "Save Page As..." feature:
DownloadItemImpl::DownloadItemImpl(
DownloadItemImplDelegate* delegate,
+ DownloadId download_id,
const base::FilePath& path,
const GURL& url,
- DownloadId download_id,
const std::string& mime_type,
scoped_ptr<DownloadRequestHandleInterface> request_handle,
const net::BoundNetLog& bound_net_log)
@@ -237,7 +235,7 @@
opened_(false),
delegate_delayed_complete_(false),
bound_net_log_(bound_net_log),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
+ weak_ptr_factory_(this) {
delegate_->Attach();
Init(true /* actively downloading */, SRC_SAVE_PAGE_AS);
}
@@ -349,7 +347,7 @@
// |SavePackage| integration.
// |download_file_| can be NULL if Interrupt() is called after the
// download file has been released.
- if (!is_save_package_download_ && download_file_.get())
+ if (!is_save_package_download_ && download_file_)
ReleaseDownloadFile(true);
if (state_ != INTERRUPTED_INTERNAL) {
@@ -690,7 +688,7 @@
// paths that might be used by DownloadItems created from history import.
// Currently such items have null request_handle_s, where other items
// (regular and SavePackage downloads) have actual objects off the pointer.
- if (request_handle_.get())
+ if (request_handle_)
return request_handle_->GetWebContents();
return NULL;
}
@@ -1454,7 +1452,7 @@
// |SavePackage| integration.
// |download_file_| can be NULL if Interrupt() is called after the
// download file has been released.
- if (!is_save_package_download_ && download_file_.get()) {
+ if (!is_save_package_download_ && download_file_) {
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
// Will be deleted at end of task execution.
diff --git a/content/browser/download/download_item_impl.h b/content/browser/download/download_item_impl.h
index 25d1257..cc5e2b6 100644
--- a/content/browser/download/download_item_impl.h
+++ b/content/browser/download/download_item_impl.h
@@ -70,15 +70,16 @@
// Constructing for a regular download.
// |bound_net_log| is constructed externally for our use.
DownloadItemImpl(DownloadItemImplDelegate* delegate,
+ DownloadId download_id,
const DownloadCreateInfo& info,
const net::BoundNetLog& bound_net_log);
// Constructing for the "Save Page As..." feature:
// |bound_net_log| is constructed externally for our use.
DownloadItemImpl(DownloadItemImplDelegate* delegate,
+ DownloadId download_id,
const base::FilePath& path,
const GURL& url,
- DownloadId download_id,
const std::string& mime_type,
scoped_ptr<DownloadRequestHandleInterface> request_handle,
const net::BoundNetLog& bound_net_log);
diff --git a/content/browser/download/download_item_impl_unittest.cc b/content/browser/download/download_item_impl_unittest.cc
index 58c4f53..275b4d2 100644
--- a/content/browser/download/download_item_impl_unittest.cc
+++ b/content/browser/download/download_item_impl_unittest.cc
@@ -227,15 +227,16 @@
scoped_ptr<DownloadCreateInfo> info_;
info_.reset(new DownloadCreateInfo());
- static int next_id;
- info_->download_id = DownloadId(kValidDownloadItemIdDomain, ++next_id);
+ static int next_id = 0;
+ DownloadId id(DownloadId(kValidDownloadItemIdDomain, ++next_id));
info_->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo());
info_->save_info->prompt_for_save_location = false;
info_->url_chain.push_back(GURL());
info_->etag = "SomethingToSatisfyResumption";
DownloadItemImpl* download =
- new DownloadItemImpl(&delegate_, *(info_.get()), net::BoundNetLog());
+ new DownloadItemImpl(
+ &delegate_, id, *(info_.get()), net::BoundNetLog());
allocated_downloads_.insert(download);
return download;
}
@@ -324,7 +325,7 @@
}
private:
- MessageLoopForUI loop_;
+ base::MessageLoopForUI loop_;
TestBrowserThread ui_thread_; // UI thread
TestBrowserThread file_thread_; // FILE thread
StrictMock<MockDelegate> delegate_;
@@ -343,7 +344,7 @@
DownloadItemImpl* item = CreateDownloadItem();
MockObserver observer(item);
- item->UpdateProgress(kDownloadChunkSize, kDownloadSpeed, "");
+ item->UpdateProgress(kDownloadChunkSize, kDownloadSpeed, std::string());
ASSERT_TRUE(observer.CheckUpdated());
EXPECT_EQ(kDownloadSpeed, item->CurrentSpeed());
}
@@ -544,7 +545,7 @@
DownloadItemImpl* safe_item = CreateDownloadItem();
MockObserver safe_observer(safe_item);
- safe_item->OnAllDataSaved("");
+ safe_item->OnAllDataSaved(std::string());
EXPECT_TRUE(safe_observer.CheckUpdated());
safe_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
EXPECT_TRUE(safe_observer.CheckUpdated());
@@ -554,7 +555,7 @@
CreateDownloadItem();
MockObserver unsafeurl_observer(unsafeurl_item);
- unsafeurl_item->OnAllDataSaved("");
+ unsafeurl_item->OnAllDataSaved(std::string());
EXPECT_TRUE(unsafeurl_observer.CheckUpdated());
unsafeurl_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_URL);
EXPECT_TRUE(unsafeurl_observer.CheckUpdated());
@@ -566,7 +567,7 @@
CreateDownloadItem();
MockObserver unsafefile_observer(unsafefile_item);
- unsafefile_item->OnAllDataSaved("");
+ unsafefile_item->OnAllDataSaved(std::string());
EXPECT_TRUE(unsafefile_observer.CheckUpdated());
unsafefile_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
EXPECT_TRUE(unsafefile_observer.CheckUpdated());
@@ -696,7 +697,7 @@
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
final_path));
EXPECT_CALL(*download_file, Detach());
- item->DestinationObserverAsWeakPtr()->DestinationCompleted("");
+ item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
RunAllPendingInMessageLoops();
::testing::Mock::VerifyAndClearExpectations(download_file);
mock_delegate()->VerifyAndClearExpectations();
@@ -861,7 +862,7 @@
EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
.WillOnce(Return(true));
EXPECT_CALL(*download_file, Detach());
- item->DestinationObserverAsWeakPtr()->DestinationCompleted("");
+ item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
RunAllPendingInMessageLoops();
ASSERT_TRUE(item->IsComplete());
@@ -888,7 +889,7 @@
.WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
base::FilePath(kDummyPath)));
EXPECT_CALL(*download_file, Detach());
- item->DestinationObserverAsWeakPtr()->DestinationCompleted("");
+ item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
RunAllPendingInMessageLoops();
ASSERT_TRUE(item->IsComplete());
@@ -936,7 +937,7 @@
// Drive the delegate interaction.
EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
.WillOnce(Return(true));
- item->DestinationObserverAsWeakPtr()->DestinationCompleted("");
+ item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
EXPECT_FALSE(item->IsDangerous());
@@ -965,7 +966,7 @@
.WillOnce(DoAll(SaveArg<1>(&delegate_callback),
Return(false)))
.WillOnce(Return(true));
- item->DestinationObserverAsWeakPtr()->DestinationCompleted("");
+ item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
ASSERT_FALSE(delegate_callback.is_null());
copy_delegate_callback = delegate_callback;
delegate_callback.Reset();
@@ -1000,7 +1001,7 @@
.WillOnce(DoAll(SaveArg<1>(&delegate_callback),
Return(false)))
.WillOnce(Return(true));
- item->DestinationObserverAsWeakPtr()->DestinationCompleted("");
+ item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
ASSERT_FALSE(delegate_callback.is_null());
copy_delegate_callback = delegate_callback;
delegate_callback.Reset();
@@ -1046,7 +1047,7 @@
.WillOnce(DoAll(SaveArg<1>(&delegate_callback),
Return(false)))
.WillOnce(Return(true));
- item->DestinationObserverAsWeakPtr()->DestinationCompleted("");
+ item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
ASSERT_FALSE(delegate_callback.is_null());
copy_delegate_callback = delegate_callback;
delegate_callback.Reset();
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index 0e28d16..3fa9043 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -14,9 +14,9 @@
#include "base/message_loop.h"
#include "base/stl_util.h"
#include "base/stringprintf.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/supports_user_data.h"
#include "base/synchronization/lock.h"
-#include "base/sys_string_conversions.h"
#include "build/build_config.h"
#include "content/browser/byte_stream.h"
#include "content/browser/download/download_create_info.h"
@@ -58,7 +58,7 @@
params->resource_context()->GetRequestContext()->CreateRequest(
params->url(), NULL));
if (params->referrer().url.is_valid())
- request->set_referrer(params->referrer().url.spec());
+ request->SetReferrer(params->referrer().url.spec());
webkit_glue::ConfigureURLRequestForReferrerPolicy(
request.get(), params->referrer().policy);
request->set_load_flags(request->load_flags() | params->load_flags());
@@ -164,7 +164,7 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
*result = (DownloadFile::GetNumberOfDownloadFiles() == 0);
BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure());
+ BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure());
}
class DownloadItemFactoryImpl : public DownloadItemFactory {
@@ -208,20 +208,21 @@
virtual DownloadItemImpl* CreateActiveItem(
DownloadItemImplDelegate* delegate,
+ DownloadId download_id,
const DownloadCreateInfo& info,
const net::BoundNetLog& bound_net_log) OVERRIDE {
- return new DownloadItemImpl(delegate, info, bound_net_log);
+ return new DownloadItemImpl(delegate, download_id, info, bound_net_log);
}
virtual DownloadItemImpl* CreateSavePageItem(
DownloadItemImplDelegate* delegate,
+ DownloadId download_id,
const base::FilePath& path,
const GURL& url,
- DownloadId download_id,
const std::string& mime_type,
scoped_ptr<DownloadRequestHandleInterface> request_handle,
const net::BoundNetLog& bound_net_log) OVERRIDE {
- return new DownloadItemImpl(delegate, path, url, download_id,
+ return new DownloadItemImpl(delegate, download_id, path, url,
mime_type, request_handle.Pass(),
bound_net_log);
}
@@ -230,20 +231,30 @@
} // namespace
DownloadManagerImpl::DownloadManagerImpl(
- net::NetLog* net_log)
+ net::NetLog* net_log,
+ BrowserContext* browser_context)
: item_factory_(new DownloadItemFactoryImpl()),
file_factory_(new DownloadFileFactory()),
history_size_(0),
- shutdown_needed_(false),
- browser_context_(NULL),
+ shutdown_needed_(true),
+ browser_context_(browser_context),
delegate_(NULL),
net_log_(net_log) {
+ DCHECK(browser_context);
}
DownloadManagerImpl::~DownloadManagerImpl() {
DCHECK(!shutdown_needed_);
}
+void DownloadManagerImpl::CreateActiveItem(
+ DownloadId id, const DownloadCreateInfo& info) {
+ net::BoundNetLog bound_net_log =
+ net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
+ downloads_[id.local()] =
+ item_factory_->CreateActiveItem(this, id, info, bound_net_log);
+}
+
DownloadId DownloadManagerImpl::GetNextId() {
DownloadId id;
if (delegate_)
@@ -361,16 +372,6 @@
delegate_ = NULL;
}
-bool DownloadManagerImpl::Init(BrowserContext* browser_context) {
- DCHECK(browser_context);
- DCHECK(!shutdown_needed_) << "DownloadManager already initialized.";
- shutdown_needed_ = true;
-
- browser_context_ = browser_context;
-
- return true;
-}
-
DownloadItem* DownloadManagerImpl::StartDownload(
scoped_ptr<DownloadCreateInfo> info,
scoped_ptr<ByteStreamReader> stream) {
@@ -384,10 +385,21 @@
&default_download_directory, &skip_dir_check);
}
- // We create the DownloadItem before the DownloadFile because the
- // DownloadItem already needs to handle a state in which there is
- // no associated DownloadFile (history downloads, !IN_PROGRESS downloads)
- DownloadItemImpl* download = GetOrCreateDownloadItem(info.get());
+ // If we don't have a valid id, that's a signal to generate one.
+ DownloadId id(info->download_id);
+ if (!id.IsValid())
+ id = GetNextId();
+
+ // Create a new download item if this isn't a resumption.
+ bool new_download(!ContainsKey(downloads_, id.local()));
+ if (new_download)
+ CreateActiveItem(id, *info);
+
+ DownloadItemImpl* download(downloads_[id.local()]);
+ DCHECK(download);
+ DCHECK(new_download || download->IsInterrupted());
+
+ // Create the download file and start the download.
scoped_ptr<DownloadFile> download_file(
file_factory_->CreateFile(
info->save_info.Pass(), default_download_directory,
@@ -399,9 +411,13 @@
new DownloadRequestHandle(info->request_handle));
download->Start(download_file.Pass(), req_handle.Pass());
- // Delay notification until after Start() so that download_file is bound
- // to download and all the usual setters (e.g. Cancel) work.
- FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download));
+ // For interrupted downloads, Start() will transition the state to
+ // IN_PROGRESS and consumers will be notified via OnDownloadUpdated().
+ // For new downloads, we notify here, rather than earlier, so that
+ // the download_file is bound to download and all the usual
+ // setters (e.g. Cancel) work.
+ if (new_download)
+ FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download));
return download;
}
@@ -440,29 +456,6 @@
return browser_context_;
}
-DownloadItemImpl* DownloadManagerImpl::GetOrCreateDownloadItem(
- DownloadCreateInfo* info) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (!info->download_id.IsValid())
- info->download_id = GetNextId();
-
- DownloadItemImpl* download = NULL;
- if (ContainsKey(downloads_, info->download_id.local())) {
- // Resuming an existing download.
- download = downloads_[info->download_id.local()];
- DCHECK(download->IsInterrupted());
- } else {
- // New download
- net::BoundNetLog bound_net_log =
- net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
- download = item_factory_->CreateActiveItem(this, *info, bound_net_log);
- downloads_[download->GetId()] = download;
- }
-
- return download;
-}
-
DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem(
const base::FilePath& main_file_path,
const GURL& page_url,
@@ -473,9 +466,9 @@
net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
DownloadItemImpl* download_item = item_factory_->CreateSavePageItem(
this,
+ GetNextId(),
main_file_path,
page_url,
- GetNextId(),
mime_type,
request_handle.Pass(),
bound_net_log);
diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h
index ee6e6eb..6885068 100644
--- a/content/browser/download/download_manager_impl.h
+++ b/content/browser/download/download_manager_impl.h
@@ -35,7 +35,7 @@
public:
// Caller guarantees that |net_log| will remain valid
// for the lifetime of DownloadManagerImpl (until Shutdown() is called).
- DownloadManagerImpl(net::NetLog* net_log);
+ DownloadManagerImpl(net::NetLog* net_log, BrowserContext* browser_context);
// Implementation functions (not part of the DownloadManager interface).
@@ -57,7 +57,6 @@
virtual DownloadManagerDelegate* GetDelegate() const OVERRIDE;
virtual void Shutdown() OVERRIDE;
virtual void GetAllDownloads(DownloadVector* result) OVERRIDE;
- virtual bool Init(BrowserContext* browser_context) OVERRIDE;
virtual DownloadItem* StartDownload(
scoped_ptr<DownloadCreateInfo> info,
scoped_ptr<ByteStreamReader> stream) OVERRIDE;
@@ -107,11 +106,9 @@
virtual ~DownloadManagerImpl();
- // Retrieves the download item corresponding to the passed
- // DownloadCreateInfo (generated on the IO thread). This will create
- // the download item if this is a new download (common case) or retrieve an
- // existing download item if this is a resuming download.
- virtual DownloadItemImpl* GetOrCreateDownloadItem(DownloadCreateInfo* info);
+ // Create a new active item based on the info. Separate from
+ // StartDownload() for testing.
+ void CreateActiveItem(DownloadId id, const DownloadCreateInfo& info);
// Get next download id.
DownloadId GetNextId();
diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc
index bd34e7e..2abb8f9 100644
--- a/content/browser/download/download_manager_impl_unittest.cc
+++ b/content/browser/download/download_manager_impl_unittest.cc
@@ -76,7 +76,7 @@
base::Time(),
0,
0,
- DownloadItem::IN_PROGRESS,
+ DownloadItem::COMPLETE,
DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
DOWNLOAD_INTERRUPT_REASON_NONE,
false,
@@ -169,7 +169,9 @@
MOCK_CONST_METHOD0(GetUserVerifiedFilePath, base::FilePath());
MOCK_METHOD0(NotifyRemoved, void());
// May be called when vlog is on.
- virtual std::string DebugString(bool verbose) const OVERRIDE { return ""; }
+ virtual std::string DebugString(bool verbose) const OVERRIDE {
+ return std::string();
+ }
};
class MockDownloadManagerDelegate : public DownloadManagerDelegate {
@@ -240,14 +242,15 @@
const net::BoundNetLog& bound_net_log) OVERRIDE;
virtual DownloadItemImpl* CreateActiveItem(
DownloadItemImplDelegate* delegate,
+ DownloadId download_id,
const DownloadCreateInfo& info,
const net::BoundNetLog& bound_net_log) OVERRIDE;
virtual DownloadItemImpl* CreateSavePageItem(
DownloadItemImplDelegate* delegate,
+ DownloadId download_id,
const base::FilePath& path,
const GURL& url,
- DownloadId download_id,
- const std::string& mime_type,
+ const std::string& mime_type,
scoped_ptr<DownloadRequestHandleInterface> request_handle,
const net::BoundNetLog& bound_net_log) OVERRIDE;
@@ -314,9 +317,10 @@
DownloadItemImpl* MockDownloadItemFactory::CreateActiveItem(
DownloadItemImplDelegate* delegate,
+ DownloadId download_id,
const DownloadCreateInfo& info,
const net::BoundNetLog& bound_net_log) {
- int local_id = info.download_id.local();
+ int local_id = download_id.local();
DCHECK(items_.find(local_id) == items_.end());
MockDownloadItemImpl* result =
@@ -324,7 +328,7 @@
EXPECT_CALL(*result, GetId())
.WillRepeatedly(Return(local_id));
EXPECT_CALL(*result, GetGlobalId())
- .WillRepeatedly(Return(DownloadId(delegate, local_id)));
+ .WillRepeatedly(Return(download_id));
items_[local_id] = result;
// Active items are created and then immediately are called to start
@@ -336,9 +340,9 @@
DownloadItemImpl* MockDownloadItemFactory::CreateSavePageItem(
DownloadItemImplDelegate* delegate,
+ DownloadId download_id,
const base::FilePath& path,
const GURL& url,
- DownloadId download_id,
const std::string& mime_type,
scoped_ptr<DownloadRequestHandleInterface> request_handle,
const net::BoundNetLog& bound_net_log) {
@@ -454,7 +458,8 @@
EXPECT_CALL(*mock_browser_context_.get(), IsOffTheRecord())
.WillRepeatedly(Return(false));
- download_manager_ = new DownloadManagerImpl(NULL);
+ download_manager_ = new DownloadManagerImpl(
+ NULL, mock_browser_context_.get());
download_manager_->SetDownloadItemFactoryForTesting(
scoped_ptr<DownloadItemFactory>(
mock_download_item_factory_.get()).Pass());
@@ -464,7 +469,6 @@
observer_.reset(new MockDownloadManagerObserver());
download_manager_->AddObserver(observer_.get());
download_manager_->SetDelegate(mock_download_manager_delegate_.get());
- download_manager_->Init(mock_browser_context_.get());
}
virtual void TearDown() {
@@ -498,10 +502,9 @@
// null.
int id = next_download_id_;
++next_download_id_;
- info.download_id = DownloadId(kDownloadIdDomain, id);
info.request_handle = DownloadRequestHandle();
- download_manager_->GetOrCreateDownloadItem(&info);
-
+ download_manager_->CreateActiveItem(DownloadId(kDownloadIdDomain, id),
+ info);
DCHECK(mock_download_item_factory_->GetItem(id));
MockDownloadItemImpl& item(*mock_download_item_factory_->GetItem(id));
// Satisfy expectation. If the item is created in StartDownload(),
@@ -565,7 +568,7 @@
base::FilePath intermediate_path_;
private:
- MessageLoopForUI message_loop_;
+ base::MessageLoopForUI message_loop_;
TestBrowserThread ui_thread_;
TestBrowserThread file_thread_;
base::WeakPtr<MockDownloadItemFactory> mock_download_item_factory_;
diff --git a/content/browser/download/download_resource_handler.cc b/content/browser/download/download_resource_handler.cc
index a803d01..388bcd1 100644
--- a/content/browser/download/download_resource_handler.cc
+++ b/content/browser/download/download_resource_handler.cc
@@ -380,7 +380,7 @@
// Send the info down the stream. Conditional is in case we get
// OnResponseCompleted without OnResponseStarted.
- if (stream_writer_.get())
+ if (stream_writer_)
stream_writer_->Close(reason);
// If the error mapped to something unknown, record it so that
@@ -480,7 +480,7 @@
CallStartedCB(NULL, net::ERR_ACCESS_DENIED);
// Remove output stream callback if a stream exists.
- if (stream_writer_.get())
+ if (stream_writer_)
stream_writer_->RegisterCallback(base::Closure());
UMA_HISTOGRAM_TIMES("SB2.DownloadDuration",
diff --git a/content/browser/download/download_stats.cc b/content/browser/download/download_stats.cc
index cad6cbe..e13200e 100644
--- a/content/browser/download/download_stats.cc
+++ b/content/browser/download/download_stats.cc
@@ -305,8 +305,8 @@
const std::string& content_disposition_string) {
if (content_disposition_string.empty())
return;
- net::HttpContentDisposition content_disposition(
- content_disposition_string, "");
+ net::HttpContentDisposition content_disposition(content_disposition_string,
+ std::string());
int result = content_disposition.parse_result_flags();
bool is_valid = !content_disposition.filename().empty();
diff --git a/content/browser/download/drag_download_file.cc b/content/browser/download/drag_download_file.cc
index d87a7e0..5bbc9cb 100644
--- a/content/browser/download/drag_download_file.cc
+++ b/content/browser/download/drag_download_file.cc
@@ -37,7 +37,7 @@
const Referrer& referrer,
const std::string& referrer_encoding,
WebContents* web_contents,
- MessageLoop* on_completed_loop,
+ base::MessageLoop* on_completed_loop,
const OnCompleted& on_completed)
: on_completed_loop_(on_completed_loop),
on_completed_(on_completed),
@@ -46,7 +46,7 @@
referrer_encoding_(referrer_encoding),
web_contents_(web_contents),
download_item_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
+ weak_ptr_factory_(this) {
DCHECK(on_completed_loop_);
DCHECK(!on_completed_.is_null());
DCHECK(web_contents_);
@@ -132,7 +132,7 @@
download_item_ = NULL;
}
- MessageLoop* on_completed_loop_;
+ base::MessageLoop* on_completed_loop_;
OnCompleted on_completed_;
GURL url_;
Referrer referrer_;
@@ -154,10 +154,10 @@
WebContents* web_contents)
: file_path_(file_path),
file_stream_(file_stream.Pass()),
- drag_message_loop_(MessageLoop::current()),
+ drag_message_loop_(base::MessageLoop::current()),
state_(INITIALIZED),
drag_ui_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
+ weak_ptr_factory_(this) {
drag_ui_ = new DragDownloadFileUI(
url,
referrer,
@@ -231,7 +231,7 @@
void DragDownloadFile::CheckThread() {
#if defined(OS_WIN)
- DCHECK(drag_message_loop_ == MessageLoop::current());
+ DCHECK(drag_message_loop_ == base::MessageLoop::current());
#else
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
#endif
diff --git a/content/browser/download/drag_download_file.h b/content/browser/download/drag_download_file.h
index e97f585..2151d44 100644
--- a/content/browser/download/drag_download_file.h
+++ b/content/browser/download/drag_download_file.h
@@ -63,7 +63,7 @@
base::FilePath file_path_;
scoped_ptr<net::FileStream> file_stream_;
- MessageLoop* drag_message_loop_;
+ base::MessageLoop* drag_message_loop_;
State state_;
scoped_refptr<ui::DownloadFileObserver> observer_;
base::RunLoop nested_loop_;
diff --git a/content/browser/download/drag_download_file_browsertest.cc b/content/browser/download/drag_download_file_browsertest.cc
index e35cbfb..ebbec59 100644
--- a/content/browser/download/drag_download_file_browsertest.cc
+++ b/content/browser/download/drag_download_file_browsertest.cc
@@ -52,9 +52,9 @@
virtual ~DragDownloadFileTest() {}
void Succeed() {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- MessageLoopForUI::current()->QuitClosure());
+ BrowserThread::PostTask(BrowserThread::UI,
+ FROM_HERE,
+ base::MessageLoopForUI::current()->QuitClosure());
}
void FailFast() {
@@ -116,10 +116,6 @@
Referrer referrer;
std::string referrer_encoding;
net::FileStream* stream = NULL;
-#if defined(OS_POSIX)
- stream = CreateFileStreamForDrop(
- &name, GetContentClient()->browser()->GetNetLog());
-#endif
SetUpServer();
DragDownloadFile* file = new DragDownloadFile(
name, scoped_ptr<net::FileStream>(stream), url, referrer,
diff --git a/content/browser/download/drag_download_util.cc b/content/browser/download/drag_download_util.cc
index ea1c897..c69829c 100644
--- a/content/browser/download/drag_download_util.cc
+++ b/content/browser/download/drag_download_util.cc
@@ -114,7 +114,7 @@
PromiseFileFinalizer::~PromiseFileFinalizer() {}
void PromiseFileFinalizer::Cleanup() {
- if (drag_file_downloader_.get())
+ if (drag_file_downloader_)
drag_file_downloader_ = NULL;
}
diff --git a/content/browser/download/mhtml_generation_browsertest.cc b/content/browser/download/mhtml_generation_browsertest.cc
index 6944a6c..26835dd 100644
--- a/content/browser/download/mhtml_generation_browsertest.cc
+++ b/content/browser/download/mhtml_generation_browsertest.cc
@@ -12,7 +12,7 @@
#include "content/shell/shell.h"
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"
-#include "net/test/test_server.h"
+#include "net/test/spawned_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
@@ -24,7 +24,7 @@
void MHTMLGenerated(const base::FilePath& path, int64 size) {
mhtml_generated_ = true;
file_size_ = size;
- MessageLoopForUI::current()->Quit();
+ base::MessageLoopForUI::current()->Quit();
}
protected:
diff --git a/content/browser/download/save_file.cc b/content/browser/download/save_file.cc
index 3e7f7bd..80caf13 100644
--- a/content/browser/download/save_file.cc
+++ b/content/browser/download/save_file.cc
@@ -20,7 +20,7 @@
GURL(),
0,
calculate_hash,
- "",
+ std::string(),
scoped_ptr<net::FileStream>(),
net::BoundNetLog()),
info_(info) {
diff --git a/content/browser/download/save_package.cc b/content/browser/download/save_package.cc
index c5171ee..7553a54 100644
--- a/content/browser/download/save_package.cc
+++ b/content/browser/download/save_package.cc
@@ -13,9 +13,9 @@
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/stl_util.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread.h"
#include "base/utf_string_conversions.h"
#include "content/browser/download/download_item_impl.h"
@@ -365,7 +365,7 @@
// with SavePackage flow.
if (download_->IsInProgress()) {
download_->SetTotalBytes(size);
- download_->UpdateProgress(size, 0, "");
+ download_->UpdateProgress(size, 0, std::string());
// Must call OnAllDataSaved here in order for
// GDataDownloadObserver::ShouldUpload() to return true.
// ShouldCompleteDownload() may depend on the gdata uploader to finish.
@@ -424,7 +424,7 @@
dir_path.value().length() -
file_name_ext.length());
// Need an extra space for the separator.
- if (!file_util::EndsWithSeparator(dir_path))
+ if (!dir_path.EndsWithSeparator())
--available_length;
// Plenty of room.
@@ -449,7 +449,11 @@
base::FilePath::StringType* generated_name) {
// TODO(jungshik): Figure out the referrer charset when having one
// makes sense and pass it to GenerateFileName.
- base::FilePath file_path = net::GenerateFileName(url, disposition, "", "", "",
+ base::FilePath file_path = net::GenerateFileName(url,
+ disposition,
+ std::string(),
+ std::string(),
+ std::string(),
kDefaultSaveName);
DCHECK(!file_path.empty());
@@ -788,7 +792,8 @@
// with SavePackage flow.
if (download_->IsInProgress()) {
if (save_type_ != SAVE_PAGE_TYPE_AS_MHTML) {
- download_->UpdateProgress(all_save_items_count_, CurrentSpeed(), "");
+ download_->UpdateProgress(
+ all_save_items_count_, CurrentSpeed(), std::string());
download_->OnAllDataSaved(DownloadItem::kEmptyFileHash);
}
download_->MarkAsComplete();
@@ -818,7 +823,7 @@
// TODO(rdsmith/benjhayden): Integrate canceling on DownloadItem
// with SavePackage flow.
if (download_ && download_->IsInProgress())
- download_->UpdateProgress(completed_count(), CurrentSpeed(), "");
+ download_->UpdateProgress(completed_count(), CurrentSpeed(), std::string());
if (save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM &&
save_item->url() == page_url_ && !save_item->received_bytes()) {
@@ -863,7 +868,7 @@
// TODO(rdsmith/benjhayden): Integrate canceling on DownloadItem
// with SavePackage flow.
if (download_ && download_->IsInProgress())
- download_->UpdateProgress(completed_count(), CurrentSpeed(), "");
+ download_->UpdateProgress(completed_count(), CurrentSpeed(), std::string());
if ((save_type_ == SAVE_PAGE_TYPE_AS_ONLY_HTML) ||
(save_type_ == SAVE_PAGE_TYPE_AS_MHTML) ||
diff --git a/content/browser/download/save_package_unittest.cc b/content/browser/download/save_package_unittest.cc
index b5a07ae..e40af08 100644
--- a/content/browser/download/save_package_unittest.cc
+++ b/content/browser/download/save_package_unittest.cc
@@ -221,20 +221,21 @@
base::FilePath::StringType filename;
// Test that the filename is successfully shortened to fit.
- ASSERT_TRUE(GetGeneratedFilename(true, "", url, false, &filename));
+ ASSERT_TRUE(GetGeneratedFilename(true, std::string(), url, false, &filename));
EXPECT_TRUE(filename.length() < long_file.length());
EXPECT_FALSE(HasOrdinalNumber(filename));
// Test that the filename is successfully shortened to fit, and gets an
// an ordinal appended.
- ASSERT_TRUE(GetGeneratedFilename(true, "", url, false, &filename));
+ ASSERT_TRUE(GetGeneratedFilename(true, std::string(), url, false, &filename));
EXPECT_TRUE(filename.length() < long_file.length());
EXPECT_TRUE(HasOrdinalNumber(filename));
// Test that the filename is successfully shortened to fit, and gets a
// different ordinal appended.
base::FilePath::StringType filename2;
- ASSERT_TRUE(GetGeneratedFilename(true, "", url, false, &filename2));
+ ASSERT_TRUE(
+ GetGeneratedFilename(true, std::string(), url, false, &filename2));
EXPECT_TRUE(filename2.length() < long_file.length());
EXPECT_TRUE(HasOrdinalNumber(filename2));
EXPECT_NE(filename, filename2);
diff --git a/content/browser/fileapi/browser_file_system_helper.cc b/content/browser/fileapi/browser_file_system_helper.cc
index 710c3bd..75a8aae7 100644
--- a/content/browser/fileapi/browser_file_system_helper.cc
+++ b/content/browser/fileapi/browser_file_system_helper.cc
@@ -12,7 +12,10 @@
#include "base/threading/sequenced_worker_pool.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/url_constants.h"
#include "webkit/fileapi/external_mount_points.h"
#include "webkit/fileapi/file_permission_policy.h"
#include "webkit/fileapi/file_system_options.h"
@@ -22,34 +25,33 @@
#include "webkit/quota/quota_manager.h"
namespace content {
-namespace {
-const char kChromeScheme[] = "chrome";
-const char kExtensionScheme[] = "chrome-extension";
+namespace {
using fileapi::FileSystemOptions;
FileSystemOptions CreateBrowserFileSystemOptions(bool is_incognito) {
- std::vector<std::string> additional_allowed_schemes;
- additional_allowed_schemes.push_back(kChromeScheme);
- additional_allowed_schemes.push_back(kExtensionScheme);
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kAllowFileAccessFromFiles)) {
- additional_allowed_schemes.push_back("file");
- }
FileSystemOptions::ProfileMode profile_mode =
is_incognito ? FileSystemOptions::PROFILE_MODE_INCOGNITO
: FileSystemOptions::PROFILE_MODE_NORMAL;
+ std::vector<std::string> additional_allowed_schemes;
+ GetContentClient()->browser()->GetAdditionalAllowedSchemesForFileSystem(
+ &additional_allowed_schemes);
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kAllowFileAccessFromFiles)) {
+ additional_allowed_schemes.push_back(chrome::kFileScheme);
+ }
return FileSystemOptions(profile_mode, additional_allowed_schemes);
}
-} // anonymous namespace
+} // namespace
scoped_refptr<fileapi::FileSystemContext> CreateFileSystemContext(
- const base::FilePath& profile_path, bool is_incognito,
- fileapi::ExternalMountPoints* external_mount_points,
- quota::SpecialStoragePolicy* special_storage_policy,
- quota::QuotaManagerProxy* quota_manager_proxy) {
+ const base::FilePath& profile_path,
+ bool is_incognito,
+ fileapi::ExternalMountPoints* external_mount_points,
+ quota::SpecialStoragePolicy* special_storage_policy,
+ quota::QuotaManagerProxy* quota_manager_proxy) {
base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
base::SequencedWorkerPool::SequenceToken media_sequence_token =
pool->GetNamedSequenceToken(fileapi::kMediaTaskRunnerName);
@@ -60,11 +62,17 @@
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
pool->GetSequencedTaskRunner(media_sequence_token)));
+ // Setting up additional mount point providers.
+ ScopedVector<fileapi::FileSystemMountPointProvider> additional_providers;
+ GetContentClient()->browser()->GetAdditionalFileSystemMountPointProviders(
+ profile_path, &additional_providers);
+
return new fileapi::FileSystemContext(
task_runners.Pass(),
external_mount_points,
special_storage_policy,
quota_manager_proxy,
+ additional_providers.Pass(),
profile_path,
CreateBrowserFileSystemOptions(is_incognito));
}
diff --git a/content/browser/fileapi/file_system_browsertest.cc b/content/browser/fileapi/file_system_browsertest.cc
index 74633a0..6fe2f8c 100644
--- a/content/browser/fileapi/file_system_browsertest.cc
+++ b/content/browser/fileapi/file_system_browsertest.cc
@@ -17,7 +17,7 @@
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"
#include "content/test/layout_browsertest.h"
-#include "net/test/test_server.h"
+#include "net/test/spawned_test_server.h"
#include "webkit/quota/quota_manager.h"
using quota::QuotaManager;
diff --git a/content/browser/fileapi/fileapi_message_filter.cc b/content/browser/fileapi/fileapi_message_filter.cc
index 7472115..966490e 100644
--- a/content/browser/fileapi/fileapi_message_filter.cc
+++ b/content/browser/fileapi/fileapi_message_filter.cc
@@ -35,6 +35,7 @@
#include "webkit/fileapi/isolated_context.h"
#include "webkit/fileapi/local_file_system_operation.h"
#include "webkit/fileapi/sandbox_mount_point_provider.h"
+#include "webkit/quota/quota_manager.h"
using fileapi::FileSystemFileUtil;
using fileapi::FileSystemMountPointProvider;
@@ -89,7 +90,7 @@
void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) {
BrowserMessageFilter::OnChannelConnected(peer_pid);
- if (request_context_getter_.get()) {
+ if (request_context_getter_) {
DCHECK(!request_context_);
request_context_ = request_context_getter_->GetURLRequestContext();
request_context_getter_ = NULL;
@@ -110,20 +111,18 @@
in_transit_snapshot_files_.clear();
// Close all files that are previously OpenFile()'ed in this process.
- if (!open_filesystem_urls_.empty()) {
+ if (!on_close_callbacks_.IsEmpty()) {
DLOG(INFO)
<< "File API: Renderer process shut down before NotifyCloseFile"
- << " for " << open_filesystem_urls_.size() << " files opened in PPAPI";
+ << " for " << on_close_callbacks_.size() << " files opened in PPAPI";
}
- for (std::multiset<GURL>::const_iterator iter =
- open_filesystem_urls_.begin();
- iter != open_filesystem_urls_.end(); ++iter) {
- FileSystemURL url(context_->CrackURL(*iter));
- FileSystemOperation* operation = context_->CreateFileSystemOperation(
- url, NULL);
- if (operation)
- operation->NotifyCloseFile(url);
+
+ for (OnCloseCallbackMap::iterator itr(&on_close_callbacks_);
+ !itr.IsAtEnd(); itr.Advance()) {
+ itr.GetCurrentValue()->Run();
}
+
+ on_close_callbacks_.Clear();
}
void FileAPIMessageFilter::OverrideThreadForMessage(
@@ -157,8 +156,6 @@
OnCreateSnapshotFile)
IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidReceiveSnapshotFile,
OnDidReceiveSnapshotFile)
- IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile_Deprecated,
- OnCreateSnapshotFile_Deprecated)
IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate)
IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate)
IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath,
@@ -453,31 +450,39 @@
return;
}
+ quota::QuotaLimitType quota_policy = quota::kQuotaLimitTypeUnknown;
+ quota::QuotaManagerProxy* quota_manager_proxy =
+ context_->quota_manager_proxy();
+ CHECK(quota_manager_proxy);
+ CHECK(quota_manager_proxy->quota_manager());
+
+ if (quota_manager_proxy->quota_manager()->IsStorageUnlimited(
+ url.origin(), FileSystemTypeToQuotaStorageType(url.type()))) {
+ quota_policy = quota::kQuotaLimitTypeUnlimited;
+ } else {
+ quota_policy = quota::kQuotaLimitTypeLimited;
+ }
+
FileSystemOperation* operation = GetNewOperation(url, request_id);
if (!operation)
return;
operation->OpenFile(
url, file_flags, peer_handle(),
- base::Bind(&FileAPIMessageFilter::DidOpenFile, this, request_id, path));
+ base::Bind(&FileAPIMessageFilter::DidOpenFile, this, request_id,
+ quota_policy));
}
-void FileAPIMessageFilter::OnNotifyCloseFile(const GURL& path) {
+void FileAPIMessageFilter::OnNotifyCloseFile(int file_open_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- // Remove |path| from the set of opened urls. It must only be called for a URL
- // that is successfully opened and enrolled in DidOpenFile.
- std::multiset<GURL>::iterator iter = open_filesystem_urls_.find(path);
- DCHECK(iter != open_filesystem_urls_.end());
- open_filesystem_urls_.erase(iter);
-
- FileSystemURL url(context_->CrackURL(path));
-
- // Do not use GetNewOperation() here, because NotifyCloseFile is a one-way
- // operation that does not have request_id by which we respond back.
- FileSystemOperation* operation = context_->CreateFileSystemOperation(
- url, NULL);
- if (operation)
- operation->NotifyCloseFile(url);
+ // Remove |file_open_id| from the map of |on_close_callback|s.
+ // It must only be called for a ID that is successfully opened and enrolled in
+ // DidOpenFile.
+ base::Closure* on_close_callback = on_close_callbacks_.Lookup(file_open_id);
+ if (on_close_callback && !on_close_callback->is_null()) {
+ on_close_callback->Run();
+ on_close_callbacks_.Remove(file_open_id);
+ }
}
void FileAPIMessageFilter::OnWillUpdate(const GURL& path) {
@@ -538,32 +543,6 @@
in_transit_snapshot_files_.erase(request_id);
}
-void FileAPIMessageFilter::OnCreateSnapshotFile_Deprecated(
- int request_id, const GURL& blob_url, const GURL& path) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- FileSystemURL url(context_->CrackURL(path));
- base::Callback<void(const base::FilePath&)> register_file_callback =
- base::Bind(&FileAPIMessageFilter::RegisterFileAsBlob,
- this, blob_url, url);
-
- // Make sure if this file can be read by the renderer as this is
- // called when the renderer is about to create a new File object
- // (for reading the file).
- base::PlatformFileError error;
- if (!HasPermissionsForFile(url, fileapi::kReadFilePermissions, &error)) {
- Send(new FileSystemMsg_DidFail(request_id, error));
- return;
- }
-
- FileSystemOperation* operation = GetNewOperation(url, request_id);
- if (!operation)
- return;
- operation->CreateSnapshotFile(
- url,
- base::Bind(&FileAPIMessageFilter::DidCreateSnapshot_Deprecated,
- this, request_id, register_file_callback));
-}
-
void FileAPIMessageFilter::OnStartBuildingBlob(const GURL& url) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
blob_storage_context_->controller()->StartBuildingBlob(url);
@@ -681,19 +660,26 @@
}
void FileAPIMessageFilter::DidOpenFile(int request_id,
- const GURL& path,
+ quota::QuotaLimitType quota_policy,
base::PlatformFileError result,
base::PlatformFile file,
+ const base::Closure& on_close_callback,
base::ProcessHandle peer_handle) {
if (result == base::PLATFORM_FILE_OK) {
IPC::PlatformFileForTransit file_for_transit =
file != base::kInvalidPlatformFileValue ?
IPC::GetFileHandleForProcess(file, peer_handle, true) :
IPC::InvalidPlatformFileForTransit();
- open_filesystem_urls_.insert(path);
- Send(new FileSystemMsg_DidOpenFile(request_id, file_for_transit));
+ int file_open_id = on_close_callbacks_.Add(
+ new base::Closure(on_close_callback));
+
+ Send(new FileSystemMsg_DidOpenFile(request_id,
+ file_for_transit,
+ file_open_id,
+ quota_policy));
} else {
- Send(new FileSystemMsg_DidFail(request_id, result));
+ Send(new FileSystemMsg_DidFail(request_id,
+ result));
}
UnregisterOperation(request_id);
}
@@ -766,7 +752,7 @@
// already been granted read permission for the file's nominal path, but
// for drive files, platform paths differ from the nominal paths.
DCHECK(snapshot_file ||
- fileapi::SandboxMountPointProvider::CanHandleType(url.type()) ||
+ fileapi::SandboxMountPointProvider::IsSandboxType(url.type()) ||
url.type() == fileapi::kFileSystemTypeDrive);
ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
process_id_, platform_path);
@@ -788,80 +774,6 @@
request_id, info, platform_path));
}
-void FileAPIMessageFilter::DidCreateSnapshot_Deprecated(
- int request_id,
- const base::Callback<void(const base::FilePath&)>& register_file_callback,
- base::PlatformFileError result,
- const base::PlatformFileInfo& info,
- const base::FilePath& platform_path,
- const scoped_refptr<webkit_blob::ShareableFileReference>& unused) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (result != base::PLATFORM_FILE_OK) {
- Send(new FileSystemMsg_DidFail(request_id, result));
- return;
- }
-
- // Register the created file to the blob registry by calling
- // RegisterFileAsBlob.
- // Blob storage automatically finds and refs the file_ref, so we don't
- // need to do anything for the returned file reference (|unused|) here.
- register_file_callback.Run(platform_path);
-
- // Return the file info and platform_path.
- Send(new FileSystemMsg_DidReadMetadata(request_id, info, platform_path));
-}
-
-void FileAPIMessageFilter::RegisterFileAsBlob(
- const GURL& blob_url,
- const FileSystemURL& url,
- const base::FilePath& platform_path) {
- // Use the virtual path's extension to determine MIME type.
- base::FilePath::StringType extension = url.path().Extension();
- if (!extension.empty())
- extension = extension.substr(1); // Strip leading ".".
-
- scoped_refptr<webkit_blob::ShareableFileReference> shareable_file =
- webkit_blob::ShareableFileReference::Get(platform_path);
- if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
- process_id_, platform_path)) {
- // In order for the renderer to be able to read the file, it must be granted
- // read permission for the file's platform path. By now, it has already been
- // verified that the renderer has sufficient permissions to read the file.
- // It is still possible that ChildProcessSecurityPolicyImpl doesn't reflect
- // that the renderer can read the file's platform path. If this is the case
- // the renderer should be granted read permission for the file's platform
- // path. This can happen in the following situations:
- // - the file comes from sandboxed filesystem. Reading sandboxed files is
- // always permitted, but only implicitly.
- // - the underlying filesystem returned newly created snapshot file.
- // - the file comes from an external drive filesystem. The renderer has
- // already been granted read permission for the file's nominal path, but
- // for drive files, platform paths differ from the nominal paths.
- DCHECK(shareable_file ||
- fileapi::SandboxMountPointProvider::CanHandleType(url.type()) ||
- url.type() == fileapi::kFileSystemTypeDrive);
- ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
- process_id_, platform_path);
- if (shareable_file) {
- // This will revoke all permissions for the file when the last ref
- // of the file is dropped (assuming it's ok).
- shareable_file->AddFinalReleaseCallback(
- base::Bind(&RevokeFilePermission, process_id_));
- }
- }
-
- // This may fail, but then we'll be just setting the empty mime type.
- std::string mime_type;
- net::GetWellKnownMimeTypeFromExtension(extension, &mime_type);
- BlobData::Item item;
- item.SetToFilePathRange(platform_path, 0, -1, base::Time());
- BlobStorageController* controller = blob_storage_context_->controller();
- controller->StartBuildingBlob(blob_url);
- controller->AppendBlobDataItem(blob_url, item);
- controller->FinishBuildingBlob(blob_url, mime_type);
- blob_urls_.insert(blob_url.spec());
-}
-
bool FileAPIMessageFilter::HasPermissionsForFile(
const FileSystemURL& url, int permissions, base::PlatformFileError* error) {
return CheckFileSystemPermissionsForProcess(context_, process_id_, url,
diff --git a/content/browser/fileapi/fileapi_message_filter.h b/content/browser/fileapi/fileapi_message_filter.h
index 4f8ce5b..99c3a1e 100644
--- a/content/browser/fileapi/fileapi_message_filter.h
+++ b/content/browser/fileapi/fileapi_message_filter.h
@@ -18,6 +18,7 @@
#include "content/public/browser/browser_message_filter.h"
#include "webkit/blob/blob_data.h"
#include "webkit/fileapi/file_system_types.h"
+#include "webkit/quota/quota_types.h"
class GURL;
@@ -110,7 +111,7 @@
const base::Time& last_modified_time);
void OnCancel(int request_id, int request_to_cancel);
void OnOpenFile(int request_id, const GURL& path, int file_flags);
- void OnNotifyCloseFile(const GURL& path);
+ void OnNotifyCloseFile(int file_open_id);
void OnWillUpdate(const GURL& path);
void OnDidUpdate(const GURL& path, int64 delta);
void OnSyncGetPlatformPath(const GURL& path,
@@ -119,10 +120,6 @@
const GURL& path);
void OnDidReceiveSnapshotFile(int request_id);
- void OnCreateSnapshotFile_Deprecated(int request_id,
- const GURL& blob_url,
- const GURL& path);
-
void OnStartBuildingBlob(const GURL& url);
void OnAppendBlobDataItem(const GURL& url,
const webkit_blob::BlobData::Item& item);
@@ -144,9 +141,10 @@
const std::vector<base::FileUtilProxy::Entry>& entries,
bool has_more);
void DidOpenFile(int request_id,
- const GURL& path,
+ quota::QuotaLimitType quota_policy,
base::PlatformFileError result,
base::PlatformFile file,
+ const base::Closure& on_close_callback,
base::ProcessHandle peer_handle);
void DidWrite(int request_id,
base::PlatformFileError result,
@@ -166,19 +164,6 @@
const base::FilePath& platform_path,
const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref);
- void DidCreateSnapshot_Deprecated(
- int request_id,
- const base::Callback<void(const base::FilePath&)>& register_file_callback,
- base::PlatformFileError result,
- const base::PlatformFileInfo& info,
- const base::FilePath& platform_path,
- const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref);
- // Registers the given file pointed by |virtual_path| and backed by
- // |platform_path| as the |blob_url|. Called by DidCreateSnapshot_Deprecated.
- void RegisterFileAsBlob(const GURL& blob_url,
- const fileapi::FileSystemURL& url,
- const base::FilePath& platform_path);
-
// Checks renderer's access permissions for single file.
bool HasPermissionsForFile(const fileapi::FileSystemURL& url,
int permissions,
@@ -213,9 +198,10 @@
std::map<int, scoped_refptr<webkit_blob::ShareableFileReference> >
in_transit_snapshot_files_;
- // Keep track of file system file URLs opened by OpenFile() in this process.
+ // Keep track of file system file opened by OpenFile() in this process.
// Need to close all of them when the renderer process dies.
- std::multiset<GURL> open_filesystem_urls_;
+ typedef IDMap<base::Closure, IDMapOwnPointer> OnCloseCallbackMap;
+ OnCloseCallbackMap on_close_callbacks_;
DISALLOW_COPY_AND_ASSIGN(FileAPIMessageFilter);
};
diff --git a/content/browser/font_list_async.cc b/content/browser/font_list_async.cc
index 819e62b..4225319 100644
--- a/content/browser/font_list_async.cc
+++ b/content/browser/font_list_async.cc
@@ -38,7 +38,9 @@
DCHECK(well_known_thread)
<< "Can only call GetFontList from a well-known thread.";
- BrowserThread::PostBlockingPoolTask(FROM_HERE,
+ BrowserThread::PostBlockingPoolSequencedTask(
+ kFontListSequenceToken,
+ FROM_HERE,
base::Bind(&GetFontListInBlockingPool, id, callback));
}
diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm
index 8748730..84bad06 100644
--- a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm
+++ b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm
@@ -301,7 +301,7 @@
// Copy to the current state to the output buffer, using the mapping
// function, if there is one available.
- pads->length = data_.length;
+ pads->length = WebKit::WebGamepads::itemsLengthCap;
for (size_t i = 0; i < WebKit::WebGamepads::itemsLengthCap; ++i) {
if (associated_[i].mapper)
associated_[i].mapper(data_.items[i], &pads->items[i]);
diff --git a/content/browser/gamepad/gamepad_provider.cc b/content/browser/gamepad/gamepad_provider.cc
index 8231683..1dad482 100644
--- a/content/browser/gamepad/gamepad_provider.cc
+++ b/content/browser/gamepad/gamepad_provider.cc
@@ -68,7 +68,7 @@
base::AutoLock lock(is_paused_lock_);
is_paused_ = true;
}
- MessageLoop* polling_loop = polling_thread_->message_loop();
+ base::MessageLoop* polling_loop = polling_thread_->message_loop();
polling_loop->PostTask(
FROM_HERE,
base::Bind(&GamepadProvider::SendPauseHint, Unretained(this), true));
@@ -82,7 +82,7 @@
is_paused_ = false;
}
- MessageLoop* polling_loop = polling_thread_->message_loop();
+ base::MessageLoop* polling_loop = polling_thread_->message_loop();
polling_loop->PostTask(
FROM_HERE,
base::Bind(&GamepadProvider::SendPauseHint, Unretained(this), false));
@@ -93,8 +93,8 @@
void GamepadProvider::RegisterForUserGesture(const base::Closure& closure) {
base::AutoLock lock(user_gesture_lock_);
- user_gesture_observers_.push_back(
- ClosureAndThread(closure, MessageLoop::current()->message_loop_proxy()));
+ user_gesture_observers_.push_back(ClosureAndThread(
+ closure, base::MessageLoop::current()->message_loop_proxy()));
}
void GamepadProvider::OnDevicesChanged(base::SystemMonitor::DeviceType type) {
@@ -114,7 +114,7 @@
polling_thread_.reset(new base::Thread("Gamepad polling thread"));
polling_thread_->StartWithOptions(
- base::Thread::Options(MessageLoop::TYPE_IO, 0));
+ base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
polling_thread_->message_loop()->PostTask(
FROM_HERE,
@@ -125,22 +125,22 @@
void GamepadProvider::DoInitializePollingThread(
scoped_ptr<GamepadDataFetcher> fetcher) {
- DCHECK(MessageLoop::current() == polling_thread_->message_loop());
+ DCHECK(base::MessageLoop::current() == polling_thread_->message_loop());
DCHECK(!data_fetcher_.get()); // Should only initialize once.
- if (!fetcher.get())
+ if (!fetcher)
fetcher.reset(new GamepadPlatformDataFetcher);
data_fetcher_ = fetcher.Pass();
}
void GamepadProvider::SendPauseHint(bool paused) {
- DCHECK(MessageLoop::current() == polling_thread_->message_loop());
- if (data_fetcher_.get())
+ DCHECK(base::MessageLoop::current() == polling_thread_->message_loop());
+ if (data_fetcher_)
data_fetcher_->PauseHint(paused);
}
void GamepadProvider::DoPoll() {
- DCHECK(MessageLoop::current() == polling_thread_->message_loop());
+ DCHECK(base::MessageLoop::current() == polling_thread_->message_loop());
DCHECK(have_scheduled_do_poll_);
have_scheduled_do_poll_ = false;
@@ -171,7 +171,7 @@
}
void GamepadProvider::ScheduleDoPoll() {
- DCHECK(MessageLoop::current() == polling_thread_->message_loop());
+ DCHECK(base::MessageLoop::current() == polling_thread_->message_loop());
if (have_scheduled_do_poll_)
return;
@@ -181,7 +181,7 @@
return;
}
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&GamepadProvider::DoPoll, Unretained(this)),
base::TimeDelta::FromMilliseconds(kDesiredSamplingIntervalMs));
diff --git a/content/browser/gamepad/gamepad_provider_unittest.cc b/content/browser/gamepad/gamepad_provider_unittest.cc
index 18bafc3..12d8845 100644
--- a/content/browser/gamepad/gamepad_provider_unittest.cc
+++ b/content/browser/gamepad/gamepad_provider_unittest.cc
@@ -22,7 +22,7 @@
class UserGestureListener {
public:
UserGestureListener()
- : weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ : weak_factory_(this),
has_user_gesture_(false) {
}
diff --git a/content/browser/gamepad/gamepad_service.cc b/content/browser/gamepad/gamepad_service.cc
index 2f6b6bd..11a6964 100644
--- a/content/browser/gamepad/gamepad_service.cc
+++ b/content/browser/gamepad/gamepad_service.cc
@@ -35,7 +35,7 @@
num_readers_++;
DCHECK(num_readers_ > 0);
- if (!provider_.get())
+ if (!provider_)
provider_.reset(new GamepadProvider);
provider_->Resume();
}
diff --git a/content/browser/gamepad/gamepad_standard_mappings.h b/content/browser/gamepad/gamepad_standard_mappings.h
index 35b01f8..6f5d72f 100644
--- a/content/browser/gamepad/gamepad_standard_mappings.h
+++ b/content/browser/gamepad/gamepad_standard_mappings.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_GAMEPAD_GAMEPAD_STANDARD_MAPPINGS_H_
#define CONTENT_BROWSER_GAMEPAD_GAMEPAD_STANDARD_MAPPINGS_H_
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
namespace WebKit {
class WebGamepad;
diff --git a/content/browser/gamepad/gamepad_test_helpers.cc b/content/browser/gamepad/gamepad_test_helpers.cc
index abf4187..e4db14c 100644
--- a/content/browser/gamepad/gamepad_test_helpers.cc
+++ b/content/browser/gamepad/gamepad_test_helpers.cc
@@ -4,7 +4,6 @@
#include "content/browser/gamepad/gamepad_test_helpers.h"
-#include "base/system_monitor/system_monitor.h"
#include "content/browser/gamepad/gamepad_service.h"
namespace content {
@@ -37,10 +36,6 @@
}
GamepadTestHelper::GamepadTestHelper() {
-#if defined(OS_MACOSX)
- base::SystemMonitor::AllocateSystemIOPorts();
-#endif
- system_monitor_.reset(new base::SystemMonitor);
}
GamepadTestHelper::~GamepadTestHelper() {
diff --git a/content/browser/gamepad/gamepad_test_helpers.h b/content/browser/gamepad/gamepad_test_helpers.h
index 9abba01..7b8bb4b 100644
--- a/content/browser/gamepad/gamepad_test_helpers.h
+++ b/content/browser/gamepad/gamepad_test_helpers.h
@@ -12,10 +12,6 @@
#include "content/browser/gamepad/gamepad_data_fetcher.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebGamepads.h"
-namespace base {
-class SystemMonitor;
-}
-
namespace content {
class GamepadService;
@@ -54,13 +50,11 @@
GamepadTestHelper();
virtual ~GamepadTestHelper();
- MessageLoop& message_loop() { return message_loop_; }
+ base::MessageLoop& message_loop() { return message_loop_; }
private:
// This must be constructed before the system monitor.
- MessageLoop message_loop_;
-
- scoped_ptr<base::SystemMonitor> system_monitor_;
+ base::MessageLoop message_loop_;
DISALLOW_COPY_AND_ASSIGN(GamepadTestHelper);
};
diff --git a/content/browser/geolocation/core_location_data_provider_mac.mm b/content/browser/geolocation/core_location_data_provider_mac.mm
index 8c0d338..9942502 100644
--- a/content/browser/geolocation/core_location_data_provider_mac.mm
+++ b/content/browser/geolocation/core_location_data_provider_mac.mm
@@ -192,7 +192,7 @@
namespace content {
CoreLocationDataProviderMac::CoreLocationDataProviderMac() {
- if (MessageLoop::current() !=
+ if (base::MessageLoop::current() !=
GeolocationProvider::GetInstance()->message_loop()) {
NOTREACHED() << "CoreLocation data provider must be created on "
"the Geolocation thread.";
@@ -247,7 +247,7 @@
}
void CoreLocationDataProviderMac::PositionUpdated(Geoposition position) {
- DCHECK(MessageLoop::current() ==
+ DCHECK(base::MessageLoop::current() ==
GeolocationProvider::GetInstance()->message_loop());
if (provider_)
provider_->SetPosition(&position);
diff --git a/content/browser/geolocation/device_data_provider.h b/content/browser/geolocation/device_data_provider.h
index 4918e30..431d706 100644
--- a/content/browser/geolocation/device_data_provider.h
+++ b/content/browser/geolocation/device_data_provider.h
@@ -92,7 +92,7 @@
class DeviceDataProviderImplBase : public DeviceDataProviderImplBaseHack {
public:
DeviceDataProviderImplBase()
- : container_(NULL), client_loop_(MessageLoop::current()) {
+ : container_(NULL), client_loop_(base::MessageLoop::current()) {
DCHECK(client_loop_);
}
@@ -138,12 +138,10 @@
}
bool CalledOnClientThread() const {
- return MessageLoop::current() == this->client_loop_;
+ return base::MessageLoop::current() == this->client_loop_;
}
- MessageLoop* client_loop() const {
- return client_loop_;
- }
+ base::MessageLoop* client_loop() const { return client_loop_; }
private:
void NotifyListenersInClientLoop() {
@@ -162,7 +160,7 @@
// Reference to the client's message loop, all callbacks and access to
// the listeners_ member should happen in this context.
- MessageLoop* client_loop_;
+ base::MessageLoop* client_loop_;
ListenersSet listeners_;
diff --git a/content/browser/geolocation/device_data_provider_unittest.cc b/content/browser/geolocation/device_data_provider_unittest.cc
index 0f0c957..42a678c 100644
--- a/content/browser/geolocation/device_data_provider_unittest.cc
+++ b/content/browser/geolocation/device_data_provider_unittest.cc
@@ -22,7 +22,7 @@
// run for correct behaviour, but we run it in this test to help smoke out
// any race conditions between processing in the main loop and the setup /
// tear down of the DeviceDataProvider thread.
- MessageLoopForUI main_message_loop;
+ base::MessageLoopForUI main_message_loop;
NullWifiDataListenerInterface listener;
for (int i = 0; i < 10; i++) {
DeviceDataProvider<WifiData>::Register(&listener);
diff --git a/content/browser/geolocation/geolocation_provider.cc b/content/browser/geolocation/geolocation_provider.cc
index 80420b9..7a2b689 100644
--- a/content/browser/geolocation/geolocation_provider.cc
+++ b/content/browser/geolocation/geolocation_provider.cc
@@ -95,7 +95,7 @@
}
bool GeolocationProvider::OnGeolocationThread() const {
- return MessageLoop::current() == message_loop();
+ return base::MessageLoop::current() == message_loop();
}
void GeolocationProvider::OnClientsChanged() {
diff --git a/content/browser/geolocation/geolocation_provider_unittest.cc b/content/browser/geolocation/geolocation_provider_unittest.cc
index dcffef0..ea22700 100644
--- a/content/browser/geolocation/geolocation_provider_unittest.cc
+++ b/content/browser/geolocation/geolocation_provider_unittest.cc
@@ -67,7 +67,7 @@
// GeolocationObserver
virtual void OnLocationUpdate(const Geoposition& position) OVERRIDE {
MockGeolocationObserver::OnLocationUpdate(position);
- MessageLoop::current()->Quit();
+ base::MessageLoop::current()->Quit();
}
};
@@ -134,7 +134,7 @@
// Called on provider thread.
void GetProvidersStarted(bool* started);
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
TestBrowserThread io_thread_;
scoped_ptr<LocationProviderForTestArbitrator> provider_;
};
@@ -142,31 +142,31 @@
bool GeolocationProviderTest::ProvidersStarted() {
DCHECK(provider_->IsRunning());
- DCHECK(MessageLoop::current() == &message_loop_);
+ DCHECK(base::MessageLoop::current() == &message_loop_);
bool started;
provider_->message_loop_proxy()->PostTaskAndReply(
FROM_HERE,
base::Bind(&GeolocationProviderTest::GetProvidersStarted,
base::Unretained(this),
&started),
- MessageLoop::QuitClosure());
+ base::MessageLoop::QuitClosure());
message_loop_.Run();
return started;
}
void GeolocationProviderTest::GetProvidersStarted(bool* started) {
- DCHECK(MessageLoop::current() == provider_->message_loop());
+ DCHECK(base::MessageLoop::current() == provider_->message_loop());
*started = provider_->mock_arbitrator()->providers_started();
}
void GeolocationProviderTest::SendMockLocation(const Geoposition& position) {
DCHECK(provider_->IsRunning());
- DCHECK(MessageLoop::current() == &message_loop_);
- provider_->message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&GeolocationProvider::OnLocationUpdate,
- base::Unretained(provider_.get()),
- position));
+ DCHECK(base::MessageLoop::current() == &message_loop_);
+ provider_->message_loop()
+ ->PostTask(FROM_HERE,
+ base::Bind(&GeolocationProvider::OnLocationUpdate,
+ base::Unretained(provider_.get()),
+ position));
}
// Regression test for http://crbug.com/59377
@@ -201,7 +201,7 @@
EXPECT_CALL(first_observer, OnLocationUpdate(GeopositionEq(first_position)));
provider()->AddObserver(&first_observer, options);
SendMockLocation(first_position);
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
provider()->RemoveObserver(&first_observer);
@@ -217,13 +217,13 @@
// is sent.
EXPECT_CALL(second_observer, OnLocationUpdate(testing::_)).Times(0);
provider()->AddObserver(&second_observer, options);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
// The second observer should receive the new position now.
EXPECT_CALL(second_observer,
OnLocationUpdate(GeopositionEq(second_position)));
SendMockLocation(second_position);
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
provider()->RemoveObserver(&second_observer);
EXPECT_FALSE(ProvidersStarted());
diff --git a/content/browser/geolocation/gps_location_provider_linux.cc b/content/browser/geolocation/gps_location_provider_linux.cc
index 74a9537..e511e52 100644
--- a/content/browser/geolocation/gps_location_provider_linux.cc
+++ b/content/browser/geolocation/gps_location_provider_linux.cc
@@ -216,7 +216,7 @@
poll_period_moving_millis_(kPollPeriodMovingMillis),
poll_period_stationary_millis_(kPollPeriodStationaryMillis),
libgps_factory_(libgps_factory),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ weak_factory_(this) {
DCHECK(libgps_factory_);
}
@@ -285,7 +285,7 @@
void GpsLocationProviderLinux::ScheduleNextGpsPoll(int interval) {
weak_factory_.InvalidateWeakPtrs();
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&GpsLocationProviderLinux::DoGpsPollTask,
weak_factory_.GetWeakPtr()),
diff --git a/content/browser/geolocation/gps_location_provider_unittest_linux.cc b/content/browser/geolocation/gps_location_provider_unittest_linux.cc
index 6aaff15..985479f 100644
--- a/content/browser/geolocation/gps_location_provider_unittest_linux.cc
+++ b/content/browser/geolocation/gps_location_provider_unittest_linux.cc
@@ -53,7 +53,7 @@
// LocationProviderBase::ListenerInterface
virtual void LocationUpdateAvailable(
LocationProviderBase* provider) OVERRIDE {
- MessageLoop::current()->Quit();
+ base::MessageLoop::current()->Quit();
}
};
@@ -70,7 +70,7 @@
}
protected:
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
BrowserThreadImpl ui_thread_;
LocaionProviderListenerLoopQuitter location_listener_;
scoped_ptr<GpsLocationProviderLinux> provider_;
@@ -151,7 +151,7 @@
MockLibGps::g_instance_->get_position_.timestamp =
base::Time::FromDoubleT(200);
EXPECT_TRUE(MockLibGps::g_instance_->get_position_.Validate());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
EXPECT_EQ(1, MockLibGps::g_instance_->get_position_calls_);
EXPECT_EQ(1, MockLibGps::g_instance_->gps_open_calls_);
EXPECT_EQ(1, MockLibGps::g_instance_->gps_read_calls_);
@@ -160,7 +160,7 @@
// Movement. This will block for up to half a second.
MockLibGps::g_instance_->get_position_.latitude += 0.01;
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
provider_->GetPosition(&position);
EXPECT_EQ(2, MockLibGps::g_instance_->get_position_calls_);
EXPECT_EQ(1, MockLibGps::g_instance_->gps_open_calls_);
@@ -194,11 +194,11 @@
EXPECT_TRUE(MockLibGps::g_instance_->get_position_.Validate());
// This task makes gps_open() and LibGps::Start() to succeed after
// 1500ms.
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&EnableGpsOpenCallback),
base::TimeDelta::FromMilliseconds(1500));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
provider_->GetPosition(&position);
EXPECT_TRUE(position.Validate());
// 3 gps_open() calls are expected (2 failures and 1 success)
diff --git a/content/browser/geolocation/location_arbitrator_impl.cc b/content/browser/geolocation/location_arbitrator_impl.cc
index 97cae8e..9b1594f 100644
--- a/content/browser/geolocation/location_arbitrator_impl.cc
+++ b/content/browser/geolocation/location_arbitrator_impl.cc
@@ -125,7 +125,7 @@
}
AccessTokenStore* GeolocationArbitratorImpl::GetAccessTokenStore() {
- if (!access_token_store_.get())
+ if (!access_token_store_)
access_token_store_ = NewAccessTokenStore();
return access_token_store_.get();
}
diff --git a/content/browser/geolocation/location_arbitrator_impl_unittest.cc b/content/browser/geolocation/location_arbitrator_impl_unittest.cc
index e2b39ee..1beb07f 100644
--- a/content/browser/geolocation/location_arbitrator_impl_unittest.cc
+++ b/content/browser/geolocation/location_arbitrator_impl_unittest.cc
@@ -144,7 +144,7 @@
scoped_refptr<FakeAccessTokenStore> access_token_store_;
scoped_ptr<MockLocationObserver> observer_;
scoped_ptr<TestingGeolocationArbitrator> arbitrator_;
- MessageLoop loop_;
+ base::MessageLoop loop_;
};
TEST_F(GeolocationLocationArbitratorTest, CreateDestroy) {
diff --git a/content/browser/geolocation/mock_location_provider.cc b/content/browser/geolocation/mock_location_provider.cc
index e146f38..7c083c7 100644
--- a/content/browser/geolocation/mock_location_provider.cc
+++ b/content/browser/geolocation/mock_location_provider.cc
@@ -72,7 +72,7 @@
AutoMockLocationProvider(bool has_valid_location,
bool requires_permission_to_start)
: MockLocationProvider(&instance_),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+ weak_factory_(this),
requires_permission_to_start_(requires_permission_to_start),
listeners_updated_(false) {
if (has_valid_location) {
@@ -104,10 +104,11 @@
void UpdateListenersIfNeeded() {
if (!listeners_updated_) {
listeners_updated_ = true;
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&MockLocationProvider::HandlePositionChanged,
- weak_factory_.GetWeakPtr(), position_));
+ weak_factory_.GetWeakPtr(),
+ position_));
}
}
diff --git a/content/browser/geolocation/network_location_provider.cc b/content/browser/geolocation/network_location_provider.cc
index 0167fd9..8cf98bb 100644
--- a/content/browser/geolocation/network_location_provider.cc
+++ b/content/browser/geolocation/network_location_provider.cc
@@ -114,7 +114,7 @@
access_token_(access_token),
is_permission_granted_(false),
is_new_data_available_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ weak_factory_(this) {
// Create the position cache.
position_cache_.reset(new PositionCache());
@@ -194,7 +194,7 @@
// provider and it will be deleted by ref counting.
wifi_data_provider_ = WifiDataProvider::Register(this);
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&NetworkLocationProvider::RequestPosition,
weak_factory_.GetWeakPtr()),
diff --git a/content/browser/geolocation/network_location_provider_unittest.cc b/content/browser/geolocation/network_location_provider_unittest.cc
index fb01795..ccbfc1b 100644
--- a/content/browser/geolocation/network_location_provider_unittest.cc
+++ b/content/browser/geolocation/network_location_provider_unittest.cc
@@ -31,7 +31,7 @@
: public LocationProviderBase::ListenerInterface {
public:
MessageLoopQuitListener()
- : client_message_loop_(MessageLoop::current()),
+ : client_message_loop_(base::MessageLoop::current()),
updated_provider_(NULL),
movement_provider_(NULL) {
CHECK(client_message_loop_);
@@ -39,11 +39,11 @@
// ListenerInterface
virtual void LocationUpdateAvailable(
LocationProviderBase* provider) OVERRIDE {
- EXPECT_EQ(client_message_loop_, MessageLoop::current());
+ EXPECT_EQ(client_message_loop_, base::MessageLoop::current());
updated_provider_ = provider;
client_message_loop_->Quit();
}
- MessageLoop* client_message_loop_;
+ base::MessageLoop* client_message_loop_;
LocationProviderBase* updated_provider_;
LocationProviderBase* movement_provider_;
};
@@ -324,7 +324,7 @@
}
GURL test_server_url_;
- MessageLoop main_message_loop_;
+ base::MessageLoop main_message_loop_;
scoped_refptr<FakeAccessTokenStore> access_token_store_;
net::TestURLFetcherFactory url_fetcher_factory_;
scoped_refptr<MockDeviceDataProviderImpl<WifiData> > wifi_data_provider_;
@@ -332,7 +332,7 @@
TEST_F(GeolocationNetworkProviderTest, CreateDestroy) {
// Test fixture members were SetUp correctly.
- EXPECT_EQ(&main_message_loop_, MessageLoop::current());
+ EXPECT_EQ(&main_message_loop_, base::MessageLoop::current());
scoped_ptr<LocationProviderBase> provider(CreateProvider(true));
EXPECT_TRUE(NULL != provider.get());
provider.reset();
@@ -344,7 +344,7 @@
EXPECT_TRUE(provider->StartProvider(false));
net::TestURLFetcher* fetcher = get_url_fetcher_and_advance_id();
ASSERT_TRUE(fetcher != NULL);
- CheckRequestIsValid(*fetcher, 0, 0, 0, "");
+ CheckRequestIsValid(*fetcher, 0, 0, 0, std::string());
}
TEST_F(GeolocationNetworkProviderTest, StartProviderDefaultUrl) {
@@ -353,10 +353,9 @@
EXPECT_TRUE(provider->StartProvider(false));
net::TestURLFetcher* fetcher = get_url_fetcher_and_advance_id();
ASSERT_TRUE(fetcher != NULL);
- CheckRequestIsValid(*fetcher, 0, 0, 0, "");
+ CheckRequestIsValid(*fetcher, 0, 0, 0, std::string());
}
-
TEST_F(GeolocationNetworkProviderTest, StartProviderLongRequest) {
scoped_ptr<LocationProviderBase> provider(CreateProvider(true));
EXPECT_TRUE(provider->StartProvider(false));
@@ -369,7 +368,7 @@
// in length by not including access points with the lowest signal strength
// in the request.
EXPECT_LT(fetcher->GetOriginalURL().spec().size(), size_t(2048));
- CheckRequestIsValid(*fetcher, 0, 16, 4, "");
+ CheckRequestIsValid(*fetcher, 0, 16, 4, std::string());
}
TEST_F(GeolocationNetworkProviderTest, MultiRegistrations) {
@@ -418,7 +417,7 @@
fetcher = get_url_fetcher_and_advance_id();
ASSERT_TRUE(fetcher != NULL);
// The request should have the wifi data.
- CheckRequestIsValid(*fetcher, 0, kFirstScanAps, 0, "");
+ CheckRequestIsValid(*fetcher, 0, kFirstScanAps, 0, std::string());
// Send a reply with good position fix.
const char* kReferenceNetworkResponse =
@@ -472,7 +471,7 @@
fetcher->set_url(test_server_url_);
fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, -1));
fetcher->set_response_code(200); // should be ignored
- fetcher->SetResponseString("");
+ fetcher->SetResponseString(std::string());
fetcher->delegate()->OnURLFetchComplete(fetcher);
// Error means we now no longer have a fix.
diff --git a/content/browser/geolocation/wifi_data_provider_chromeos_unittest.cc b/content/browser/geolocation/wifi_data_provider_chromeos_unittest.cc
index 8fcb6c5..6672715 100644
--- a/content/browser/geolocation/wifi_data_provider_chromeos_unittest.cc
+++ b/content/browser/geolocation/wifi_data_provider_chromeos_unittest.cc
@@ -60,7 +60,7 @@
message_loop_.RunUntilIdle();
}
- MessageLoopForUI message_loop_;
+ base::MessageLoopForUI message_loop_;
scoped_refptr<WifiDataProviderChromeOs> provider_;
chromeos::ShillManagerClient* manager_client_;
chromeos::ShillManagerClient::TestInterface* manager_test_;
diff --git a/content/browser/geolocation/wifi_data_provider_common.cc b/content/browser/geolocation/wifi_data_provider_common.cc
index fd5667a..b00b0a2 100644
--- a/content/browser/geolocation/wifi_data_provider_common.cc
+++ b/content/browser/geolocation/wifi_data_provider_common.cc
@@ -27,7 +27,7 @@
WifiDataProviderCommon::WifiDataProviderCommon()
: Thread("Geolocation_wifi_provider"),
is_first_scan_complete_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ weak_factory_(this) {
}
WifiDataProviderCommon::~WifiDataProviderCommon() {
diff --git a/content/browser/geolocation/wifi_data_provider_common_unittest.cc b/content/browser/geolocation/wifi_data_provider_common_unittest.cc
index 84b1d15..341f392 100644
--- a/content/browser/geolocation/wifi_data_provider_common_unittest.cc
+++ b/content/browser/geolocation/wifi_data_provider_common_unittest.cc
@@ -61,7 +61,7 @@
class MessageLoopQuitListener
: public WifiDataProviderCommon::ListenerInterface {
public:
- explicit MessageLoopQuitListener(MessageLoop* message_loop)
+ explicit MessageLoopQuitListener(base::MessageLoop* message_loop)
: message_loop_to_quit_(message_loop) {
CHECK(message_loop_to_quit_ != NULL);
}
@@ -69,11 +69,11 @@
virtual void DeviceDataUpdateAvailable(
DeviceDataProvider<WifiData>* provider) OVERRIDE {
// Provider should call back on client's thread.
- EXPECT_EQ(MessageLoop::current(), message_loop_to_quit_);
+ EXPECT_EQ(base::MessageLoop::current(), message_loop_to_quit_);
provider_ = provider;
message_loop_to_quit_->QuitNow();
}
- MessageLoop* message_loop_to_quit_;
+ base::MessageLoop* message_loop_to_quit_;
DeviceDataProvider<WifiData>* provider_;
};
@@ -127,7 +127,7 @@
}
protected:
- MessageLoop main_message_loop_;
+ base::MessageLoop main_message_loop_;
MessageLoopQuitListener quit_listener_;
scoped_refptr<WifiDataProviderCommonWithMock> provider_;
MockWlanApi* wlan_api_;
@@ -136,7 +136,7 @@
TEST_F(GeolocationWifiDataProviderCommonTest, CreateDestroy) {
// Test fixture members were SetUp correctly.
- EXPECT_EQ(&main_message_loop_, MessageLoop::current());
+ EXPECT_EQ(&main_message_loop_, base::MessageLoop::current());
EXPECT_TRUE(NULL != provider_.get());
EXPECT_TRUE(NULL != wlan_api_);
}
diff --git a/content/browser/geolocation/wifi_data_provider_corewlan_mac.mm b/content/browser/geolocation/wifi_data_provider_corewlan_mac.mm
index f552984..ab4a729 100644
--- a/content/browser/geolocation/wifi_data_provider_corewlan_mac.mm
+++ b/content/browser/geolocation/wifi_data_provider_corewlan_mac.mm
@@ -12,7 +12,7 @@
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/memory/scoped_nsobject.h"
#include "base/metrics/histogram.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
// Define a subset of the CoreWLAN interfaces we require. We can't depend on
// CoreWLAN.h existing as we need to build on 10.5 SDKs. We can't just send
@@ -89,7 +89,7 @@
}
// "Leak" dl_handle rather than dlclose it, to ensure |merge_key_|
// remains valid.
- if (!merge_key_.get()) {
+ if (!merge_key_) {
// Fall back to a known-working value should the lookup fail (if
// this value is itself wrong it's not the end of the world, we might just
// get very slightly lower quality location fixes due to SSID merges).
diff --git a/content/browser/geolocation/wifi_data_provider_linux.cc b/content/browser/geolocation/wifi_data_provider_linux.cc
index 709063a..09a60f3 100644
--- a/content/browser/geolocation/wifi_data_provider_linux.cc
+++ b/content/browser/geolocation/wifi_data_provider_linux.cc
@@ -148,7 +148,7 @@
device_proxy->CallMethodAndBlock(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
- if (!response.get()) {
+ if (!response) {
LOG(WARNING) << "Failed to get the device type for "
<< device_path.value();
continue; // Check the next device.
@@ -180,7 +180,7 @@
network_manager_proxy_->CallMethodAndBlock(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
- if (!response.get()) {
+ if (!response) {
LOG(WARNING) << "Failed to get the device list";
return false;
}
@@ -208,7 +208,7 @@
device_proxy->CallMethodAndBlock(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
- if (!response.get()) {
+ if (!response) {
LOG(WARNING) << "Failed to get access points data for "
<< adapter_path.value();
return false;
@@ -236,7 +236,7 @@
{
scoped_ptr<dbus::Response> response(
GetAccessPointProperty(access_point_proxy, "Ssid"));
- if (!response.get())
+ if (!response)
continue;
// The response should contain a variant that contains an array of bytes.
dbus::MessageReader reader(response.get());
@@ -260,7 +260,7 @@
{ // Read the mac address
scoped_ptr<dbus::Response> response(
GetAccessPointProperty(access_point_proxy, "HwAddress"));
- if (!response.get())
+ if (!response)
continue;
dbus::MessageReader reader(response.get());
std::string mac;
@@ -270,7 +270,7 @@
continue;
}
- ReplaceSubstringsAfterOffset(&mac, 0U, ":", "");
+ ReplaceSubstringsAfterOffset(&mac, 0U, ":", std::string());
std::vector<uint8> mac_bytes;
if (!base::HexStringToBytes(mac, &mac_bytes) || mac_bytes.size() != 6) {
LOG(WARNING) << "Can't parse mac address (found " << mac_bytes.size()
@@ -284,7 +284,7 @@
{ // Read signal strength.
scoped_ptr<dbus::Response> response(
GetAccessPointProperty(access_point_proxy, "Strength"));
- if (!response.get())
+ if (!response)
continue;
dbus::MessageReader reader(response.get());
uint8 strength = 0;
@@ -300,7 +300,7 @@
{ // Read the channel
scoped_ptr<dbus::Response> response(
GetAccessPointProperty(access_point_proxy, "Frequency"));
- if (!response.get())
+ if (!response)
continue;
dbus::MessageReader reader(response.get());
uint32 frequency = 0;
@@ -335,7 +335,7 @@
scoped_ptr<dbus::Response> response = access_point_proxy->CallMethodAndBlock(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
- if (!response.get()) {
+ if (!response) {
LOG(WARNING) << "Failed to get property for " << property_name;
}
return response.Pass();
diff --git a/content/browser/geolocation/wifi_data_provider_linux_unittest.cc b/content/browser/geolocation/wifi_data_provider_linux_unittest.cc
index 4585008..718fb5d 100644
--- a/content/browser/geolocation/wifi_data_provider_linux_unittest.cc
+++ b/content/browser/geolocation/wifi_data_provider_linux_unittest.cc
@@ -104,7 +104,7 @@
// DeviceDataProviderImplBase, a super class of WifiDataProviderLinux,
// requires a message loop to be present. message_loop_ is defined here,
// as it should outlive wifi_provider_linux_.
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
scoped_refptr<dbus::MockBus> mock_bus_;
scoped_refptr<dbus::MockObjectProxy> mock_network_manager_proxy_;
scoped_refptr<dbus::MockObjectProxy> mock_access_point_proxy_;
diff --git a/content/browser/geolocation/wifi_data_provider_unittest_win.cc b/content/browser/geolocation/wifi_data_provider_unittest_win.cc
index e4cd77b..c74f42c 100644
--- a/content/browser/geolocation/wifi_data_provider_unittest_win.cc
+++ b/content/browser/geolocation/wifi_data_provider_unittest_win.cc
@@ -12,7 +12,7 @@
TEST(GeolocationWin32WifiDataProviderTest, CreateDestroy) {
// WifiDataProviderCommon requires the client to have a message loop.
- MessageLoop dummy_loop;
+ base::MessageLoop dummy_loop;
scoped_refptr<Win32WifiDataProvider> instance(new Win32WifiDataProvider);
instance = NULL;
SUCCEED();
diff --git a/content/browser/geolocation/wifi_data_provider_win.cc b/content/browser/geolocation/wifi_data_provider_win.cc
index abd21ac..bdf50f3 100644
--- a/content/browser/geolocation/wifi_data_provider_win.cc
+++ b/content/browser/geolocation/wifi_data_provider_win.cc
@@ -618,7 +618,7 @@
if (buffer_size == 0) {
return false;
}
- scoped_array<char16> buffer(new char16[buffer_size]);
+ scoped_ptr<char16[]> buffer(new char16[buffer_size]);
// Return value excludes terminating NULL.
int characters_written = ::GetSystemDirectory(buffer.get(), buffer_size);
diff --git a/content/browser/geolocation/win7_location_provider_unittest_win.cc b/content/browser/geolocation/win7_location_provider_unittest_win.cc
index 9c2e299..6083db2 100644
--- a/content/browser/geolocation/win7_location_provider_unittest_win.cc
+++ b/content/browser/geolocation/win7_location_provider_unittest_win.cc
@@ -63,17 +63,17 @@
class LocationProviderListenerLoopQuitter
: public LocationProviderBase::ListenerInterface {
public:
- explicit LocationProviderListenerLoopQuitter(MessageLoop* message_loop)
+ explicit LocationProviderListenerLoopQuitter(base::MessageLoop* message_loop)
: message_loop_to_quit_(message_loop) {
CHECK(message_loop_to_quit_ != NULL);
}
virtual void LocationUpdateAvailable(LocationProviderBase* provider) {
- EXPECT_EQ(MessageLoop::current(), message_loop_to_quit_);
+ EXPECT_EQ(base::MessageLoop::current(), message_loop_to_quit_);
provider_ = provider;
message_loop_to_quit_->Quit();
}
- MessageLoop* message_loop_to_quit_;
+ base::MessageLoop* message_loop_to_quit_;
LocationProviderBase* provider_;
};
@@ -97,7 +97,7 @@
protected:
MockWin7LocationApi* api_;
LocationProviderListenerLoopQuitter location_listener_;
- MessageLoop main_message_loop_;
+ base::MessageLoop main_message_loop_;
Win7LocationProvider* provider_;
};
diff --git a/content/browser/geolocation/win7_location_provider_win.cc b/content/browser/geolocation/win7_location_provider_win.cc
index fa7122d..ae33c2f 100644
--- a/content/browser/geolocation/win7_location_provider_win.cc
+++ b/content/browser/geolocation/win7_location_provider_win.cc
@@ -46,7 +46,7 @@
}
Win7LocationProvider::Win7LocationProvider(Win7LocationApi* api)
- : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ : weak_factory_(this) {
DCHECK(api != NULL);
api_.reset(api);
}
@@ -91,7 +91,7 @@
}
void Win7LocationProvider::ScheduleNextPoll(int interval) {
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&Win7LocationProvider::DoPollTask, weak_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(interval));
diff --git a/content/browser/gpu/OWNERS b/content/browser/gpu/OWNERS
index 584b4f7..fed3782 100644
--- a/content/browser/gpu/OWNERS
+++ b/content/browser/gpu/OWNERS
@@ -2,5 +2,4 @@
kbr@chromium.org
gman@chromium.org
piman@chromium.org
-jbates@chromium.org
zmo@chromium.org
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc
index ca18691..00ab6c3 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.cc
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -251,7 +251,7 @@
GpuChannelHost* BrowserGpuChannelHostFactory::EstablishGpuChannelSync(
CauseForGpuLaunch cause_for_gpu_launch) {
- if (gpu_channel_.get()) {
+ if (gpu_channel_) {
// Recreate the channel if it has been lost.
if (gpu_channel_->state() == GpuChannelHost::kLost)
gpu_channel_ = NULL;
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.h b/content/browser/gpu/browser_gpu_channel_host_factory.h
index f9290bb..2d3c021 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.h
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.h
@@ -23,7 +23,7 @@
// GpuChannelHostFactory implementation.
virtual bool IsMainThread() OVERRIDE;
virtual bool IsIOThread() OVERRIDE;
- virtual MessageLoop* GetMainLoop() OVERRIDE;
+ virtual base::MessageLoop* GetMainLoop() OVERRIDE;
virtual scoped_refptr<base::MessageLoopProxy> GetIOLoopProxy() OVERRIDE;
virtual base::WaitableEvent* GetShutDownEvent() OVERRIDE;
virtual scoped_ptr<base::SharedMemory> AllocateSharedMemory(
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc
index 9e679b0..0b34932 100644
--- a/content/browser/gpu/compositor_util.cc
+++ b/content/browser/gpu/compositor_util.cc
@@ -9,24 +9,23 @@
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/gpu_feature_type.h"
namespace content {
namespace {
bool CanDoAcceleratedCompositing() {
- const GpuDataManager* gpu_data_manager = GpuDataManager::GetInstance();
- GpuFeatureType blacklisted_features =
- gpu_data_manager->GetBlacklistedFeatures();
+ const GpuDataManager* manager = GpuDataManager::GetInstance();
// Don't run the field trial if gpu access has been blocked or
// accelerated compositing is blacklisted.
- if (!gpu_data_manager->GpuAccessAllowed() ||
- blacklisted_features & GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)
+ if (!manager->GpuAccessAllowed(NULL) ||
+ manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING))
return false;
- // Check for the software rasterizer (SwiftShader).
- if (gpu_data_manager->ShouldUseSoftwareRendering())
+ // Check for SwiftShader.
+ if (manager->ShouldUseSwiftShader())
return false;
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
@@ -37,10 +36,8 @@
}
bool IsForceCompositingModeBlacklisted() {
- GpuFeatureType blacklisted_features =
- GpuDataManager::GetInstance()->GetBlacklistedFeatures();
- return GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE ==
- (blacklisted_features & GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE);
+ return GpuDataManager::GetInstance()->IsFeatureBlacklisted(
+ GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE);
}
} // namespace
diff --git a/content/browser/gpu/gpu_blacklist.cc b/content/browser/gpu/gpu_blacklist.cc
index cd080f4..c8fcbfa 100644
--- a/content/browser/gpu/gpu_blacklist.cc
+++ b/content/browser/gpu/gpu_blacklist.cc
@@ -18,34 +18,33 @@
// static
GpuBlacklist* GpuBlacklist::Create() {
GpuBlacklist* list = new GpuBlacklist();
- list->AddFeature("accelerated_2d_canvas",
- GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS);
- list->AddFeature("accelerated_compositing",
- GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING);
- list->AddFeature("webgl",
- GPU_FEATURE_TYPE_WEBGL);
- list->AddFeature("multisampling",
- GPU_FEATURE_TYPE_MULTISAMPLING);
- list->AddFeature("flash_3d",
- GPU_FEATURE_TYPE_FLASH3D);
- list->AddFeature("flash_stage3d",
- GPU_FEATURE_TYPE_FLASH_STAGE3D);
- list->AddFeature("flash_stage3d_baseline",
- GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE);
- list->AddFeature("texture_sharing",
- GPU_FEATURE_TYPE_TEXTURE_SHARING);
- list->AddFeature("accelerated_video_decode",
- GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE);
- list->AddFeature("3d_css",
- GPU_FEATURE_TYPE_3D_CSS);
- list->AddFeature("accelerated_video",
- GPU_FEATURE_TYPE_ACCELERATED_VIDEO);
- list->AddFeature("panel_fitting",
- GPU_FEATURE_TYPE_PANEL_FITTING);
- list->AddFeature("force_compositing_mode",
- GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE);
- list->AddFeature("all",
- GPU_FEATURE_TYPE_ALL);
+ list->AddSupportedFeature("accelerated_2d_canvas",
+ GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS);
+ list->AddSupportedFeature("accelerated_compositing",
+ GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING);
+ list->AddSupportedFeature("webgl",
+ GPU_FEATURE_TYPE_WEBGL);
+ list->AddSupportedFeature("multisampling",
+ GPU_FEATURE_TYPE_MULTISAMPLING);
+ list->AddSupportedFeature("flash_3d",
+ GPU_FEATURE_TYPE_FLASH3D);
+ list->AddSupportedFeature("flash_stage3d",
+ GPU_FEATURE_TYPE_FLASH_STAGE3D);
+ list->AddSupportedFeature("flash_stage3d_baseline",
+ GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE);
+ list->AddSupportedFeature("texture_sharing",
+ GPU_FEATURE_TYPE_TEXTURE_SHARING);
+ list->AddSupportedFeature("accelerated_video_decode",
+ GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE);
+ list->AddSupportedFeature("3d_css",
+ GPU_FEATURE_TYPE_3D_CSS);
+ list->AddSupportedFeature("accelerated_video",
+ GPU_FEATURE_TYPE_ACCELERATED_VIDEO);
+ list->AddSupportedFeature("panel_fitting",
+ GPU_FEATURE_TYPE_PANEL_FITTING);
+ list->AddSupportedFeature("force_compositing_mode",
+ GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE);
+ list->set_supports_feature_type_all(true);
return list;
}
diff --git a/content/browser/gpu/gpu_blacklist_unittest.cc b/content/browser/gpu/gpu_blacklist_unittest.cc
index 43d0bc0..89c0b10 100644
--- a/content/browser/gpu/gpu_blacklist_unittest.cc
+++ b/content/browser/gpu/gpu_blacklist_unittest.cc
@@ -51,9 +51,10 @@
scoped_ptr<GpuBlacklist> blacklist(GpuBlacklist::Create());
EXPECT_TRUE(blacklist->LoadList(json, GpuBlacklist::kAllOs));
- int type = blacklist->MakeDecision(
+ std::set<int> type = blacklist->MakeDecision(
GpuBlacklist::kOsMacosx, kOsVersion, gpu_info());
- EXPECT_EQ(static_cast<int>(feature_type), type);
+ EXPECT_EQ(1u, type.size());
+ EXPECT_EQ(1u, type.count(feature_type));
}
protected:
@@ -90,7 +91,7 @@
int64 data_file_size64 = 0;
ASSERT_TRUE(file_util::GetFileSize(data_file, &data_file_size64));
int data_file_size = static_cast<int>(data_file_size64);
- scoped_array<char> data(new char[data_file_size]);
+ scoped_ptr<char[]> data(new char[data_file_size]);
ASSERT_EQ(data_file_size,
file_util::ReadFile(data_file, data.get(), data_file_size));
std::string json_string(data.get(), data_file_size);
@@ -156,8 +157,4 @@
"force_compositing_mode",
GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE)
-GPU_BLACKLIST_FEATURE_TEST(All,
- "all",
- GPU_FEATURE_TYPE_ALL)
-
} // namespace content
diff --git a/content/browser/gpu/gpu_control_list.cc b/content/browser/gpu/gpu_control_list.cc
index 0d57e7b..0fba7c8 100644
--- a/content/browser/gpu/gpu_control_list.cc
+++ b/content/browser/gpu/gpu_control_list.cc
@@ -7,8 +7,8 @@
#include "base/cpu.h"
#include "base/json/json_reader.h"
#include "base/logging.h"
-#include "base/string_number_conversions.h"
#include "base/string_util.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/sys_info.h"
#include "content/browser/gpu/gpu_util.h"
@@ -217,8 +217,8 @@
const std::string& version_string2) {
type_ = StringToOsType(os);
if (type_ != kOsUnknown) {
- version_info_.reset(
- new VersionInfo(version_op, "", version_string, version_string2));
+ version_info_.reset(new VersionInfo(
+ version_op, std::string(), version_string, version_string2));
}
}
@@ -265,8 +265,8 @@
const std::string& version_string,
const std::string& version_string2) {
name_info_.reset(new StringInfo(name_op, name_value));
- version_info_.reset(
- new VersionInfo(version_op, "", version_string, version_string2));
+ version_info_.reset(new VersionInfo(
+ version_op, std::string(), version_string, version_string2));
}
GpuControlList::MachineModelInfo::~MachineModelInfo() {}
@@ -329,13 +329,15 @@
: op_(kUnknown),
value_(0.f),
value2_(0.f) {
+ op_ = StringToNumericOp(float_op);
+ if (op_ == kAny)
+ return;
double dvalue = 0;
if (!base::StringToDouble(float_value, &dvalue)) {
op_ = kUnknown;
return;
}
value_ = static_cast<float>(dvalue);
- op_ = StringToNumericOp(float_op);
if (op_ == kBetween) {
if (!base::StringToDouble(float_value2, &dvalue)) {
op_ = kUnknown;
@@ -375,11 +377,13 @@
: op_(kUnknown),
value_(0),
value2_(0) {
+ op_ = StringToNumericOp(int_op);
+ if (op_ == kAny)
+ return;
if (!base::StringToInt(int_value, &value_)) {
op_ = kUnknown;
return;
}
- op_ = StringToNumericOp(int_op);
if (op_ == kBetween &&
!base::StringToInt(int_value2, &value2_))
op_ = kUnknown;
@@ -413,7 +417,8 @@
GpuControlList::ScopedGpuControlListEntry
GpuControlList::GpuControlListEntry::GetEntryFromValue(
const base::DictionaryValue* value, bool top_level,
- const FeatureMap& feature_map) {
+ const FeatureMap& feature_map,
+ bool supports_feature_type_all) {
DCHECK(value);
ScopedGpuControlListEntry entry(new GpuControlListEntry());
@@ -720,7 +725,8 @@
return NULL;
}
}
- if (!entry->SetFeatures(feature_list, feature_map)) {
+ if (!entry->SetFeatures(
+ feature_list, feature_map, supports_feature_type_all)) {
LOG(WARNING) << "Malformed feature entry " << entry->id();
return NULL;
}
@@ -737,8 +743,8 @@
LOG(WARNING) << "Malformed exceptions entry " << entry->id();
return NULL;
}
- ScopedGpuControlListEntry exception(
- GetEntryFromValue(exception_value, false, feature_map));
+ ScopedGpuControlListEntry exception(GetEntryFromValue(
+ exception_value, false, feature_map, supports_feature_type_all));
if (exception == NULL) {
LOG(WARNING) << "Malformed exceptions entry " << entry->id();
return NULL;
@@ -858,7 +864,7 @@
const std::string& date_string,
const std::string& date_string2) {
driver_date_info_.reset(
- new VersionInfo(date_op, "", date_string, date_string2));
+ new VersionInfo(date_op, std::string(), date_string, date_string2));
return driver_date_info_->IsValid();
}
@@ -928,20 +934,25 @@
bool GpuControlList::GpuControlListEntry::SetFeatures(
const std::vector<std::string>& feature_strings,
- const FeatureMap& feature_map) {
+ const FeatureMap& feature_map,
+ bool supports_feature_type_all) {
size_t size = feature_strings.size();
if (size == 0)
return false;
- int features = 0;
+ features_.clear();
for (size_t i = 0; i < size; ++i) {
int feature = 0;
- bool valid = StringToFeature(feature_strings[i], &feature, feature_map);
- if (valid)
- features |= feature;
+ if (supports_feature_type_all && feature_strings[i] == "all") {
+ for (FeatureMap::const_iterator iter = feature_map.begin();
+ iter != feature_map.end(); ++iter)
+ features_.insert(iter->second);
+ continue;
+ }
+ if (StringToFeature(feature_strings[i], &feature, feature_map))
+ features_.insert(feature);
else
- contains_unknown_features_ = true;
+ contains_unknown_features_ = true;
}
- features_ = features;
return true;
}
@@ -1103,7 +1114,7 @@
return disabled_;
}
-int GpuControlList::GpuControlListEntry::GetFeatures() const {
+const std::set<int>& GpuControlList::GpuControlListEntry::features() const {
return features_;
}
@@ -1122,7 +1133,8 @@
GpuControlList::GpuControlList()
: max_entry_id_(0),
contains_unknown_fields_(false),
- needs_more_info_(false) {
+ needs_more_info_(false),
+ supports_feature_type_all_(false) {
}
GpuControlList::~GpuControlList() {
@@ -1184,8 +1196,8 @@
if (browser_version_support == kUnsupported)
continue;
DCHECK(browser_version_support == kSupported);
- ScopedGpuControlListEntry entry(
- GpuControlListEntry::GetEntryFromValue(list_item, true, feature_map_));
+ ScopedGpuControlListEntry entry(GpuControlListEntry::GetEntryFromValue(
+ list_item, true, feature_map_, supports_feature_type_all_));
if (entry == NULL)
return false;
if (entry->id() > max_entry_id)
@@ -1207,22 +1219,22 @@
OsType entry_os = entries[i]->GetOsType();
if (os_filter == GpuControlList::kAllOs ||
entry_os == kOsAny || entry_os == my_os)
- feature_list_.push_back(entries[i]);
+ entries_.push_back(entries[i]);
}
max_entry_id_ = max_entry_id;
contains_unknown_fields_ = contains_unknown_fields;
return true;
}
-int GpuControlList::MakeDecision(
+std::set<int> GpuControlList::MakeDecision(
GpuControlList::OsType os,
std::string os_version,
const GPUInfo& gpu_info) {
active_entries_.clear();
- int features = 0;
+ std::set<int> features;
needs_more_info_ = false;
- int possible_features = 0;
+ std::set<int> possible_features;
if (os == kOsAny)
os = GetOsType();
@@ -1236,20 +1248,18 @@
if (!ProcessVersionString(os_version, '.', &pieces))
os_version = "0";
- for (size_t i = 0; i < feature_list_.size(); ++i) {
- if (feature_list_[i]->Contains(os, os_version, gpu_info)) {
- if (!feature_list_[i]->disabled()) {
- bool not_final = feature_list_[i]->NeedsMoreInfo(gpu_info);
- if (not_final)
- possible_features |= feature_list_[i]->GetFeatures();
- else
- features |= feature_list_[i]->GetFeatures();
+ for (size_t i = 0; i < entries_.size(); ++i) {
+ if (entries_[i]->Contains(os, os_version, gpu_info)) {
+ if (!entries_[i]->disabled()) {
+ MergeFeatureSets(&possible_features, entries_[i]->features());
+ if (!entries_[i]->NeedsMoreInfo(gpu_info))
+ MergeFeatureSets(&features, entries_[i]->features());
}
- active_entries_.push_back(feature_list_[i]);
+ active_entries_.push_back(entries_[i]);
}
}
- if (possible_features != 0 && (possible_features | features) != features)
+ if (possible_features.size() > features.size())
needs_more_info_ = true;
return features;
@@ -1291,14 +1301,14 @@
}
size_t GpuControlList::num_entries() const {
- return feature_list_.size();
+ return entries_.size();
}
uint32 GpuControlList::max_entry_id() const {
return max_entry_id_;
}
-std::string GpuControlList::GetVersion() const {
+std::string GpuControlList::version() const {
return version_;
}
@@ -1319,7 +1329,7 @@
}
void GpuControlList::Clear() {
- feature_list_.clear();
+ entries_.clear();
active_entries_.clear();
max_entry_id_ = 0;
contains_unknown_fields_ = false;
@@ -1338,8 +1348,8 @@
browser_version_value->GetString("number", &version_string);
browser_version_value->GetString("number2", &version_string2);
scoped_ptr<VersionInfo> browser_version_info;
- browser_version_info.reset(
- new VersionInfo(version_op, "", version_string, version_string2));
+ browser_version_info.reset(new VersionInfo(
+ version_op, std::string(), version_string, version_string2));
if (!browser_version_info->IsValid())
return kMalformed;
if (browser_version_info->Contains(browser_version_))
@@ -1369,10 +1379,14 @@
return kUnknown;
}
-void GpuControlList::AddFeature(
+void GpuControlList::AddSupportedFeature(
const std::string& feature_name, int feature_id) {
feature_map_[feature_name] = feature_id;
}
+void GpuControlList::set_supports_feature_type_all(bool supported) {
+ supports_feature_type_all_ = supported;
+}
+
} // namespace content
diff --git a/content/browser/gpu/gpu_control_list.h b/content/browser/gpu/gpu_control_list.h
index 1f7e9e1..cd7f69b 100644
--- a/content/browser/gpu/gpu_control_list.h
+++ b/content/browser/gpu/gpu_control_list.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_GPU_GPU_CONTROL_LIST_H_
#define CONTENT_BROWSER_GPU_GPU_CONTROL_LIST_H_
+#include <set>
#include <string>
#include <vector>
@@ -53,7 +54,7 @@
// system and returns the union of features specified in each entry.
// If os is kOsAny, use the current OS; if os_version is empty, use the
// current OS version.
- int MakeDecision(
+ std::set<int> MakeDecision(
OsType os, std::string os_version, const GPUInfo& gpu_info);
// Collects the active entries from the last MakeDecision() call.
@@ -76,8 +77,8 @@
// Return the largest entry id. This is used for histogramming.
uint32 max_entry_id() const;
- // Returns the version of the current blacklist.
- std::string GetVersion() const;
+ // Returns the version of the control list.
+ std::string version() const;
// Check if we need more gpu info to make the decisions.
// This is computed from the last MakeDecision() call.
@@ -91,9 +92,18 @@
size_t num_entries() const;
// Register a feature to FeatureMap - used to construct a GpuControlList.
- void AddFeature(const std::string& feature_name, int feature_id);
+ void AddSupportedFeature(const std::string& feature_name, int feature_id);
+ // Register whether "all" is recognized as all features.
+ void set_supports_feature_type_all(bool supported);
private:
+ friend class GpuControlListEntryTest;
+ friend class MachineModelInfoTest;
+ friend class NumberInfoTest;
+ friend class OsInfoTest;
+ friend class StringInfoTest;
+ friend class VersionInfoTest;
+
enum BrowserVersionSupport {
kSupported,
kUnsupported,
@@ -111,7 +121,7 @@
kUnknown // Indicates the data is invalid.
};
- class VersionInfo {
+ class CONTENT_EXPORT VersionInfo {
public:
// If version_style is empty, it defaults to kNumerical.
VersionInfo(const std::string& version_op,
@@ -145,10 +155,9 @@
// Return 1 if version > version_ref,
// 0 if version = version_ref,
// -1 if version < version_ref.
- // Note that we only compare as many as segments as version_ref contains.
- // If version_ref is xxx.yyy, it's considered as xxx.yyy.*
+ // Note that we only compare as many segments as both versions contain.
// For example: Compare("10.3.1", "10.3") returns 0,
- // Compare("10.3", "10.3.1") returns -1.
+ // Compare("10.3", "10.3.1") returns 0.
// If "version_style" is Lexical, the first segment is compared
// numerically, all other segments are compared lexically.
// Lexical is used for AMD Linux driver versions only.
@@ -162,7 +171,7 @@
std::vector<std::string> version2_;
};
- class OsInfo {
+ class CONTENT_EXPORT OsInfo {
public:
OsInfo(const std::string& os,
const std::string& version_op,
@@ -186,7 +195,7 @@
scoped_ptr<VersionInfo> version_info_;
};
- class StringInfo {
+ class CONTENT_EXPORT StringInfo {
public:
StringInfo(const std::string& string_op, const std::string& string_value);
@@ -212,7 +221,7 @@
std::string value_;
};
- class FloatInfo {
+ class CONTENT_EXPORT FloatInfo {
public:
FloatInfo(const std::string& float_op,
const std::string& float_value,
@@ -230,7 +239,7 @@
float value2_;
};
- class IntInfo {
+ class CONTENT_EXPORT IntInfo {
public:
IntInfo(const std::string& int_op,
const std::string& int_value,
@@ -248,7 +257,7 @@
int value2_;
};
- class MachineModelInfo {
+ class CONTENT_EXPORT MachineModelInfo {
public:
MachineModelInfo(const std::string& name_op,
const std::string& name_value,
@@ -273,13 +282,15 @@
typedef base::hash_map<std::string, int> FeatureMap;
- class GpuControlListEntry : public base::RefCounted<GpuControlListEntry> {
+ class CONTENT_EXPORT GpuControlListEntry
+ : public base::RefCounted<GpuControlListEntry> {
public:
// Constructs GpuControlListEntry from DictionaryValue loaded from json.
// Top-level entry must have an id number. Others are exceptions.
static ScopedGpuControlListEntry GetEntryFromValue(
const base::DictionaryValue* value, bool top_level,
- const FeatureMap& feature_map);
+ const FeatureMap& feature_map,
+ bool supports_feature_type_all);
// Determines if a given os/gc/machine_model/driver is included in the
// Entry set.
@@ -306,8 +317,8 @@
const std::vector<int>& cr_bugs() const { return cr_bugs_; }
const std::vector<int>& webkit_bugs() const { return webkit_bugs_; }
- // Returns the features.
- int GetFeatures() const;
+ // Returns the blacklisted features in this entry.
+ const std::set<int>& features() const;
// Returns true if an unknown field is encountered.
bool contains_unknown_fields() const {
@@ -398,7 +409,8 @@
const std::string& int_string2);
bool SetFeatures(const std::vector<std::string>& features,
- const FeatureMap& feature_map);
+ const FeatureMap& feature_map,
+ bool supports_feature_type_all);
void AddException(ScopedGpuControlListEntry exception);
@@ -434,7 +446,7 @@
scoped_ptr<FloatInfo> perf_overall_info_;
scoped_ptr<MachineModelInfo> machine_model_info_;
scoped_ptr<IntInfo> gpu_count_info_;
- int features_;
+ std::set<int> features_;
std::vector<ScopedGpuControlListEntry> exceptions_;
bool contains_unknown_fields_;
bool contains_unknown_features_;
@@ -456,13 +468,13 @@
static NumericOp StringToNumericOp(const std::string& op);
std::string version_;
- std::vector<ScopedGpuControlListEntry> feature_list_;
+ std::vector<ScopedGpuControlListEntry> entries_;
std::string browser_version_;
// This records all the blacklist entries that are appliable to the current
- // user machine. It is updated everytime MakeBlacklistDecision() is
- // called and is used later by GetDecisionEntries().
+ // user machine. It is updated everytime MakeDecision() is called and is
+ // used later by GetDecisionEntries().
std::vector<ScopedGpuControlListEntry> active_entries_;
uint32 max_entry_id_;
@@ -473,6 +485,7 @@
// The features a GpuControlList recognizes and handles.
FeatureMap feature_map_;
+ bool supports_feature_type_all_;
};
} // namespace content
diff --git a/content/browser/gpu/gpu_control_list_entry_unittest.cc b/content/browser/gpu/gpu_control_list_entry_unittest.cc
new file mode 100644
index 0000000..16b2eb3
--- /dev/null
+++ b/content/browser/gpu/gpu_control_list_entry_unittest.cc
@@ -0,0 +1,748 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/json/json_reader.h"
+#include "content/browser/gpu/gpu_control_list.h"
+#include "content/public/common/gpu_info.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#define LONG_STRING_CONST(...) #__VA_ARGS__
+
+namespace content {
+
+enum TestFeatureType {
+ TEST_FEATURE_0 = 0,
+ TEST_FEATURE_1,
+ TEST_FEATURE_2
+};
+
+class GpuControlListEntryTest : public testing::Test {
+ public:
+ GpuControlListEntryTest() { }
+ virtual ~GpuControlListEntryTest() { }
+
+ const GPUInfo& gpu_info() const {
+ return gpu_info_;
+ }
+
+ typedef GpuControlList::ScopedGpuControlListEntry ScopedEntry;
+
+ static ScopedEntry GetEntryFromString(
+ const std::string& json, bool supports_feature_type_all) {
+ scoped_ptr<base::Value> root;
+ root.reset(base::JSONReader::Read(json));
+ DictionaryValue* value = NULL;
+ if (root.get() == NULL || !root->GetAsDictionary(&value))
+ return NULL;
+
+ GpuControlList::FeatureMap feature_map;
+ feature_map["test_feature_0"] = TEST_FEATURE_0;
+ feature_map["test_feature_1"] = TEST_FEATURE_1;
+ feature_map["test_feature_2"] = TEST_FEATURE_2;
+
+ return GpuControlList::GpuControlListEntry::GetEntryFromValue(
+ value, true, feature_map, supports_feature_type_all);
+ }
+
+ static ScopedEntry GetEntryFromString(const std::string& json) {
+ return GetEntryFromString(json, false);
+ }
+
+ virtual void SetUp() {
+ gpu_info_.gpu.vendor_id = 0x10de;
+ gpu_info_.gpu.device_id = 0x0640;
+ gpu_info_.driver_vendor = "NVIDIA";
+ gpu_info_.driver_version = "1.6.18";
+ gpu_info_.driver_date = "7-14-2009";
+ gpu_info_.machine_model = "MacBookPro 7.1";
+ gpu_info_.gl_vendor = "NVIDIA Corporation";
+ gpu_info_.gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine";
+ gpu_info_.performance_stats.graphics = 5.0;
+ gpu_info_.performance_stats.gaming = 5.0;
+ gpu_info_.performance_stats.overall = 5.0;
+ }
+
+ private:
+ GPUInfo gpu_info_;
+};
+
+TEST_F(GpuControlListEntryTest, DetailedEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 5,
+ "description": "test entry",
+ "cr_bugs": [1024, 678],
+ "webkit_bugs": [1950],
+ "os": {
+ "type": "macosx",
+ "version": {
+ "op": "=",
+ "number": "10.6.4"
+ }
+ },
+ "vendor_id": "0x10de",
+ "device_id": ["0x0640"],
+ "driver_version": {
+ "op": "=",
+ "number": "1.6.18"
+ },
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_EQ(GpuControlList::kOsMacosx, entry->GetOsType());
+ EXPECT_FALSE(entry->disabled());
+ EXPECT_EQ(5u, entry->id());
+ EXPECT_STREQ("test entry", entry->description().c_str());
+ EXPECT_EQ(2u, entry->cr_bugs().size());
+ EXPECT_EQ(1024, entry->cr_bugs()[0]);
+ EXPECT_EQ(678, entry->cr_bugs()[1]);
+ EXPECT_EQ(1u, entry->webkit_bugs().size());
+ EXPECT_EQ(1950, entry->webkit_bugs()[0]);
+ EXPECT_EQ(1u, entry->features().size());
+ EXPECT_EQ(1u, entry->features().count(TEST_FEATURE_0));
+ EXPECT_FALSE(entry->contains_unknown_fields());
+ EXPECT_FALSE(entry->contains_unknown_features());
+ EXPECT_FALSE(entry->NeedsMoreInfo(gpu_info()));
+ EXPECT_TRUE(entry->Contains(
+ GpuControlList::kOsMacosx, "10.6.4", gpu_info()));
+}
+
+TEST_F(GpuControlListEntryTest, VendorOnAllOsEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "vendor_id": "0x10de",
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_EQ(GpuControlList::kOsAny, entry->GetOsType());
+
+ const GpuControlList::OsType os_type[] = {
+ GpuControlList::kOsMacosx,
+ GpuControlList::kOsWin,
+ GpuControlList::kOsLinux,
+ GpuControlList::kOsChromeOS,
+ GpuControlList::kOsAndroid
+ };
+ for (size_t i = 0; i < arraysize(os_type); ++i)
+ EXPECT_TRUE(entry->Contains(os_type[i], "10.6", gpu_info()));
+}
+
+TEST_F(GpuControlListEntryTest, VendorOnLinuxEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "os": {
+ "type": "linux"
+ },
+ "vendor_id": "0x10de",
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType());
+
+ const GpuControlList::OsType os_type[] = {
+ GpuControlList::kOsMacosx,
+ GpuControlList::kOsWin,
+ GpuControlList::kOsChromeOS,
+ GpuControlList::kOsAndroid
+ };
+ for (size_t i = 0; i < arraysize(os_type); ++i)
+ EXPECT_FALSE(entry->Contains(os_type[i], "10.6", gpu_info()));
+ EXPECT_TRUE(entry->Contains(
+ GpuControlList::kOsLinux, "10.6", gpu_info()));
+}
+
+TEST_F(GpuControlListEntryTest, AllExceptNVidiaOnLinuxEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "os": {
+ "type": "linux"
+ },
+ "exceptions": [
+ {
+ "vendor_id": "0x10de"
+ }
+ ],
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType());
+
+ const GpuControlList::OsType os_type[] = {
+ GpuControlList::kOsMacosx,
+ GpuControlList::kOsWin,
+ GpuControlList::kOsLinux,
+ GpuControlList::kOsChromeOS,
+ GpuControlList::kOsAndroid
+ };
+ for (size_t i = 0; i < arraysize(os_type); ++i)
+ EXPECT_FALSE(entry->Contains(os_type[i], "10.6", gpu_info()));
+}
+
+TEST_F(GpuControlListEntryTest, AllExceptIntelOnLinuxEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "os": {
+ "type": "linux"
+ },
+ "exceptions": [
+ {
+ "vendor_id": "0x8086"
+ }
+ ],
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType());
+
+ const GpuControlList::OsType os_type[] = {
+ GpuControlList::kOsMacosx,
+ GpuControlList::kOsWin,
+ GpuControlList::kOsChromeOS,
+ GpuControlList::kOsAndroid
+ };
+ for (size_t i = 0; i < arraysize(os_type); ++i)
+ EXPECT_FALSE(entry->Contains(os_type[i], "10.6", gpu_info()));
+ EXPECT_TRUE(entry->Contains(
+ GpuControlList::kOsLinux, "10.6", gpu_info()));
+}
+
+TEST_F(GpuControlListEntryTest, DateOnWindowsEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "os": {
+ "type": "win"
+ },
+ "driver_date": {
+ "op": "<",
+ "number": "2010.5.8"
+ },
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_EQ(GpuControlList::kOsWin, entry->GetOsType());
+
+ GPUInfo gpu_info;
+ gpu_info.driver_date = "4-12-2010";
+ EXPECT_TRUE(entry->Contains(
+ GpuControlList::kOsWin, "10.6", gpu_info));
+ gpu_info.driver_date = "5-8-2010";
+ EXPECT_FALSE(entry->Contains(
+ GpuControlList::kOsWin, "10.6", gpu_info));
+ gpu_info.driver_date = "5-9-2010";
+ EXPECT_FALSE(entry->Contains(
+ GpuControlList::kOsWin, "10.6", gpu_info));
+}
+
+TEST_F(GpuControlListEntryTest, MultipleDevicesEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "vendor_id": "0x10de",
+ "device_id": ["0x1023", "0x0640"],
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_EQ(GpuControlList::kOsAny, entry->GetOsType());
+
+ const GpuControlList::OsType os_type[] = {
+ GpuControlList::kOsMacosx,
+ GpuControlList::kOsWin,
+ GpuControlList::kOsLinux,
+ GpuControlList::kOsChromeOS,
+ GpuControlList::kOsAndroid
+ };
+ for (size_t i = 0; i < arraysize(os_type); ++i)
+ EXPECT_TRUE(entry->Contains(os_type[i], "10.6", gpu_info()));
+}
+
+TEST_F(GpuControlListEntryTest, ChromeOSEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "os": {
+ "type": "chromeos"
+ },
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_EQ(GpuControlList::kOsChromeOS, entry->GetOsType());
+
+ const GpuControlList::OsType os_type[] = {
+ GpuControlList::kOsMacosx,
+ GpuControlList::kOsWin,
+ GpuControlList::kOsLinux,
+ GpuControlList::kOsAndroid
+ };
+ for (size_t i = 0; i < arraysize(os_type); ++i)
+ EXPECT_FALSE(entry->Contains(os_type[i], "10.6", gpu_info()));
+ EXPECT_TRUE(entry->Contains(
+ GpuControlList::kOsChromeOS, "10.6", gpu_info()));
+}
+
+TEST_F(GpuControlListEntryTest, MalformedVendor) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "vendor_id": "[0x10de]",
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry == NULL);
+}
+
+TEST_F(GpuControlListEntryTest, UnknownFieldEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "unknown_field": 0,
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->contains_unknown_fields());
+ EXPECT_FALSE(entry->contains_unknown_features());
+}
+
+TEST_F(GpuControlListEntryTest, UnknownExceptionFieldEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 2,
+ "exceptions": [
+ {
+ "unknown_field": 0
+ }
+ ],
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->contains_unknown_fields());
+ EXPECT_FALSE(entry->contains_unknown_features());
+}
+
+TEST_F(GpuControlListEntryTest, UnknownFeatureEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "features": [
+ "some_unknown_feature",
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_FALSE(entry->contains_unknown_fields());
+ EXPECT_TRUE(entry->contains_unknown_features());
+ EXPECT_EQ(1u, entry->features().size());
+ EXPECT_EQ(1u, entry->features().count(TEST_FEATURE_0));
+
+ const GpuControlList::OsType os_type[] = {
+ GpuControlList::kOsMacosx,
+ GpuControlList::kOsWin,
+ GpuControlList::kOsLinux,
+ GpuControlList::kOsChromeOS,
+ GpuControlList::kOsAndroid
+ };
+ for (size_t i = 0; i < arraysize(os_type); ++i)
+ EXPECT_TRUE(entry->Contains(os_type[i], "10.6", gpu_info()));
+}
+
+TEST_F(GpuControlListEntryTest, GlVendorEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "gl_vendor": {
+ "op": "beginwith",
+ "value": "NVIDIA"
+ },
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+
+ const GpuControlList::OsType os_type[] = {
+ GpuControlList::kOsMacosx,
+ GpuControlList::kOsWin,
+ GpuControlList::kOsLinux,
+ GpuControlList::kOsChromeOS,
+ GpuControlList::kOsAndroid
+ };
+ for (size_t i = 0; i < arraysize(os_type); ++i)
+ EXPECT_TRUE(entry->Contains(os_type[i], "10.6", gpu_info()));
+}
+
+TEST_F(GpuControlListEntryTest, GlRendererEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "gl_renderer": {
+ "op": "contains",
+ "value": "GeForce"
+ },
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+
+ const GpuControlList::OsType os_type[] = {
+ GpuControlList::kOsMacosx,
+ GpuControlList::kOsWin,
+ GpuControlList::kOsLinux,
+ GpuControlList::kOsChromeOS,
+ GpuControlList::kOsAndroid
+ };
+ for (size_t i = 0; i < arraysize(os_type); ++i)
+ EXPECT_TRUE(entry->Contains(os_type[i], "10.6", gpu_info()));
+}
+
+TEST_F(GpuControlListEntryTest, PerfGraphicsEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "perf_graphics": {
+ "op": "<",
+ "value": "6.0"
+ },
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->Contains(
+ GpuControlList::kOsWin, "10.6", gpu_info()));
+}
+
+TEST_F(GpuControlListEntryTest, PerfGamingEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "perf_graphics": {
+ "op": "<=",
+ "value": "4.0"
+ },
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_FALSE(entry->Contains(
+ GpuControlList::kOsWin, "10.6", gpu_info()));
+}
+
+TEST_F(GpuControlListEntryTest, PerfOverallEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "perf_overall": {
+ "op": "between",
+ "value": "1.0",
+ "value2": "9.0"
+ },
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->Contains(
+ GpuControlList::kOsWin, "10.6", gpu_info()));
+}
+
+TEST_F(GpuControlListEntryTest, DisabledEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "disabled": true,
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->disabled());
+}
+
+TEST_F(GpuControlListEntryTest, OptimusEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "os": {
+ "type": "linux"
+ },
+ "multi_gpu_style": "optimus",
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ GPUInfo gpu_info;
+ gpu_info.optimus = true;
+
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType());
+ EXPECT_TRUE(entry->Contains(
+ GpuControlList::kOsLinux, "10.6", gpu_info));
+}
+
+TEST_F(GpuControlListEntryTest, AMDSwitchableEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "os": {
+ "type": "macosx"
+ },
+ "multi_gpu_style": "amd_switchable",
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ GPUInfo gpu_info;
+ gpu_info.amd_switchable = true;
+
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_EQ(GpuControlList::kOsMacosx, entry->GetOsType());
+ EXPECT_TRUE(entry->Contains(
+ GpuControlList::kOsMacosx, "10.6", gpu_info));
+}
+
+TEST_F(GpuControlListEntryTest, LexicalDriverVersionEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "os": {
+ "type": "linux"
+ },
+ "vendor_id": "0x1002",
+ "driver_version": {
+ "op": "=",
+ "style": "lexical",
+ "number": "8.76"
+ },
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ GPUInfo gpu_info;
+ gpu_info.gpu.vendor_id = 0x1002;
+
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_EQ(GpuControlList::kOsLinux, entry->GetOsType());
+
+ gpu_info.driver_version = "8.76";
+ EXPECT_TRUE(entry->Contains(
+ GpuControlList::kOsLinux, "10.6", gpu_info));
+
+ gpu_info.driver_version = "8.768";
+ EXPECT_TRUE(entry->Contains(
+ GpuControlList::kOsLinux, "10.6", gpu_info));
+
+ gpu_info.driver_version = "8.76.8";
+ EXPECT_TRUE(entry->Contains(
+ GpuControlList::kOsLinux, "10.6", gpu_info));
+}
+
+TEST_F(GpuControlListEntryTest, MultipleGPUsAnyEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "os": {
+ "type": "macosx"
+ },
+ "vendor_id": "0x8086",
+ "device_id": ["0x0166"],
+ "multi_gpu_category": "any",
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_EQ(GpuControlList::kOsMacosx, entry->GetOsType());
+
+ GPUInfo gpu_info;
+ gpu_info.gpu.vendor_id = 0x10de;
+ gpu_info.gpu.device_id = 0x1976;
+ EXPECT_FALSE(entry->Contains(
+ GpuControlList::kOsMacosx, "10.6", gpu_info));
+
+ GPUInfo::GPUDevice gpu_device;
+ gpu_device.vendor_id = 0x8086;
+ gpu_device.device_id = 0x0166;
+ gpu_info.secondary_gpus.push_back(gpu_device);
+ EXPECT_TRUE(entry->Contains(
+ GpuControlList::kOsMacosx, "10.6", gpu_info));
+}
+
+TEST_F(GpuControlListEntryTest, MultipleGPUsSecondaryEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "os": {
+ "type": "macosx"
+ },
+ "vendor_id": "0x8086",
+ "device_id": ["0x0166"],
+ "multi_gpu_category": "secondary",
+ "features": [
+ "test_feature_0"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_EQ(GpuControlList::kOsMacosx, entry->GetOsType());
+
+ GPUInfo gpu_info;
+ gpu_info.gpu.vendor_id = 0x10de;
+ gpu_info.gpu.device_id = 0x1976;
+ EXPECT_FALSE(entry->Contains(
+ GpuControlList::kOsMacosx, "10.6", gpu_info));
+
+ GPUInfo::GPUDevice gpu_device;
+ gpu_device.vendor_id = 0x8086;
+ gpu_device.device_id = 0x0166;
+ gpu_info.secondary_gpus.push_back(gpu_device);
+ EXPECT_TRUE(entry->Contains(
+ GpuControlList::kOsMacosx, "10.6", gpu_info));
+}
+
+TEST_F(GpuControlListEntryTest, NeedsMoreInfoEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "vendor_id": "0x8086",
+ "driver_version": {
+ "op": "<",
+ "number": "10.7"
+ },
+ "features": [
+ "test_feature_1"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+
+ GPUInfo gpu_info;
+ gpu_info.gpu.vendor_id = 0x8086;
+ EXPECT_TRUE(entry->NeedsMoreInfo(gpu_info));
+
+ gpu_info.driver_version = "10.6";
+ EXPECT_FALSE(entry->NeedsMoreInfo(gpu_info));
+}
+
+TEST_F(GpuControlListEntryTest, NeedsMoreInfoForExceptionsEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "vendor_id": "0x8086",
+ "exceptions": [
+ {
+ "gl_renderer": {
+ "op": "contains",
+ "value": "mesa"
+ }
+ }
+ ],
+ "features": [
+ "test_feature_1"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json));
+ EXPECT_TRUE(entry != NULL);
+
+ GPUInfo gpu_info;
+ gpu_info.gpu.vendor_id = 0x8086;
+ EXPECT_TRUE(entry->NeedsMoreInfo(gpu_info));
+
+ gpu_info.gl_renderer = "mesa";
+ EXPECT_FALSE(entry->NeedsMoreInfo(gpu_info));
+}
+
+TEST_F(GpuControlListEntryTest, FeatureTypeAllEntry) {
+ const std::string json = LONG_STRING_CONST(
+ {
+ "id": 1,
+ "features": [
+ "all"
+ ]
+ }
+ );
+ ScopedEntry entry(GetEntryFromString(json, true));
+ EXPECT_TRUE(entry != NULL);
+ EXPECT_EQ(3u, entry->features().size());
+ EXPECT_EQ(1u, entry->features().count(TEST_FEATURE_0));
+ EXPECT_EQ(1u, entry->features().count(TEST_FEATURE_1));
+ EXPECT_EQ(1u, entry->features().count(TEST_FEATURE_2));
+}
+
+} // namespace content
+
diff --git a/content/browser/gpu/gpu_control_list_machine_model_info_unittest.cc b/content/browser/gpu/gpu_control_list_machine_model_info_unittest.cc
new file mode 100644
index 0000000..8d00a33
--- /dev/null
+++ b/content/browser/gpu/gpu_control_list_machine_model_info_unittest.cc
@@ -0,0 +1,57 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/gpu/gpu_control_list.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class MachineModelInfoTest : public testing::Test {
+ public:
+ MachineModelInfoTest() { }
+ virtual ~MachineModelInfoTest() { }
+
+ typedef GpuControlList::MachineModelInfo MachineModelInfo;
+};
+
+TEST_F(MachineModelInfoTest, ValidModelInfo) {
+ const std::string name_op[] = {
+ "contains",
+ "beginwith",
+ "endwith",
+ "="
+ };
+ const std::string version_op[] = {
+ "=",
+ "<",
+ "<=",
+ ">",
+ ">=",
+ "any",
+ "between"
+ };
+ for (size_t i = 0; i < arraysize(name_op); ++i) {
+ for (size_t j = 0; j < arraysize(version_op); ++j) {
+ std::string version1;
+ std::string version2;
+ if (version_op[j] != "any")
+ version1 = "3.14";
+ if (version_op[j] == "between")
+ version2 = "5.4";
+ MachineModelInfo info(name_op[i], "model",
+ version_op[j], version1, version2);
+ EXPECT_TRUE(info.IsValid());
+ }
+ }
+}
+
+TEST_F(MachineModelInfoTest, ModelComparison) {
+ MachineModelInfo info("=", "model_a", ">", "3.4", std::string());
+ EXPECT_TRUE(info.Contains("model_a", "4"));
+ EXPECT_FALSE(info.Contains("model_b", "4"));
+ EXPECT_FALSE(info.Contains("model_a", "3.2"));
+}
+
+} // namespace content
+
diff --git a/content/browser/gpu/gpu_control_list_number_info_unittest.cc b/content/browser/gpu/gpu_control_list_number_info_unittest.cc
new file mode 100644
index 0000000..0cb72a7
--- /dev/null
+++ b/content/browser/gpu/gpu_control_list_number_info_unittest.cc
@@ -0,0 +1,210 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/gpu/gpu_control_list.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class NumberInfoTest : public testing::Test {
+ public:
+ NumberInfoTest() { }
+ virtual ~NumberInfoTest() { }
+
+ typedef GpuControlList::FloatInfo FloatInfo;
+ typedef GpuControlList::IntInfo IntInfo;
+};
+
+TEST_F(NumberInfoTest, ValidFloatInfo) {
+ const std::string op[] = {
+ "=",
+ "<",
+ "<=",
+ ">",
+ ">=",
+ "any",
+ "between"
+ };
+ for (size_t i = 0; i < arraysize(op); ++i) {
+ std::string value1;
+ std::string value2;
+ if (op[i] != "any")
+ value1 = "3.14";
+ if (op[i] == "between")
+ value2 = "4.21";
+ FloatInfo info(op[i], value1, value2);
+ EXPECT_TRUE(info.IsValid());
+ }
+
+ const std::string value[] = {
+ "1.0E12",
+ "1.0e12",
+ "2013",
+ "1.0e-12",
+ "2.1400",
+ "-2.14",
+ };
+ for (size_t i = 0; i < arraysize(value); ++i) {
+ FloatInfo info("=", value[i], std::string());
+ EXPECT_TRUE(info.IsValid());
+ }
+}
+
+TEST_F(NumberInfoTest, InvalidFloatInfo) {
+ const std::string op[] = {
+ "=",
+ "<",
+ "<=",
+ ">",
+ ">=",
+ };
+ for (size_t i = 0; i < arraysize(op); ++i) {
+ FloatInfo info(op[i], std::string(), std::string());
+ EXPECT_FALSE(info.IsValid());
+ }
+ {
+ FloatInfo info("between", "3.14", std::string());
+ EXPECT_FALSE(info.IsValid());
+ }
+ const std::string value[] = {
+ "1.0 E12",
+ "1.0e 12",
+ " 2013",
+ "2013 ",
+ "- 2.14",
+ };
+ for (size_t i = 0; i < arraysize(value); ++i) {
+ FloatInfo info("=", value[i], std::string());
+ EXPECT_FALSE(info.IsValid());
+ }
+}
+
+TEST_F(NumberInfoTest, FloatComparison) {
+ {
+ FloatInfo info("=", "3.14", std::string());
+ EXPECT_TRUE(info.Contains(3.14f));
+ EXPECT_TRUE(info.Contains(3.1400f));
+ EXPECT_FALSE(info.Contains(3.1f));
+ EXPECT_FALSE(info.Contains(3));
+ }
+ {
+ FloatInfo info(">", "3.14", std::string());
+ EXPECT_FALSE(info.Contains(3.14f));
+ EXPECT_TRUE(info.Contains(3.141f));
+ EXPECT_FALSE(info.Contains(3.1f));
+ }
+ {
+ FloatInfo info("<=", "3.14", std::string());
+ EXPECT_TRUE(info.Contains(3.14f));
+ EXPECT_FALSE(info.Contains(3.141f));
+ EXPECT_TRUE(info.Contains(3.1f));
+ }
+ {
+ FloatInfo info("any", std::string(), std::string());
+ EXPECT_TRUE(info.Contains(3.14f));
+ }
+ {
+ FloatInfo info("between", "3.14", "5.4");
+ EXPECT_TRUE(info.Contains(3.14f));
+ EXPECT_TRUE(info.Contains(5.4f));
+ EXPECT_TRUE(info.Contains(4));
+ EXPECT_FALSE(info.Contains(5.6f));
+ EXPECT_FALSE(info.Contains(3.12f));
+ }
+}
+
+TEST_F(NumberInfoTest, ValidIntInfo) {
+ const std::string op[] = {
+ "=",
+ "<",
+ "<=",
+ ">",
+ ">=",
+ "any",
+ "between"
+ };
+ for (size_t i = 0; i < arraysize(op); ++i) {
+ std::string value1;
+ std::string value2;
+ if (op[i] != "any")
+ value1 = "3";
+ if (op[i] == "between")
+ value2 = "9";
+ IntInfo info(op[i], value1, value2);
+ EXPECT_TRUE(info.IsValid());
+ }
+
+ const std::string value[] = {
+ "12",
+ "-12",
+ };
+ for (size_t i = 0; i < arraysize(value); ++i) {
+ IntInfo info("=", value[i], std::string());
+ EXPECT_TRUE(info.IsValid());
+ }
+}
+
+TEST_F(NumberInfoTest, InvalidIntInfo) {
+ const std::string op[] = {
+ "=",
+ "<",
+ "<=",
+ ">",
+ ">=",
+ };
+ for (size_t i = 0; i < arraysize(op); ++i) {
+ IntInfo info(op[i], std::string(), std::string());
+ EXPECT_FALSE(info.IsValid());
+ }
+ {
+ IntInfo info("between", "3", std::string());
+ EXPECT_FALSE(info.IsValid());
+ }
+ const std::string value[] = {
+ " 12",
+ "12 ",
+ "- 12",
+ " -12",
+ "3.14"
+ };
+ for (size_t i = 0; i < arraysize(value); ++i) {
+ IntInfo info("=", value[i], std::string());
+ EXPECT_FALSE(info.IsValid());
+ }
+}
+
+TEST_F(NumberInfoTest, IntComparison) {
+ {
+ IntInfo info("=", "3", std::string());
+ EXPECT_TRUE(info.Contains(3));
+ EXPECT_FALSE(info.Contains(4));
+ }
+ {
+ IntInfo info(">", "3", std::string());
+ EXPECT_FALSE(info.Contains(2));
+ EXPECT_FALSE(info.Contains(3));
+ EXPECT_TRUE(info.Contains(4));
+ }
+ {
+ IntInfo info("<=", "3", std::string());
+ EXPECT_TRUE(info.Contains(2));
+ EXPECT_TRUE(info.Contains(3));
+ EXPECT_FALSE(info.Contains(4));
+ }
+ {
+ IntInfo info("any", std::string(), std::string());
+ EXPECT_TRUE(info.Contains(3));
+ }
+ {
+ IntInfo info("between", "3", "5");
+ EXPECT_TRUE(info.Contains(3));
+ EXPECT_TRUE(info.Contains(5));
+ EXPECT_TRUE(info.Contains(4));
+ EXPECT_FALSE(info.Contains(6));
+ EXPECT_FALSE(info.Contains(2));
+ }
+}
+
+} // namespace content
+
diff --git a/content/browser/gpu/gpu_control_list_os_info_unittest.cc b/content/browser/gpu/gpu_control_list_os_info_unittest.cc
new file mode 100644
index 0000000..5ea03b2
--- /dev/null
+++ b/content/browser/gpu/gpu_control_list_os_info_unittest.cc
@@ -0,0 +1,111 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/gpu/gpu_control_list.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class OsInfoTest : public testing::Test {
+ public:
+ OsInfoTest() { }
+ virtual ~OsInfoTest() { }
+
+ typedef GpuControlList::OsInfo OsInfo;
+};
+
+TEST_F(OsInfoTest, ValidOsInfo) {
+ const std::string os[] = {
+ "win",
+ "linux",
+ "macosx",
+ "chromeos",
+ "android",
+ "any"
+ };
+ const GpuControlList::OsType os_type[] = {
+ GpuControlList::kOsWin,
+ GpuControlList::kOsLinux,
+ GpuControlList::kOsMacosx,
+ GpuControlList::kOsChromeOS,
+ GpuControlList::kOsAndroid,
+ GpuControlList::kOsAny
+ };
+ for (size_t i = 0; i < arraysize(os); ++i) {
+ OsInfo info(os[i], "=", "10.6", std::string());
+ EXPECT_TRUE(info.IsValid());
+ EXPECT_EQ(os_type[i], info.type());
+ }
+ {
+ OsInfo info("any", "any", std::string(), std::string());
+ EXPECT_TRUE(info.IsValid());
+ }
+}
+
+TEST_F(OsInfoTest, InvalidOsInfo) {
+ const std::string os[] = {
+ "win",
+ "linux",
+ "macosx",
+ "chromeos",
+ "android",
+ "any"
+ };
+ for (size_t i = 0; i < arraysize(os); ++i) {
+ {
+ OsInfo info(os[i], std::string(), std::string(), std::string());
+ EXPECT_FALSE(info.IsValid());
+ }
+ {
+ OsInfo info(os[i], "=", std::string(), std::string());
+ EXPECT_FALSE(info.IsValid());
+ }
+ {
+ OsInfo info(os[i], std::string(), "10.6", std::string());
+ EXPECT_FALSE(info.IsValid());
+ }
+ }
+ const std::string os_cap[] = {
+ "Win",
+ "Linux",
+ "MacOSX",
+ "ChromeOS",
+ "Android",
+ };
+ for (size_t i = 0; i < arraysize(os_cap); ++i) {
+ OsInfo info(os_cap[i], "=", "10.6", std::string());
+ EXPECT_FALSE(info.IsValid());
+ }
+}
+
+TEST_F(OsInfoTest, OsComparison) {
+ {
+ OsInfo info("any", "any", std::string(), std::string());
+ const GpuControlList::OsType os_type[] = {
+ GpuControlList::kOsWin, GpuControlList::kOsLinux,
+ GpuControlList::kOsMacosx, GpuControlList::kOsChromeOS,
+ GpuControlList::kOsAndroid,
+ };
+ for (size_t i = 0; i < arraysize(os_type); ++i) {
+ EXPECT_TRUE(info.Contains(os_type[i], std::string()));
+ EXPECT_TRUE(info.Contains(os_type[i], "7.8"));
+ }
+ }
+ {
+ OsInfo info("win", ">=", "6", std::string());
+ EXPECT_FALSE(info.Contains(GpuControlList::kOsMacosx, "10.8.3"));
+ EXPECT_FALSE(info.Contains(GpuControlList::kOsLinux, "10"));
+ EXPECT_FALSE(info.Contains(GpuControlList::kOsChromeOS, "13"));
+ EXPECT_FALSE(info.Contains(GpuControlList::kOsAndroid, "7"));
+ EXPECT_FALSE(info.Contains(GpuControlList::kOsAny, "7"));
+ EXPECT_FALSE(info.Contains(GpuControlList::kOsWin, std::string()));
+ EXPECT_TRUE(info.Contains(GpuControlList::kOsWin, "6"));
+ EXPECT_TRUE(info.Contains(GpuControlList::kOsWin, "6.1"));
+ EXPECT_TRUE(info.Contains(GpuControlList::kOsWin, "7"));
+ EXPECT_FALSE(info.Contains(GpuControlList::kOsWin, "5"));
+ }
+}
+
+} // namespace content
+
diff --git a/content/browser/gpu/gpu_control_list_string_info_unittest.cc b/content/browser/gpu/gpu_control_list_string_info_unittest.cc
new file mode 100644
index 0000000..c2c8009
--- /dev/null
+++ b/content/browser/gpu/gpu_control_list_string_info_unittest.cc
@@ -0,0 +1,98 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/gpu/gpu_control_list.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class StringInfoTest : public testing::Test {
+ public:
+ StringInfoTest() { }
+ virtual ~StringInfoTest() { }
+
+ typedef GpuControlList::StringInfo StringInfo;
+};
+
+TEST_F(StringInfoTest, ValidStringInfo) {
+ const std::string op[] = {
+ "contains",
+ "beginwith",
+ "endwith",
+ "="
+ };
+ for (size_t i = 0; i < arraysize(op); ++i) {
+ {
+ StringInfo info(op[i], std::string());
+ EXPECT_TRUE(info.IsValid());
+ }
+ {
+ StringInfo info(op[i], "hello");
+ EXPECT_TRUE(info.IsValid());
+ }
+ }
+}
+
+TEST_F(StringInfoTest, InvalidStringInfo) {
+ const std::string op[] = {
+ "Contains",
+ "BeginWith",
+ "EndWith",
+ " =",
+ "= "
+ };
+ for (size_t i = 0; i < arraysize(op); ++i) {
+ StringInfo info(op[i], "hello");
+ EXPECT_FALSE(info.IsValid());
+ }
+}
+
+TEST_F(StringInfoTest, StringComparison) {
+ {
+ StringInfo info("contains", "happy");
+ EXPECT_TRUE(info.Contains("unhappy"));
+ EXPECT_TRUE(info.Contains("happy1"));
+ EXPECT_TRUE(info.Contains("happy"));
+ EXPECT_TRUE(info.Contains("a happy dog"));
+ EXPECT_TRUE(info.Contains("Happy"));
+ EXPECT_TRUE(info.Contains("HAPPY"));
+ EXPECT_FALSE(info.Contains("ha-ppy"));
+ }
+ {
+ StringInfo info("beginwith", "happy");
+ EXPECT_FALSE(info.Contains("unhappy"));
+ EXPECT_TRUE(info.Contains("happy1"));
+ EXPECT_TRUE(info.Contains("happy"));
+ EXPECT_FALSE(info.Contains("a happy dog"));
+ EXPECT_TRUE(info.Contains("Happy"));
+ EXPECT_TRUE(info.Contains("HAPPY"));
+ EXPECT_FALSE(info.Contains("ha-ppy"));
+ }
+ {
+ StringInfo info("endwith", "happy");
+ EXPECT_TRUE(info.Contains("unhappy"));
+ EXPECT_FALSE(info.Contains("happy1"));
+ EXPECT_TRUE(info.Contains("happy"));
+ EXPECT_FALSE(info.Contains("a happy dog"));
+ EXPECT_TRUE(info.Contains("Happy"));
+ EXPECT_TRUE(info.Contains("HAPPY"));
+ EXPECT_FALSE(info.Contains("ha-ppy"));
+ }
+ {
+ StringInfo info("=", "happy");
+ EXPECT_FALSE(info.Contains("unhappy"));
+ EXPECT_FALSE(info.Contains("happy1"));
+ EXPECT_TRUE(info.Contains("happy"));
+ EXPECT_FALSE(info.Contains("a happy dog"));
+ EXPECT_TRUE(info.Contains("Happy"));
+ EXPECT_TRUE(info.Contains("HAPPY"));
+ EXPECT_FALSE(info.Contains("ha-ppy"));
+ EXPECT_FALSE(info.Contains("ha ppy"));
+ EXPECT_FALSE(info.Contains(" happy"));
+ EXPECT_FALSE(info.Contains("happy "));
+ }
+}
+
+} // namespace content
+
diff --git a/content/browser/gpu/gpu_control_list_unittest.cc b/content/browser/gpu/gpu_control_list_unittest.cc
index 8793986..0991d27 100644
--- a/content/browser/gpu/gpu_control_list_unittest.cc
+++ b/content/browser/gpu/gpu_control_list_unittest.cc
@@ -17,6 +17,10 @@
#define LONG_STRING_CONST(...) #__VA_ARGS__
+#define EXPECT_EMPTY_SET(feature_set) EXPECT_EQ(0u, feature_set.size())
+#define EXPECT_SINGLE_FEATURE(feature_set, feature) \
+ EXPECT_TRUE(feature_set.size() == 1 && feature_set.count(feature) == 1)
+
namespace content {
enum TestFeatureType {
@@ -37,9 +41,9 @@
GpuControlList* Create() {
GpuControlList* rt = new GpuControlList();
- rt->AddFeature("test_feature_0", TEST_FEATURE_0);
- rt->AddFeature("test_feature_1", TEST_FEATURE_1);
- rt->AddFeature("test_feature_2", TEST_FEATURE_2);
+ rt->AddSupportedFeature("test_feature_0", TEST_FEATURE_0);
+ rt->AddSupportedFeature("test_feature_1", TEST_FEATURE_1);
+ rt->AddSupportedFeature("test_feature_2", TEST_FEATURE_2);
return rt;
}
@@ -68,9 +72,9 @@
TEST_F(GpuControlListTest, DefaultControlListSettings) {
scoped_ptr<GpuControlList> control_list(Create());
// Default control list settings: all feature are allowed.
- int features = control_list->MakeDecision(
+ std::set<int> features = control_list->MakeDecision(
GpuControlList::kOsMacosx, kOsVersion, gpu_info());
- EXPECT_EQ(0, features);
+ EXPECT_EMPTY_SET(features);
}
TEST_F(GpuControlListTest, EmptyControlList) {
@@ -87,10 +91,10 @@
EXPECT_TRUE(control_list->LoadList(empty_list_json,
GpuControlList::kAllOs));
- EXPECT_EQ("2.5", control_list->GetVersion());
- int features = control_list->MakeDecision(
+ EXPECT_EQ("2.5", control_list->version());
+ std::set<int> features = control_list->MakeDecision(
GpuControlList::kOsMacosx, kOsVersion, gpu_info());
- EXPECT_EQ(0, features);
+ EXPECT_EMPTY_SET(features);
}
TEST_F(GpuControlListTest, DetailedEntryAndInvalidJson) {
@@ -125,9 +129,9 @@
scoped_ptr<GpuControlList> control_list(Create());
EXPECT_TRUE(control_list->LoadList(exact_list_json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
+ std::set<int> features = control_list->MakeDecision(
GpuControlList::kOsMacosx, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
+ EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
// Invalid json input should not change the current control_list settings.
const std::string invalid_json = "invalid";
@@ -135,7 +139,7 @@
EXPECT_FALSE(control_list->LoadList(invalid_json, GpuControlList::kAllOs));
features = control_list->MakeDecision(
GpuControlList::kOsMacosx, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
+ EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
std::vector<uint32> entries;
control_list->GetDecisionEntries(&entries, false);
ASSERT_EQ(1u, entries.size());
@@ -164,15 +168,15 @@
// ControlList entries won't be filtered to the current OS only upon loading.
EXPECT_TRUE(control_list->LoadList(vendor_json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
+ std::set<int> features = control_list->MakeDecision(
GpuControlList::kOsMacosx, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
+ EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
features = control_list->MakeDecision(
GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
+ EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
features = control_list->MakeDecision(
GpuControlList::kOsLinux, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
+ EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX) || \
defined(OS_OPENBSD)
// ControlList entries will be filtered to the current OS only upon loading.
@@ -180,260 +184,16 @@
vendor_json, GpuControlList::kCurrentOsOnly));
features = control_list->MakeDecision(
GpuControlList::kOsMacosx, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
+ EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
features = control_list->MakeDecision(
GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
+ EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
features = control_list->MakeDecision(
GpuControlList::kOsLinux, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
+ EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
#endif
}
-TEST_F(GpuControlListTest, VendorOnLinuxEntry) {
- // ControlList a vendor on Linux only.
- const std::string vendor_linux_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "os": {
- "type": "linux"
- },
- "vendor_id": "0x10de",
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- scoped_ptr<GpuControlList> control_list(Create());
-
- EXPECT_TRUE(control_list->LoadList(
- vendor_linux_json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsMacosx, kOsVersion, gpu_info());
- EXPECT_EQ(0, features);
- features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(0, features);
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
-}
-
-TEST_F(GpuControlListTest, AllExceptNVidiaOnLinuxEntry) {
- // ControlList all cards in Linux except NVIDIA.
- const std::string linux_except_nvidia_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "os": {
- "type": "linux"
- },
- "exceptions": [
- {
- "vendor_id": "0x10de"
- }
- ],
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- scoped_ptr<GpuControlList> control_list(Create());
-
- EXPECT_TRUE(control_list->LoadList(
- linux_except_nvidia_json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsMacosx, kOsVersion, gpu_info());
- EXPECT_EQ(0, features);
- features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(0, features);
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info());
- EXPECT_EQ(0, features);
-}
-
-TEST_F(GpuControlListTest, AllExceptIntelOnLinuxEntry) {
- // ControlList all cards in Linux except Intel.
- const std::string linux_except_intel_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "os": {
- "type": "linux"
- },
- "exceptions": [
- {
- "vendor_id": "0x8086"
- }
- ],
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- scoped_ptr<GpuControlList> control_list(Create());
-
- EXPECT_TRUE(control_list->LoadList(
- linux_except_intel_json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsMacosx, kOsVersion, gpu_info());
- EXPECT_EQ(0, features);
- features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(0, features);
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
-}
-
-TEST_F(GpuControlListTest, DateOnWindowsEntry) {
- // ControlList all drivers earlier than 2010-5-8 in Windows.
- const std::string date_windows_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "os": {
- "type": "win"
- },
- "driver_date": {
- "op": "<",
- "number": "2010.5.8"
- },
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- scoped_ptr<GpuControlList> control_list(Create());
-
- GPUInfo gpu_info;
- gpu_info.driver_date = "7-14-2009";
-
- EXPECT_TRUE(control_list->LoadList(
- date_windows_json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsMacosx, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
- features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_date = "07-14-2009";
- features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_date = "1-1-2010";
- features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_date = "05-07-2010";
- features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_date = "5-8-2010";
- features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-
- gpu_info.driver_date = "5-9-2010";
- features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-
- gpu_info.driver_date = "6-2-2010";
- features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-}
-
-TEST_F(GpuControlListTest, MultipleDevicesEntry) {
- const std::string devices_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "vendor_id": "0x10de",
- "device_id": ["0x1023", "0x0640"],
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- scoped_ptr<GpuControlList> control_list(Create());
-
- EXPECT_TRUE(control_list->LoadList(devices_json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsMacosx, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
- features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
-}
-
-TEST_F(GpuControlListTest, ChromeOSEntry) {
- const std::string devices_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "os": {
- "type": "chromeos"
- },
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- scoped_ptr<GpuControlList> control_list(Create());
-
- EXPECT_TRUE(control_list->LoadList(devices_json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsChromeOS, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info());
- EXPECT_EQ(0, features);
-}
-
TEST_F(GpuControlListTest, ChromeVersionEntry) {
const std::string browser_version_json = LONG_STRING_CONST(
{
@@ -456,39 +216,16 @@
scoped_ptr<GpuControlList> control_list9(Create());
EXPECT_TRUE(control_list9->LoadList(
"9.0", browser_version_json, GpuControlList::kAllOs));
- int features = control_list9->MakeDecision(
+ std::set<int> features = control_list9->MakeDecision(
GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(0, features);
+ EXPECT_EMPTY_SET(features);
scoped_ptr<GpuControlList> control_list10(Create());
EXPECT_TRUE(control_list10->LoadList(
"10.0", browser_version_json, GpuControlList::kAllOs));
features = control_list10->MakeDecision(
GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
-}
-
-TEST_F(GpuControlListTest, MalformedVendor) {
- // vendor_id is defined as list instead of string.
- const std::string malformed_vendor_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "vendor_id": "[0x10de]",
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- scoped_ptr<GpuControlList> control_list(Create());
-
- EXPECT_FALSE(control_list->LoadList(
- malformed_vendor_json, GpuControlList::kAllOs));
+ EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
}
TEST_F(GpuControlListTest, UnknownField) {
@@ -519,9 +256,9 @@
unknown_field_json, GpuControlList::kAllOs));
EXPECT_EQ(1u, control_list->num_entries());
EXPECT_TRUE(control_list->contains_unknown_fields());
- int features = control_list->MakeDecision(
+ std::set<int> features = control_list->MakeDecision(
GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
+ EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
}
TEST_F(GpuControlListTest, UnknownExceptionField) {
@@ -563,168 +300,9 @@
unknown_exception_field_json, GpuControlList::kAllOs));
EXPECT_EQ(1u, control_list->num_entries());
EXPECT_TRUE(control_list->contains_unknown_fields());
- int features = control_list->MakeDecision(
+ std::set<int> features = control_list->MakeDecision(
GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
-}
-
-TEST_F(GpuControlListTest, UnknownFeature) {
- const std::string unknown_feature_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "features": [
- "some_unknown_feature",
- "test_feature_0"
- ]
- }
- ]
- }
- );
- scoped_ptr<GpuControlList> control_list(Create());
-
- EXPECT_TRUE(control_list->LoadList(
- unknown_feature_json, GpuControlList::kAllOs));
- EXPECT_EQ(1u, control_list->num_entries());
- EXPECT_TRUE(control_list->contains_unknown_fields());
- int features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
-}
-
-TEST_F(GpuControlListTest, GlVendor) {
- const std::string gl_vendor_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "gl_vendor": {
- "op": "beginwith",
- "value": "NVIDIA"
- },
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- scoped_ptr<GpuControlList> control_list(Create());
- EXPECT_TRUE(control_list->LoadList(gl_vendor_json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
-}
-
-TEST_F(GpuControlListTest, GlRenderer) {
- const std::string gl_renderer_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "gl_renderer": {
- "op": "contains",
- "value": "GeForce"
- },
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
-
- scoped_ptr<GpuControlList> control_list(Create());
- EXPECT_TRUE(control_list->LoadList(gl_renderer_json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
-}
-
-TEST_F(GpuControlListTest, PerfGraphics) {
- const std::string json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "perf_graphics": {
- "op": "<",
- "value": "6.0"
- },
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- scoped_ptr<GpuControlList> control_list(Create());
- EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
-}
-
-TEST_F(GpuControlListTest, PerfGaming) {
- const std::string json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "perf_gaming": {
- "op": "<=",
- "value": "4.0"
- },
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- scoped_ptr<GpuControlList> control_list(Create());
- EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(0, features);
-}
-
-TEST_F(GpuControlListTest, PerfOverall) {
- const std::string json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "perf_overall": {
- "op": "between",
- "value": "1.0",
- "value2": "9.0"
- },
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- scoped_ptr<GpuControlList> control_list(Create());
- EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(TEST_FEATURE_0, features);
+ EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
}
TEST_F(GpuControlListTest, DisabledEntry) {
@@ -745,9 +323,9 @@
);
scoped_ptr<GpuControlList> control_list(Create());
EXPECT_TRUE(control_list->LoadList(disabled_json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
+ std::set<int> features = control_list->MakeDecision(
GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(features, 0);
+ EXPECT_EMPTY_SET(features);
std::vector<uint32> flag_entries;
control_list->GetDecisionEntries(&flag_entries, false);
EXPECT_EQ(0u, flag_entries.size());
@@ -755,471 +333,6 @@
EXPECT_EQ(1u, flag_entries.size());
}
-TEST_F(GpuControlListTest, Optimus) {
- const std::string optimus_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "os": {
- "type": "linux"
- },
- "multi_gpu_style": "optimus",
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- GPUInfo gpu_info;
- gpu_info.optimus = true;
-
- scoped_ptr<GpuControlList> control_list(Create());
- EXPECT_TRUE(control_list->LoadList(optimus_json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-}
-
-TEST_F(GpuControlListTest, AMDSwitchable) {
- const std::string amd_switchable_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "os": {
- "type": "macosx"
- },
- "multi_gpu_style": "amd_switchable",
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- GPUInfo gpu_info;
- gpu_info.amd_switchable = true;
-
- scoped_ptr<GpuControlList> control_list(Create());
- EXPECT_TRUE(control_list->LoadList(amd_switchable_json,
- GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsMacosx, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-}
-
-TEST_F(GpuControlListTest, LexicalDriverVersion) {
- const std::string lexical_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "os": {
- "type": "linux"
- },
- "vendor_id": "0x1002",
- "driver_version": {
- "op": "<",
- "style": "lexical",
- "number": "8.201"
- },
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- GPUInfo gpu_info;
- gpu_info.gpu.vendor_id = 0x1002;
-
- scoped_ptr<GpuControlList> control_list(Create());
- EXPECT_TRUE(control_list->LoadList(lexical_json, GpuControlList::kAllOs));
-
- gpu_info.driver_version = "8.001.100";
- int features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.109";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.10900";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.109.100";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.2";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.20";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.200";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.20.100";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.201";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-
- gpu_info.driver_version = "8.2010";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-
- gpu_info.driver_version = "8.21";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-
- gpu_info.driver_version = "8.21.100";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-
- gpu_info.driver_version = "9.002";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-
- gpu_info.driver_version = "9.201";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-
- gpu_info.driver_version = "12";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-
- gpu_info.driver_version = "12.201";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-}
-
-TEST_F(GpuControlListTest, LexicalDriverVersion2) {
- const std::string lexical_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "os": {
- "type": "linux"
- },
- "vendor_id": "0x1002",
- "driver_version": {
- "op": "<",
- "style": "lexical",
- "number": "9.002"
- },
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- GPUInfo gpu_info;
- gpu_info.gpu.vendor_id = 0x1002;
-
- scoped_ptr<GpuControlList> control_list(Create());
- EXPECT_TRUE(control_list->LoadList(lexical_json, GpuControlList::kAllOs));
-
- gpu_info.driver_version = "8.001.100";
- int features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.109";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.10900";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.109.100";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.2";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.20";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.200";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.20.100";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.201";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.2010";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.21";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.21.100";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "9.002";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-
- gpu_info.driver_version = "9.201";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-
- gpu_info.driver_version = "12";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-
- gpu_info.driver_version = "12.201";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-}
-
-TEST_F(GpuControlListTest, LexicalDriverVersion3) {
- const std::string lexical_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "os": {
- "type": "linux"
- },
- "vendor_id": "0x1002",
- "driver_version": {
- "op": "=",
- "style": "lexical",
- "number": "8.76"
- },
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- GPUInfo gpu_info;
- gpu_info.gpu.vendor_id = 0x1002;
-
- scoped_ptr<GpuControlList> control_list(Create());
- EXPECT_TRUE(control_list->LoadList(lexical_json, GpuControlList::kAllOs));
-
- gpu_info.driver_version = "8.76";
- int features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.768";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-
- gpu_info.driver_version = "8.76.8";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-}
-
-TEST_F(GpuControlListTest, MultipleGPUsAny) {
- const std::string multi_gpu_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "os": {
- "type": "macosx"
- },
- "vendor_id": "0x8086",
- "device_id": ["0x0166"],
- "multi_gpu_category": "any",
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- GPUInfo gpu_info;
- gpu_info.gpu.vendor_id = kNvidiaVendorId;
- gpu_info.gpu.device_id = kNvidiaDeviceId;
-
- scoped_ptr<GpuControlList> control_list(Create());
- EXPECT_TRUE(control_list->LoadList(multi_gpu_json,
- GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsMacosx, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-
- GPUInfo::GPUDevice gpu_device;
- gpu_device.vendor_id = kIntelVendorId;
- gpu_device.device_id = kIntelDeviceId;
- gpu_info.secondary_gpus.push_back(gpu_device);
- features = control_list->MakeDecision(
- GpuControlList::kOsMacosx, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-}
-
-TEST_F(GpuControlListTest, MultipleGPUsSecondary) {
- const std::string multi_gpu_json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "os": {
- "type": "macosx"
- },
- "vendor_id": "0x8086",
- "device_id": ["0x0166"],
- "multi_gpu_category": "secondary",
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- GPUInfo gpu_info;
- gpu_info.gpu.vendor_id = kNvidiaVendorId;
- gpu_info.gpu.device_id = kNvidiaDeviceId;
-
- scoped_ptr<GpuControlList> control_list(Create());
- EXPECT_TRUE(control_list->LoadList(multi_gpu_json,
- GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
- GpuControlList::kOsMacosx, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
-
- GPUInfo::GPUDevice gpu_device;
- gpu_device.vendor_id = kIntelVendorId;
- gpu_device.device_id = kIntelDeviceId;
- gpu_info.secondary_gpus.push_back(gpu_device);
- features = control_list->MakeDecision(
- GpuControlList::kOsMacosx, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
-}
-
-TEST_F(GpuControlListTest, NeedsMoreInfo) {
- const std::string json = LONG_STRING_CONST(
- {
- "name": "gpu control list",
- "version": "0.1",
- "entries": [
- {
- "id": 1,
- "os": {
- "type": "linux"
- },
- "vendor_id": "0x8086",
- "driver_version": {
- "op": "<",
- "number": "10.7"
- },
- "features": [
- "test_feature_0"
- ]
- }
- ]
- }
- );
- GPUInfo gpu_info;
- gpu_info.gpu.vendor_id = kIntelVendorId;
-
- scoped_ptr<GpuControlList> control_list(Create());
- EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs));
-
- // The case this entry does not apply.
- int features = control_list->MakeDecision(
- GpuControlList::kOsMacosx, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
- EXPECT_FALSE(control_list->needs_more_info());
-
- // The case this entry might apply, but need more info.
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
- EXPECT_TRUE(control_list->needs_more_info());
-
- // The case we have full info, and this entry applies.
- gpu_info.driver_version = "10.6";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
- EXPECT_FALSE(control_list->needs_more_info());
-
- // The case we have full info, and this entry does not apply.
- gpu_info.driver_version = "10.8";
- features = control_list->MakeDecision(
- GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
- EXPECT_FALSE(control_list->needs_more_info());
-}
-
TEST_F(GpuControlListTest, NeedsMoreInfoForExceptions) {
const std::string json = LONG_STRING_CONST(
{
@@ -1254,15 +367,15 @@
EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs));
// The case this entry does not apply.
- int features = control_list->MakeDecision(
+ std::set<int> features = control_list->MakeDecision(
GpuControlList::kOsMacosx, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
+ EXPECT_EMPTY_SET(features);
EXPECT_FALSE(control_list->needs_more_info());
// The case this entry might apply, but need more info.
features = control_list->MakeDecision(
GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
+ EXPECT_EMPTY_SET(features);
EXPECT_TRUE(control_list->needs_more_info());
// The case we have full info, and the exception applies (so the entry
@@ -1270,14 +383,14 @@
gpu_info.gl_renderer = "mesa";
features = control_list->MakeDecision(
GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(0, features);
+ EXPECT_EMPTY_SET(features);
EXPECT_FALSE(control_list->needs_more_info());
// The case we have full info, and this entry applies.
gpu_info.gl_renderer = "my renderer";
features = control_list->MakeDecision(GpuControlList::kOsLinux, kOsVersion,
gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
+ EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
EXPECT_FALSE(control_list->needs_more_info());
}
@@ -1321,9 +434,9 @@
scoped_ptr<GpuControlList> control_list(Create());
EXPECT_TRUE(control_list->LoadList(json, GpuControlList::kAllOs));
- int features = control_list->MakeDecision(
+ std::set<int> features = control_list->MakeDecision(
GpuControlList::kOsLinux, kOsVersion, gpu_info);
- EXPECT_EQ(TEST_FEATURE_0, features);
+ EXPECT_SINGLE_FEATURE(features, TEST_FEATURE_0);
EXPECT_FALSE(control_list->needs_more_info());
}
diff --git a/content/browser/gpu/gpu_control_list_version_info_unittest.cc b/content/browser/gpu/gpu_control_list_version_info_unittest.cc
new file mode 100644
index 0000000..eb18648
--- /dev/null
+++ b/content/browser/gpu/gpu_control_list_version_info_unittest.cc
@@ -0,0 +1,258 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/gpu/gpu_control_list.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class VersionInfoTest : public testing::Test {
+ public:
+ VersionInfoTest() { }
+ virtual ~VersionInfoTest() { }
+
+ typedef GpuControlList::VersionInfo VersionInfo;
+};
+
+TEST_F(VersionInfoTest, ValidVersionInfo) {
+ const std::string op[] = {
+ "=",
+ "<",
+ "<=",
+ ">",
+ ">=",
+ "any",
+ "between"
+ };
+ for (size_t i = 0; i < arraysize(op); ++i) {
+ std::string string1;
+ std::string string2;
+ if (op[i] != "any")
+ string1 = "8.9";
+ if (op[i] == "between")
+ string2 = "9.0";
+ VersionInfo info(op[i], std::string(), string1, string2);
+ EXPECT_TRUE(info.IsValid());
+ }
+
+ const std::string style[] = {
+ "lexical",
+ "numerical",
+ "" // Default, same as "numerical"
+ };
+ for (size_t i =0; i < arraysize(style); ++i) {
+ VersionInfo info("=", style[i], "8.9", std::string());
+ EXPECT_TRUE(info.IsValid());
+ if (style[i] == "lexical")
+ EXPECT_TRUE(info.IsLexical());
+ else
+ EXPECT_FALSE(info.IsLexical());
+ }
+
+ const std::string number[] = {
+ "10",
+ "10.9",
+ "10.0",
+ "10.0.9",
+ "0.8",
+ // Leading 0s are valid.
+ "10.09",
+ // Whitespaces are ignored.
+ " 10.9",
+ "10.9 ",
+ "10 .9",
+ "10. 9",
+ };
+ for (size_t i =0; i < arraysize(number); ++i) {
+ VersionInfo info("=", std::string(), number[i], std::string());
+ EXPECT_TRUE(info.IsValid());
+ }
+}
+
+TEST_F(VersionInfoTest, InvalidVersionInfo) {
+ const std::string op[] = {
+ "=",
+ "<",
+ "<=",
+ ">",
+ ">=",
+ "any",
+ "between"
+ };
+ for (size_t i = 0; i < arraysize(op); ++i) {
+ {
+ VersionInfo info(op[i], std::string(), "8.9", std::string());
+ if (op[i] == "between")
+ EXPECT_FALSE(info.IsValid());
+ else
+ EXPECT_TRUE(info.IsValid());
+ }
+ {
+ VersionInfo info(op[i], std::string(), std::string(), std::string());
+ if (op[i] == "any")
+ EXPECT_TRUE(info.IsValid());
+ else
+ EXPECT_FALSE(info.IsValid());
+ }
+ {
+ VersionInfo info(op[i], std::string(), "8.9", "9.0");
+ EXPECT_TRUE(info.IsValid());
+ }
+ }
+
+ const std::string number[] = {
+ "8.E",
+ "8-9",
+ };
+ for (size_t i = 0; i < arraysize(number); ++i) {
+ VersionInfo info("=", std::string(), number[i], std::string());
+ EXPECT_FALSE(info.IsValid());
+ }
+}
+
+TEST_F(VersionInfoTest, VersionComparison) {
+ {
+ VersionInfo info("any", std::string(), std::string(), std::string());
+ EXPECT_TRUE(info.Contains("0"));
+ EXPECT_TRUE(info.Contains("8.9"));
+ EXPECT_TRUE(info.Contains("100"));
+ }
+ {
+ VersionInfo info(">", std::string(), "8.9", std::string());
+ EXPECT_FALSE(info.Contains("7"));
+ EXPECT_FALSE(info.Contains("8.9"));
+ EXPECT_FALSE(info.Contains("8.9.1"));
+ EXPECT_TRUE(info.Contains("9"));
+ }
+ {
+ VersionInfo info(">=", std::string(), "8.9", std::string());
+ EXPECT_FALSE(info.Contains("7"));
+ EXPECT_TRUE(info.Contains("8.9"));
+ EXPECT_TRUE(info.Contains("8.9.1"));
+ EXPECT_TRUE(info.Contains("9"));
+ }
+ {
+ VersionInfo info("=", std::string(), "8.9", std::string());
+ EXPECT_FALSE(info.Contains("7"));
+ EXPECT_TRUE(info.Contains("8"));
+ EXPECT_TRUE(info.Contains("8.9"));
+ EXPECT_TRUE(info.Contains("8.9.1"));
+ EXPECT_FALSE(info.Contains("9"));
+ }
+ {
+ VersionInfo info("<", std::string(), "8.9", std::string());
+ EXPECT_TRUE(info.Contains("7"));
+ EXPECT_TRUE(info.Contains("8.8"));
+ EXPECT_FALSE(info.Contains("8"));
+ EXPECT_FALSE(info.Contains("8.9"));
+ EXPECT_FALSE(info.Contains("8.9.1"));
+ EXPECT_FALSE(info.Contains("9"));
+ }
+ {
+ VersionInfo info("<=", std::string(), "8.9", std::string());
+ EXPECT_TRUE(info.Contains("7"));
+ EXPECT_TRUE(info.Contains("8.8"));
+ EXPECT_TRUE(info.Contains("8"));
+ EXPECT_TRUE(info.Contains("8.9"));
+ EXPECT_TRUE(info.Contains("8.9.1"));
+ EXPECT_FALSE(info.Contains("9"));
+ }
+ {
+ VersionInfo info("between", std::string(), "8.9", "9.1");
+ EXPECT_FALSE(info.Contains("7"));
+ EXPECT_FALSE(info.Contains("8.8"));
+ EXPECT_TRUE(info.Contains("8"));
+ EXPECT_TRUE(info.Contains("8.9"));
+ EXPECT_TRUE(info.Contains("8.9.1"));
+ EXPECT_TRUE(info.Contains("9"));
+ EXPECT_TRUE(info.Contains("9.1"));
+ EXPECT_TRUE(info.Contains("9.1.9"));
+ EXPECT_FALSE(info.Contains("9.2"));
+ EXPECT_FALSE(info.Contains("10"));
+ }
+}
+
+TEST_F(VersionInfoTest, DateComparison) {
+ // When we use '-' as splitter, we assume a format of mm-dd-yyyy
+ // or mm-yyyy, i.e., a date.
+ {
+ VersionInfo info("=", std::string(), "1976.3.21", std::string());
+ EXPECT_TRUE(info.Contains("3-21-1976", '-'));
+ EXPECT_TRUE(info.Contains("3-1976", '-'));
+ EXPECT_TRUE(info.Contains("03-1976", '-'));
+ EXPECT_FALSE(info.Contains("21-3-1976", '-'));
+ }
+ {
+ VersionInfo info(">", std::string(), "1976.3.21", std::string());
+ EXPECT_TRUE(info.Contains("3-22-1976", '-'));
+ EXPECT_TRUE(info.Contains("4-1976", '-'));
+ EXPECT_TRUE(info.Contains("04-1976", '-'));
+ EXPECT_FALSE(info.Contains("3-1976", '-'));
+ EXPECT_FALSE(info.Contains("2-1976", '-'));
+ }
+ {
+ VersionInfo info("between", std::string(), "1976.3.21", "2012.12.25");
+ EXPECT_FALSE(info.Contains("3-20-1976", '-'));
+ EXPECT_TRUE(info.Contains("3-21-1976", '-'));
+ EXPECT_TRUE(info.Contains("3-22-1976", '-'));
+ EXPECT_TRUE(info.Contains("3-1976", '-'));
+ EXPECT_TRUE(info.Contains("4-1976", '-'));
+ EXPECT_TRUE(info.Contains("1-1-2000", '-'));
+ EXPECT_TRUE(info.Contains("1-2000", '-'));
+ EXPECT_TRUE(info.Contains("2000", '-'));
+ EXPECT_TRUE(info.Contains("11-2012", '-'));
+ EXPECT_TRUE(info.Contains("12-2012", '-'));
+ EXPECT_TRUE(info.Contains("12-24-2012", '-'));
+ EXPECT_TRUE(info.Contains("12-25-2012", '-'));
+ EXPECT_FALSE(info.Contains("12-26-2012", '-'));
+ EXPECT_FALSE(info.Contains("1-2013", '-'));
+ EXPECT_FALSE(info.Contains("2013", '-'));
+ }
+}
+
+TEST_F(VersionInfoTest, LexicalComparison) {
+ // When we use lexical style, we assume a format major.minor.*.
+ // We apply numerical comparison to major, lexical comparison to others.
+ {
+ VersionInfo info("<", "lexical", "8.201", std::string());
+ EXPECT_TRUE(info.Contains("8.001.100"));
+ EXPECT_TRUE(info.Contains("8.109"));
+ EXPECT_TRUE(info.Contains("8.10900"));
+ EXPECT_TRUE(info.Contains("8.109.100"));
+ EXPECT_TRUE(info.Contains("8.2"));
+ EXPECT_TRUE(info.Contains("8.20"));
+ EXPECT_TRUE(info.Contains("8.200"));
+ EXPECT_TRUE(info.Contains("8.20.100"));
+ EXPECT_FALSE(info.Contains("8.201"));
+ EXPECT_FALSE(info.Contains("8.2010"));
+ EXPECT_FALSE(info.Contains("8.21"));
+ EXPECT_FALSE(info.Contains("8.21.100"));
+ EXPECT_FALSE(info.Contains("9.002"));
+ EXPECT_FALSE(info.Contains("9.201"));
+ EXPECT_FALSE(info.Contains("12"));
+ EXPECT_FALSE(info.Contains("12.201"));
+ }
+ {
+ VersionInfo info("<", "lexical", "9.002", std::string());
+ EXPECT_TRUE(info.Contains("8.001.100"));
+ EXPECT_TRUE(info.Contains("8.109"));
+ EXPECT_TRUE(info.Contains("8.10900"));
+ EXPECT_TRUE(info.Contains("8.109.100"));
+ EXPECT_TRUE(info.Contains("8.2"));
+ EXPECT_TRUE(info.Contains("8.20"));
+ EXPECT_TRUE(info.Contains("8.200"));
+ EXPECT_TRUE(info.Contains("8.20.100"));
+ EXPECT_TRUE(info.Contains("8.201"));
+ EXPECT_TRUE(info.Contains("8.2010"));
+ EXPECT_TRUE(info.Contains("8.21"));
+ EXPECT_TRUE(info.Contains("8.21.100"));
+ EXPECT_FALSE(info.Contains("9.002"));
+ EXPECT_FALSE(info.Contains("9.201"));
+ EXPECT_FALSE(info.Contains("12"));
+ EXPECT_FALSE(info.Contains("12.201"));
+ }
+}
+
+} // namespace content
+
diff --git a/content/browser/gpu/gpu_data_manager_impl.cc b/content/browser/gpu/gpu_data_manager_impl.cc
index cdc65ee..5f17f0a 100644
--- a/content/browser/gpu/gpu_data_manager_impl.cc
+++ b/content/browser/gpu/gpu_data_manager_impl.cc
@@ -11,11 +11,13 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
+#include "base/debug/trace_event.h"
#include "base/file_util.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
-#include "base/string_piece.h"
#include "base/stringprintf.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
#include "base/sys_info.h"
#include "base/values.h"
#include "base/version.h"
@@ -28,12 +30,14 @@
#include "content/public/common/content_client.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/gpu_feature_type.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "grit/content_resources.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_switches.h"
#include "ui/gl/gpu_switching_manager.h"
+#include "webkit/glue/webpreferences.h"
#include "webkit/plugins/plugin_switches.h"
#if defined(OS_WIN)
@@ -58,6 +62,18 @@
return version_string;
}
+// Combine the integers into a string, seperated by ','.
+std::string IntSetToString(const std::set<int>& list) {
+ std::string rt;
+ for (std::set<int>::const_iterator it = list.begin();
+ it != list.end(); ++it) {
+ if (!rt.empty())
+ rt += ",";
+ rt += base::IntToString(*it);
+ }
+ return rt;
+}
+
#if defined(OS_MACOSX)
void DisplayReconfigCallback(CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags,
@@ -102,22 +118,41 @@
// This function is for testing only, so disable histograms.
update_histograms_ = false;
- InitializeImpl(gpu_blacklist_json, "", "", gpu_info);
+ InitializeImpl(gpu_blacklist_json, std::string(), std::string(), gpu_info);
}
-GpuFeatureType GpuDataManagerImpl::GetBlacklistedFeatures() const {
- if (software_rendering_) {
- GpuFeatureType flags;
-
+bool GpuDataManagerImpl::IsFeatureBlacklisted(int feature) const {
+ if (use_swiftshader_) {
// Skia's software rendering is probably more efficient than going through
// software emulation of the GPU, so use that.
- flags = GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS;
- return flags;
+ if (feature == GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)
+ return true;
+ return false;
}
- return blacklisted_features_;
+ return (blacklisted_features_.count(feature) == 1);
}
+size_t GpuDataManagerImpl::GetBlacklistedFeatureCount() const {
+ if (use_swiftshader_)
+ return 1;
+ return blacklisted_features_.size();
+}
+
+void GpuDataManagerImpl::AddGpuSwitchCallback(
+ const GpuSwitchCallback& callback) {
+ gpu_switch_callbacks_.push_back(callback);
+}
+
+void GpuDataManagerImpl::RemoveGpuSwitchCallback(
+ const GpuSwitchCallback& callback) {
+ for (size_t i = 0; i < gpu_switch_callbacks_.size(); i++) {
+ if (gpu_switch_callbacks_[i].Equals(callback)) {
+ gpu_switch_callbacks_.erase(gpu_switch_callbacks_.begin() + i);
+ return;
+ }
+ }
+}
GPUInfo GpuDataManagerImpl::GetGPUInfo() const {
GPUInfo gpu_info;
@@ -133,30 +168,51 @@
GpuProcessHost::GetProcessHandles(callback);
}
-bool GpuDataManagerImpl::GpuAccessAllowed() const {
- if (software_rendering_)
+bool GpuDataManagerImpl::GpuAccessAllowed(std::string* reason) const {
+ if (use_swiftshader_)
return true;
- if (!gpu_info_.gpu_accessible)
+ if (!gpu_info_.gpu_accessible) {
+ if (reason) {
+ *reason = "GPU process launch failed.";
+ }
return false;
+ }
- if (card_blacklisted_)
+ if (card_blacklisted_) {
+ if (reason) {
+ *reason = "GPU access is disabled ";
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kDisableGpu))
+ *reason += "through commandline switch --disable-gpu.";
+ else
+ *reason += "in chrome://settings.";
+ }
return false;
+ }
// We only need to block GPU process if more features are disallowed other
// than those in the preliminary gpu feature flags because the latter work
// through renderer commandline switches.
- uint32 mask = ~(preliminary_blacklisted_features_);
- if ((blacklisted_features_ & mask) != 0)
+ std::set<int> features = preliminary_blacklisted_features_;
+ MergeFeatureSets(&features, blacklisted_features_);
+ if (features.size() > preliminary_blacklisted_features_.size()) {
+ if (reason) {
+ *reason = "Features are disabled upon full but not preliminary GPU info.";
+ }
return false;
+ }
- if (blacklisted_features_ == GPU_FEATURE_TYPE_ALL) {
+ if (blacklisted_features_.size() == NUMBER_OF_GPU_FEATURE_TYPES) {
// On Linux, we use cached GL strings to make blacklist decsions at browser
// startup time. We need to launch the GPU process to validate these
// strings even if all features are blacklisted. If all GPU features are
// disabled, the GPU process will only initialize GL bindings, create a GL
// context, and collect full GPU info.
#if !defined(OS_LINUX)
+ if (reason) {
+ *reason = "All GPU features are blacklisted.";
+ }
return false;
#endif
}
@@ -190,13 +246,13 @@
new GpuMsg_GetVideoMemoryUsageStats());
}
-bool GpuDataManagerImpl::ShouldUseSoftwareRendering() const {
- return software_rendering_;
+bool GpuDataManagerImpl::ShouldUseSwiftShader() const {
+ return use_swiftshader_;
}
void GpuDataManagerImpl::RegisterSwiftShaderPath(const base::FilePath& path) {
swiftshader_path_ = path;
- EnableSoftwareRenderingIfNecessary();
+ EnableSwiftShaderIfNecessary();
}
void GpuDataManagerImpl::AddObserver(GpuDataManagerObserver* observer) {
@@ -276,12 +332,17 @@
void GpuDataManagerImpl::Initialize() {
+ TRACE_EVENT0("startup", "GpuDataManagerImpl::Initialize");
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kSkipGpuDataLoading))
return;
GPUInfo gpu_info;
- gpu_info_collector::CollectBasicGraphicsInfo(&gpu_info);
+ {
+ TRACE_EVENT0("startup",
+ "GpuDataManagerImpl::Initialize:CollectBasicGraphicsInfo");
+ gpu_info_collector::CollectBasicGraphicsInfo(&gpu_info);
+ }
#if defined(ARCH_CPU_X86_FAMILY)
if (!gpu_info.gpu.vendor_id || !gpu_info.gpu.device_id)
gpu_info.finalized = true;
@@ -313,8 +374,8 @@
}
void GpuDataManagerImpl::UpdateGpuInfo(const GPUInfo& gpu_info) {
- // No further update of gpu_info if falling back to software renderer.
- if (software_rendering_)
+ // No further update of gpu_info if falling back to SwiftShader.
+ if (use_swiftshader_)
return;
GPUInfo my_gpu_info;
@@ -328,27 +389,27 @@
GetContentClient()->SetGpuInfo(my_gpu_info);
- if (gpu_blacklist_.get()) {
- int features = gpu_blacklist_->MakeDecision(
- GpuControlList::kOsAny, "", my_gpu_info);
+ if (gpu_blacklist_) {
+ std::set<int> features = gpu_blacklist_->MakeDecision(
+ GpuControlList::kOsAny, std::string(), my_gpu_info);
if (update_histograms_)
UpdateStats(gpu_blacklist_.get(), features);
- UpdateBlacklistedFeatures(static_cast<GpuFeatureType>(features));
+ UpdateBlacklistedFeatures(features);
}
- if (gpu_switching_list_.get()) {
- int option = gpu_switching_list_->MakeDecision(
- GpuControlList::kOsAny, "", my_gpu_info);
- if (option != GPU_SWITCHING_OPTION_UNKNOWN) {
+ if (gpu_switching_list_) {
+ std::set<int> option = gpu_switching_list_->MakeDecision(
+ GpuControlList::kOsAny, std::string(), my_gpu_info);
+ if (option.size() == 1) {
// Blacklist decision should not overwrite commandline switch from users.
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (!command_line->HasSwitch(switches::kGpuSwitching))
- gpu_switching_ = static_cast<GpuSwitchingOption>(option);
+ gpu_switching_ = static_cast<GpuSwitchingOption>(*(option.begin()));
}
}
- if (gpu_driver_bug_list_.get())
+ if (gpu_driver_bug_list_)
gpu_driver_bugs_ = gpu_driver_bug_list_->MakeDecision(
- GpuControlList::kOsAny, "", my_gpu_info);
+ GpuControlList::kOsAny, std::string(), my_gpu_info);
// We have to update GpuFeatureType before notify all the observers.
NotifyGpuInfoUpdate();
@@ -364,8 +425,7 @@
CommandLine* command_line) const {
DCHECK(command_line);
- uint32 flags = GetBlacklistedFeatures();
- if ((flags & GPU_FEATURE_TYPE_WEBGL)) {
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL)) {
#if !defined(OS_ANDROID)
if (!command_line->HasSwitch(switches::kDisableExperimentalWebGL))
command_line->AppendSwitch(switches::kDisableExperimentalWebGL);
@@ -373,19 +433,19 @@
if (!command_line->HasSwitch(switches::kDisablePepper3d))
command_line->AppendSwitch(switches::kDisablePepper3d);
}
- if ((flags & GPU_FEATURE_TYPE_MULTISAMPLING) &&
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING) &&
!command_line->HasSwitch(switches::kDisableGLMultisampling))
command_line->AppendSwitch(switches::kDisableGLMultisampling);
- if ((flags & GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) &&
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) &&
!command_line->HasSwitch(switches::kDisableAcceleratedCompositing))
command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
- if ((flags & GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS) &&
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS) &&
!command_line->HasSwitch(switches::kDisableAccelerated2dCanvas))
command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas);
- if ((flags & GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) &&
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) &&
!command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode))
command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
- if (ShouldUseSoftwareRendering())
+ if (ShouldUseSwiftShader())
command_line->AppendSwitch(switches::kDisableFlashFullscreen3d);
}
@@ -398,20 +458,19 @@
base::FilePath swiftshader_path =
CommandLine::ForCurrentProcess()->GetSwitchValuePath(
switches::kSwiftShaderPath);
- uint32 flags = GetBlacklistedFeatures();
- if ((flags & GPU_FEATURE_TYPE_MULTISAMPLING) &&
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING) &&
!command_line->HasSwitch(switches::kDisableGLMultisampling))
command_line->AppendSwitch(switches::kDisableGLMultisampling);
- if (flags & GPU_FEATURE_TYPE_TEXTURE_SHARING)
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_TEXTURE_SHARING))
command_line->AppendSwitch(switches::kDisableImageTransportSurface);
- if (software_rendering_) {
+ if (use_swiftshader_) {
command_line->AppendSwitchASCII(switches::kUseGL, "swiftshader");
if (swiftshader_path.empty())
swiftshader_path = swiftshader_path_;
- } else if ((flags & (GPU_FEATURE_TYPE_WEBGL |
- GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING |
- GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)) &&
+ } else if ((IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL) ||
+ IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
+ IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)) &&
(use_gl == "any")) {
command_line->AppendSwitchASCII(
switches::kUseGL, gfx::kGLImplementationOSMesaName);
@@ -441,6 +500,11 @@
command_line->AppendSwitchPath(switches::kSwiftShaderPath,
swiftshader_path);
+ if (!gpu_driver_bugs_.empty()) {
+ command_line->AppendSwitchASCII(switches::kGpuDriverBugWorkarounds,
+ IntSetToString(gpu_driver_bugs_));
+ }
+
#if defined(OS_WIN)
// DisplayLink 7.1 and earlier can cause the GPU process to crash on startup.
// http://crbug.com/177611
@@ -483,11 +547,10 @@
DCHECK(command_line);
#if defined(OS_MACOSX)
- uint32 flags = GetBlacklistedFeatures();
// TODO(jbauman): Add proper blacklist support for core animation plugins so
// special-casing this video card won't be necessary. See
// http://crbug.com/134015
- if ((flags & GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableAcceleratedCompositing)) {
if (!command_line->HasSwitch(
@@ -498,6 +561,42 @@
#endif
}
+void GpuDataManagerImpl::UpdateRendererWebPrefs(WebPreferences* prefs) const {
+ DCHECK(prefs);
+
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING))
+ prefs->accelerated_compositing_enabled = false;
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL))
+ prefs->experimental_webgl_enabled = false;
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH3D))
+ prefs->flash_3d_enabled = false;
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH_STAGE3D)) {
+ prefs->flash_stage3d_enabled = false;
+ prefs->flash_stage3d_baseline_enabled = false;
+ }
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE))
+ prefs->flash_stage3d_baseline_enabled = false;
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS))
+ prefs->accelerated_2d_canvas_enabled = false;
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING))
+ prefs->gl_multisampling_enabled = false;
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_3D_CSS)) {
+ prefs->accelerated_compositing_for_3d_transforms_enabled = false;
+ prefs->accelerated_compositing_for_animation_enabled = false;
+ }
+ if (IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_VIDEO))
+ prefs->accelerated_compositing_for_video_enabled = false;
+
+ // Accelerated video and animation are slower than regular when using
+ // SwiftShader. 3D CSS may also be too slow to be worthwhile.
+ if (ShouldUseSwiftShader()) {
+ prefs->accelerated_compositing_for_video_enabled = false;
+ prefs->accelerated_compositing_for_animation_enabled = false;
+ prefs->accelerated_compositing_for_3d_transforms_enabled = false;
+ prefs->accelerated_compositing_for_plugins_enabled = false;
+ }
+}
+
GpuSwitchingOption GpuDataManagerImpl::GetGpuSwitchingOption() const {
if (!ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus())
return GPU_SWITCHING_OPTION_UNKNOWN;
@@ -507,21 +606,22 @@
void GpuDataManagerImpl::DisableHardwareAcceleration() {
card_blacklisted_ = true;
- blacklisted_features_ = GPU_FEATURE_TYPE_ALL;
+ for (int i = 0; i < NUMBER_OF_GPU_FEATURE_TYPES; ++i)
+ blacklisted_features_.insert(i);
- EnableSoftwareRenderingIfNecessary();
+ EnableSwiftShaderIfNecessary();
NotifyGpuInfoUpdate();
}
std::string GpuDataManagerImpl::GetBlacklistVersion() const {
- if (gpu_blacklist_.get())
- return gpu_blacklist_->GetVersion();
+ if (gpu_blacklist_)
+ return gpu_blacklist_->version();
return "0";
}
base::ListValue* GpuDataManagerImpl::GetBlacklistReasons() const {
ListValue* reasons = new ListValue();
- if (gpu_blacklist_.get())
+ if (gpu_blacklist_)
gpu_blacklist_->GetReasons(reasons);
return reasons;
}
@@ -559,11 +659,10 @@
}
void GpuDataManagerImpl::HandleGpuSwitch() {
- if (complete_gpu_info_already_requested_) {
- complete_gpu_info_already_requested_ = false;
- gpu_info_.finalized = false;
- RequestCompleteGpuInfoIfNeeded();
- }
+ complete_gpu_info_already_requested_ = false;
+ gpu_info_.finalized = false;
+ for (size_t i = 0; i < gpu_switch_callbacks_.size(); ++i)
+ gpu_switch_callbacks_[i].Run();
}
#if defined(OS_WIN)
@@ -573,16 +672,12 @@
if (gpu_info_.amd_switchable)
return false;
- if (software_rendering_)
+ if (use_swiftshader_)
return false;
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kDisableImageTransportSurface))
return false;
- uint32 flags = GetBlacklistedFeatures();
- if (flags & GPU_FEATURE_TYPE_TEXTURE_SHARING)
- return false;
-
- return true;
+ return !IsFeatureBlacklisted(GPU_FEATURE_TYPE_TEXTURE_SHARING);
}
#endif
@@ -614,11 +709,9 @@
GpuDataManagerImpl::GpuDataManagerImpl()
: complete_gpu_info_already_requested_(false),
- blacklisted_features_(GPU_FEATURE_TYPE_UNKNOWN),
- preliminary_blacklisted_features_(GPU_FEATURE_TYPE_UNKNOWN),
gpu_switching_(GPU_SWITCHING_OPTION_AUTOMATIC),
observer_list_(new GpuDataManagerObserverList),
- software_rendering_(false),
+ use_swiftshader_(false),
card_blacklisted_(false),
update_histograms_(true),
window_count_(0),
@@ -687,23 +780,22 @@
}
void GpuDataManagerImpl::UpdateBlacklistedFeatures(
- GpuFeatureType features) {
+ const std::set<int>& features) {
CommandLine* command_line = CommandLine::ForCurrentProcess();
- int flags = features;
+ blacklisted_features_ = features;
// Force disable using the GPU for these features, even if they would
// otherwise be allowed.
if (card_blacklisted_ ||
command_line->HasSwitch(switches::kBlacklistAcceleratedCompositing)) {
- flags |= GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING;
+ blacklisted_features_.insert(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING);
}
if (card_blacklisted_ ||
command_line->HasSwitch(switches::kBlacklistWebGL)) {
- flags |= GPU_FEATURE_TYPE_WEBGL;
+ blacklisted_features_.insert(GPU_FEATURE_TYPE_WEBGL);
}
- blacklisted_features_ = static_cast<GpuFeatureType>(flags);
- EnableSoftwareRenderingIfNecessary();
+ EnableSwiftShaderIfNecessary();
}
void GpuDataManagerImpl::UpdatePreliminaryBlacklistedFeatures() {
@@ -733,13 +825,13 @@
observer_list_->Notify(&GpuDataManagerObserver::OnGpuInfoUpdate);
}
-void GpuDataManagerImpl::EnableSoftwareRenderingIfNecessary() {
- if (!GpuAccessAllowed() ||
- (blacklisted_features_ & GPU_FEATURE_TYPE_WEBGL)) {
+void GpuDataManagerImpl::EnableSwiftShaderIfNecessary() {
+ if (!GpuAccessAllowed(NULL) ||
+ blacklisted_features_.count(GPU_FEATURE_TYPE_WEBGL)) {
if (!swiftshader_path_.empty() &&
!CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableSoftwareRasterizer))
- software_rendering_ = true;
+ use_swiftshader_ = true;
}
}
diff --git a/content/browser/gpu/gpu_data_manager_impl.h b/content/browser/gpu/gpu_data_manager_impl.h
index 93fc6c5..5fa8780 100644
--- a/content/browser/gpu/gpu_data_manager_impl.h
+++ b/content/browser/gpu/gpu_data_manager_impl.h
@@ -7,8 +7,11 @@
#include <list>
#include <map>
+#include <set>
#include <string>
+#include <vector>
+#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
@@ -25,10 +28,12 @@
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/common/gpu_info.h"
#include "content/public/common/gpu_memory_stats.h"
+#include "content/public/common/gpu_switching_option.h"
#include "content/public/common/three_d_api_types.h"
class CommandLine;
class GURL;
+struct WebPreferences;
namespace content {
@@ -60,15 +65,15 @@
virtual void InitializeForTesting(
const std::string& gpu_blacklist_json,
const GPUInfo& gpu_info) OVERRIDE;
- virtual GpuFeatureType GetBlacklistedFeatures() const OVERRIDE;
+ virtual bool IsFeatureBlacklisted(int feature) const OVERRIDE;
virtual GPUInfo GetGPUInfo() const OVERRIDE;
virtual void GetGpuProcessHandles(
const GetGpuProcessHandlesCallback& callback) const OVERRIDE;
- virtual bool GpuAccessAllowed() const OVERRIDE;
+ virtual bool GpuAccessAllowed(std::string* reason) const OVERRIDE;
virtual void RequestCompleteGpuInfoIfNeeded() OVERRIDE;
virtual bool IsCompleteGpuInfoAvailable() const OVERRIDE;
virtual void RequestVideoMemoryUsageStatsUpdate() const OVERRIDE;
- virtual bool ShouldUseSoftwareRendering() const OVERRIDE;
+ virtual bool ShouldUseSwiftShader() const OVERRIDE;
virtual void RegisterSwiftShaderPath(const base::FilePath& path) OVERRIDE;
virtual void AddObserver(GpuDataManagerObserver* observer) OVERRIDE;
virtual void RemoveObserver(GpuDataManagerObserver* observer) OVERRIDE;
@@ -106,6 +111,9 @@
// kDisableCoreAnimationPlugins.
void AppendPluginCommandLine(CommandLine* command_line) const;
+ // Update WebPreferences for renderer based on blacklisting decisions.
+ void UpdateRendererWebPrefs(WebPreferences* prefs) const;
+
GpuSwitchingOption GetGpuSwitchingOption() const;
std::string GetBlacklistVersion() const;
@@ -155,6 +163,15 @@
// Disables domain blocking for 3D APIs. For use only in tests.
void DisableDomainBlockingFor3DAPIsForTesting();
+ // Get number of features being blacklisted.
+ size_t GetBlacklistedFeatureCount() const;
+
+ typedef base::Callback<void()> GpuSwitchCallback;
+
+ // Add and remove gpu switch callback.
+ void AddGpuSwitchCallback(const GpuSwitchCallback& callback);
+ void RemoveGpuSwitchCallback(const GpuSwitchCallback& callback);
+
private:
struct DomainBlockEntry {
DomainGuilt last_guilt;
@@ -172,11 +189,11 @@
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplTest, GpuSideExceptions);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplTest,
DisableHardwareAcceleration);
- FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplTest, SoftwareRendering);
- FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplTest, SoftwareRendering2);
+ FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplTest, SwiftShaderRendering);
+ FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplTest, SwiftShaderRendering2);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplTest, GpuInfoUpdate);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplTest,
- NoGpuInfoUpdateWithSoftwareRendering);
+ NoGpuInfoUpdateWithSwiftShader);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplTest,
GPUVideoMemoryUsageStatsUpdate);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplTest,
@@ -189,6 +206,8 @@
UnblockOtherDomainFrom3DAPIs);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplTest,
UnblockThisDomainFrom3DAPIs);
+ FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplTest, GpuDriverBugListSingle);
+ FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplTest, GpuDriverBugListMultiple);
GpuDataManagerImpl();
virtual ~GpuDataManagerImpl();
@@ -198,7 +217,7 @@
const std::string& gpu_driver_bug_list_json,
const GPUInfo& gpu_info);
- void UpdateBlacklistedFeatures(GpuFeatureType features);
+ void UpdateBlacklistedFeatures(const std::set<int>& features);
// This should only be called once at initialization time, when preliminary
// gpu info is collected.
@@ -211,8 +230,8 @@
// Notify all observers whenever there is a GPU info update.
void NotifyGpuInfoUpdate();
- // Try to switch to software rendering, if possible and necessary.
- void EnableSoftwareRenderingIfNecessary();
+ // Try to switch to SwiftShader rendering, if possible and necessary.
+ void EnableSwiftShaderIfNecessary();
// Helper to extract the domain from a given URL.
std::string GetDomainFromURL(const GURL& url) const;
@@ -232,12 +251,12 @@
bool complete_gpu_info_already_requested_;
- GpuFeatureType blacklisted_features_;
- GpuFeatureType preliminary_blacklisted_features_;
+ std::set<int> blacklisted_features_;
+ std::set<int> preliminary_blacklisted_features_;
GpuSwitchingOption gpu_switching_;
- int gpu_driver_bugs_;
+ std::set<int> gpu_driver_bugs_;
GPUInfo gpu_info_;
mutable base::Lock gpu_info_lock_;
@@ -251,7 +270,7 @@
ListValue log_messages_;
mutable base::Lock log_messages_lock_;
- bool software_rendering_;
+ bool use_swiftshader_;
base::FilePath swiftshader_path_;
@@ -270,6 +289,8 @@
mutable std::list<base::Time> timestamps_of_gpu_resets_;
bool domain_blocking_enabled_;
+ std::vector<GpuSwitchCallback> gpu_switch_callbacks_;
+
DISALLOW_COPY_AND_ASSIGN(GpuDataManagerImpl);
};
diff --git a/content/browser/gpu/gpu_data_manager_impl_unittest.cc b/content/browser/gpu/gpu_data_manager_impl_unittest.cc
index c8c1dc6..efbcdfb 100644
--- a/content/browser/gpu/gpu_data_manager_impl_unittest.cc
+++ b/content/browser/gpu/gpu_data_manager_impl_unittest.cc
@@ -2,13 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/run_loop.h"
#include "base/time.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/public/browser/gpu_data_manager_observer.h"
+#include "content/public/common/gpu_feature_type.h"
#include "content/public/common/gpu_info.h"
#include "googleurl/src/gurl.h"
+#include "gpu/command_buffer/service/gpu_switches.h"
#include "testing/gtest/include/gtest/gtest.h"
#define LONG_STRING_CONST(...) #__VA_ARGS__
@@ -96,7 +99,7 @@
void TestUnblockingDomainFrom3DAPIs(
GpuDataManagerImpl::DomainGuilt guilt_level);
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
};
// We use new method instead of GetInstance() method because we want
@@ -109,8 +112,10 @@
// access, to be on the safe side.
ScopedGpuDataManagerImpl manager;
ASSERT_TRUE(manager.get());
- EXPECT_EQ(0, manager->GetBlacklistedFeatures());
- EXPECT_TRUE(manager->GpuAccessAllowed());
+ EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
+ std::string reason;
+ EXPECT_TRUE(manager->GpuAccessAllowed(&reason));
+ EXPECT_TRUE(reason.empty());
const std::string blacklist_json = LONG_STRING_CONST(
{
@@ -142,23 +147,27 @@
gpu_info.gpu.device_id = 0x0640;
manager->InitializeForTesting(blacklist_json, gpu_info);
- EXPECT_TRUE(manager->GpuAccessAllowed());
- EXPECT_EQ(GPU_FEATURE_TYPE_WEBGL, manager->GetBlacklistedFeatures());
+ EXPECT_TRUE(manager->GpuAccessAllowed(&reason));
+ EXPECT_TRUE(reason.empty());
+ EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount());
+ EXPECT_TRUE(manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL));
gpu_info.gl_vendor = "NVIDIA";
gpu_info.gl_renderer = "NVIDIA GeForce GT 120";
manager->UpdateGpuInfo(gpu_info);
- EXPECT_FALSE(manager->GpuAccessAllowed());
- EXPECT_EQ(GPU_FEATURE_TYPE_WEBGL |
- GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS,
- manager->GetBlacklistedFeatures());
+ EXPECT_FALSE(manager->GpuAccessAllowed(&reason));
+ EXPECT_FALSE(reason.empty());
+ EXPECT_EQ(2u, manager->GetBlacklistedFeatureCount());
+ EXPECT_TRUE(manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL));
+ EXPECT_TRUE(manager->IsFeatureBlacklisted(
+ GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS));
}
TEST_F(GpuDataManagerImplTest, GpuSideExceptions) {
ScopedGpuDataManagerImpl manager;
ASSERT_TRUE(manager.get());
- EXPECT_EQ(0, manager->GetBlacklistedFeatures());
- EXPECT_TRUE(manager->GpuAccessAllowed());
+ EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
const std::string blacklist_json = LONG_STRING_CONST(
{
@@ -187,68 +196,74 @@
gpu_info.gpu.device_id = 0x0640;
manager->InitializeForTesting(blacklist_json, gpu_info);
- EXPECT_TRUE(manager->GpuAccessAllowed());
- EXPECT_EQ(0, manager->GetBlacklistedFeatures());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
// Now assume gpu process launches and full GPU info is collected.
gpu_info.gl_renderer = "NVIDIA GeForce GT 120";
manager->UpdateGpuInfo(gpu_info);
- EXPECT_TRUE(manager->GpuAccessAllowed());
- EXPECT_EQ(0, manager->GetBlacklistedFeatures());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
}
TEST_F(GpuDataManagerImplTest, DisableHardwareAcceleration) {
ScopedGpuDataManagerImpl manager;
ASSERT_TRUE(manager.get());
- EXPECT_EQ(0, manager->GetBlacklistedFeatures());
- EXPECT_TRUE(manager->GpuAccessAllowed());
+ EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
+ std::string reason;
+ EXPECT_TRUE(manager->GpuAccessAllowed(&reason));
+ EXPECT_TRUE(reason.empty());
manager->DisableHardwareAcceleration();
- EXPECT_FALSE(manager->GpuAccessAllowed());
- EXPECT_EQ(GPU_FEATURE_TYPE_ALL, manager->GetBlacklistedFeatures());
+ EXPECT_FALSE(manager->GpuAccessAllowed(&reason));
+ EXPECT_FALSE(reason.empty());
+ EXPECT_EQ(static_cast<size_t>(NUMBER_OF_GPU_FEATURE_TYPES),
+ manager->GetBlacklistedFeatureCount());
}
-TEST_F(GpuDataManagerImplTest, SoftwareRendering) {
+TEST_F(GpuDataManagerImplTest, SwiftShaderRendering) {
// Blacklist, then register SwiftShader.
ScopedGpuDataManagerImpl manager;
ASSERT_TRUE(manager.get());
- EXPECT_EQ(0, manager->GetBlacklistedFeatures());
- EXPECT_TRUE(manager->GpuAccessAllowed());
- EXPECT_FALSE(manager->ShouldUseSoftwareRendering());
+ EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_FALSE(manager->ShouldUseSwiftShader());
manager->DisableHardwareAcceleration();
- EXPECT_FALSE(manager->GpuAccessAllowed());
- EXPECT_FALSE(manager->ShouldUseSoftwareRendering());
+ EXPECT_FALSE(manager->GpuAccessAllowed(NULL));
+ EXPECT_FALSE(manager->ShouldUseSwiftShader());
- // If software rendering is enabled, even if we blacklist GPU,
+ // If SwiftShader is enabled, even if we blacklist GPU,
// GPU process is still allowed.
const base::FilePath test_path(FILE_PATH_LITERAL("AnyPath"));
manager->RegisterSwiftShaderPath(test_path);
- EXPECT_TRUE(manager->ShouldUseSoftwareRendering());
- EXPECT_TRUE(manager->GpuAccessAllowed());
- EXPECT_EQ(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS,
- manager->GetBlacklistedFeatures());
+ EXPECT_TRUE(manager->ShouldUseSwiftShader());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount());
+ EXPECT_TRUE(
+ manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS));
}
-TEST_F(GpuDataManagerImplTest, SoftwareRendering2) {
+TEST_F(GpuDataManagerImplTest, SwiftShaderRendering2) {
// Register SwiftShader, then blacklist.
ScopedGpuDataManagerImpl manager;
ASSERT_TRUE(manager.get());
- EXPECT_EQ(0, manager->GetBlacklistedFeatures());
- EXPECT_TRUE(manager->GpuAccessAllowed());
- EXPECT_FALSE(manager->ShouldUseSoftwareRendering());
+ EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_FALSE(manager->ShouldUseSwiftShader());
const base::FilePath test_path(FILE_PATH_LITERAL("AnyPath"));
manager->RegisterSwiftShaderPath(test_path);
- EXPECT_EQ(0, manager->GetBlacklistedFeatures());
- EXPECT_TRUE(manager->GpuAccessAllowed());
- EXPECT_FALSE(manager->ShouldUseSoftwareRendering());
+ EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_FALSE(manager->ShouldUseSwiftShader());
manager->DisableHardwareAcceleration();
- EXPECT_TRUE(manager->GpuAccessAllowed());
- EXPECT_TRUE(manager->ShouldUseSoftwareRendering());
- EXPECT_EQ(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS,
- manager->GetBlacklistedFeatures());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_TRUE(manager->ShouldUseSwiftShader());
+ EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount());
+ EXPECT_TRUE(
+ manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS));
}
TEST_F(GpuDataManagerImplTest, GpuInfoUpdate) {
@@ -273,15 +288,15 @@
EXPECT_TRUE(observer.gpu_info_updated());
}
-TEST_F(GpuDataManagerImplTest, NoGpuInfoUpdateWithSoftwareRendering) {
+TEST_F(GpuDataManagerImplTest, NoGpuInfoUpdateWithSwiftShader) {
ScopedGpuDataManagerImpl manager;
ASSERT_TRUE(manager.get());
manager->DisableHardwareAcceleration();
const base::FilePath test_path(FILE_PATH_LITERAL("AnyPath"));
manager->RegisterSwiftShaderPath(test_path);
- EXPECT_TRUE(manager->ShouldUseSoftwareRendering());
- EXPECT_TRUE(manager->GpuAccessAllowed());
+ EXPECT_TRUE(manager->ShouldUseSwiftShader());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
{
base::RunLoop run_loop;
@@ -462,8 +477,8 @@
ScopedGpuDataManagerImpl manager;
ASSERT_TRUE(manager.get());
- EXPECT_EQ(0, manager->GetBlacklistedFeatures());
- EXPECT_TRUE(manager->GpuAccessAllowed());
+ EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
const std::string blacklist_json = LONG_STRING_CONST(
{
@@ -495,16 +510,17 @@
manager->InitializeForTesting(blacklist_json, gpu_info);
// Not enough GPUInfo.
- EXPECT_TRUE(manager->GpuAccessAllowed());
- EXPECT_EQ(0, manager->GetBlacklistedFeatures());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
// Now assume browser gets GL strings from local state.
// The entry applies, blacklist more features than from the preliminary step.
// However, GPU process is not blocked because this is all browser side and
// happens before renderer launching.
manager->SetGLStrings(kGLVendorMesa, kGLRendererMesa, kGLVersionMesa801);
- EXPECT_TRUE(manager->GpuAccessAllowed());
- EXPECT_EQ(GPU_FEATURE_TYPE_WEBGL, manager->GetBlacklistedFeatures());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount());
+ EXPECT_TRUE(manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL));
}
TEST_F(GpuDataManagerImplTest, SetGLStringsNoEffects) {
@@ -515,8 +531,8 @@
ScopedGpuDataManagerImpl manager;
ASSERT_TRUE(manager.get());
- EXPECT_EQ(0, manager->GetBlacklistedFeatures());
- EXPECT_TRUE(manager->GpuAccessAllowed());
+ EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
const std::string blacklist_json = LONG_STRING_CONST(
{
@@ -553,16 +569,88 @@
manager->InitializeForTesting(blacklist_json, gpu_info);
// Full GPUInfo, the entry applies.
- EXPECT_TRUE(manager->GpuAccessAllowed());
- EXPECT_EQ(GPU_FEATURE_TYPE_WEBGL, manager->GetBlacklistedFeatures());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount());
+ EXPECT_TRUE(manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL));
// Now assume browser gets GL strings from local state.
// SetGLStrings() has no effects because GPUInfo already got these strings.
// (Otherwise the entry should not apply.)
manager->SetGLStrings(kGLVendorMesa, kGLRendererMesa, kGLVersionMesa802);
- EXPECT_TRUE(manager->GpuAccessAllowed());
- EXPECT_EQ(GPU_FEATURE_TYPE_WEBGL, manager->GetBlacklistedFeatures());
+ EXPECT_TRUE(manager->GpuAccessAllowed(NULL));
+ EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount());
+ EXPECT_TRUE(manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL));
}
#endif // OS_LINUX
+TEST_F(GpuDataManagerImplTest, GpuDriverBugListSingle) {
+ ScopedGpuDataManagerImpl manager;
+ ASSERT_TRUE(manager.get());
+ manager->gpu_driver_bugs_.insert(5);
+
+ CommandLine command_line(0, NULL);
+ manager->AppendGpuCommandLine(&command_line);
+
+ EXPECT_TRUE(command_line.HasSwitch(switches::kGpuDriverBugWorkarounds));
+ std::string args = command_line.GetSwitchValueASCII(
+ switches::kGpuDriverBugWorkarounds);
+ EXPECT_STREQ("5", args.c_str());
+}
+
+TEST_F(GpuDataManagerImplTest, GpuDriverBugListMultiple) {
+ ScopedGpuDataManagerImpl manager;
+ ASSERT_TRUE(manager.get());
+ manager->gpu_driver_bugs_.insert(5);
+ manager->gpu_driver_bugs_.insert(7);
+
+ CommandLine command_line(0, NULL);
+ manager->AppendGpuCommandLine(&command_line);
+
+ EXPECT_TRUE(command_line.HasSwitch(switches::kGpuDriverBugWorkarounds));
+ std::string args = command_line.GetSwitchValueASCII(
+ switches::kGpuDriverBugWorkarounds);
+ EXPECT_STREQ("5,7", args.c_str());
+}
+
+TEST_F(GpuDataManagerImplTest, BlacklistAllFeatures) {
+ ScopedGpuDataManagerImpl manager;
+ ASSERT_TRUE(manager.get());
+ EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount());
+ std::string reason;
+ EXPECT_TRUE(manager->GpuAccessAllowed(&reason));
+ EXPECT_TRUE(reason.empty());
+
+ const std::string blacklist_json = LONG_STRING_CONST(
+ {
+ "name": "gpu blacklist",
+ "version": "0.1",
+ "entries": [
+ {
+ "id": 1,
+ "features": [
+ "all"
+ ]
+ }
+ ]
+ }
+ );
+
+ GPUInfo gpu_info;
+ gpu_info.gpu.vendor_id = 0x10de;
+ gpu_info.gpu.device_id = 0x0640;
+ manager->InitializeForTesting(blacklist_json, gpu_info);
+
+ EXPECT_EQ(NUMBER_OF_GPU_FEATURE_TYPES,
+ manager->GetBlacklistedFeatureCount());
+ // TODO(zmo): remove the Linux specific behavior once we fix
+ // crbug.com/238466.
+#if defined(OS_LINUX)
+ EXPECT_TRUE(manager->GpuAccessAllowed(&reason));
+ EXPECT_TRUE(reason.empty());
+#else
+ EXPECT_FALSE(manager->GpuAccessAllowed(&reason));
+ EXPECT_FALSE(reason.empty());
+#endif
+}
+
} // namespace content
diff --git a/content/browser/gpu/gpu_driver_bug_list.cc b/content/browser/gpu/gpu_driver_bug_list.cc
index 2ffad72..9ab93f2 100644
--- a/content/browser/gpu/gpu_driver_bug_list.cc
+++ b/content/browser/gpu/gpu_driver_bug_list.cc
@@ -4,10 +4,21 @@
#include "content/browser/gpu/gpu_driver_bug_list.h"
-#include "content/public/common/gpu_feature_type.h"
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "gpu/command_buffer/service/gpu_driver_bug_workaround_type.h"
namespace content {
+namespace {
+
+struct DriverBugInfo {
+ int feature_type;
+ std::string feature_name;
+};
+
+} // namespace anonymous
+
GpuDriverBugList::GpuDriverBugList()
: GpuControlList() {
}
@@ -18,6 +29,18 @@
// static
GpuDriverBugList* GpuDriverBugList::Create() {
GpuDriverBugList* list = new GpuDriverBugList();
+
+ const DriverBugInfo kFeatureList[] = {
+#define GPU_OP(type, name) { gpu::type, #name },
+ GPU_DRIVER_BUG_WORKAROUNDS(GPU_OP)
+#undef GPU_OP
+ };
+ DCHECK_EQ(static_cast<int>(arraysize(kFeatureList)),
+ gpu::NUMBER_OF_GPU_DRIVER_BUG_WORKAROUND_TYPES);
+ for (int i = 0; i < gpu::NUMBER_OF_GPU_DRIVER_BUG_WORKAROUND_TYPES; ++i) {
+ list->AddSupportedFeature(kFeatureList[i].feature_name,
+ kFeatureList[i].feature_type);
+ }
return list;
}
diff --git a/content/browser/gpu/gpu_driver_bug_list.json b/content/browser/gpu/gpu_driver_bug_list.json
index 9ee21df..c559173 100644
--- a/content/browser/gpu/gpu_driver_bug_list.json
+++ b/content/browser/gpu/gpu_driver_bug_list.json
@@ -38,11 +38,12 @@
// 16. "gpu_count" is a INT structure (defined below).
// 17 "cpu_info" is a STRING structure (defined below).
// 18. "exceptions" is a list of entries.
-// 19. "features" is a list of gpu switching options.
+// 19. "features" is a list of driver bug types. For a list of supported types,
+// see src/gpu/command_buffer/service/gpu_driver_bug_workaround_type.h
// This field is mandatory.
// 20. "description" has the description of the entry.
// 21. "webkit_bugs" is an array of associated webkit bug numbers.
-// 22. "cr_bugs" is an array of associated webkit bug numbers.
+// 22. "cr_bugs" is an array of associated chromium bug numbers.
// 23. "browser_version" is a VERSION structure (defined below). If this
// condition is not satisfied, the entry will be ignored. If it is not
// present, then the entry applies to all versions of the browser.
@@ -71,7 +72,234 @@
{
"name": "gpu driver bug list",
// Please update the version number whenever you change this file.
- "version": "1.0",
+ "version": "1.3",
"entries": [
+ {
+ "id": 1,
+ "description": "Imagination driver doesn't like uploading lots of buffer data constantly",
+ "os": {
+ "type": "android"
+ },
+ "gl_vendor": {
+ "op": "beginwith",
+ "value": "Imagination"
+ },
+ "features": [
+ "use_client_side_arrays_for_stream_buffers"
+ ]
+ },
+ {
+ "id": 2,
+ "description": "ARM driver doesn't like uploading lots of buffer data constantly",
+ "os": {
+ "type": "android"
+ },
+ "gl_vendor": {
+ "op": "beginwith",
+ "value": "ARM"
+ },
+ "features": [
+ "use_client_side_arrays_for_stream_buffers"
+ ]
+ },
+ {
+ "id": 3,
+ "features": [
+ "set_texture_filter_before_generating_mipmap"
+ ]
+ },
+ {
+ "id": 4,
+ "description": "Need to set the alpha to 255",
+ "features": [
+ "clear_alpha_in_readpixels"
+ ]
+ },
+ {
+ "id": 5,
+ "vendor_id": "0x10de",
+ "features": [
+ "use_current_program_after_successful_link"
+ ]
+ },
+ {
+ "id": 6,
+ "os": {
+ "type": "android"
+ },
+ "gl_vendor": {
+ "op": "beginwith",
+ "value": "Qualcomm"
+ },
+ "features": [
+ "restore_scissor_on_fbo_change",
+ "flush_on_context_switch",
+ "delete_instead_of_resize_fbo" // Only need this on the ICS driver.
+ ]
+ },
+ {
+ "id": 7,
+ "cr_bugs": [89557],
+ "os": {
+ "type": "macosx"
+ },
+ "vendor_id": "0x10de",
+ "features": [
+ "needs_offscreen_buffer_workaround"
+ ]
+ },
+ {
+ "id": 8,
+ "os": {
+ "type": "macosx"
+ },
+ "vendor_id": "0x1002",
+ "features": [
+ "needs_glsl_built_in_function_emulation"
+ ]
+ },
+ {
+ "id": 9,
+ "description": "Mac AMD drivers get gl_PointCoord backward, rdar://problem/11883495",
+ "os": {
+ "type": "macosx"
+ },
+ "vendor_id": "0x1002",
+ "features": [
+ "reverse_point_sprite_coord_origin"
+ ]
+ },
+ {
+ "id": 10,
+ "description": "Mac Intel drivers get gl_PointCoord backward, rdar://problem/11883495",
+ "os": {
+ "type": "macosx"
+ },
+ "vendor_id": "0x8086",
+ "features": [
+ "reverse_point_sprite_coord_origin"
+ ]
+ },
+ {
+ "id": 11,
+ "os": {
+ "type": "macosx"
+ },
+ "vendor_id": "0x8086",
+ "features": [
+ "max_texture_size_limit_4096"
+ ]
+ },
+ {
+ "id": 12,
+ "os": {
+ "type": "macosx"
+ },
+ "vendor_id": "0x8086",
+ "features": [
+ "max_cube_map_texture_size_limit_1024"
+ ]
+ },
+ {
+ "id": 13,
+ "os": {
+ "type": "macosx",
+ "version": {
+ "op": "<",
+ "number": "10.7.3"
+ }
+ },
+ "vendor_id": "0x8086",
+ "features": [
+ "max_cube_map_texture_size_limit_512"
+ ]
+ },
+ {
+ "id": 14,
+ "os": {
+ "type": "macosx"
+ },
+ "vendor_id": "0x1002",
+ "features": [
+ "max_texture_size_limit_4096",
+ "max_cube_map_texture_size_limit_4096"
+ ]
+ },
+ {
+ "id": 15,
+ "description": "Some Android Qualcomm drivers falsely report GL_ANGLE_framebuffer_multisample",
+ "cr_bugs": [165736],
+ "os": {
+ "type": "android"
+ },
+ "gl_vendor": {
+ "op": "beginwith",
+ "value": "Qualcomm"
+ },
+ "features": [
+ "disable_angle_framebuffer_multisample"
+ ]
+ },
+ {
+ "id": 16,
+ "description": "Intel drivers on Linux appear to be buggy",
+ "os": {
+ "type": "linux"
+ },
+ "vendor_id": "0x8086",
+ "features": [
+ "disable_ext_occlusion_query"
+ ]
+ },
+ {
+ "id": 17,
+ "description": "Some drivers are unable to reset the D3D device in the GPU process sandbox",
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "exit_on_context_lost"
+ ]
+ },
+ {
+ "id": 18,
+ "description": "Everything except async + NPOT + multiple-of-8 textures are brutally slow for Imagination drivers",
+ "os": {
+ "type": "android"
+ },
+ "gl_vendor": {
+ "op": "beginwith",
+ "value": "Imagination"
+ },
+ "features": [
+ "enable_chromium_fast_npot_mo8_textures"
+ ]
+ },
+ {
+ "id": 19,
+ "os": {
+ "type": "android"
+ },
+ "gl_vendor": {
+ "op": "beginwith",
+ "value": "Qualcomm"
+ },
+ "features": [
+ "disable_depth_texture"
+ ]
+ },
+ {
+ "id": 20,
+ "description": "Disable EXT_draw_buffers on GeForce GT 650M on Mac OS X due to driver bugs.",
+ "os": {
+ "type": "macosx"
+ },
+ "vendor_id": "0x10de",
+ "device_id": ["0x0fd5"],
+ "multi_gpu_category": "any",
+ "features": [
+ "disable_ext_draw_buffers"
+ ]
+ }
]
}
diff --git a/content/browser/gpu/gpu_driver_bug_list_unittest.cc b/content/browser/gpu/gpu_driver_bug_list_unittest.cc
index 4eb6009..931274c 100644
--- a/content/browser/gpu/gpu_driver_bug_list_unittest.cc
+++ b/content/browser/gpu/gpu_driver_bug_list_unittest.cc
@@ -5,10 +5,12 @@
#include "base/base_paths.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
+#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "content/browser/gpu/gpu_driver_bug_list.h"
#include "content/public/common/gpu_info.h"
+#include "gpu/command_buffer/service/gpu_driver_bug_workaround_type.h"
#include "testing/gtest/include/gtest/gtest.h"
const char kOsVersion[] = "10.6.4";
@@ -25,6 +27,30 @@
return gpu_info_;
}
+ bool GetCurrentDriverBugList(std::string* json) {
+ DCHECK(json);
+ base::FilePath data_file;
+ if (!PathService::Get(base::DIR_SOURCE_ROOT, &data_file))
+ return false;
+ data_file =
+ data_file.Append(FILE_PATH_LITERAL("content"))
+ .Append(FILE_PATH_LITERAL("browser"))
+ .Append(FILE_PATH_LITERAL("gpu"))
+ .Append(FILE_PATH_LITERAL("gpu_driver_bug_list.json"));
+ if (!file_util::PathExists(data_file))
+ return false;
+ int64 data_file_size64 = 0;
+ if (!file_util::GetFileSize(data_file, &data_file_size64))
+ return false;
+ int data_file_size = static_cast<int>(data_file_size64);
+ scoped_ptr<char[]> data(new char[data_file_size]);
+ if (file_util::ReadFile(data_file, data.get(), data_file_size) !=
+ data_file_size)
+ return false;
+ *json = std::string(data.get(), data_file_size);
+ return true;
+ }
+
protected:
virtual void SetUp() {
gpu_info_.gpu.vendor_id = 0x10de;
@@ -49,25 +75,40 @@
#if !defined(OS_ANDROID)
TEST_F(GpuDriverBugListTest, CurrentDriverBugListValidation) {
- base::FilePath data_file;
- ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_file));
- data_file =
- data_file.Append(FILE_PATH_LITERAL("content"))
- .Append(FILE_PATH_LITERAL("browser"))
- .Append(FILE_PATH_LITERAL("gpu"))
- .Append(FILE_PATH_LITERAL("gpu_driver_bug_list.json"));
- ASSERT_TRUE(file_util::PathExists(data_file));
- int64 data_file_size64 = 0;
- ASSERT_TRUE(file_util::GetFileSize(data_file, &data_file_size64));
- int data_file_size = static_cast<int>(data_file_size64);
- scoped_array<char> data(new char[data_file_size]);
- ASSERT_EQ(data_file_size,
- file_util::ReadFile(data_file, data.get(), data_file_size));
- std::string json_string(data.get(), data_file_size);
scoped_ptr<GpuDriverBugList> list(GpuDriverBugList::Create());
- EXPECT_TRUE(list->LoadList(json_string, GpuControlList::kAllOs));
+ std::string json;
+ EXPECT_TRUE(GetCurrentDriverBugList(&json));
+ EXPECT_TRUE(list->LoadList(json, GpuControlList::kAllOs));
EXPECT_FALSE(list->contains_unknown_fields());
}
+
+TEST_F(GpuDriverBugListTest, CurrentListForARM) {
+ scoped_ptr<GpuDriverBugList> list(GpuDriverBugList::Create());
+ std::string json;
+ EXPECT_TRUE(GetCurrentDriverBugList(&json));
+ EXPECT_TRUE(list->LoadList(json, GpuControlList::kAllOs));
+
+ GPUInfo gpu_info;
+ gpu_info.gl_vendor = "ARM";
+ gpu_info.gl_renderer = "MALi_T604";
+ std::set<int> bugs = list->MakeDecision(
+ GpuControlList::kOsAndroid, "4.1", gpu_info);
+ EXPECT_EQ(1u, bugs.count(gpu::USE_CLIENT_SIDE_ARRAYS_FOR_STREAM_BUFFERS));
+}
+
+TEST_F(GpuDriverBugListTest, CurrentListForImagination) {
+ scoped_ptr<GpuDriverBugList> list(GpuDriverBugList::Create());
+ std::string json;
+ EXPECT_TRUE(GetCurrentDriverBugList(&json));
+ EXPECT_TRUE(list->LoadList(json, GpuControlList::kAllOs));
+
+ GPUInfo gpu_info;
+ gpu_info.gl_vendor = "Imagination Technologies";
+ gpu_info.gl_renderer = "PowerVR SGX 540";
+ std::set<int> bugs = list->MakeDecision(
+ GpuControlList::kOsAndroid, "4.1", gpu_info);
+ EXPECT_EQ(1u, bugs.count(gpu::USE_CLIENT_SIDE_ARRAYS_FOR_STREAM_BUFFERS));
+}
#endif
} // namespace content
diff --git a/content/browser/gpu/gpu_functional_browsertest.cc b/content/browser/gpu/gpu_functional_browsertest.cc
new file mode 100644
index 0000000..6d31c2a
--- /dev/null
+++ b/content/browser/gpu/gpu_functional_browsertest.cc
@@ -0,0 +1,130 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/command_line.h"
+#include "base/path_service.h"
+#include "content/browser/gpu/gpu_process_host.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/content_paths.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/url_constants.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/shell/shell.h"
+#include "content/test/content_browser_test.h"
+#include "content/test/content_browser_test_utils.h"
+
+namespace content {
+
+namespace {
+ void VerifyGPUProcessLaunch(bool* result) {
+ GpuProcessHost* host =
+ GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
+ content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH);
+ *result = !!host;
+ }
+}
+
+class GpuFunctionalTest : public ContentBrowserTest {
+ protected:
+ virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
+ base::FilePath test_dir;
+ ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &test_dir));
+ gpu_test_dir_ = test_dir.AppendASCII("gpu");
+ }
+
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ command_line->AppendSwitch(switches::kDisableGpuProcessPrelaunch);
+ }
+
+ void VerifyHardwareAccelerated(const std::string& feature) {
+ NavigateToURL(shell(),
+ GURL(std::string(chrome::kChromeUIScheme).
+ append("://").
+ append(kChromeUIGpuHost)));
+
+ {
+ // Verify that the given feature is hardware accelerated..
+ std::string javascript =
+ "function VerifyHardwareAccelerated(feature) {"
+ " var list = document.querySelector(\".feature-status-list\");"
+ " for (var i=0; i < list.childElementCount; i++) {"
+ " var span_list = list.children[i].getElementsByTagName('span');"
+ " var feature_str = span_list[0].textContent;"
+ " var value_str = span_list[1].textContent;"
+ " if ((feature_str == feature) &&"
+ " (value_str == 'Hardware accelerated')) {"
+ " domAutomationController.send(\"success\");"
+ " }"
+ " }"
+ "};";
+ javascript.append("VerifyHardwareAccelerated(\"");
+ javascript.append(feature);
+ javascript.append("\");");
+ std::string result;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(shell()->web_contents(),
+ javascript,
+ &result));
+ EXPECT_EQ(result, "success");
+ }
+ }
+
+ void VerifyGPUProcessOnPage(std::string filename, bool html) {
+ Shell::Initialize();
+ ASSERT_TRUE(test_server()->Start());
+
+ if (html) {
+ std::string url("files/gpu/");
+ GURL full_url = test_server()->GetURL(url.append(filename));
+ NavigateToURL(shell(), full_url);
+ } else {
+ NavigateToURL(shell(),
+ GetFileUrlWithQuery(gpu_test_dir_.AppendASCII(filename),
+ ""));
+ }
+
+ bool result = false;
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&VerifyGPUProcessLaunch, &result),
+ base::MessageLoop::QuitClosure());
+ base::MessageLoop::current()->Run();
+ EXPECT_TRUE(result);
+ }
+
+ base::FilePath gpu_test_dir_;
+};
+
+IN_PROC_BROWSER_TEST_F(GpuFunctionalTest,
+ MANUAL_TestFeatureHardwareAccelerated) {
+ VerifyHardwareAccelerated("WebGL: ");
+ VerifyHardwareAccelerated("Canvas: ");
+ VerifyHardwareAccelerated("3D CSS: ");
+}
+
+// Verify that gpu process is spawned in webgl example.
+IN_PROC_BROWSER_TEST_F(GpuFunctionalTest, MANUAL_TestWebGL) {
+ VerifyGPUProcessOnPage("functional_webgl.html", true);
+}
+
+// Verify that gpu process is spawned when viewing a 2D canvas.
+IN_PROC_BROWSER_TEST_F(GpuFunctionalTest, MANUAL_Test2dCanvas) {
+ VerifyGPUProcessOnPage("functional_canvas_demo.html", true);
+}
+
+// Verify that gpu process is spawned when viewing a 3D CSS page.
+IN_PROC_BROWSER_TEST_F(GpuFunctionalTest, MANUAL_Test3dCss) {
+ VerifyGPUProcessOnPage("functional_3d_css.html", true);
+}
+
+// TestGpuWithVideo is failing on all platforms
+// http://crbug.com/237208
+#define MANUAL_TestGpuWithVideo DISABLED_MANUAL_TestGpuWithVideo
+
+// Verify that gpu process is started when viewing video.
+IN_PROC_BROWSER_TEST_F(GpuFunctionalTest, MANUAL_TestGpuWithVideo) {
+ VerifyGPUProcessOnPage("functional_color2.ogv", false);
+}
+
+} // namespace content
diff --git a/content/browser/gpu/gpu_internals_ui.cc b/content/browser/gpu/gpu_internals_ui.cc
index 62b85e3..eb7646c 100644
--- a/content/browser/gpu/gpu_internals_ui.cc
+++ b/content/browser/gpu/gpu_internals_ui.cc
@@ -25,6 +25,7 @@
#include "content/public/browser/web_ui_message_handler.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/gpu_feature_type.h"
#include "content/public/common/gpu_info.h"
#include "content/public/common/url_constants.h"
#include "grit/content_resources.h"
@@ -42,7 +43,7 @@
};
WebUIDataSource* CreateGpuHTMLSource() {
- WebUIDataSource* source = WebUIDataSource::Create(chrome::kChromeUIGpuHost);
+ WebUIDataSource* source = WebUIDataSource::Create(kChromeUIGpuHost);
source->SetJsonPath("strings.js");
source->AddResourcePath("gpu_internals.js", IDR_GPU_INTERNALS_JS);
@@ -191,16 +192,17 @@
base::Value* GetFeatureStatus() {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
+ std::string gpu_access_blocked_reason;
bool gpu_access_blocked =
- !GpuDataManagerImpl::GetInstance()->GpuAccessAllowed();
+ !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
- uint32 flags = GpuDataManagerImpl::GetInstance()->GetBlacklistedFeatures();
base::DictionaryValue* status = new base::DictionaryValue();
const GpuFeatureInfo kGpuFeatureInfo[] = {
{
"2d_canvas",
- flags & GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS,
+ manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS),
command_line.HasSwitch(switches::kDisableAccelerated2dCanvas) ||
!SupportsAccelerated2dCanvas(),
"Accelerated 2D canvas is unavailable: either disabled at the command"
@@ -209,7 +211,8 @@
},
{
"compositing",
- flags & GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING,
+ manager->IsFeatureBlacklisted(
+ GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING),
command_line.HasSwitch(switches::kDisableAcceleratedCompositing),
"Accelerated compositing has been disabled, either via about:flags or"
" command line. This adversely affects performance of all hardware"
@@ -218,16 +221,18 @@
},
{
"3d_css",
- flags & (GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING |
- GPU_FEATURE_TYPE_3D_CSS),
+ manager->IsFeatureBlacklisted(
+ GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
+ manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_3D_CSS),
command_line.HasSwitch(switches::kDisableAcceleratedLayers),
"Accelerated layers have been disabled at the command line.",
false
},
{
"css_animation",
- flags & (GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING |
- GPU_FEATURE_TYPE_3D_CSS),
+ manager->IsFeatureBlacklisted(
+ GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
+ manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_3D_CSS),
command_line.HasSwitch(cc::switches::kDisableThreadedAnimation) ||
command_line.HasSwitch(switches::kDisableAcceleratedCompositing) ||
command_line.HasSwitch(switches::kDisableAcceleratedLayers),
@@ -236,7 +241,7 @@
},
{
"webgl",
- flags & GPU_FEATURE_TYPE_WEBGL,
+ manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_WEBGL),
#if defined(OS_ANDROID)
!command_line.HasSwitch(switches::kEnableExperimentalWebGL),
#else
@@ -247,7 +252,7 @@
},
{
"multisampling",
- flags & GPU_FEATURE_TYPE_MULTISAMPLING,
+ manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_MULTISAMPLING),
command_line.HasSwitch(switches::kDisableGLMultisampling),
"Multisampling has been disabled, either via about:flags or command"
" line.",
@@ -255,7 +260,7 @@
},
{
"flash_3d",
- flags & GPU_FEATURE_TYPE_FLASH3D,
+ manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH3D),
command_line.HasSwitch(switches::kDisableFlash3d),
"Using 3d in flash has been disabled, either via about:flags or"
" command line.",
@@ -263,7 +268,7 @@
},
{
"flash_stage3d",
- flags & GPU_FEATURE_TYPE_FLASH_STAGE3D,
+ manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH_STAGE3D),
command_line.HasSwitch(switches::kDisableFlashStage3d),
"Using Stage3d in Flash has been disabled, either via about:flags or"
" command line.",
@@ -271,8 +276,9 @@
},
{
"flash_stage3d_baseline",
- flags & (content::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE |
- content::GPU_FEATURE_TYPE_FLASH_STAGE3D),
+ manager->IsFeatureBlacklisted(
+ GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE) ||
+ manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_FLASH_STAGE3D),
command_line.HasSwitch(switches::kDisableFlashStage3d),
"Using Stage3d Baseline profile in Flash has been disabled, either"
" via about:flags or command line.",
@@ -280,7 +286,7 @@
},
{
"texture_sharing",
- flags & GPU_FEATURE_TYPE_TEXTURE_SHARING,
+ manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_TEXTURE_SHARING),
command_line.HasSwitch(switches::kDisableImageTransportSurface),
"Sharing textures between processes has been disabled, either via"
" about:flags or command line.",
@@ -288,7 +294,8 @@
},
{
"video_decode",
- flags & GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE,
+ manager->IsFeatureBlacklisted(
+ GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE),
command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode),
"Accelerated video decode has been disabled, either via about:flags"
" or command line.",
@@ -296,7 +303,7 @@
},
{
"video",
- flags & GPU_FEATURE_TYPE_ACCELERATED_VIDEO,
+ manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_ACCELERATED_VIDEO),
command_line.HasSwitch(switches::kDisableAcceleratedVideo) ||
command_line.HasSwitch(switches::kDisableAcceleratedCompositing),
"Accelerated video presentation has been disabled, either via"
@@ -305,7 +312,7 @@
},
{
"panel_fitting",
- flags & GPU_FEATURE_TYPE_PANEL_FITTING,
+ manager->IsFeatureBlacklisted(GPU_FEATURE_TYPE_PANEL_FITTING),
#if defined(OS_CHROMEOS)
command_line.HasSwitch(switches::kDisablePanelFitting),
#else
@@ -317,10 +324,12 @@
},
{
"force_compositing_mode",
- (flags & GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE) &&
+ manager->IsFeatureBlacklisted(
+ GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE) &&
!IsForceCompositingModeEnabled(),
!IsForceCompositingModeEnabled() &&
- !(flags & GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE),
+ !manager->IsFeatureBlacklisted(
+ GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE),
"Force compositing mode is off, either disabled at the command"
" line or not supported by the current system.",
false
@@ -361,8 +370,7 @@
else
status += "_off";
}
- } else if (GpuDataManagerImpl::GetInstance()->
- ShouldUseSoftwareRendering()) {
+ } else if (GpuDataManagerImpl::GetInstance()->ShouldUseSwiftShader()) {
status = "unavailable_software";
} else if (kGpuFeatureInfo[i].blocked ||
gpu_access_blocked) {
@@ -375,7 +383,8 @@
status = "enabled";
if (kGpuFeatureInfo[i].name == "webgl" &&
(command_line.HasSwitch(switches::kDisableAcceleratedCompositing) ||
- (flags & GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)))
+ manager->IsFeatureBlacklisted(
+ GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)))
status += "_readback";
bool has_thread = IsThreadedCompositingEnabled();
if (kGpuFeatureInfo[i].name == "compositing") {
@@ -431,10 +440,10 @@
if (gpu_access_blocked) {
base::DictionaryValue* problem = new base::DictionaryValue();
problem->SetString("description",
- "GPU process was unable to boot. Access to GPU disallowed.");
+ "GPU process was unable to boot: " + gpu_access_blocked_reason);
problem->Set("crBugs", new base::ListValue());
problem->Set("webkitBugs", new base::ListValue());
- problem_list->Append(problem);
+ problem_list->Insert(0, problem);
}
for (size_t i = 0; i < kNumFeatures; ++i) {
@@ -471,6 +480,9 @@
// GpuDataManagerObserver implementation.
virtual void OnGpuInfoUpdate() OVERRIDE;
+ // Gpu switch handler.
+ void OnGpuSwitch();
+
// Messages
void OnBrowserBridgeInitialized(const base::ListValue* list);
void OnCallAsync(const base::ListValue* list);
@@ -484,6 +496,8 @@
// DCHECK).
bool observing_;
+ GpuDataManagerImpl::GpuSwitchCallback gpu_switch_callback_;
+
DISALLOW_COPY_AND_ASSIGN(GpuMessageHandler);
};
@@ -494,11 +508,15 @@
////////////////////////////////////////////////////////////////////////////////
GpuMessageHandler::GpuMessageHandler()
- : observing_(false) {
+ : observing_(false),
+ gpu_switch_callback_(base::Bind(&GpuMessageHandler::OnGpuSwitch,
+ base::Unretained(this))) {
}
GpuMessageHandler::~GpuMessageHandler() {
GpuDataManagerImpl::GetInstance()->RemoveObserver(this);
+ GpuDataManagerImpl::GetInstance()->RemoveGpuSwitchCallback(
+ gpu_switch_callback_);
}
/* BrowserBridge.callAsync prepends a requestID to these messages. */
@@ -565,8 +583,11 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// Watch for changes in GPUInfo
- if (!observing_)
+ if (!observing_) {
GpuDataManagerImpl::GetInstance()->AddObserver(this);
+ GpuDataManagerImpl::GetInstance()->AddGpuSwitchCallback(
+ gpu_switch_callback_);
+ }
observing_ = true;
// Tell GpuDataManager it should have full GpuInfo. If the
@@ -618,6 +639,10 @@
*(gpu_info_val.get()));
}
+void GpuMessageHandler::OnGpuSwitch() {
+ GpuDataManagerImpl::GetInstance()->RequestCompleteGpuInfoIfNeeded();
+}
+
} // namespace
diff --git a/content/browser/gpu/gpu_memory_test.cc b/content/browser/gpu/gpu_memory_test.cc
index 36584c3..832b947 100644
--- a/content/browser/gpu/gpu_memory_test.cc
+++ b/content/browser/gpu/gpu_memory_test.cc
@@ -116,12 +116,8 @@
js_call << mb_to_use;
js_call << ");";
std::string message;
- ASSERT_TRUE(
- ExecuteScriptInFrameAndExtractString(
- tab_to_load->web_contents(),
- "",
- js_call.str(),
- &message));
+ ASSERT_TRUE(ExecuteScriptInFrameAndExtractString(
+ tab_to_load->web_contents(), std::string(), js_call.str(), &message));
EXPECT_EQ("DONE_USE_GPU_MEMORY", message);
}
@@ -196,12 +192,8 @@
" domAutomationController.send(\"DONE_RAF\");"
"})");
std::string message;
- ASSERT_TRUE(
- ExecuteScriptInFrameAndExtractString(
- (*it)->web_contents(),
- "",
- js_call,
- &message));
+ ASSERT_TRUE(ExecuteScriptInFrameAndExtractString(
+ (*it)->web_contents(), std::string(), js_call, &message));
EXPECT_EQ("DONE_RAF", message);
}
// TODO(ccameron): send an IPC from Browser -> Renderer (delay it until
diff --git a/content/browser/gpu/gpu_pixel_browsertest.cc b/content/browser/gpu/gpu_pixel_browsertest.cc
index e146a08..fb93076 100644
--- a/content/browser/gpu/gpu_pixel_browsertest.cc
+++ b/content/browser/gpu/gpu_pixel_browsertest.cc
@@ -54,8 +54,8 @@
// should have been encoded using |gfx::PNGCodec::Encode|.
bool ReadPNGFile(const base::FilePath& file_path, SkBitmap* bitmap) {
DCHECK(bitmap);
- base::FilePath abs_path(file_path);
- if (!file_util::AbsolutePath(&abs_path))
+ base::FilePath abs_path(base::MakeAbsoluteFilePath(file_path));
+ if (abs_path.empty())
return false;
std::string png_data;
@@ -147,7 +147,7 @@
"DISABLED_", "FLAKY_", "FAILS_", "MANUAL_"};
for (size_t i = 0; i < arraysize(test_status_prefixes); ++i) {
ReplaceFirstSubstringAfterOffset(
- &test_name_, 0, test_status_prefixes[i], "");
+ &test_name_, 0, test_status_prefixes[i], std::string());
}
ui::DisableTestCompositor();
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index 699ce42..560fed2 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -19,7 +19,6 @@
#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host_ui_shim.h"
-#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/browser/gpu/shader_disk_cache.h"
#include "content/browser/renderer_host/render_widget_helper.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -42,9 +41,6 @@
#include "ipc/ipc_switches.h"
#include "ui/gl/gl_switches.h"
-#if defined(TOOLKIT_GTK)
-#include "ui/gfx/gtk_native_view_id_manager.h"
-#endif
#if defined(OS_WIN)
#include "base/win/windows_version.h"
@@ -74,14 +70,6 @@
// only be accessed from the IO thread.
GpuProcessHost* g_gpu_process_hosts[GpuProcessHost::GPU_PROCESS_KIND_COUNT];
-#if defined(TOOLKIT_GTK)
-
-void ReleasePermanentXIDDispatcher(gfx::PluginWindowHandle surface) {
- GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
- manager->ReleasePermanentXID(surface);
-}
-
-#endif
void SendGpuProcessMessage(GpuProcessHost::GpuProcessKind kind,
CauseForGpuLaunch cause,
@@ -254,6 +242,9 @@
return;
}
+ // Block this DLL even if it is not loaded by the browser process.
+ policy->AddDllToUnload(L"cmsetac.dll");
+
#ifdef USE_AURA
// GPU also needs to add sections to the browser for aura
// TODO(jschuh): refactor the GPU channel to remove this. crbug.com/128786
@@ -287,33 +278,6 @@
} // anonymous namespace
-#if defined(TOOLKIT_GTK)
-// Used to put a lock on surfaces so that the window to which the GPU
-// process is drawing to doesn't disappear while it is drawing when
-// a WebContents is closed.
-class GpuProcessHost::SurfaceRef {
- public:
- explicit SurfaceRef(gfx::PluginWindowHandle surface);
- ~SurfaceRef();
- private:
- gfx::PluginWindowHandle surface_;
-};
-
-GpuProcessHost::SurfaceRef::SurfaceRef(gfx::PluginWindowHandle surface)
- : surface_(surface) {
- GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
- if (!manager->AddRefPermanentXID(surface_)) {
- LOG(ERROR) << "Surface " << surface << " cannot be referenced.";
- }
-}
-
-GpuProcessHost::SurfaceRef::~SurfaceRef() {
- BrowserThread::PostTask(BrowserThread::UI,
- FROM_HERE,
- base::Bind(&ReleasePermanentXIDDispatcher, surface_));
-}
-#endif // defined(TOOLKIT_GTK)
-
// This class creates a GPU thread (instead of a GPU process), when running
// with --in-process-gpu or --single-process.
class GpuMainThread : public base::Thread {
@@ -361,13 +325,13 @@
if (!host)
return false;
- // The Gpu process is invalid if it's not using software, the card is
+ // The Gpu process is invalid if it's not using SwiftShader, the card is
// blacklisted, and we can kill it and start over.
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) ||
CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU) ||
(host->valid_ &&
- (host->software_rendering() ||
- !GpuDataManagerImpl::GetInstance()->ShouldUseSoftwareRendering()))) {
+ (host->swiftshader_rendering_ ||
+ !GpuDataManagerImpl::GetInstance()->ShouldUseSwiftShader()))) {
return true;
}
@@ -383,7 +347,7 @@
// Don't grant further access to GPU if it is not allowed.
GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance();
DCHECK(gpu_data_manager);
- if (!gpu_data_manager->GpuAccessAllowed())
+ if (!gpu_data_manager->GpuAccessAllowed(NULL))
return NULL;
if (g_gpu_process_hosts[kind] && ValidateHost(g_gpu_process_hosts[kind]))
@@ -459,7 +423,7 @@
: host_id_(host_id),
valid_(true),
in_process_(false),
- software_rendering_(false),
+ swiftshader_rendering_(false),
kind_(kind),
process_launched_(false),
initialized_(false),
@@ -503,20 +467,19 @@
static int gpu_recent_crash_count = 0;
static base::Time last_gpu_crash_time;
static bool crashed_before = false;
- static int gpu_software_crash_count = 0;
+ static int swiftshader_crash_count = 0;
// Ending only acts as a failure if the GPU process was actually started and
// was intended for actual rendering (and not just checking caps or other
// options).
if (process_launched_ && kind_ == GPU_PROCESS_KIND_SANDBOXED) {
- if (software_rendering_) {
- UMA_HISTOGRAM_ENUMERATION("GPU.SoftwareRendererLifetimeEvents",
- DIED_FIRST_TIME + gpu_software_crash_count,
+ if (swiftshader_rendering_) {
+ UMA_HISTOGRAM_ENUMERATION("GPU.SwiftShaderLifetimeEvents",
+ DIED_FIRST_TIME + swiftshader_crash_count,
GPU_PROCESS_LIFETIME_EVENT_MAX);
- if (++gpu_software_crash_count >= kGpuMaxCrashCount) {
- // The software renderer is too unstable to use. Disable it for current
- // session.
+ if (++swiftshader_crash_count >= kGpuMaxCrashCount) {
+ // SwiftShader is too unstable to use. Disable it for current session.
gpu_enabled_ = false;
}
} else {
@@ -632,7 +595,7 @@
bool GpuProcessHost::Init() {
init_start_time_ = base::TimeTicks::Now();
- TRACE_EVENT_INSTANT0("gpu", "LaunchGpuProcess");
+ TRACE_EVENT_INSTANT0("gpu", "LaunchGpuProcess", TRACE_EVENT_SCOPE_THREAD);
std::string channel_id = process_->GetHost()->CreateChannel();
if (channel_id.empty())
@@ -742,7 +705,7 @@
TRACE_EVENT0("gpu", "GpuProcessHost::EstablishGpuChannel");
// If GPU features are already blacklisted, no need to establish the channel.
- if (!GpuDataManagerImpl::GetInstance()->GpuAccessAllowed()) {
+ if (!GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL)) {
callback.Run(IPC::ChannelHandle(), GPUInfo());
return;
}
@@ -769,26 +732,12 @@
DCHECK(CalledOnValidThread());
-#if defined(TOOLKIT_GTK)
- // There should only be one such command buffer (for the compositor). In
- // practice, if the GPU process lost a context, GraphicsContext3D with
- // associated command buffer and view surface will not be gone until new
- // one is in place and all layers are reattached.
- linked_ptr<SurfaceRef> surface_ref;
- SurfaceRefMap::iterator it = surface_refs_.find(surface_id);
- if (it != surface_refs_.end())
- surface_ref = (*it).second;
- else
- surface_ref.reset(new SurfaceRef(compositing_surface.handle));
-#endif // defined(TOOLKIT_GTK)
-
if (!compositing_surface.is_null() &&
Send(new GpuMsg_CreateViewCommandBuffer(
compositing_surface, surface_id, client_id, init_params))) {
create_command_buffer_requests_.push(callback);
-#if defined(TOOLKIT_GTK)
- surface_refs_.insert(std::make_pair(surface_id, surface_ref));
-#endif
+ surface_refs_.insert(std::make_pair(surface_id,
+ GpuSurfaceTracker::GetInstance()->GetSurfaceRefForSurface(surface_id)));
} else {
callback.Run(MSG_ROUTING_NONE);
}
@@ -828,13 +777,21 @@
const IPC::ChannelHandle& channel_handle) {
TRACE_EVENT0("gpu", "GpuProcessHost::OnChannelEstablished");
+ if (channel_requests_.empty()) {
+ // This happens when GPU process is compromised.
+ RouteOnUIThread(GpuHostMsg_OnLogMessage(
+ logging::LOG_WARNING,
+ "WARNING",
+ "Received a ChannelEstablished message but no requests in queue."));
+ return;
+ }
EstablishChannelCallback callback = channel_requests_.front();
channel_requests_.pop();
// Currently if any of the GPU features are blacklisted, we don't establish a
// GPU channel.
if (!channel_handle.name.empty() &&
- !GpuDataManagerImpl::GetInstance()->GpuAccessAllowed()) {
+ !GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL)) {
Send(new GpuMsg_CloseChannel(channel_handle));
callback.Run(IPC::ChannelHandle(), GPUInfo());
RouteOnUIThread(GpuHostMsg_OnLogMessage(
@@ -862,12 +819,10 @@
void GpuProcessHost::OnDestroyCommandBuffer(int32 surface_id) {
TRACE_EVENT0("gpu", "GpuProcessHost::OnDestroyCommandBuffer");
-
-#if defined(TOOLKIT_GTK)
SurfaceRefMap::iterator it = surface_refs_.find(surface_id);
- if (it != surface_refs_.end())
+ if (it != surface_refs_.end()) {
surface_refs_.erase(it);
-#endif // defined(TOOLKIT_GTK)
+ }
}
void GpuProcessHost::OnImageCreated(const gfx::Size size) {
@@ -1017,13 +972,6 @@
return;
}
- scoped_refptr<media::VideoFrame> target_frame;
- RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback copy_callback;
- FrameSubscriberMap::iterator it = frame_subscribers_.find(params.surface_id);
- bool should_copy = false;
- if (it != frame_subscribers_.end() && it->second)
- should_copy = it->second->ShouldCaptureFrame(&target_frame, ©_callback);
-
scoped_completion_runner.Release();
presenter->AsyncPresentAndAcknowledge(
params.size,
@@ -1034,14 +982,19 @@
params.surface_id,
params.surface_handle));
- // It is a potential improvement to do the copy in present, but we use a
- // simpler approach now.
- if (should_copy) {
- // The timestamp here is not the acutal presentation time but it is close
- // enough.
- presenter->AsyncCopyToVideoFrame(
- gfx::Rect(params.size), target_frame,
- base::Bind(copy_callback, base::Time::Now()));
+ FrameSubscriberMap::iterator it = frame_subscribers_.find(params.surface_id);
+ if (it != frame_subscribers_.end() && it->second) {
+ const base::Time present_time = base::Time::Now();
+ scoped_refptr<media::VideoFrame> target_frame;
+ RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback copy_callback;
+ if (it->second->ShouldCaptureFrame(present_time,
+ &target_frame, ©_callback)) {
+ // It is a potential improvement to do the copy in present, but we use a
+ // simpler approach for now.
+ presenter->AsyncCopyToVideoFrame(
+ gfx::Rect(params.size), target_frame,
+ base::Bind(copy_callback, present_time));
+ }
}
}
@@ -1107,10 +1060,6 @@
process_->GetTerminationStatus(NULL));
}
-bool GpuProcessHost::software_rendering() {
- return software_rendering_;
-}
-
GpuProcessHost::GpuProcessKind GpuProcessHost::kind() {
return kind_;
}
@@ -1136,7 +1085,7 @@
bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) {
if (!(gpu_enabled_ &&
- GpuDataManagerImpl::GetInstance()->ShouldUseSoftwareRendering()) &&
+ GpuDataManagerImpl::GetInstance()->ShouldUseSwiftShader()) &&
!hardware_gpu_enabled_) {
SendOutstandingReplies();
return false;
@@ -1208,11 +1157,12 @@
GpuDataManagerImpl::GetInstance()->AppendGpuCommandLine(cmd_line);
if (cmd_line->HasSwitch(switches::kUseGL)) {
- software_rendering_ =
+ swiftshader_rendering_ =
(cmd_line->GetSwitchValueASCII(switches::kUseGL) == "swiftshader");
}
- UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessSoftwareRendering", software_rendering_);
+ UMA_HISTOGRAM_BOOLEAN("GPU.GPU.GPUProcessSoftwareRendering",
+ swiftshader_rendering_);
// If specified, prepend a launcher program to the command line.
if (!gpu_launcher.empty())
@@ -1241,6 +1191,13 @@
channel_requests_.pop();
callback.Run(IPC::ChannelHandle(), GPUInfo());
}
+
+ while (!create_command_buffer_requests_.empty()) {
+ CreateCommandBufferCallback callback =
+ create_command_buffer_requests_.front();
+ create_command_buffer_requests_.pop();
+ callback.Run(MSG_ROUTING_NONE);
+ }
}
void GpuProcessHost::BlockLiveOffscreenContexts() {
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h
index 405918f..6474d56 100644
--- a/content/browser/gpu/gpu_process_host.h
+++ b/content/browser/gpu/gpu_process_host.h
@@ -12,10 +12,10 @@
#include "base/callback.h"
#include "base/hash_tables.h"
-#include "base/memory/linked_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/time.h"
+#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/common/content_export.h"
#include "content/common/gpu/gpu_memory_uma_stats.h"
#include "content/common/gpu/gpu_process_launch_causes.h"
@@ -68,7 +68,8 @@
// is not safe to store the pointer once control has returned to the message
// loop as it can be destroyed. Instead store the associated GPU host ID.
// This could return NULL if GPU access is not allowed (blacklisted).
- static GpuProcessHost* Get(GpuProcessKind kind, CauseForGpuLaunch cause);
+ CONTENT_EXPORT static GpuProcessHost* Get(GpuProcessKind kind,
+ CauseForGpuLaunch cause);
// Retrieves a list of process handles for all gpu processes.
static void GetProcessHandles(
@@ -118,9 +119,6 @@
// Tells the GPU process to delete image.
void DeleteImage(int client_id, int image_id, int sync_point);
- // Whether this GPU process is set up to use software rendering.
- bool software_rendering();
-
// What kind of GPU process, e.g. sandboxed or unsandboxed.
GpuProcessKind kind();
@@ -202,18 +200,6 @@
// The pending create image requests we need to reply to.
std::queue<CreateImageCallback> create_image_requests_;
-#if defined(TOOLKIT_GTK)
- // Encapsulates surfaces that we lock when creating view command buffers.
- // We release this lock once the command buffer (or associated GPU process)
- // is destroyed. This prevents the browser from destroying the surface
- // while the GPU process is drawing to it.
-
- // Multimap is used to simulate reference counting, see comment in
- // GpuProcessHostUIShim::CreateViewCommandBuffer.
- class SurfaceRef;
- typedef std::multimap<int, linked_ptr<SurfaceRef> > SurfaceRefMap;
- SurfaceRefMap surface_refs_;
-#endif
// Qeueud messages to send when the process launches.
std::queue<IPC::Message*> queued_messages_;
@@ -225,7 +211,7 @@
// of a separate GPU process.
bool in_process_;
- bool software_rendering_;
+ bool swiftshader_rendering_;
GpuProcessKind kind_;
scoped_ptr<GpuMainThread> in_process_gpu_thread_;
@@ -272,6 +258,13 @@
std::string shader_prefix_key_;
+ // Keep an extra reference to the SurfaceRef stored in the GpuSurfaceTracker
+ // in this map so that we don't destroy it whilst the GPU process is
+ // drawing to it.
+ typedef std::multimap<int, scoped_refptr<GpuSurfaceTracker::SurfaceRef> >
+ SurfaceRefMap;
+ SurfaceRefMap surface_refs_;
+
DISALLOW_COPY_AND_ASSIGN(GpuProcessHost);
};
diff --git a/content/browser/gpu/gpu_process_host_ui_shim.cc b/content/browser/gpu/gpu_process_host_ui_shim.cc
index 4237e49..a243115 100644
--- a/content/browser/gpu/gpu_process_host_ui_shim.cc
+++ b/content/browser/gpu/gpu_process_host_ui_shim.cc
@@ -209,6 +209,7 @@
OnVideoMemoryUsageStatsReceived);
IPC_MESSAGE_HANDLER(GpuHostMsg_UpdateVSyncParameters,
OnUpdateVSyncParameters)
+ IPC_MESSAGE_HANDLER(GpuHostMsg_FrameDrawn, OnFrameDrawn)
#if defined(TOOLKIT_GTK) || defined(OS_WIN)
IPC_MESSAGE_HANDLER(GpuHostMsg_ResizeView, OnResizeView)
@@ -341,6 +342,9 @@
view->AcceleratedSurfaceBuffersSwapped(params, host_id_);
}
+void GpuProcessHostUIShim::OnFrameDrawn(const cc::LatencyInfo& latency_info) {
+}
+
void GpuProcessHostUIShim::OnAcceleratedSurfacePostSubBuffer(
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params) {
TRACE_EVENT0("renderer",
diff --git a/content/browser/gpu/gpu_process_host_ui_shim.h b/content/browser/gpu/gpu_process_host_ui_shim.h
index 27f1e9a..243cfd1 100644
--- a/content/browser/gpu/gpu_process_host_ui_shim.h
+++ b/content/browser/gpu/gpu_process_host_ui_shim.h
@@ -28,6 +28,10 @@
struct GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params;
struct GpuHostMsg_AcceleratedSurfaceRelease_Params;
+namespace cc {
+struct LatencyInfo;
+}
+
namespace gfx {
class Size;
}
@@ -103,6 +107,7 @@
void OnUpdateVSyncParameters(int surface_id,
base::TimeTicks timebase,
base::TimeDelta interval);
+ void OnFrameDrawn(const cc::LatencyInfo& latency_info);
// The serial number of the GpuProcessHost / GpuProcessHostUIShim pair.
int host_id_;
diff --git a/content/browser/gpu/gpu_surface_tracker.cc b/content/browser/gpu/gpu_surface_tracker.cc
index 2c4873a..ce1e956 100644
--- a/content/browser/gpu/gpu_surface_tracker.cc
+++ b/content/browser/gpu/gpu_surface_tracker.cc
@@ -10,8 +10,57 @@
#include "base/logging.h"
+#if defined(TOOLKIT_GTK)
+#include "base/bind.h"
+#include "content/public/browser/browser_thread.h"
+#include "ui/gfx/gtk_native_view_id_manager.h"
+#endif // defined(TOOLKIT_GTK)
+
namespace content {
+namespace {
+#if defined(TOOLKIT_GTK)
+
+void ReleasePermanentXIDDispatcher(
+ const gfx::PluginWindowHandle& surface) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
+ manager->ReleasePermanentXID(surface);
+}
+
+// Implementation of SurfaceRef that allows GTK to ref and unref the
+// surface with the GtkNativeViewManager.
+class SurfaceRefPluginWindow : public GpuSurfaceTracker::SurfaceRef {
+ public:
+ SurfaceRefPluginWindow(const gfx::PluginWindowHandle& surface_ref);
+ private:
+ virtual ~SurfaceRefPluginWindow();
+ gfx::PluginWindowHandle surface_;
+};
+
+SurfaceRefPluginWindow::SurfaceRefPluginWindow(
+ const gfx::PluginWindowHandle& surface)
+ : surface_(surface) {
+ if (surface_ != gfx::kNullPluginWindow) {
+ GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
+ if (!manager->AddRefPermanentXID(surface_)) {
+ LOG(ERROR) << "Surface " << surface << " cannot be referenced.";
+ }
+ }
+}
+
+SurfaceRefPluginWindow::~SurfaceRefPluginWindow() {
+ if (surface_ != gfx::kNullPluginWindow) {
+ BrowserThread::PostTask(BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&ReleasePermanentXIDDispatcher,
+ surface_));
+ }
+}
+#endif // defined(TOOLKIT_GTK)
+} // anonymous
+
GpuSurfaceTracker::GpuSurfaceTracker()
: next_surface_id_(1) {
GpuSurfaceLookup::InitInstance(this);
@@ -28,13 +77,10 @@
int GpuSurfaceTracker::AddSurfaceForRenderer(int renderer_id,
int render_widget_id) {
base::AutoLock lock(lock_);
- SurfaceInfo info = {
- renderer_id,
- render_widget_id,
- gfx::kNullAcceleratedWidget
- };
int surface_id = next_surface_id_++;
- surface_map_[surface_id] = info;
+ surface_map_[surface_id] =
+ SurfaceInfo(renderer_id, render_widget_id, gfx::kNullAcceleratedWidget,
+ gfx::GLSurfaceHandle(), NULL);
return surface_id;
}
@@ -55,9 +101,9 @@
int GpuSurfaceTracker::AddSurfaceForNativeWidget(
gfx::AcceleratedWidget widget) {
base::AutoLock lock(lock_);
- SurfaceInfo info = { 0, 0, widget };
int surface_id = next_surface_id_++;
- surface_map_[surface_id] = info;
+ surface_map_[surface_id] =
+ SurfaceInfo(0, 0, widget, gfx::GLSurfaceHandle(), NULL);
return surface_id;
}
@@ -86,6 +132,9 @@
DCHECK(surface_map_.find(surface_id) != surface_map_.end());
SurfaceInfo& info = surface_map_[surface_id];
info.handle = handle;
+#if defined(TOOLKIT_GTK)
+ info.surface_ref = new SurfaceRefPluginWindow(handle.handle);
+#endif // defined(TOOLKIT_GTK)
}
gfx::GLSurfaceHandle GpuSurfaceTracker::GetSurfaceHandle(int surface_id) {
@@ -111,11 +160,14 @@
}
void GpuSurfaceTracker::SetNativeWidget(
- int surface_id, gfx::AcceleratedWidget widget) {
+ int surface_id, gfx::AcceleratedWidget widget,
+ SurfaceRef* surface_ref) {
base::AutoLock lock(lock_);
SurfaceMap::iterator it = surface_map_.find(surface_id);
DCHECK(it != surface_map_.end());
- it->second.native_widget = widget;
+ SurfaceInfo& info = it->second;
+ info.native_widget = widget;
+ info.surface_ref = surface_ref;
}
std::size_t GpuSurfaceTracker::GetSurfaceCount() {
@@ -123,4 +175,24 @@
return surface_map_.size();
}
+GpuSurfaceTracker::SurfaceInfo::SurfaceInfo()
+ : renderer_id(0),
+ render_widget_id(0),
+ native_widget(gfx::kNullAcceleratedWidget) { }
+
+GpuSurfaceTracker::SurfaceInfo::SurfaceInfo(
+ int renderer_id,
+ int render_widget_id,
+ const gfx::AcceleratedWidget& native_widget,
+ const gfx::GLSurfaceHandle& handle,
+ const scoped_refptr<SurfaceRef>& surface_ref)
+ : renderer_id(renderer_id),
+ render_widget_id(render_widget_id),
+ native_widget(native_widget),
+ handle(handle),
+ surface_ref(surface_ref) { }
+
+GpuSurfaceTracker::SurfaceInfo::~SurfaceInfo() { }
+
+
} // namespace content
diff --git a/content/browser/gpu/gpu_surface_tracker.h b/content/browser/gpu/gpu_surface_tracker.h
index ddf0a66..de9d666 100644
--- a/content/browser/gpu/gpu_surface_tracker.h
+++ b/content/browser/gpu/gpu_surface_tracker.h
@@ -8,6 +8,7 @@
#include <map>
#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
#include "content/common/gpu/gpu_surface_lookup.h"
@@ -27,6 +28,27 @@
// it is unamibiguously identified.
class GpuSurfaceTracker : public GpuSurfaceLookup {
public:
+ // Base class for reference counting surfaces. We store a
+ // reference to an instance of this class in the surface_map_
+ // and GpuProcessHost (if the GPU process is drawing to
+ // the surface with a Command Buffer). The reference count ensures that
+ // we don't destroy the object until it's released from both places.
+ //
+ // This is especially important on Android and GTK where the surface must
+ // not be destroyed when the WebContents is closed if the GPU is still
+ // drawing to it. Those platforms extend this class with the functionality
+ // they need to implement on tear down (see SurfaceRefPluginWindow for GTK and
+ // SurfaceRefAndroid for Android).
+ class SurfaceRef : public base::RefCountedThreadSafe<SurfaceRef> {
+ protected:
+ SurfaceRef() { }
+ virtual ~SurfaceRef() { }
+
+ private:
+ friend class base::RefCountedThreadSafe<SurfaceRef>;
+ DISALLOW_COPY_AND_ASSIGN(SurfaceRef);
+ };
+
// GpuSurfaceLookup implementation:
// Returns the native widget associated with a given surface_id.
virtual gfx::AcceleratedWidget AcquireNativeWidget(int surface_id) OVERRIDE;
@@ -62,7 +84,10 @@
void SetSurfaceHandle(int surface_id, const gfx::GLSurfaceHandle& handle);
// Sets the native widget associated with the surface_id.
- void SetNativeWidget(int surface_id, gfx::AcceleratedWidget widget);
+ void SetNativeWidget(
+ int surface_id,
+ gfx::AcceleratedWidget widget,
+ SurfaceRef* surface_ref);
// Gets the native handle for the given surface.
// Note: This is an O(log N) lookup.
@@ -75,12 +100,24 @@
// named that way for the implementation of Singleton.
static GpuSurfaceTracker* GetInstance();
+ scoped_refptr<SurfaceRef> GetSurfaceRefForSurface(int surface_id) {
+ return surface_map_[surface_id].surface_ref;
+ }
+
private:
struct SurfaceInfo {
+ SurfaceInfo();
+ SurfaceInfo(int renderer_id,
+ int render_widget_id,
+ const gfx::AcceleratedWidget& native_widget,
+ const gfx::GLSurfaceHandle& handle,
+ const scoped_refptr<SurfaceRef>& surface_ref);
+ ~SurfaceInfo();
int renderer_id;
int render_widget_id;
gfx::AcceleratedWidget native_widget;
gfx::GLSurfaceHandle handle;
+ scoped_refptr<SurfaceRef> surface_ref;
};
typedef std::map<int, SurfaceInfo> SurfaceMap;
diff --git a/content/browser/gpu/gpu_switching_list.cc b/content/browser/gpu/gpu_switching_list.cc
index da795c1..0097015 100644
--- a/content/browser/gpu/gpu_switching_list.cc
+++ b/content/browser/gpu/gpu_switching_list.cc
@@ -18,10 +18,10 @@
// static
GpuSwitchingList* GpuSwitchingList::Create() {
GpuSwitchingList* list = new GpuSwitchingList();
- list->AddFeature("force_integrated",
- GPU_SWITCHING_OPTION_FORCE_INTEGRATED);
- list->AddFeature("force_discrete",
- GPU_SWITCHING_OPTION_FORCE_DISCRETE);
+ list->AddSupportedFeature("force_integrated",
+ GPU_SWITCHING_OPTION_FORCE_INTEGRATED);
+ list->AddSupportedFeature("force_discrete",
+ GPU_SWITCHING_OPTION_FORCE_DISCRETE);
return list;
}
diff --git a/content/browser/gpu/gpu_switching_list_unittest.cc b/content/browser/gpu/gpu_switching_list_unittest.cc
index da1171f..b6ceb4b 100644
--- a/content/browser/gpu/gpu_switching_list_unittest.cc
+++ b/content/browser/gpu/gpu_switching_list_unittest.cc
@@ -65,7 +65,7 @@
int64 data_file_size64 = 0;
ASSERT_TRUE(file_util::GetFileSize(data_file, &data_file_size64));
int data_file_size = static_cast<int>(data_file_size64);
- scoped_array<char> data(new char[data_file_size]);
+ scoped_ptr<char[]> data(new char[data_file_size]);
ASSERT_EQ(data_file_size,
file_util::ReadFile(data_file, data.get(), data_file_size));
std::string json_string(data.get(), data_file_size);
@@ -104,10 +104,10 @@
);
scoped_ptr<GpuSwitchingList> switching_list(GpuSwitchingList::Create());
EXPECT_TRUE(switching_list->LoadList(json, GpuControlList::kAllOs));
- int switching = switching_list->MakeDecision(
+ std::set<int> switching = switching_list->MakeDecision(
GpuControlList::kOsMacosx, kOsVersion, gpu_info());
- EXPECT_EQ(GPU_SWITCHING_OPTION_FORCE_DISCRETE,
- static_cast<GpuSwitchingOption>(switching));
+ EXPECT_EQ(1u, switching.size());
+ EXPECT_EQ(1u, switching.count(GPU_SWITCHING_OPTION_FORCE_DISCRETE));
std::vector<uint32> entries;
switching_list->GetDecisionEntries(&entries, false);
ASSERT_EQ(1u, entries.size());
@@ -117,8 +117,8 @@
EXPECT_TRUE(switching_list->LoadList(json, GpuControlList::kAllOs));
switching = switching_list->MakeDecision(
GpuControlList::kOsWin, kOsVersion, gpu_info());
- EXPECT_EQ(GPU_SWITCHING_OPTION_FORCE_INTEGRATED,
- static_cast<GpuSwitchingOption>(switching));
+ EXPECT_EQ(1u, switching.size());
+ EXPECT_EQ(1u, switching.count(GPU_SWITCHING_OPTION_FORCE_INTEGRATED));
switching_list->GetDecisionEntries(&entries, false);
ASSERT_EQ(1u, entries.size());
EXPECT_EQ(2u, entries[0]);
diff --git a/content/browser/gpu/gpu_util.cc b/content/browser/gpu/gpu_util.cc
index 7d7d932..5aa5433 100644
--- a/content/browser/gpu/gpu_util.cc
+++ b/content/browser/gpu/gpu_util.cc
@@ -13,27 +13,12 @@
#include "base/version.h"
#include "content/browser/gpu/gpu_blacklist.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/gpu_feature_type.h"
#include "ui/gl/gl_switches.h"
namespace content {
namespace {
-const char kGpuFeatureNameAccelerated2dCanvas[] = "accelerated_2d_canvas";
-const char kGpuFeatureNameAcceleratedCompositing[] = "accelerated_compositing";
-const char kGpuFeatureNameWebgl[] = "webgl";
-const char kGpuFeatureNameMultisampling[] = "multisampling";
-const char kGpuFeatureNameFlash3d[] = "flash_3d";
-const char kGpuFeatureNameFlashStage3d[] = "flash_stage3d";
-const char kGpuFeatureNameFlashStage3dBaseline[] = "flash_stage3d_baseline";
-const char kGpuFeatureNameTextureSharing[] = "texture_sharing";
-const char kGpuFeatureNameAcceleratedVideoDecode[] = "accelerated_video_decode";
-const char kGpuFeatureName3dCss[] = "3d_css";
-const char kGpuFeatureNameAcceleratedVideo[] = "accelerated_video";
-const char kGpuFeatureNamePanelFitting[] = "panel_fitting";
-const char kGpuFeatureNameForceCompositingMode[] = "force_compositing_mode";
-const char kGpuFeatureNameAll[] = "all";
-const char kGpuFeatureNameUnknown[] = "unknown";
-
enum GpuFeatureStatus {
kGpuFeatureEnabled = 0,
kGpuFeatureBlacklisted = 1,
@@ -85,76 +70,7 @@
}
#endif // OS_WIN
-} // namespace
-
-GpuFeatureType StringToGpuFeatureType(const std::string& feature_string) {
- if (feature_string == kGpuFeatureNameAccelerated2dCanvas)
- return GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS;
- if (feature_string == kGpuFeatureNameAcceleratedCompositing)
- return GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING;
- if (feature_string == kGpuFeatureNameWebgl)
- return GPU_FEATURE_TYPE_WEBGL;
- if (feature_string == kGpuFeatureNameMultisampling)
- return GPU_FEATURE_TYPE_MULTISAMPLING;
- if (feature_string == kGpuFeatureNameFlash3d)
- return GPU_FEATURE_TYPE_FLASH3D;
- if (feature_string == kGpuFeatureNameFlashStage3d)
- return GPU_FEATURE_TYPE_FLASH_STAGE3D;
- if (feature_string == kGpuFeatureNameFlashStage3dBaseline)
- return GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE;
- if (feature_string == kGpuFeatureNameTextureSharing)
- return GPU_FEATURE_TYPE_TEXTURE_SHARING;
- if (feature_string == kGpuFeatureNameAcceleratedVideoDecode)
- return GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE;
- if (feature_string == kGpuFeatureName3dCss)
- return GPU_FEATURE_TYPE_3D_CSS;
- if (feature_string == kGpuFeatureNameAcceleratedVideo)
- return GPU_FEATURE_TYPE_ACCELERATED_VIDEO;
- if (feature_string == kGpuFeatureNamePanelFitting)
- return GPU_FEATURE_TYPE_PANEL_FITTING;
- if (feature_string == kGpuFeatureNameForceCompositingMode)
- return GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE;
- if (feature_string == kGpuFeatureNameAll)
- return GPU_FEATURE_TYPE_ALL;
- return GPU_FEATURE_TYPE_UNKNOWN;
-}
-
-std::string GpuFeatureTypeToString(GpuFeatureType type) {
- std::vector<std::string> matches;
- if (type == GPU_FEATURE_TYPE_ALL) {
- matches.push_back(kGpuFeatureNameAll);
- } else {
- if (type & GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)
- matches.push_back(kGpuFeatureNameAccelerated2dCanvas);
- if (type & GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)
- matches.push_back(kGpuFeatureNameAcceleratedCompositing);
- if (type & GPU_FEATURE_TYPE_WEBGL)
- matches.push_back(kGpuFeatureNameWebgl);
- if (type & GPU_FEATURE_TYPE_MULTISAMPLING)
- matches.push_back(kGpuFeatureNameMultisampling);
- if (type & GPU_FEATURE_TYPE_FLASH3D)
- matches.push_back(kGpuFeatureNameFlash3d);
- if (type & GPU_FEATURE_TYPE_FLASH_STAGE3D)
- matches.push_back(kGpuFeatureNameFlashStage3d);
- if (type & GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE)
- matches.push_back(kGpuFeatureNameFlashStage3dBaseline);
- if (type & GPU_FEATURE_TYPE_TEXTURE_SHARING)
- matches.push_back(kGpuFeatureNameTextureSharing);
- if (type & GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE)
- matches.push_back(kGpuFeatureNameAcceleratedVideoDecode);
- if (type & GPU_FEATURE_TYPE_3D_CSS)
- matches.push_back(kGpuFeatureName3dCss);
- if (type & GPU_FEATURE_TYPE_ACCELERATED_VIDEO)
- matches.push_back(kGpuFeatureNameAcceleratedVideo);
- if (type & GPU_FEATURE_TYPE_PANEL_FITTING)
- matches.push_back(kGpuFeatureNamePanelFitting);
- if (type & GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE)
- matches.push_back(kGpuFeatureNameForceCompositingMode);
- if (!matches.size())
- matches.push_back(kGpuFeatureNameUnknown);
- }
- return JoinString(matches, ',');
-}
+} // namespace anonymous
GpuSwitchingOption StringToGpuSwitchingOption(
const std::string& switching_string) {
@@ -181,7 +97,7 @@
}
void UpdateStats(const GpuBlacklist* blacklist,
- uint32 blacklisted_features) {
+ const std::set<int>& blacklisted_features) {
uint32 max_entry_id = blacklist->max_entry_id();
if (max_entry_id == 0) {
// GPU Blacklist was not loaded. No need to go further.
@@ -190,7 +106,7 @@
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
bool disabled = false;
- if (blacklisted_features == 0) {
+ if (blacklisted_features.size() == 0) {
UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry",
0, max_entry_id + 1);
} else {
@@ -245,7 +161,7 @@
// We can't use UMA_HISTOGRAM_ENUMERATION here because the same name is
// expected if the macro is used within a loop.
GpuFeatureStatus value = kGpuFeatureEnabled;
- if (blacklisted_features & kGpuFeatures[i])
+ if (blacklisted_features.count(kGpuFeatures[i]))
value = kGpuFeatureBlacklisted;
else if (kGpuFeatureUserFlags[i])
value = kGpuFeatureDisabled;
@@ -265,4 +181,11 @@
}
}
+void MergeFeatureSets(std::set<int>* dst, const std::set<int>& src) {
+ DCHECK(dst);
+ if (src.empty())
+ return;
+ dst->insert(src.begin(), src.end());
+}
+
} // namespace content
diff --git a/content/browser/gpu/gpu_util.h b/content/browser/gpu/gpu_util.h
index cac15d8..0a277fc 100644
--- a/content/browser/gpu/gpu_util.h
+++ b/content/browser/gpu/gpu_util.h
@@ -5,27 +5,17 @@
#ifndef CONTENT_BROWSER_GPU_GPU_UTIL_H_
#define CONTENT_BROWSER_GPU_GPU_UTIL_H_
+#include <set>
#include <string>
#include "base/basictypes.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
-#include "content/public/common/gpu_feature_type.h"
#include "content/public/common/gpu_switching_option.h"
namespace content {
class GpuBlacklist;
-// Maps string to GpuFeatureType; returns GPU_FEATURE_TYPE_UNKNOWN if an
-// unknown name is input (case-sensitive).
-CONTENT_EXPORT GpuFeatureType StringToGpuFeatureType(
- const std::string& feature_string);
-
-// Gets a string version of a feature type for use in about:gpu. Will yield
-// strings from StringToGpuFeatureType, e.g.
-// GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS becomes "accelerated_2d_canvas"
-CONTENT_EXPORT std::string GpuFeatureTypeToString(GpuFeatureType feature);
-
// Maps string to GpuSwitchingOption; returns GPU_SWITCHING_UNKNOWN if an
// unknown name is input (case-sensitive).
CONTENT_EXPORT GpuSwitchingOption StringToGpuSwitchingOption(
@@ -37,7 +27,11 @@
// Send UMA histograms about the enabled features.
CONTENT_EXPORT void UpdateStats(
- const GpuBlacklist* blacklist, uint32 blacklisted_features);
+ const GpuBlacklist* blacklist, const std::set<int>& blacklisted_features);
+
+// Merge features in src into dst.
+CONTENT_EXPORT void MergeFeatureSets(
+ std::set<int>* dst, const std::set<int>& src);
} // namespace content
diff --git a/content/browser/gpu/gpu_util_unittest.cc b/content/browser/gpu/gpu_util_unittest.cc
index bb1ef2b..5bc7d77 100644
--- a/content/browser/gpu/gpu_util_unittest.cc
+++ b/content/browser/gpu/gpu_util_unittest.cc
@@ -8,87 +8,7 @@
namespace content {
-TEST(GpuUtilsTest, GpuFeatureTypFromString) {
- // Test StringToGpuFeatureType.
- EXPECT_EQ(StringToGpuFeatureType("accelerated_2d_canvas"),
- GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS);
- EXPECT_EQ(StringToGpuFeatureType("accelerated_compositing"),
- GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING);
- EXPECT_EQ(StringToGpuFeatureType("webgl"), GPU_FEATURE_TYPE_WEBGL);
- EXPECT_EQ(StringToGpuFeatureType("multisampling"),
- GPU_FEATURE_TYPE_MULTISAMPLING);
- EXPECT_EQ(StringToGpuFeatureType("flash_3d"), GPU_FEATURE_TYPE_FLASH3D);
- EXPECT_EQ(StringToGpuFeatureType("flash_stage3d"),
- GPU_FEATURE_TYPE_FLASH_STAGE3D);
- EXPECT_EQ(StringToGpuFeatureType("texture_sharing"),
- GPU_FEATURE_TYPE_TEXTURE_SHARING);
- EXPECT_EQ(StringToGpuFeatureType("accelerated_video_decode"),
- GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE);
- EXPECT_EQ(StringToGpuFeatureType("3d_css"), GPU_FEATURE_TYPE_3D_CSS);
- EXPECT_EQ(StringToGpuFeatureType("accelerated_video"),
- GPU_FEATURE_TYPE_ACCELERATED_VIDEO);
- EXPECT_EQ(StringToGpuFeatureType("panel_fitting"),
- GPU_FEATURE_TYPE_PANEL_FITTING);
- EXPECT_EQ(StringToGpuFeatureType("force_compositing_mode"),
- GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE);
- EXPECT_EQ(StringToGpuFeatureType("all"), GPU_FEATURE_TYPE_ALL);
- EXPECT_EQ(StringToGpuFeatureType("xxx"), GPU_FEATURE_TYPE_UNKNOWN);
-}
-
-TEST(GpuUtilsTest, GpuFeatureTypeToString) {
- // Test GpuFeatureTypeToString for single-bit enums using the all enum
- EXPECT_STREQ(
- GpuFeatureTypeToString(GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING).c_str(),
- "accelerated_compositing");
- EXPECT_STREQ(
- GpuFeatureTypeToString(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS).c_str(),
- "accelerated_2d_canvas");
- EXPECT_STREQ(
- GpuFeatureTypeToString(GPU_FEATURE_TYPE_WEBGL).c_str(), "webgl");
- EXPECT_STREQ(
- GpuFeatureTypeToString(GPU_FEATURE_TYPE_MULTISAMPLING).c_str(),
- "multisampling");
- EXPECT_STREQ(
- GpuFeatureTypeToString(GPU_FEATURE_TYPE_FLASH3D).c_str(), "flash_3d");
- EXPECT_STREQ(
- GpuFeatureTypeToString(GPU_FEATURE_TYPE_FLASH_STAGE3D).c_str(),
- "flash_stage3d");
- EXPECT_STREQ(
- GpuFeatureTypeToString(GPU_FEATURE_TYPE_TEXTURE_SHARING).c_str(),
- "texture_sharing");
- EXPECT_STREQ(
- GpuFeatureTypeToString(GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE).c_str(),
- "accelerated_video_decode");
- EXPECT_STREQ(
- GpuFeatureTypeToString(GPU_FEATURE_TYPE_3D_CSS).c_str(), "3d_css");
- EXPECT_STREQ(
- GpuFeatureTypeToString(GPU_FEATURE_TYPE_ACCELERATED_VIDEO).c_str(),
- "accelerated_video");
- EXPECT_STREQ(
- GpuFeatureTypeToString(GPU_FEATURE_TYPE_PANEL_FITTING).c_str(),
- "panel_fitting");
- EXPECT_STREQ(
- GpuFeatureTypeToString(GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE).c_str(),
- "force_compositing_mode");
- EXPECT_STREQ(
- GpuFeatureTypeToString(GPU_FEATURE_TYPE_ALL).c_str(), "all");
- EXPECT_STREQ(GpuFeatureTypeToString(
- GPU_FEATURE_TYPE_UNKNOWN).c_str(), "unknown");
- EXPECT_STREQ(
- GpuFeatureTypeToString(
- static_cast<GpuFeatureType>(
- GPU_FEATURE_TYPE_WEBGL |
- GPU_FEATURE_TYPE_MULTISAMPLING)).c_str(),
- "webgl,multisampling");
- EXPECT_STREQ(
- GpuFeatureTypeToString(
- static_cast<GpuFeatureType>(
- GPU_FEATURE_TYPE_WEBGL |
- GPU_FEATURE_TYPE_ALL)).c_str(),
- "all");
-}
-
-TEST(GpuUtilsTest, GpuSwitchingOptionFromString) {
+TEST(GpuUtilTest, GpuSwitchingOptionFromString) {
// Test StringToGpuSwitchingOption.
EXPECT_EQ(StringToGpuSwitchingOption(
switches::kGpuSwitchingOptionNameAutomatic),
@@ -102,7 +22,7 @@
EXPECT_EQ(StringToGpuSwitchingOption("xxx"), GPU_SWITCHING_OPTION_UNKNOWN);
}
-TEST(GpuUtilsTest, GpuSwitchingOptionToString) {
+TEST(GpuUtilTest, GpuSwitchingOptionToString) {
// Test GpuSwitchingOptionToString.
EXPECT_STREQ(
GpuSwitchingOptionToString(GPU_SWITCHING_OPTION_AUTOMATIC).c_str(),
@@ -115,4 +35,44 @@
switches::kGpuSwitchingOptionNameForceIntegrated);
}
+TEST(GpuUtilTest, MergeFeatureSets) {
+ {
+ // Merge two empty sets.
+ std::set<int> src;
+ std::set<int> dst;
+ EXPECT_TRUE(dst.empty());
+ MergeFeatureSets(&dst, src);
+ EXPECT_TRUE(dst.empty());
+ }
+ {
+ // Merge an empty set into a set with elements.
+ std::set<int> src;
+ std::set<int> dst;
+ dst.insert(1);
+ EXPECT_EQ(1u, dst.size());
+ MergeFeatureSets(&dst, src);
+ EXPECT_EQ(1u, dst.size());
+ }
+ {
+ // Merge two sets where the source elements are already in the target set.
+ std::set<int> src;
+ std::set<int> dst;
+ src.insert(1);
+ dst.insert(1);
+ EXPECT_EQ(1u, dst.size());
+ MergeFeatureSets(&dst, src);
+ EXPECT_EQ(1u, dst.size());
+ }
+ {
+ // Merge two sets with different elements.
+ std::set<int> src;
+ std::set<int> dst;
+ src.insert(1);
+ dst.insert(2);
+ EXPECT_EQ(1u, dst.size());
+ MergeFeatureSets(&dst, src);
+ EXPECT_EQ(2u, dst.size());
+ }
+}
+
} // namespace content
diff --git a/content/browser/gpu/shader_disk_cache.cc b/content/browser/gpu/shader_disk_cache.cc
index ca30937..621d7d53 100644
--- a/content/browser/gpu/shader_disk_cache.cc
+++ b/content/browser/gpu/shader_disk_cache.cc
@@ -101,6 +101,38 @@
DISALLOW_COPY_AND_ASSIGN(ShaderDiskReadHelper);
};
+class ShaderClearHelper : public base::RefCounted<ShaderClearHelper> {
+ public:
+ ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache,
+ const base::FilePath& path,
+ const base::Time& delete_begin,
+ const base::Time& delete_end,
+ const base::Closure& callback);
+ void Clear();
+
+ private:
+ friend class base::RefCounted<ShaderClearHelper>;
+
+ enum OpType {
+ TERMINATE,
+ VERIFY_CACHE_SETUP,
+ DELETE_CACHE
+ };
+
+ ~ShaderClearHelper();
+
+ void DoClearShaderCache(int rv);
+
+ scoped_refptr<ShaderDiskCache> cache_;
+ OpType op_type_;
+ base::FilePath path_;
+ base::Time delete_begin_;
+ base::Time delete_end_;
+ base::Closure callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(ShaderClearHelper);
+};
+
ShaderDiskCacheEntry::ShaderDiskCacheEntry(base::WeakPtr<ShaderDiskCache> cache,
const std::string& key,
const std::string& shader)
@@ -309,6 +341,62 @@
base::Bind(&EntryCloser, entry_));
}
+ShaderClearHelper::ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache,
+ const base::FilePath& path,
+ const base::Time& delete_begin,
+ const base::Time& delete_end,
+ const base::Closure& callback)
+ : cache_(cache),
+ op_type_(VERIFY_CACHE_SETUP),
+ path_(path),
+ delete_begin_(delete_begin),
+ delete_end_(delete_end),
+ callback_(callback) {
+}
+
+ShaderClearHelper::~ShaderClearHelper() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+}
+
+void ShaderClearHelper::Clear() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DoClearShaderCache(net::OK);
+}
+
+void ShaderClearHelper::DoClearShaderCache(int rv) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ // Hold a ref to ourselves so when we do the CacheCleared call we don't get
+ // auto-deleted when our ref count drops to zero.
+ scoped_refptr<ShaderClearHelper> helper = this;
+
+ while (rv != net::ERR_IO_PENDING) {
+ switch (op_type_) {
+ case VERIFY_CACHE_SETUP:
+ rv = cache_->SetAvailableCallback(
+ base::Bind(&ShaderClearHelper::DoClearShaderCache, this));
+ op_type_ = DELETE_CACHE;
+ break;
+ case DELETE_CACHE:
+ rv = cache_->Clear(
+ delete_begin_, delete_end_,
+ base::Bind(&ShaderClearHelper::DoClearShaderCache, this));
+ op_type_ = TERMINATE;
+ break;
+ case TERMINATE:
+ ShaderCacheFactory::GetInstance()->CacheCleared(path_);
+ callback_.Run();
+ rv = net::ERR_IO_PENDING; // Break the loop.
+ break;
+ default:
+ NOTREACHED(); // Invalid state provided.
+ op_type_ = TERMINATE;
+ break;
+ }
+ }
+}
+
+// static
ShaderCacheFactory* ShaderCacheFactory::GetInstance() {
return Singleton<ShaderCacheFactory,
LeakySingletonTraits<ShaderCacheFactory> >::get();
@@ -322,7 +410,7 @@
void ShaderCacheFactory::SetCacheInfo(int32 client_id,
const base::FilePath& path) {
- client_id_to_path_map_[client_id] = path.Append(kGpuCachePath);
+ client_id_to_path_map_[client_id] = path;
}
void ShaderCacheFactory::RemoveCacheInfo(int32 client_id) {
@@ -330,18 +418,21 @@
}
scoped_refptr<ShaderDiskCache> ShaderCacheFactory::Get(int32 client_id) {
- ClientIdToPathMap::iterator client_iter =
+ ClientIdToPathMap::iterator iter =
client_id_to_path_map_.find(client_id);
- if (client_iter == client_id_to_path_map_.end())
+ if (iter == client_id_to_path_map_.end())
return NULL;
+ return ShaderCacheFactory::GetByPath(iter->second);
+}
- ShaderCacheMap::iterator iter = shader_cache_map_.find(client_iter->second);
+scoped_refptr<ShaderDiskCache> ShaderCacheFactory::GetByPath(
+ const base::FilePath& path) {
+ ShaderCacheMap::iterator iter = shader_cache_map_.find(path);
if (iter != shader_cache_map_.end())
return iter->second;
- ShaderDiskCache* cache = new ShaderDiskCache(client_iter->second);
+ ShaderDiskCache* cache = new ShaderDiskCache(path);
cache->Init();
-
return cache;
}
@@ -354,6 +445,54 @@
shader_cache_map_.erase(key);
}
+void ShaderCacheFactory::ClearByPath(const base::FilePath& path,
+ const base::Time& delete_begin,
+ const base::Time& delete_end,
+ const base::Closure& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(!callback.is_null());
+
+ scoped_refptr<ShaderClearHelper> helper = new ShaderClearHelper(
+ GetByPath(path), path, delete_begin, delete_end, callback);
+
+ // We could receive requests to clear the same path with different
+ // begin/end times. So, we keep a list of requests. If we haven't seen this
+ // path before we kick off the clear and add it to the list. If we have see it
+ // already, then we already have a clear running. We add this clear to the
+ // list and wait for any previous clears to finish.
+ ShaderClearMap::iterator iter = shader_clear_map_.find(path);
+ if (iter != shader_clear_map_.end()) {
+ iter->second.push(helper);
+ return;
+ }
+
+ shader_clear_map_.insert(
+ std::pair<base::FilePath, ShaderClearQueue>(path, ShaderClearQueue()));
+ shader_clear_map_[path].push(helper);
+ helper->Clear();
+}
+
+void ShaderCacheFactory::CacheCleared(const base::FilePath& path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ ShaderClearMap::iterator iter = shader_clear_map_.find(path);
+ if (iter == shader_clear_map_.end()) {
+ LOG(ERROR) << "Completed clear but missing clear helper.";
+ return;
+ }
+
+ iter->second.pop();
+
+ // If there are remaining items in the list we trigger the Clear on the
+ // next one.
+ if (!iter->second.empty()) {
+ iter->second.front()->Clear();
+ return;
+ }
+
+ shader_clear_map_.erase(path);
+}
+
ShaderDiskCache::ShaderDiskCache(const base::FilePath& cache_path)
: cache_available_(false),
max_cache_size_(0),
@@ -366,6 +505,8 @@
ShaderDiskCache::~ShaderDiskCache() {
ShaderCacheFactory::GetInstance()->RemoveFromCache(cache_path_);
+ if (backend_)
+ delete backend_;
}
void ShaderDiskCache::Init() {
@@ -377,7 +518,7 @@
int rv = disk_cache::CreateCacheBackend(
net::SHADER_CACHE,
- cache_path_,
+ cache_path_.Append(kGpuCachePath),
max_cache_size_,
true,
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE),
@@ -400,24 +541,69 @@
entry_map_[shim] = shim;
}
+int ShaderDiskCache::Clear(
+ const base::Time begin_time, const base::Time end_time,
+ const net::CompletionCallback& completion_callback) {
+ int rv;
+ if (begin_time.is_null()) {
+ rv = backend_->DoomAllEntries(completion_callback);
+ } else {
+ rv = backend_->DoomEntriesBetween(begin_time, end_time,
+ completion_callback);
+ }
+ return rv;
+}
+
+int32 ShaderDiskCache::Size() {
+ if (!cache_available_)
+ return -1;
+ return backend_->GetEntryCount();
+}
+
+int ShaderDiskCache::SetAvailableCallback(
+ const net::CompletionCallback& callback) {
+ if (cache_available_)
+ return net::OK;
+ available_callback_ = callback;
+ return net::ERR_IO_PENDING;
+}
+
void ShaderDiskCache::CacheCreatedCallback(int rv) {
if (rv != net::OK) {
LOG(ERROR) << "Shader Cache Creation failed: " << rv;
return;
}
-
- cache_available_ = true;
-
helper_ = new ShaderDiskReadHelper(AsWeakPtr(), host_id_);
helper_->LoadCache();
}
void ShaderDiskCache::EntryComplete(void* entry) {
entry_map_.erase(entry);
+
+ if (entry_map_.empty() && !cache_complete_callback_.is_null())
+ cache_complete_callback_.Run(net::OK);
}
void ShaderDiskCache::ReadComplete() {
helper_ = NULL;
+
+ // The cache is considered available after we have finished reading any
+ // of the old cache values off disk. This prevents a potential race where we
+ // are reading from disk and execute a cache clear at the same time.
+ cache_available_ = true;
+ if (!available_callback_.is_null()) {
+ available_callback_.Run(net::OK);
+ available_callback_.Reset();
+ }
+}
+
+int ShaderDiskCache::SetCacheCompleteCallback(
+ const net::CompletionCallback& callback) {
+ if (entry_map_.empty()) {
+ return net::OK;
+ }
+ cache_complete_callback_ = callback;
+ return net::ERR_IO_PENDING;
}
} // namespace content
diff --git a/content/browser/gpu/shader_disk_cache.h b/content/browser/gpu/shader_disk_cache.h
index 3ca5420..48438e4 100644
--- a/content/browser/gpu/shader_disk_cache.h
+++ b/content/browser/gpu/shader_disk_cache.h
@@ -6,17 +6,20 @@
#define CONTENT_BROWSER_GPU_SHADER_DISK_CACHE_H_
#include <map>
+#include <queue>
#include <string>
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
+#include "content/common/content_export.h"
#include "net/disk_cache/disk_cache.h"
namespace content {
class ShaderDiskCacheEntry;
class ShaderDiskReadHelper;
+class ShaderClearHelper;
// ShaderDiskCache is the interface to the on disk cache for
// GL shaders.
@@ -24,7 +27,7 @@
// While this class is both RefCounted and SupportsWeakPtr
// when using this class you should work with the RefCounting.
// The WeakPtr is needed interally.
-class ShaderDiskCache
+class CONTENT_EXPORT ShaderDiskCache
: public base::RefCounted<ShaderDiskCache>,
public base::SupportsWeakPtr<ShaderDiskCache> {
public:
@@ -35,8 +38,35 @@
max_cache_size_ = max_cache_size;
}
+ // Store the |shader| into the cache under |key|.
void Cache(const std::string& key, const std::string& shader);
+ // Clear a range of entries. This supports unbounded deletes in either
+ // direction by using null Time values for either |begin_time| or |end_time|.
+ // The return value is a net error code. If this method returns
+ // ERR_IO_PENDING, the |completion_callback| will be invoked when the
+ // operation completes.
+ int Clear(
+ const base::Time begin_time,
+ const base::Time end_time,
+ const net::CompletionCallback& completion_callback);
+
+ // Sets a callback for when the cache is available. If the cache is
+ // already available the callback will not be called and net::OK is returned.
+ // If the callback is set net::ERR_IO_PENDING is returned and the callback
+ // will be executed when the cache is available.
+ int SetAvailableCallback(const net::CompletionCallback& callback);
+
+ // Returns the number of elements currently in the cache.
+ int32 Size();
+
+ // Set a callback notification for when all current entries have been
+ // written to the cache.
+ // The return value is a net error code. If this method returns
+ // ERR_IO_PENDING, the |callback| will be invoked when all entries have
+ // been written to the cache.
+ int SetCacheCompleteCallback(const net::CompletionCallback& callback);
+
private:
friend class base::RefCounted<ShaderDiskCache>;
friend class ShaderDiskCacheEntry;
@@ -58,6 +88,8 @@
int host_id_;
base::FilePath cache_path_;
bool is_initialized_;
+ net::CompletionCallback available_callback_;
+ net::CompletionCallback cache_complete_callback_;
disk_cache::Backend* backend_;
@@ -69,30 +101,54 @@
// ShaderCacheFactory maintains a cache of ShaderDiskCache objects
// so we only create one per profile directory.
-class ShaderCacheFactory {
+class CONTENT_EXPORT ShaderCacheFactory {
public:
static ShaderCacheFactory* GetInstance();
+ // Clear the shader disk cache for the given |path|. This supports unbounded
+ // deletes in either direction by using null Time values for either
+ // |begin_time| or |end_time|. The |callback| will be executed when the
+ // clear is complete.
+ void ClearByPath(const base::FilePath& path,
+ const base::Time& begin_time,
+ const base::Time& end_time,
+ const base::Closure& callback);
+
+ // Retrieve the shader disk cache for the provided |client_id|.
scoped_refptr<ShaderDiskCache> Get(int32 client_id);
+ // Set the |path| to be used for the disk cache for |client_id|.
void SetCacheInfo(int32 client_id, const base::FilePath& path);
+
+ // Remove the path mapping for |client_id|.
void RemoveCacheInfo(int32 client_id);
+ // Set the provided |cache| into the cache map for the given |path|.
void AddToCache(const base::FilePath& path, ShaderDiskCache* cache);
+
+ // Remove the provided |path| from our cache map.
void RemoveFromCache(const base::FilePath& path);
private:
friend struct DefaultSingletonTraits<ShaderCacheFactory>;
+ friend class ShaderClearHelper;
ShaderCacheFactory();
~ShaderCacheFactory();
+ scoped_refptr<ShaderDiskCache> GetByPath(const base::FilePath& path);
+ void CacheCleared(const base::FilePath& path);
+
typedef std::map<base::FilePath, ShaderDiskCache*> ShaderCacheMap;
ShaderCacheMap shader_cache_map_;
typedef std::map<int32, base::FilePath> ClientIdToPathMap;
ClientIdToPathMap client_id_to_path_map_;
+ typedef std::queue<scoped_refptr<ShaderClearHelper> > ShaderClearQueue;
+ typedef std::map<base::FilePath, ShaderClearQueue> ShaderClearMap;
+ ShaderClearMap shader_clear_map_;
+
DISALLOW_COPY_AND_ASSIGN(ShaderCacheFactory);
};
diff --git a/content/browser/gpu/shader_disk_cache_unittest.cc b/content/browser/gpu/shader_disk_cache_unittest.cc
new file mode 100644
index 0000000..93ed979
--- /dev/null
+++ b/content/browser/gpu/shader_disk_cache_unittest.cc
@@ -0,0 +1,78 @@
+// 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/files/scoped_temp_dir.h"
+#include "base/threading/thread.h"
+#include "content/browser/browser_thread_impl.h"
+#include "content/browser/gpu/shader_disk_cache.h"
+#include "content/public/test/test_browser_thread.h"
+#include "net/base/test_completion_callback.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+const int kDefaultClientId = 42;
+const char kCacheKey[] = "key";
+const char kCacheValue[] = "cached value";
+
+} // namespace
+
+class ShaderDiskCacheTest : public testing::Test {
+ public:
+ ShaderDiskCacheTest()
+ : cache_thread_(BrowserThread::CACHE, &message_loop_),
+ io_thread_(BrowserThread::IO, &message_loop_) {
+ }
+
+ virtual ~ShaderDiskCacheTest() {}
+
+ const base::FilePath& cache_path() { return temp_dir_.path(); }
+
+ void InitCache() {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ ShaderCacheFactory::GetInstance()->SetCacheInfo(kDefaultClientId,
+ cache_path());
+ }
+
+ private:
+ virtual void TearDown() OVERRIDE {
+ ShaderCacheFactory::GetInstance()->RemoveCacheInfo(kDefaultClientId);
+ }
+
+ base::ScopedTempDir temp_dir_;
+ base::MessageLoopForIO message_loop_;
+ TestBrowserThread cache_thread_;
+ TestBrowserThread io_thread_;
+
+ DISALLOW_COPY_AND_ASSIGN(ShaderDiskCacheTest);
+};
+
+TEST_F(ShaderDiskCacheTest, ClearsCache) {
+ InitCache();
+
+ scoped_refptr<ShaderDiskCache> cache =
+ ShaderCacheFactory::GetInstance()->Get(kDefaultClientId);
+ ASSERT_TRUE(cache.get() != NULL);
+
+ net::TestCompletionCallback available_cb;
+ int rv = cache->SetAvailableCallback(available_cb.callback());
+ ASSERT_EQ(net::OK, available_cb.GetResult(rv));
+ EXPECT_EQ(0, cache->Size());
+
+ cache->Cache(kCacheKey, kCacheValue);
+
+ net::TestCompletionCallback complete_cb;
+ rv = cache->SetCacheCompleteCallback(complete_cb.callback());
+ ASSERT_EQ(net::OK, complete_cb.GetResult(rv));
+ EXPECT_EQ(1, cache->Size());
+
+ base::Time time;
+ net::TestCompletionCallback clear_cb;
+ rv = cache->Clear(time, time, clear_cb.callback());
+ ASSERT_EQ(net::OK, clear_cb.GetResult(rv));
+ EXPECT_EQ(0, cache->Size());
+};
+
+} // namespace content
diff --git a/content/browser/gpu/software_rendering_list.json b/content/browser/gpu/software_rendering_list.json
index f8d317f..3621b02 100644
--- a/content/browser/gpu/software_rendering_list.json
+++ b/content/browser/gpu/software_rendering_list.json
@@ -75,7 +75,7 @@
{
"name": "software rendering list",
// Please update the version number whenever you change this file.
- "version": "5.0",
+ "version": "5.3",
"entries": [
{
"id": 1,
@@ -1015,6 +1015,84 @@
"features": [
"all"
]
+ },
+ {
+ "id": 69,
+ "description": "NVIDIA driver 8.17.11.9621 is buggy with Stage3D baseline mode.",
+ "cr_bugs": [172771],
+ "os": {
+ "type": "win"
+ },
+ "vendor_id": "0x10de",
+ "driver_version": {
+ "op": "=",
+ "number": "8.17.11.9621"
+ },
+ "features": [
+ "flash_stage3d_baseline"
+ ]
+ },
+ {
+ "id": 70,
+ "description": "NVIDIA driver 8.17.11.8267 is buggy with Stage3D baseline mode.",
+ "cr_bugs": [172771],
+ "os": {
+ "type": "win"
+ },
+ "vendor_id": "0x10de",
+ "driver_version": {
+ "op": "=",
+ "number": "8.17.11.8267"
+ },
+ "features": [
+ "flash_stage3d_baseline"
+ ]
+ },
+ {
+ "id": 71,
+ "description": "All Intel drivers before 8.15.10.2021 are buggy with Stage3D baseline mode.",
+ "cr_bugs": [172771],
+ "os": {
+ "type": "win"
+ },
+ "vendor_id": "0x8086",
+ "driver_version": {
+ "op": "<",
+ "number": "8.15.10.2021"
+ },
+ "features": [
+ "flash_stage3d_baseline"
+ ]
+ },
+ {
+ "id": 72,
+ "description": "NVIDIA GeForce 6200 LE is buggy with WebGL.",
+ "cr_bugs": [232529],
+ "os": {
+ "type": "win"
+ },
+ "vendor_id": "0x10de",
+ "device_id": ["0x0163"],
+ "features": [
+ "webgl"
+ ]
+ },
+ {
+ "id": 73,
+ "description": "WebGL is buggy with the NVIDIA GeForce GT 330M, 9400, and 9400M on MacOSX earlier than 10.8",
+ "cr_bugs": [233523],
+ "os": {
+ "type": "macosx",
+ "version": {
+ "op": "<",
+ "number": "10.8"
+ }
+ },
+ "vendor_id": "0x10de",
+ "device_id": ["0x0a29", "0x0861", "0x0863"],
+ "features": [
+ "webgl"
+ ]
}
]
}
diff --git a/content/browser/histogram_controller.cc b/content/browser/histogram_controller.cc
index 54f760b..240de25 100644
--- a/content/browser/histogram_controller.cc
+++ b/content/browser/histogram_controller.cc
@@ -73,8 +73,13 @@
int pending_processes = 0;
for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
int type = iter.GetData().process_type;
- if (type != PROCESS_TYPE_PLUGIN && type != PROCESS_TYPE_GPU)
+ if (type != PROCESS_TYPE_PLUGIN &&
+ type != PROCESS_TYPE_GPU &&
+ type != PROCESS_TYPE_PPAPI_PLUGIN &&
+ type != PROCESS_TYPE_PPAPI_BROKER) {
continue;
+ }
+
++pending_processes;
if (!iter.Send(new ChildProcessMsg_GetChildHistogramData(sequence_number)))
--pending_processes;
diff --git a/content/browser/histogram_synchronizer.cc b/content/browser/histogram_synchronizer.cc
index b2db39b..5a1e6f9 100644
--- a/content/browser/histogram_synchronizer.cc
+++ b/content/browser/histogram_synchronizer.cc
@@ -201,7 +201,7 @@
base::TimeDelta::FromMinutes(1));
}
-void FetchHistogramsAsynchronously(MessageLoop* callback_thread,
+void FetchHistogramsAsynchronously(base::MessageLoop* callback_thread,
const base::Closure& callback,
base::TimeDelta wait_time) {
HistogramSynchronizer::FetchHistogramsAsynchronously(
@@ -210,7 +210,7 @@
// static
void HistogramSynchronizer::FetchHistogramsAsynchronously(
- MessageLoop* callback_thread,
+ base::MessageLoop* callback_thread,
const base::Closure& callback,
base::TimeDelta wait_time) {
DCHECK(callback_thread != NULL);
@@ -287,10 +287,10 @@
}
void HistogramSynchronizer::SetCallbackTaskAndThread(
- MessageLoop* callback_thread,
+ base::MessageLoop* callback_thread,
const base::Closure& callback) {
base::Closure old_callback;
- MessageLoop* old_thread = NULL;
+ base::MessageLoop* old_thread = NULL;
{
base::AutoLock auto_lock(lock_);
old_callback = callback_;
@@ -307,7 +307,7 @@
void HistogramSynchronizer::ForceHistogramSynchronizationDoneCallback(
int sequence_number) {
base::Closure callback;
- MessageLoop* thread = NULL;
+ base::MessageLoop* thread = NULL;
{
base::AutoLock lock(lock_);
if (sequence_number != async_sequence_number_)
@@ -320,7 +320,7 @@
InternalPostTask(thread, callback);
}
-void HistogramSynchronizer::InternalPostTask(MessageLoop* thread,
+void HistogramSynchronizer::InternalPostTask(base::MessageLoop* thread,
const base::Closure& callback) {
if (callback.is_null() || !thread)
return;
diff --git a/content/browser/histogram_synchronizer.h b/content/browser/histogram_synchronizer.h
index 0968abd..0b279a0 100644
--- a/content/browser/histogram_synchronizer.h
+++ b/content/browser/histogram_synchronizer.h
@@ -15,7 +15,9 @@
#include "base/time.h"
#include "content/browser/histogram_subscriber.h"
+namespace base {
class MessageLoop;
+}
namespace content {
@@ -68,7 +70,7 @@
// changes to histograms. When all changes have been acquired, or when the
// wait time expires (whichever is sooner), post the callback to the
// specified message loop. Note the callback is posted exactly once.
- static void FetchHistogramsAsynchronously(MessageLoop* callback_thread,
+ static void FetchHistogramsAsynchronously(base::MessageLoop* callback_thread,
const base::Closure& callback,
base::TimeDelta wait_time);
@@ -109,13 +111,14 @@
// callaback_thread_. This side effect should not generally happen, but is in
// place to assure correctness (that any tasks that were set, are eventually
// called, and never merely discarded).
- void SetCallbackTaskAndThread(MessageLoop* callback_thread,
+ void SetCallbackTaskAndThread(base::MessageLoop* callback_thread,
const base::Closure& callback);
void ForceHistogramSynchronizationDoneCallback(int sequence_number);
// Internal helper function, to post task, and record callback stats.
- void InternalPostTask(MessageLoop* thread, const base::Closure& callback);
+ void InternalPostTask(base::MessageLoop* thread,
+ const base::Closure& callback);
// Gets a new sequence number to be sent to processes from browser process.
int GetNextAvailableSequenceNumber(ProcessHistogramRequester requester);
@@ -127,7 +130,7 @@
// the task and thread we use to post a completion notification in
// callback_ and callback_thread_.
base::Closure callback_;
- MessageLoop* callback_thread_;
+ base::MessageLoop* callback_thread_;
// We don't track the actual processes that are contacted for an update, only
// the count of the number of processes, and we can sometimes time-out and
diff --git a/content/browser/host_zoom_map_impl.cc b/content/browser/host_zoom_map_impl.cc
index a60a923..ad70977 100644
--- a/content/browser/host_zoom_map_impl.cc
+++ b/content/browser/host_zoom_map_impl.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <cmath>
-
#include "content/browser/host_zoom_map_impl.h"
-#include "base/string_piece.h"
+#include <cmath>
+
+#include "base/strings/string_piece.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
diff --git a/content/browser/host_zoom_map_impl_unittest.cc b/content/browser/host_zoom_map_impl_unittest.cc
index 055e061..ccb04e4 100644
--- a/content/browser/host_zoom_map_impl_unittest.cc
+++ b/content/browser/host_zoom_map_impl_unittest.cc
@@ -18,7 +18,7 @@
}
protected:
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
TestBrowserThread ui_thread_;
};
diff --git a/content/browser/hyphenator/hyphenator_message_filter.cc b/content/browser/hyphenator/hyphenator_message_filter.cc
index 1653ea3..e14233a 100644
--- a/content/browser/hyphenator/hyphenator_message_filter.cc
+++ b/content/browser/hyphenator/hyphenator_message_filter.cc
@@ -31,7 +31,7 @@
RenderProcessHost* render_process_host)
: render_process_host_(render_process_host),
dictionary_file_(base::kInvalidPlatformFileValue),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ weak_factory_(this) {
}
HyphenatorMessageFilter::~HyphenatorMessageFilter() {
diff --git a/content/browser/in_process_webkit/indexed_db_browsertest.cc b/content/browser/in_process_webkit/indexed_db_browsertest.cc
index ddbc331..45c0a69 100644
--- a/content/browser/in_process_webkit/indexed_db_browsertest.cc
+++ b/content/browser/in_process_webkit/indexed_db_browsertest.cc
@@ -11,7 +11,7 @@
#include "base/process_util.h"
#include "base/test/thread_test_helper.h"
#include "base/utf_string_conversions.h"
-#include "content/browser/in_process_webkit/indexed_db_context_impl.h"
+#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@@ -113,7 +113,7 @@
BrowserThread::WEBKIT_DEPRECATED)));
EXPECT_TRUE(helper->Run());
// Wait for DidGetDiskUsage to be called.
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
return disk_usage_;
}
private:
@@ -390,7 +390,7 @@
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, PRE_VersionChangeCrashResilience) {
NavigateAndWaitForTitle(shell(), "version_change_crash.html", "#part2",
"pass - part2 - crash me");
- NavigateToURL(shell(), GURL(chrome::kChromeUIBrowserCrashHost));
+ NavigateToURL(shell(), GURL(kChromeUIBrowserCrashHost));
}
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, VersionChangeCrashResilience) {
diff --git a/content/browser/in_process_webkit/indexed_db_callbacks.cc b/content/browser/in_process_webkit/indexed_db_callbacks.cc
index 33f5f61..8884bef 100644
--- a/content/browser/in_process_webkit/indexed_db_callbacks.cc
+++ b/content/browser/in_process_webkit/indexed_db_callbacks.cc
@@ -172,12 +172,12 @@
ipc_thread_id(), ipc_callbacks_id(), IndexedDBKey(value)));
}
-void IndexedDBCallbacks<WebKit::WebDOMStringList>::onSuccess(
- const WebKit::WebDOMStringList& value) {
+void IndexedDBCallbacks<WebKit::WebVector<WebKit::WebString> >::onSuccess(
+ const WebKit::WebVector<WebKit::WebString>& value) {
std::vector<string16> list;
- for (unsigned i = 0; i < value.length(); ++i)
- list.push_back(value.item(i));
+ for (unsigned i = 0; i < value.size(); ++i)
+ list.push_back(value[i]);
dispatcher_host()->Send(
new IndexedDBMsg_CallbacksSuccessStringList(
diff --git a/content/browser/in_process_webkit/indexed_db_callbacks.h b/content/browser/in_process_webkit/indexed_db_callbacks.h
index b7d7094..4ab0ab1 100644
--- a/content/browser/in_process_webkit/indexed_db_callbacks.h
+++ b/content/browser/in_process_webkit/indexed_db_callbacks.h
@@ -10,11 +10,11 @@
#include "content/browser/in_process_webkit/indexed_db_dispatcher_host.h"
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebData.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBCallbacks.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBCursor.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabase.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabaseError.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBCallbacks.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBCursor.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabase.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabaseError.h"
namespace content {
@@ -137,11 +137,11 @@
DISALLOW_IMPLICIT_CONSTRUCTORS(IndexedDBCallbacks);
};
-// WebDOMStringList is implemented in WebKit as opposed to being an
+// WebVector is implemented in WebKit as opposed to being an
// interface Chromium implements. Thus we pass a const ___& version and thus
// we need this specialization.
template <>
-class IndexedDBCallbacks<WebKit::WebDOMStringList>
+class IndexedDBCallbacks<WebKit::WebVector<WebKit::WebString> >
: public IndexedDBCallbacksBase {
public:
IndexedDBCallbacks(
@@ -151,7 +151,7 @@
: IndexedDBCallbacksBase(dispatcher_host, ipc_thread_id,
ipc_callbacks_id) { }
- virtual void onSuccess(const WebKit::WebDOMStringList& value);
+ virtual void onSuccess(const WebKit::WebVector<WebKit::WebString>& value);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(IndexedDBCallbacks);
diff --git a/content/browser/in_process_webkit/indexed_db_database_callbacks.h b/content/browser/in_process_webkit/indexed_db_database_callbacks.h
index 981b218..43b3fb1 100644
--- a/content/browser/in_process_webkit/indexed_db_database_callbacks.h
+++ b/content/browser/in_process_webkit/indexed_db_database_callbacks.h
@@ -6,7 +6,7 @@
#define CONTENT_BROWSER_IN_PROCESS_WEBKIT_INDEXED_DB_DATABASE_CALLBACKS_H_
#include "base/memory/ref_counted.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabaseCallbacks.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabaseCallbacks.h"
namespace content {
class IndexedDBDispatcherHost;
diff --git a/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc b/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc
index 71d0ab3..ee0c3ad 100644
--- a/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc
+++ b/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc
@@ -12,8 +12,8 @@
#include "base/process_util.h"
#include "base/utf_string_conversions.h"
#include "content/browser/in_process_webkit/indexed_db_callbacks.h"
-#include "content/browser/in_process_webkit/indexed_db_context_impl.h"
#include "content/browser/in_process_webkit/indexed_db_database_callbacks.h"
+#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/renderer_host/render_message_filter.h"
#include "content/common/indexed_db/indexed_db_messages.h"
#include "content/public/browser/browser_thread.h"
@@ -22,23 +22,20 @@
#include "content/public/common/result_codes.h"
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebData.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBCursor.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabase.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabaseCallbacks.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabaseError.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabaseException.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBFactory.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBMetadata.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMStringList.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBCursor.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabase.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/WebIDBDatabaseException.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBFactory.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBMetadata.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
#include "webkit/base/file_path_string_conversions.h"
#include "webkit/database/database_util.h"
using webkit_database::DatabaseUtil;
-using WebKit::WebDOMStringList;
using WebKit::WebData;
-using WebKit::WebExceptionCode;
using WebKit::WebIDBCallbacks;
using WebKit::WebIDBCursor;
using WebKit::WebIDBDatabase;
@@ -47,7 +44,7 @@
using WebKit::WebIDBKey;
using WebKit::WebIDBMetadata;
using WebKit::WebIDBObjectStore;
-using WebKit::WebSecurityOrigin;
+using WebKit::WebString;
using WebKit::WebVector;
namespace content {
@@ -64,10 +61,8 @@
IndexedDBDispatcherHost::IndexedDBDispatcherHost(
int ipc_process_id, IndexedDBContextImpl* indexed_db_context)
: indexed_db_context_(indexed_db_context),
- ALLOW_THIS_IN_INITIALIZER_LIST(database_dispatcher_host_(
- new DatabaseDispatcherHost(this))),
- ALLOW_THIS_IN_INITIALIZER_LIST(cursor_dispatcher_host_(
- new CursorDispatcherHost(this))),
+ database_dispatcher_host_(new DatabaseDispatcherHost(this)),
+ cursor_dispatcher_host_(new CursorDispatcherHost(this)),
ipc_process_id_(ipc_process_id) {
DCHECK(indexed_db_context_.get());
}
@@ -135,7 +130,7 @@
}
int32 IndexedDBDispatcherHost::Add(WebIDBCursor* idb_cursor) {
- if (!cursor_dispatcher_host_.get()) {
+ if (!cursor_dispatcher_host_) {
delete idb_cursor;
return 0;
}
@@ -145,7 +140,7 @@
int32 IndexedDBDispatcherHost::Add(WebIDBDatabase* idb_database,
int32 ipc_thread_id,
const GURL& origin_url) {
- if (!database_dispatcher_host_.get()) {
+ if (!database_dispatcher_host_) {
delete idb_database;
return 0;
}
@@ -230,12 +225,9 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
base::FilePath indexed_db_path = indexed_db_context_->data_path();
- WebSecurityOrigin origin(
- WebSecurityOrigin::createFromDatabaseIdentifier(params.origin));
-
Context()->GetIDBFactory()->getDatabaseNames(
- new IndexedDBCallbacks<WebDOMStringList>(this, params.ipc_thread_id,
- params.ipc_callbacks_id), origin, NULL,
+ new IndexedDBCallbacks<WebVector<WebString> >(this, params.ipc_thread_id,
+ params.ipc_callbacks_id), params.database_identifier,
webkit_base::FilePathToWebString(indexed_db_path));
}
@@ -244,9 +236,8 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
base::FilePath indexed_db_path = indexed_db_context_->data_path();
- GURL origin_url = DatabaseUtil::GetOriginFromIdentifier(params.origin);
- WebSecurityOrigin origin(
- WebSecurityOrigin::createFromDatabaseIdentifier(params.origin));
+ GURL origin_url =
+ DatabaseUtil::GetOriginFromIdentifier(params.database_identifier);
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
@@ -265,7 +256,8 @@
origin_url),
new IndexedDBDatabaseCallbacks(this, params.ipc_thread_id,
params.ipc_database_callbacks_id),
- origin, NULL, webkit_base::FilePathToWebString(indexed_db_path));
+ params.database_identifier,
+ webkit_base::FilePathToWebString(indexed_db_path));
}
void IndexedDBDispatcherHost::OnIDBFactoryDeleteDatabase(
@@ -278,7 +270,7 @@
new IndexedDBCallbacks<WebData>(this,
params.ipc_thread_id,
params.ipc_callbacks_id),
- WebSecurityOrigin::createFromDatabaseIdentifier(params.origin), NULL,
+ params.database_identifier,
webkit_base::FilePathToWebString(indexed_db_path));
}
@@ -770,14 +762,11 @@
if (!idb_cursor)
return;
- WebKit::WebExceptionCode ec = 0;
idb_cursor->advance(count,
new IndexedDBCallbacks<WebIDBCursor>(parent_,
ipc_thread_id,
ipc_callbacks_id,
- ipc_cursor_id),
- ec);
- DCHECK(!ec);
+ ipc_cursor_id));
}
void IndexedDBDispatcherHost::CursorDispatcherHost::OnContinue(
@@ -791,12 +780,10 @@
if (!idb_cursor)
return;
- WebKit::WebExceptionCode ec = 0;
idb_cursor->continueFunction(
key, new IndexedDBCallbacks<WebIDBCursor>(parent_, ipc_thread_id,
ipc_callbacks_id,
- ipc_cursor_id), ec);
- DCHECK(!ec);
+ ipc_cursor_id));
}
void IndexedDBDispatcherHost::CursorDispatcherHost::OnPrefetch(
@@ -810,12 +797,10 @@
if (!idb_cursor)
return;
- WebKit::WebExceptionCode ec = 0;
idb_cursor->prefetchContinue(
n, new IndexedDBCallbacks<WebIDBCursor>(parent_, ipc_thread_id,
ipc_callbacks_id,
- ipc_cursor_id), ec);
- DCHECK(!ec);
+ ipc_cursor_id));
}
void IndexedDBDispatcherHost::CursorDispatcherHost::OnPrefetchReset(
@@ -839,11 +824,9 @@
if (!idb_cursor)
return;
- WebKit::WebExceptionCode ec = 0;
idb_cursor->deleteFunction(
new IndexedDBCallbacks<WebData>(parent_, ipc_thread_id,
- ipc_callbacks_id), ec);
- DCHECK(!ec);
+ ipc_callbacks_id));
}
void IndexedDBDispatcherHost::CursorDispatcherHost::OnDestroyed(
diff --git a/content/browser/in_process_webkit/indexed_db_dispatcher_host.h b/content/browser/in_process_webkit/indexed_db_dispatcher_host.h
index 7298049..48a75d7 100644
--- a/content/browser/in_process_webkit/indexed_db_dispatcher_host.h
+++ b/content/browser/in_process_webkit/indexed_db_dispatcher_host.h
@@ -11,7 +11,6 @@
#include "base/basictypes.h"
#include "base/id_map.h"
#include "content/public/browser/browser_message_filter.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebExceptionCode.h"
class GURL;
struct IndexedDBDatabaseMetadata;
diff --git a/content/browser/indexed_db/OWNERS b/content/browser/indexed_db/OWNERS
new file mode 100644
index 0000000..b106dad
--- /dev/null
+++ b/content/browser/indexed_db/OWNERS
@@ -0,0 +1,4 @@
+dgrogan@chromium.org
+michaeln@chromium.org
+jsbell@chromium.org
+alecflett@chromium.org
diff --git a/content/browser/in_process_webkit/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc
similarity index 88%
rename from content/browser/in_process_webkit/indexed_db_context_impl.cc
rename to content/browser/indexed_db/indexed_db_context_impl.cc
index 5591dc7..b95be28 100644
--- a/content/browser/in_process_webkit/indexed_db_context_impl.cc
+++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/in_process_webkit/indexed_db_context_impl.h"
+#include "content/browser/indexed_db/indexed_db_context_impl.h"
+
+#include <vector>
#include "base/bind.h"
#include "base/command_line.h"
@@ -11,14 +13,14 @@
#include "base/message_loop_proxy.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
-#include "content/browser/in_process_webkit/indexed_db_quota_client.h"
+#include "content/browser/indexed_db/indexed_db_quota_client.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/indexed_db_info.h"
#include "content/public/common/content_switches.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabase.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBFactory.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabase.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBFactory.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
#include "webkit/base/file_path_string_conversions.h"
#include "webkit/database/database_util.h"
#include "webkit/quota/quota_manager.h"
@@ -27,7 +29,6 @@
using webkit_database::DatabaseUtil;
using WebKit::WebIDBDatabase;
using WebKit::WebIDBFactory;
-using WebKit::WebSecurityOrigin;
namespace content {
const base::FilePath::CharType IndexedDBContextImpl::kIndexedDBDirectory[] =
@@ -102,7 +103,7 @@
WebIDBFactory* IndexedDBContextImpl::GetIDBFactory() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
- if (!idb_factory_.get()) {
+ if (!idb_factory_) {
// Prime our cache of origins with existing databases so we can
// detect when dbs are newly created.
GetOriginSet();
@@ -122,6 +123,22 @@
return origins;
}
+std::vector<IndexedDBInfo> IndexedDBContextImpl::GetAllOriginsInfo() {
+ std::vector<GURL> origins = GetAllOrigins();
+ std::vector<IndexedDBInfo> result;
+ for (std::vector<GURL>::const_iterator iter = origins.begin();
+ iter != origins.end(); ++iter) {
+ const GURL& origin_url = *iter;
+
+ base::FilePath idb_directory = GetFilePath(origin_url);
+ result.push_back(IndexedDBInfo(origin_url,
+ GetOriginDiskUsage(origin_url),
+ GetOriginLastModified(origin_url),
+ idb_directory));
+ }
+ return result;
+}
+
int64 IndexedDBContextImpl::GetOriginDiskUsage(const GURL& origin_url) {
if (data_path_.empty() || !IsInOriginSet(origin_url))
return 0;
@@ -132,8 +149,7 @@
base::Time IndexedDBContextImpl::GetOriginLastModified(const GURL& origin_url) {
if (data_path_.empty() || !IsInOriginSet(origin_url))
return base::Time();
- string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin_url);
- base::FilePath idb_directory = GetIndexedDBFilePath(origin_id);
+ base::FilePath idb_directory = GetFilePath(origin_url);
base::PlatformFileInfo file_info;
if (!file_util::GetFileInfo(idb_directory, &file_info))
return base::Time();
@@ -142,6 +158,25 @@
void IndexedDBContextImpl::DeleteForOrigin(const GURL& origin_url) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
+ ForceClose(origin_url);
+ if (data_path_.empty() || !IsInOriginSet(origin_url))
+ return;
+
+ base::FilePath idb_directory = GetFilePath(origin_url);
+ EnsureDiskUsageCacheInitialized(origin_url);
+ const bool recursive = true;
+ bool deleted = file_util::Delete(idb_directory, recursive);
+
+ QueryDiskAndUpdateQuotaUsage(origin_url);
+ if (deleted) {
+ RemoveFromOriginSet(origin_url);
+ origin_size_map_.erase(origin_url);
+ space_available_map_.erase(origin_url);
+ }
+}
+
+void IndexedDBContextImpl::ForceClose(const GURL& origin_url) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
if (data_path_.empty() || !IsInOriginSet(origin_url))
return;
@@ -154,22 +189,14 @@
connections.erase(it++);
db->forceClose();
}
- DCHECK(connections_[origin_url].size() == 0);
+ DCHECK_EQ(connections_[origin_url].size(), 0UL);
connections_.erase(origin_url);
}
+}
+base::FilePath IndexedDBContextImpl::GetFilePath(const GURL& origin_url) {
string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin_url);
- base::FilePath idb_directory = GetIndexedDBFilePath(origin_id);
- EnsureDiskUsageCacheInitialized(origin_url);
- const bool recursive = true;
- bool deleted = file_util::Delete(idb_directory, recursive);
-
- QueryDiskAndUpdateQuotaUsage(origin_url);
- if (deleted) {
- RemoveFromOriginSet(origin_url);
- origin_size_map_.erase(origin_url);
- space_available_map_.erase(origin_url);
- }
+ return GetIndexedDBFilePath(origin_id);
}
base::FilePath IndexedDBContextImpl::GetFilePathForTesting(
@@ -179,7 +206,7 @@
void IndexedDBContextImpl::ConnectionOpened(const GURL& origin_url,
WebIDBDatabase* connection) {
- DCHECK(connections_[origin_url].count(connection) == 0);
+ DCHECK_EQ(connections_[origin_url].count(connection), 0UL);
if (quota_manager_proxy()) {
quota_manager_proxy()->NotifyStorageAccessed(
quota::QuotaClient::kIndexedDatabase, origin_url,
@@ -352,7 +379,7 @@
}
std::set<GURL>* IndexedDBContextImpl::GetOriginSet() {
- if (!origin_set_.get()) {
+ if (!origin_set_) {
origin_set_.reset(new std::set<GURL>);
std::vector<GURL> origins;
GetAllOriginsAndPaths(data_path_, &origins, NULL);
diff --git a/content/browser/in_process_webkit/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h
similarity index 85%
rename from content/browser/in_process_webkit/indexed_db_context_impl.h
rename to content/browser/indexed_db/indexed_db_context_impl.h
index 284f41f..e40e6ae 100644
--- a/content/browser/in_process_webkit/indexed_db_context_impl.h
+++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_BROWSER_IN_PROCESS_WEBKIT_INDEXED_DB_CONTEXT_IMPL_H_
-#define CONTENT_BROWSER_IN_PROCESS_WEBKIT_INDEXED_DB_CONTEXT_IMPL_H_
+#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_CONTEXT_IMPL_H_
+#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_CONTEXT_IMPL_H_
#include <map>
#include <set>
+#include <vector>
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
@@ -53,17 +54,16 @@
static const base::FilePath::CharType kIndexedDBExtension[];
// Disables the exit-time deletion of session-only data.
- void SetForceKeepSessionState() {
- force_keep_session_state_ = true;
- }
+ void SetForceKeepSessionState() { force_keep_session_state_ = true; }
// IndexedDBContext implementation:
virtual std::vector<GURL> GetAllOrigins() OVERRIDE;
+ virtual std::vector<IndexedDBInfo> GetAllOriginsInfo() OVERRIDE;
virtual int64 GetOriginDiskUsage(const GURL& origin_url) OVERRIDE;
virtual base::Time GetOriginLastModified(const GURL& origin_url) OVERRIDE;
virtual void DeleteForOrigin(const GURL& origin_url) OVERRIDE;
- virtual base::FilePath GetFilePathForTesting(
- const string16& origin_id) const OVERRIDE;
+ virtual base::FilePath GetFilePathForTesting(const string16& origin_id) const
+ OVERRIDE;
// Methods called by IndexedDBDispatcherHost for quota support.
void ConnectionOpened(const GURL& origin_url, WebKit::WebIDBDatabase*);
@@ -74,7 +74,13 @@
quota::QuotaManagerProxy* quota_manager_proxy();
+ void ForceClose(const GURL& origin_url);
+ base::FilePath GetFilePath(const GURL& origin_url);
base::FilePath data_path() const { return data_path_; }
+ bool IsInOriginSet(const GURL& origin_url) {
+ std::set<GURL>* set = GetOriginSet();
+ return set->find(origin_url) != set->end();
+ }
// For unit tests allow to override the |data_path_|.
void set_data_path_for_testing(const base::FilePath& data_path) {
@@ -98,8 +104,10 @@
int64 ReadUsageFromDisk(const GURL& origin_url) const;
void EnsureDiskUsageCacheInitialized(const GURL& origin_url);
void QueryDiskAndUpdateQuotaUsage(const GURL& origin_url);
- void GotUsageAndQuota(const GURL& origin_url, quota::QuotaStatusCode,
- int64 usage, int64 quota);
+ void GotUsageAndQuota(const GURL& origin_url,
+ quota::QuotaStatusCode,
+ int64 usage,
+ int64 quota);
void GotUpdatedQuota(const GURL& origin_url, int64 usage, int64 quota);
void QueryAvailableQuota(const GURL& origin_url);
@@ -110,11 +118,6 @@
void RemoveFromOriginSet(const GURL& origin_url) {
GetOriginSet()->erase(origin_url);
}
- bool IsInOriginSet(const GURL& origin_url) {
- std::set<GURL>* set = GetOriginSet();
- return set->find(origin_url) != set->end();
- }
-
// Only for testing.
void ResetCaches();
@@ -135,4 +138,4 @@
} // namespace content
-#endif // CONTENT_BROWSER_IN_PROCESS_WEBKIT_INDEXED_DB_CONTEXT_IMPL_H_
+#endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_CONTEXT_IMPL_H_
diff --git a/content/browser/indexed_db/indexed_db_internals_ui.cc b/content/browser/indexed_db/indexed_db_internals_ui.cc
new file mode 100644
index 0000000..4d6f04b
--- /dev/null
+++ b/content/browser/indexed_db/indexed_db_internals_ui.cc
@@ -0,0 +1,316 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/indexed_db/indexed_db_internals_ui.h"
+
+#include <algorithm>
+#include <string>
+
+#include "base/bind.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/memory/scoped_vector.h"
+#include "base/threading/platform_thread.h"
+#include "base/values.h"
+#include "content/browser/indexed_db/indexed_db_context_impl.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/download_manager.h"
+#include "content/public/browser/download_url_parameters.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/browser/web_ui_data_source.h"
+#include "content/public/common/url_constants.h"
+#include "grit/content_resources.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
+#include "third_party/zlib/google/zip.h"
+#include "webkit/base/file_path_string_conversions.h"
+#include "webkit/database/database_util.h"
+
+using webkit_database::DatabaseUtil;
+
+namespace content {
+
+IndexedDBInternalsUI::IndexedDBInternalsUI(WebUI* web_ui)
+ : WebUIController(web_ui) {
+ web_ui->RegisterMessageCallback(
+ "getAllOrigins",
+ base::Bind(&IndexedDBInternalsUI::GetAllOrigins, base::Unretained(this)));
+
+ web_ui->RegisterMessageCallback(
+ "downloadOriginData",
+ base::Bind(&IndexedDBInternalsUI::DownloadOriginData,
+ base::Unretained(this)));
+
+ WebUIDataSource* source =
+ WebUIDataSource::Create(kChromeUIIndexedDBInternalsHost);
+ source->SetUseJsonJSFormatV2();
+ source->SetJsonPath("strings.js");
+ source->AddResourcePath("indexeddb_internals.js",
+ IDR_INDEXED_DB_INTERNALS_JS);
+ source->AddResourcePath("indexeddb_internals.css",
+ IDR_INDEXED_DB_INTERNALS_CSS);
+ source->SetDefaultResource(IDR_INDEXED_DB_INTERNALS_HTML);
+
+ BrowserContext* browser_context =
+ web_ui->GetWebContents()->GetBrowserContext();
+ WebUIDataSource::Add(browser_context, source);
+}
+
+IndexedDBInternalsUI::~IndexedDBInternalsUI() {}
+
+void IndexedDBInternalsUI::AddContextFromStoragePartition(
+ ContextList* contexts,
+ std::vector<base::FilePath>* paths,
+ StoragePartition* partition) {
+ scoped_refptr<IndexedDBContext> context = partition->GetIndexedDBContext();
+ contexts->push_back(context);
+ paths->push_back(partition->GetPath());
+}
+
+void IndexedDBInternalsUI::GetAllOrigins(const base::ListValue* args) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ BrowserContext* browser_context =
+ web_ui()->GetWebContents()->GetBrowserContext();
+
+ scoped_ptr<std::vector<base::FilePath> > paths(
+ new std::vector<base::FilePath>);
+ scoped_ptr<ContextList> contexts(new ContextList);
+ BrowserContext::StoragePartitionCallback cb =
+ base::Bind(&AddContextFromStoragePartition, contexts.get(), paths.get());
+ BrowserContext::ForEachStoragePartition(browser_context, cb);
+
+ BrowserThread::PostTask(
+ BrowserThread::WEBKIT_DEPRECATED,
+ FROM_HERE,
+ base::Bind(&IndexedDBInternalsUI::GetAllOriginsOnWebkitThread,
+ base::Unretained(this),
+ base::Passed(&contexts),
+ base::Passed(&paths)));
+}
+
+bool HostNameComparator(const IndexedDBInfo& i, const IndexedDBInfo& j) {
+ return i.origin_.host() < j.origin_.host();
+}
+
+void IndexedDBInternalsUI::GetAllOriginsOnWebkitThread(
+ const scoped_ptr<ContextList> contexts,
+ const scoped_ptr<std::vector<base::FilePath> > context_paths) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
+ DCHECK_EQ(contexts->size(), context_paths->size());
+
+ std::vector<base::FilePath>::const_iterator path_iter =
+ context_paths->begin();
+ for (ContextList::const_iterator iter = contexts->begin();
+ iter != contexts->end();
+ ++iter, ++path_iter) {
+ IndexedDBContext* context = *iter;
+ const base::FilePath& context_path = *path_iter;
+
+ scoped_ptr<std::vector<IndexedDBInfo> > info_list(
+ new std::vector<IndexedDBInfo>(context->GetAllOriginsInfo()));
+ std::sort(info_list->begin(), info_list->end(), HostNameComparator);
+ BrowserThread::PostTask(BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&IndexedDBInternalsUI::OnOriginsReady,
+ base::Unretained(this),
+ base::Passed(&info_list),
+ context_path));
+ }
+}
+
+void IndexedDBInternalsUI::OnOriginsReady(
+ scoped_ptr<std::vector<IndexedDBInfo> > origins,
+ const base::FilePath& path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ base::ListValue urls;
+ for (std::vector<IndexedDBInfo>::const_iterator iter = origins->begin();
+ iter != origins->end();
+ ++iter) {
+ base::DictionaryValue* info = new DictionaryValue;
+ info->SetString("url", iter->origin_.spec());
+ info->SetDouble("size", iter->size_);
+ info->SetDouble("last_modified", iter->last_modified_.ToJsTime());
+ info->SetString("path", iter->path_.value());
+ urls.Append(info);
+ }
+ web_ui()->CallJavascriptFunction(
+ "indexeddb.onOriginsReady", urls, base::StringValue(path.value()));
+}
+
+static void FindContext(const base::FilePath& partition_path,
+ StoragePartition** result_partition,
+ scoped_refptr<IndexedDBContextImpl>* result_context,
+ StoragePartition* storage_partition) {
+ if (storage_partition->GetPath() == partition_path) {
+ *result_partition = storage_partition;
+ *result_context = static_cast<IndexedDBContextImpl*>(
+ storage_partition->GetIndexedDBContext());
+ }
+}
+
+void IndexedDBInternalsUI::DownloadOriginData(const base::ListValue* args) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ base::FilePath::StringType path_string;
+ if (!args->GetString(0, &path_string))
+ return;
+ const base::FilePath partition_path(path_string);
+
+ std::string url_string;
+ if (!args->GetString(1, &url_string))
+ return;
+ const GURL origin_url(url_string);
+
+ // search the origins to find the right context
+
+ BrowserContext* browser_context =
+ web_ui()->GetWebContents()->GetBrowserContext();
+
+ scoped_refptr<IndexedDBContextImpl> result_context;
+ StoragePartition* result_partition;
+ scoped_ptr<ContextList> contexts(new ContextList);
+ BrowserContext::StoragePartitionCallback cb = base::Bind(
+ &FindContext, partition_path, &result_partition, &result_context);
+ BrowserContext::ForEachStoragePartition(browser_context, cb);
+ DCHECK(result_partition);
+ DCHECK(result_context);
+
+ BrowserThread::PostTask(
+ BrowserThread::WEBKIT_DEPRECATED,
+ FROM_HERE,
+ base::Bind(&IndexedDBInternalsUI::DownloadOriginDataOnWebkitThread,
+ base::Unretained(this),
+ result_partition->GetPath(),
+ result_context,
+ origin_url));
+}
+
+void IndexedDBInternalsUI::DownloadOriginDataOnWebkitThread(
+ const base::FilePath& partition_path,
+ const scoped_refptr<IndexedDBContextImpl> context,
+ const GURL& origin_url) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
+
+ if (!context->IsInOriginSet(origin_url))
+ return;
+
+ context->ForceClose(origin_url);
+
+ base::ScopedTempDir temp_dir;
+ if (!temp_dir.CreateUniqueTempDir())
+ return;
+
+ // This will get cleaned up on the File thread after the download
+ // has completed.
+ base::FilePath temp_path = temp_dir.Take();
+
+ base::string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin_url);
+ base::FilePath::StringType zip_name =
+ webkit_base::WebStringToFilePathString(origin_id);
+ base::FilePath zip_path =
+ temp_path.Append(zip_name).AddExtension(FILE_PATH_LITERAL("zip"));
+
+ // This happens on the "webkit" thread (which is really just the IndexedDB
+ // thread) as a simple way to avoid another script reopening the origin
+ // while we are zipping.
+ zip::Zip(context->GetFilePath(origin_url), zip_path, true);
+
+ BrowserThread::PostTask(BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&IndexedDBInternalsUI::OnDownloadDataReady,
+ base::Unretained(this),
+ partition_path,
+ origin_url,
+ temp_path,
+ zip_path));
+}
+
+void IndexedDBInternalsUI::OnDownloadDataReady(
+ const base::FilePath& partition_path,
+ const GURL& origin_url,
+ const base::FilePath temp_path,
+ const base::FilePath zip_path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ const GURL url = GURL(FILE_PATH_LITERAL("file://") + zip_path.value());
+ BrowserContext* browser_context =
+ web_ui()->GetWebContents()->GetBrowserContext();
+ scoped_ptr<DownloadUrlParameters> dl_params(
+ DownloadUrlParameters::FromWebContents(web_ui()->GetWebContents(), url));
+ DownloadManager* dlm = BrowserContext::GetDownloadManager(browser_context);
+
+ const GURL referrer(web_ui()->GetWebContents()->GetURL());
+ dl_params->set_referrer(
+ content::Referrer(referrer, WebKit::WebReferrerPolicyDefault));
+
+ // This is how to watch for the download to finish: first wait for it
+ // to start, then attach a DownloadItem::Observer to observe the
+ // state change to the finished state.
+ dl_params->set_callback(base::Bind(&IndexedDBInternalsUI::OnDownloadStarted,
+ base::Unretained(this),
+ partition_path,
+ origin_url,
+ temp_path));
+ dlm->DownloadUrl(dl_params.Pass());
+}
+
+// The entire purpose of this class is to delete the temp file after
+// the download is complete.
+class FileDeleter : public DownloadItem::Observer {
+ public:
+ explicit FileDeleter(const base::FilePath& temp_dir) : temp_dir_(temp_dir) {}
+ virtual ~FileDeleter();
+
+ virtual void OnDownloadUpdated(DownloadItem* download) OVERRIDE;
+ virtual void OnDownloadOpened(DownloadItem* item) OVERRIDE {}
+ virtual void OnDownloadRemoved(DownloadItem* item) OVERRIDE {}
+ virtual void OnDownloadDestroyed(DownloadItem* item) OVERRIDE {}
+
+ private:
+ const base::FilePath temp_dir_;
+};
+
+void FileDeleter::OnDownloadUpdated(DownloadItem* item) {
+ switch (item->GetState()) {
+ case DownloadItem::IN_PROGRESS:
+ break;
+ case DownloadItem::COMPLETE:
+ case DownloadItem::CANCELLED:
+ case DownloadItem::INTERRUPTED: {
+ item->RemoveObserver(this);
+ BrowserThread::DeleteOnFileThread::Destruct(this);
+ break;
+ }
+ default:
+ NOTREACHED();
+ }
+}
+
+FileDeleter::~FileDeleter() {
+ base::ScopedTempDir path;
+ bool will_delete ALLOW_UNUSED = path.Set(temp_dir_);
+ DCHECK(will_delete);
+}
+
+void IndexedDBInternalsUI::OnDownloadStarted(
+ const base::FilePath& partition_path,
+ const GURL& origin_url,
+ const base::FilePath& temp_path,
+ DownloadItem* item,
+ net::Error error) {
+
+ if (error != net::OK) {
+ LOG(ERROR) << "Error downloading database dump: "
+ << net::ErrorToString(error);
+ return;
+ }
+
+ item->AddObserver(new FileDeleter(temp_path));
+ web_ui()->CallJavascriptFunction("indexeddb.onOriginDownloadReady",
+ base::StringValue(partition_path.value()),
+ base::StringValue(origin_url.spec()));
+}
+
+} // namespace content
diff --git a/content/browser/indexed_db/indexed_db_internals_ui.h b/content/browser/indexed_db/indexed_db_internals_ui.h
new file mode 100644
index 0000000..bc9a5da
--- /dev/null
+++ b/content/browser/indexed_db/indexed_db_internals_ui.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_INTERNALS_UI_H_
+#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_INTERNALS_UI_H_
+
+#include <vector>
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/public/browser/indexed_db_context.h"
+#include "content/public/browser/web_ui_controller.h"
+#include "net/base/net_errors.h"
+
+namespace base { class ListValue; }
+
+namespace content {
+
+class DownloadItem;
+class IndexedDBContextImpl;
+class StoragePartition;
+
+// The implementation for the chrome://indexeddb-internals page.
+class IndexedDBInternalsUI : public WebUIController {
+ public:
+ explicit IndexedDBInternalsUI(WebUI* web_ui);
+ virtual ~IndexedDBInternalsUI();
+
+ private:
+ typedef std::vector<scoped_refptr<IndexedDBContext> > ContextList;
+ void GetAllOrigins(const base::ListValue* args);
+ void GetAllOriginsOnWebkitThread(
+ const scoped_ptr<ContextList> contexts,
+ const scoped_ptr<std::vector<base::FilePath> > context_paths);
+ void OnOriginsReady(scoped_ptr<std::vector<IndexedDBInfo> > origins,
+ const base::FilePath& path);
+
+ static void AddContextFromStoragePartition(ContextList* contexts,
+ std::vector<base::FilePath>* paths,
+ StoragePartition* partition);
+
+ void DownloadOriginData(const base::ListValue* args);
+ void DownloadOriginDataOnWebkitThread(
+ const base::FilePath& partition_path,
+ const scoped_refptr<IndexedDBContextImpl> context,
+ const GURL& origin_url);
+ void OnDownloadDataReady(const base::FilePath& partition_path,
+ const GURL& origin_url,
+ const base::FilePath temp_path,
+ const base::FilePath zip_path);
+ void OnDownloadStarted(const base::FilePath& partition_path,
+ const GURL& origin_url,
+ const base::FilePath& temp_path,
+ content::DownloadItem* item,
+ net::Error error);
+
+ DISALLOW_COPY_AND_ASSIGN(IndexedDBInternalsUI);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_INTERNALS_UI_H_
diff --git a/content/browser/in_process_webkit/indexed_db_layout_browsertest.cc b/content/browser/indexed_db/indexed_db_layout_browsertest.cc
similarity index 94%
rename from content/browser/in_process_webkit/indexed_db_layout_browsertest.cc
rename to content/browser/indexed_db/indexed_db_layout_browsertest.cc
index e54958d..9f8b83b 100644
--- a/content/browser/in_process_webkit/indexed_db_layout_browsertest.cc
+++ b/content/browser/indexed_db/indexed_db_layout_browsertest.cc
@@ -24,8 +24,7 @@
static const char* kBasicTests[] = {
"basics.html",
"basics-shared-workers.html",
- // Failing on Precise bot (crbug.com/145592).
- // "basics-workers.html",
+ "basics-workers.html",
"database-basics.html",
"factory-basics.html",
"index-basics.html",
@@ -35,8 +34,9 @@
static const char* kComplexTests[] = {
"prefetch-bugfix-108071.html",
- // Flaky: http://crbug.com/123685
- // "pending-version-change-stuck-works-with-terminate.html",
+ // Flaky: http://crbug.com/226256
+ //"pending-version-change-stuck.html",
+ "pending-version-change-stuck-works-with-terminate.html",
"pending-version-change-on-exit.html",
NULL
};
@@ -44,6 +44,7 @@
static const char* kIndexTests[] = {
"deleteIndex.html",
// Flaky: http://crbug.com/123685
+ // Flaky: http://crbug.com/127244
// "index-basics-workers.html",
"index-count.html",
"index-cursor.html",
diff --git a/content/browser/in_process_webkit/indexed_db_quota_client.cc b/content/browser/indexed_db/indexed_db_quota_client.cc
similarity index 96%
rename from content/browser/in_process_webkit/indexed_db_quota_client.cc
rename to content/browser/indexed_db/indexed_db_quota_client.cc
index 3096c95..91b5af1 100644
--- a/content/browser/in_process_webkit/indexed_db_quota_client.cc
+++ b/content/browser/indexed_db/indexed_db_quota_client.cc
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/in_process_webkit/indexed_db_quota_client.h"
+#include "content/browser/indexed_db/indexed_db_quota_client.h"
#include <vector>
#include "base/file_util.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
-#include "content/browser/in_process_webkit/indexed_db_context_impl.h"
+#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/net_util.h"
#include "webkit/database/database_util.h"
diff --git a/content/browser/in_process_webkit/indexed_db_quota_client.h b/content/browser/indexed_db/indexed_db_quota_client.h
similarity index 91%
rename from content/browser/in_process_webkit/indexed_db_quota_client.h
rename to content/browser/indexed_db/indexed_db_quota_client.h
index bf37b95..a7db5a4 100644
--- a/content/browser/in_process_webkit/indexed_db_quota_client.h
+++ b/content/browser/indexed_db/indexed_db_quota_client.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_BROWER_IN_PROCESS_WEBKIT_QUOTA_CLIENT_H_
-#define CONTENT_BROWER_IN_PROCESS_WEBKIT_QUOTA_CLIENT_H_
+#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_QUOTA_CLIENT_H_
+#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_QUOTA_CLIENT_H_
#include <set>
#include <string>
@@ -53,4 +53,4 @@
} // namespace content
-#endif // CONTENT_BROWER_IN_PROCESS_WEBKIT_QUOTA_CLIENT_H_
+#endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_QUOTA_CLIENT_H_
diff --git a/content/browser/in_process_webkit/indexed_db_quota_client_unittest.cc b/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
similarity index 92%
rename from content/browser/in_process_webkit/indexed_db_quota_client_unittest.cc
rename to content/browser/indexed_db/indexed_db_quota_client_unittest.cc
index 197bfc8..ea0aa76 100644
--- a/content/browser/in_process_webkit/indexed_db_quota_client_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
@@ -11,8 +11,8 @@
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "content/browser/browser_thread_impl.h"
-#include "content/browser/in_process_webkit/indexed_db_context_impl.h"
-#include "content/browser/in_process_webkit/indexed_db_quota_client.h"
+#include "content/browser/indexed_db/indexed_db_context_impl.h"
+#include "content/browser/indexed_db/indexed_db_quota_client.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/test/test_browser_context.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -38,13 +38,13 @@
kOriginB("http://host:8000"),
kOriginOther("http://other"),
usage_(0),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
- message_loop_(MessageLoop::TYPE_IO),
+ weak_factory_(this),
+ message_loop_(base::MessageLoop::TYPE_IO),
db_thread_(BrowserThread::DB, &message_loop_),
webkit_thread_(BrowserThread::WEBKIT_DEPRECATED, &message_loop_),
file_thread_(BrowserThread::FILE, &message_loop_),
- file_user_blocking_thread_(
- BrowserThread::FILE_USER_BLOCKING, &message_loop_),
+ file_user_blocking_thread_(BrowserThread::FILE_USER_BLOCKING,
+ &message_loop_),
io_thread_(BrowserThread::IO, &message_loop_) {
browser_context_.reset(new TestBrowserContext());
idb_context_ = static_cast<IndexedDBContextImpl*>(
@@ -68,7 +68,7 @@
// doesn't outlive BrowserThread::WEBKIT_DEPRECATED.
idb_context_ = NULL;
browser_context_.reset();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
}
int64 GetOriginUsage(
@@ -80,7 +80,7 @@
origin, type,
base::Bind(&IndexedDBQuotaClientTest::OnGetOriginUsageComplete,
weak_factory_.GetWeakPtr()));
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_GT(usage_, -1);
return usage_;
}
@@ -94,7 +94,7 @@
type,
base::Bind(&IndexedDBQuotaClientTest::OnGetOriginsComplete,
weak_factory_.GetWeakPtr()));
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
return origins_;
}
@@ -108,7 +108,7 @@
type, host,
base::Bind(&IndexedDBQuotaClientTest::OnGetOriginsComplete,
weak_factory_.GetWeakPtr()));
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
return origins_;
}
@@ -119,7 +119,7 @@
origin_url, kTemp,
base::Bind(&IndexedDBQuotaClientTest::OnDeleteOriginComplete,
weak_factory_.GetWeakPtr()));
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
return delete_status_;
}
@@ -163,7 +163,7 @@
quota::StorageType type_;
scoped_refptr<IndexedDBContextImpl> idb_context_;
base::WeakPtrFactory<IndexedDBQuotaClientTest> weak_factory_;
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
BrowserThreadImpl db_thread_;
BrowserThreadImpl webkit_thread_;
BrowserThreadImpl file_thread_;
diff --git a/content/browser/in_process_webkit/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc
similarity index 95%
rename from content/browser/in_process_webkit/indexed_db_unittest.cc
rename to content/browser/indexed_db/indexed_db_unittest.cc
index 13334fe..869049d 100644
--- a/content/browser/in_process_webkit/indexed_db_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -5,12 +5,12 @@
#include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "content/browser/browser_thread_impl.h"
-#include "content/browser/in_process_webkit/indexed_db_context_impl.h"
+#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/test_browser_context.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabase.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabase.h"
#include "webkit/database/database_util.h"
#include "webkit/quota/mock_special_storage_policy.h"
#include "webkit/quota/quota_manager.h"
@@ -23,14 +23,13 @@
class IndexedDBTest : public testing::Test {
public:
IndexedDBTest()
- : message_loop_(MessageLoop::TYPE_IO),
+ : message_loop_(base::MessageLoop::TYPE_IO),
webkit_thread_(BrowserThread::WEBKIT_DEPRECATED, &message_loop_),
file_thread_(BrowserThread::FILE_USER_BLOCKING, &message_loop_),
- io_thread_(BrowserThread::IO, &message_loop_) {
- }
+ io_thread_(BrowserThread::IO, &message_loop_) {}
protected:
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
private:
BrowserThreadImpl webkit_thread_;
diff --git a/content/browser/loader/buffered_resource_handler.cc b/content/browser/loader/buffered_resource_handler.cc
index b942bb4..c41c911 100644
--- a/content/browser/loader/buffered_resource_handler.cc
+++ b/content/browser/loader/buffered_resource_handler.cc
@@ -201,7 +201,7 @@
NOTREACHED();
break;
case STATE_REPLAYING:
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&BufferedResourceHandler::CallReplayReadCompleted,
weak_ptr_factory_.GetWeakPtr()));
diff --git a/content/browser/loader/global_routing_id.h b/content/browser/loader/global_routing_id.h
new file mode 100644
index 0000000..4715c5a
--- /dev/null
+++ b/content/browser/loader/global_routing_id.h
@@ -0,0 +1,42 @@
+// 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_PUBLIC_BROWSER_GLOBAL_ROUTING_ID_H_
+#define CONTENT_PUBLIC_BROWSER_GLOBAL_ROUTING_ID_H_
+
+namespace content {
+
+// Uniquely identifies the route from which a net::URLRequest comes.
+struct GlobalRoutingID {
+ GlobalRoutingID() : child_id(-1), route_id(-1) {
+ }
+
+ GlobalRoutingID(int child_id, int route_id)
+ : child_id(child_id),
+ route_id(route_id) {
+ }
+
+ // The unique ID of the child process (different from OS's PID).
+ int child_id;
+
+ // The route ID (unique for each URLRequest source).
+ int route_id;
+
+ bool operator<(const GlobalRoutingID& other) const {
+ if (child_id == other.child_id)
+ return route_id < other.route_id;
+ return child_id < other.child_id;
+ }
+ bool operator==(const GlobalRoutingID& other) const {
+ return child_id == other.child_id &&
+ route_id == other.route_id;
+ }
+ bool operator!=(const GlobalRoutingID& other) const {
+ return !(*this == other);
+ }
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_GLOBAL_ROUTING_ID_H_
diff --git a/content/browser/loader/offline_policy.cc b/content/browser/loader/offline_policy.cc
new file mode 100644
index 0000000..9c9361f
--- /dev/null
+++ b/content/browser/loader/offline_policy.cc
@@ -0,0 +1,96 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/loader/offline_policy.h"
+
+#include "base/command_line.h"
+#include "base/metrics/histogram.h"
+#include "content/public/common/content_switches.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_response_info.h"
+#include "net/url_request/url_request.h"
+
+namespace content {
+
+OfflinePolicy::OfflinePolicy()
+ : enabled_(CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableOfflineCacheAccess)),
+ state_(INIT),
+ resource_loads_initiated_(0),
+ resource_loads_successfully_started_(0) {}
+
+OfflinePolicy::~OfflinePolicy() {
+ RecordAndResetStats();
+}
+
+void OfflinePolicy::RecordAndResetStats() {
+ if (enabled_ && OFFLINE == state_ && 0 != resource_loads_initiated_) {
+ UMA_HISTOGRAM_PERCENTAGE(
+ "OfflinePolicy.SuccessfulResourceLoadPercentage",
+ (resource_loads_successfully_started_ * 100 /
+ resource_loads_initiated_));
+ }
+ resource_loads_initiated_ = 0;
+ resource_loads_successfully_started_ = 0;
+}
+
+int OfflinePolicy::GetAdditionalLoadFlags(int current_flags,
+ bool reset_state) {
+ // Don't do anything if offline mode is disabled.
+ if (!enabled_)
+ return 0;
+
+ if (reset_state) {
+ RecordAndResetStats();
+ state_ = INIT;
+ }
+
+ ++resource_loads_initiated_;
+
+ // If a consumer has requested something contradictory, it wins; we
+ // don't modify the load flags.
+ if (current_flags &
+ (net::LOAD_BYPASS_CACHE | net::LOAD_PREFERRING_CACHE |
+ net::LOAD_ONLY_FROM_CACHE | net::LOAD_FROM_CACHE_IF_OFFLINE |
+ net::LOAD_DISABLE_CACHE)) {
+ return 0;
+ }
+
+ switch(state_) {
+ case INIT:
+ return net::LOAD_FROM_CACHE_IF_OFFLINE;
+ case ONLINE:
+ return 0;
+ case OFFLINE:
+ return net::LOAD_ONLY_FROM_CACHE;
+ }
+ NOTREACHED();
+ return 0;
+}
+
+void OfflinePolicy::UpdateStateForSuccessfullyStartedRequest(
+ const net::HttpResponseInfo& response_info) {
+ // Don't do anything if offline mode is disabled.
+ if (!enabled_)
+ return;
+
+ // If we get here, we're going to be providing some amount of information
+ // to the renderer.
+ ++resource_loads_successfully_started_;
+
+ if (state_ != INIT)
+ // We've already made the decision for the rest of this set
+ // of navigations.
+ return;
+
+ if (response_info.server_data_unavailable) {
+ state_ = OFFLINE;
+ } else if (response_info.network_accessed) {
+ // If we got the response from the network or validated it as part
+ // of this request, that means our connection to the host is working.
+ state_ = ONLINE;
+ }
+}
+
+} // namespace content
diff --git a/content/browser/loader/offline_policy.h b/content/browser/loader/offline_policy.h
new file mode 100644
index 0000000..975d4ad
--- /dev/null
+++ b/content/browser/loader/offline_policy.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_LOADER_OFFLINE_POLICY
+#define CONTENT_BROWSER_LOADER_OFFLINE_POLICY
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "content/common/content_export.h"
+
+struct ResourceHostMsg_Request;
+
+namespace net {
+class HttpResponseInfo;
+class URLRequest;
+}
+
+namespace content {
+
+// This class controls under what conditions resources will be fetched
+// from cache even if stale rather than from the network. For example,
+// one policy would be that if requests for a particular route (e.g. "tab")
+// is unable to reach the server, other requests made with the same route
+// can be loaded from cache without first requiring a network timeout.
+//
+// There is a single OfflinePolicy object per user navigation unit
+// (generally a tab).
+class CONTENT_EXPORT OfflinePolicy {
+ public:
+ OfflinePolicy();
+ ~OfflinePolicy();
+
+ // Return any additional load flags to be ORed for a request from
+ // this route with the given |resource_type|. |reset_state| indicates
+ // that this request should reinitialized the internal state for this
+ // policy object (e.g. in the case of a main frame load).
+ int GetAdditionalLoadFlags(int current_flags, bool reset_state);
+
+ // Incorporate online/offline information from a successfully started request.
+ void UpdateStateForSuccessfullyStartedRequest(
+ const net::HttpResponseInfo& response_info);
+
+private:
+ enum State { INIT, ONLINE, OFFLINE };
+
+ void RecordAndResetStats();
+
+ bool enabled_;
+ State state_;
+ int resource_loads_initiated_;
+ int resource_loads_successfully_started_;
+
+ DISALLOW_COPY_AND_ASSIGN(OfflinePolicy);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_LOADER_OFFLINE_POLICY
diff --git a/content/browser/loader/offline_policy_unittest.cc b/content/browser/loader/offline_policy_unittest.cc
new file mode 100644
index 0000000..18c09df
--- /dev/null
+++ b/content/browser/loader/offline_policy_unittest.cc
@@ -0,0 +1,96 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/loader/offline_policy.h"
+
+#include "base/command_line.h"
+#include "content/public/common/content_switches.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_response_info.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/glue/resource_type.h"
+
+namespace content {
+
+class OfflinePolicyTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableOfflineCacheAccess);
+ policy_ = new OfflinePolicy;
+ }
+
+ virtual void TearDown() {
+ delete policy_;
+ policy_ = NULL;
+ }
+
+ OfflinePolicy* policy_;
+};
+
+// Confirm that the initial state of an offline object is to return
+// LOAD_FROM_CACHE_IF_OFFLINE until it gets changed.
+TEST_F(OfflinePolicyTest, InitialState) {
+ // Two loads without any reset, no UpdateStateForSuccessfullyStartedRequest.
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, true));
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, false));
+}
+
+// Completion without any network probing doesn't change result value.
+TEST_F(OfflinePolicyTest, CompletedUncertain) {
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, true));
+ net::HttpResponseInfo response_info;
+ policy_->UpdateStateForSuccessfullyStartedRequest(response_info);
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, false));
+}
+
+// Completion with a failed network probe changes result value.
+TEST_F(OfflinePolicyTest, CompletedNoNetwork) {
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, true));
+ net::HttpResponseInfo response_info;
+ response_info.server_data_unavailable = true;
+ policy_->UpdateStateForSuccessfullyStartedRequest(response_info);
+ EXPECT_EQ(net::LOAD_ONLY_FROM_CACHE,
+ policy_->GetAdditionalLoadFlags(0, false));
+}
+
+// Completion with a successful network probe changes result value.
+TEST_F(OfflinePolicyTest, CompletedNetwork) {
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, true));
+ net::HttpResponseInfo response_info;
+ response_info.network_accessed = true;
+ policy_->UpdateStateForSuccessfullyStartedRequest(response_info);
+ EXPECT_EQ(0, policy_->GetAdditionalLoadFlags(0, false));
+}
+
+// A new navigation resets a state change.
+TEST_F(OfflinePolicyTest, NewNavigationReset) {
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, true));
+ net::HttpResponseInfo response_info;
+ response_info.network_accessed = true;
+ policy_->UpdateStateForSuccessfullyStartedRequest(response_info);
+ EXPECT_EQ(0, policy_->GetAdditionalLoadFlags(0, false));
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, true));
+ EXPECT_EQ(net::LOAD_FROM_CACHE_IF_OFFLINE,
+ policy_->GetAdditionalLoadFlags(0, false));
+}
+
+// Cache related flags inhibit the returning of any special flags.
+TEST_F(OfflinePolicyTest, ConsumerFlagOverride) {
+ EXPECT_EQ(0, policy_->GetAdditionalLoadFlags(net::LOAD_BYPASS_CACHE, true));
+ net::HttpResponseInfo response_info;
+ response_info.server_data_unavailable = true;
+ policy_->UpdateStateForSuccessfullyStartedRequest(response_info);
+ EXPECT_EQ(0, policy_->GetAdditionalLoadFlags(net::LOAD_BYPASS_CACHE, false));
+}
+
+}
diff --git a/content/browser/loader/redirect_to_file_resource_handler.cc b/content/browser/loader/redirect_to_file_resource_handler.cc
index f3f81dd..4ab04ea 100644
--- a/content/browser/loader/redirect_to_file_resource_handler.cc
+++ b/content/browser/loader/redirect_to_file_resource_handler.cc
@@ -58,7 +58,7 @@
int process_id,
ResourceDispatcherHostImpl* host)
: LayeredResourceHandler(next_handler.Pass()),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+ weak_factory_(this),
host_(host),
process_id_(process_id),
request_id_(-1),
diff --git a/content/browser/loader/render_view_host_tracker.cc b/content/browser/loader/render_view_host_tracker.cc
index 89a771b..2f006e8 100644
--- a/content/browser/loader/render_view_host_tracker.cc
+++ b/content/browser/loader/render_view_host_tracker.cc
@@ -9,44 +9,36 @@
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_scheduler.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
namespace content {
-RenderViewHostTracker::RenderViewHostTracker() {
+RenderViewHostTracker::RenderViewHostTracker()
+ : rvh_created_callback_(
+ base::Bind(&RenderViewHostTracker::RenderViewHostCreated,
+ base::Unretained(this))) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- registrar_.Add(this, NOTIFICATION_RENDER_VIEW_HOST_CREATED,
- NotificationService::AllSources());
+ RenderViewHost::AddCreatedCallback(rvh_created_callback_);
}
RenderViewHostTracker::~RenderViewHostTracker() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(observers_.empty());
+ RenderViewHost::RemoveCreatedCallback(rvh_created_callback_);
}
-void RenderViewHostTracker::Observe(
- int type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- RenderViewHost* rvh = content::Source<RenderViewHost>(source).ptr();
+void RenderViewHostTracker::RenderViewHostCreated(RenderViewHost* rvh) {
+ Observer* observer = new Observer(rvh, this);
+ observers_.insert(observer);
+
int child_id = rvh->GetProcess()->GetID();
int route_id = rvh->GetRoutingID();
-
- switch (type) {
- case NOTIFICATION_RENDER_VIEW_HOST_CREATED:
- Observer* observer = new Observer(rvh, this);
- observers_.insert(observer);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&ResourceDispatcherHostImpl::OnRenderViewHostCreated,
- base::Unretained(ResourceDispatcherHostImpl::Get()),
- child_id, route_id));
- break;
- }
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&ResourceDispatcherHostImpl::OnRenderViewHostCreated,
+ base::Unretained(ResourceDispatcherHostImpl::Get()),
+ child_id, route_id));
}
void RenderViewHostTracker::RemoveObserver(Observer* observer) {
diff --git a/content/browser/loader/render_view_host_tracker.h b/content/browser/loader/render_view_host_tracker.h
index bab36de..7fc5fa0 100644
--- a/content/browser/loader/render_view_host_tracker.h
+++ b/content/browser/loader/render_view_host_tracker.h
@@ -7,8 +7,7 @@
#include <set>
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_view_host_observer.h"
namespace content {
@@ -18,12 +17,13 @@
// operates on the IO thread. RenderViewHostTracker listens for renderer
// notifications on the UI thread, then bounces them over to the IO thread so
// the ResourceDispatcherHost can be notified.
-class CONTENT_EXPORT RenderViewHostTracker : public NotificationObserver {
+class CONTENT_EXPORT RenderViewHostTracker {
public:
RenderViewHostTracker();
virtual ~RenderViewHostTracker();
private:
+ // TODO(phajdan.jr): Move this declaration of inner class to the .cc file.
class Observer : public RenderViewHostObserver {
public:
Observer(RenderViewHost* rvh,
@@ -40,14 +40,11 @@
friend class Observer;
typedef std::set<Observer*> ObserverSet;
- // NotificationObserver interface:
- virtual void Observe(int type,
- const NotificationSource& source,
- const NotificationDetails& details) OVERRIDE;
+ void RenderViewHostCreated(RenderViewHost* rvh);
void RemoveObserver(Observer* observer);
- content::NotificationRegistrar registrar_;
+ RenderViewHost::CreatedCallback rvh_created_callback_;
ObserverSet observers_;
};
diff --git a/content/browser/loader/resource_dispatcher_host_browsertest.cc b/content/browser/loader/resource_dispatcher_host_browsertest.cc
index 282fecc..68aded9 100644
--- a/content/browser/loader/resource_dispatcher_host_browsertest.cc
+++ b/content/browser/loader/resource_dispatcher_host_browsertest.cc
@@ -20,7 +20,7 @@
#include "content/test/net/url_request_failed_job.h"
#include "content/test/net/url_request_mock_http_job.h"
#include "net/base/net_errors.h"
-#include "net/test/test_server.h"
+#include "net/test/spawned_test_server.h"
namespace content {
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 3849313..5b1a4db 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -18,6 +18,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/sparse_histogram.h"
#include "base/shared_memory.h"
#include "base/stl_util.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
@@ -67,7 +68,7 @@
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_message_start.h"
#include "net/base/auth.h"
-#include "net/base/cert_status_flags.h"
+#include "net/cert/cert_status_flags.h"
#include "net/base/load_flags.h"
#include "net/base/mime_util.h"
#include "net/base/net_errors.h"
@@ -231,8 +232,10 @@
return net_error;
}
-int BuildLoadFlagsForRequest(const ResourceHostMsg_Request& request_data,
- int child_id, bool is_sync_load) {
+int BuildLoadFlagsForRequest(
+ const ResourceHostMsg_Request& request_data,
+ int child_id,
+ bool is_sync_load) {
int load_flags = request_data.load_flags;
// Although EV status is irrelevant to sub-frames and sub-resources, we have
@@ -414,11 +417,13 @@
for (LoaderList::iterator i = loaders_to_cancel.begin();
i != loaders_to_cancel.end(); ++i) {
// There is no strict requirement that this be the case, but currently
- // downloads and transferred requests are the only requests that aren't
- // cancelled when the associated processes go away. It may be OK for this
- // invariant to change in the future, but if this assertion fires without
- // the invariant changing, then it's indicative of a leak.
- DCHECK((*i)->GetRequestInfo()->is_download() || (*i)->is_transferring());
+ // downloads, streams and transferred requests are the only requests that
+ // aren't cancelled when the associated processes go away. It may be OK for
+ // this invariant to change in the future, but if this assertion fires
+ // without the invariant changing, then it's indicative of a leak.
+ DCHECK((*i)->GetRequestInfo()->is_download() ||
+ (*i)->GetRequestInfo()->is_stream() ||
+ (*i)->is_transferring());
}
#endif
@@ -463,7 +468,7 @@
base::debug::Alias(url_buf);
CHECK(ContainsKey(active_resource_contexts_, context));
- request->set_referrer(MaybeStripReferrer(GURL(request->referrer())).spec());
+ request->SetReferrer(MaybeStripReferrer(GURL(request->referrer())).spec());
int extra_load_flags = net::LOAD_IS_DOWNLOAD;
if (prefer_cache) {
// If there is upload data attached, only retrieve from cache because there
@@ -478,6 +483,13 @@
extra_load_flags |= net::LOAD_DISABLE_CACHE;
}
request->set_load_flags(request->load_flags() | extra_load_flags);
+
+ // No need to get offline load flags for downloads, but make sure
+ // we have an OfflinePolicy to receive request completions.
+ GlobalRoutingID id(child_id, route_id);
+ if (!offline_policy_map_[id])
+ offline_policy_map_[id] = new OfflinePolicy();
+
// Check if the renderer is permitted to request the requested URL.
if (!ChildProcessSecurityPolicyImpl::GetInstance()->
CanRequestURL(child_id, url)) {
@@ -700,6 +712,12 @@
void ResourceDispatcherHostImpl::DidReceiveResponse(ResourceLoader* loader) {
ResourceRequestInfoImpl* info = loader->GetRequestInfo();
+ // There should be an entry in the map created when we dispatched the
+ // request.
+ GlobalRoutingID routing_id(info->GetGlobalRoutingID());
+ DCHECK(offline_policy_map_.end() != offline_policy_map_.find(routing_id));
+ offline_policy_map_[routing_id]->UpdateStateForSuccessfullyStartedRequest(
+ loader->request()->response_info());
int render_process_id, render_view_id;
if (!info->GetAssociatedRenderView(&render_process_id, &render_view_id))
@@ -724,27 +742,26 @@
if (info->GetResourceType() == ResourceType::MAIN_FRAME) {
// This enumeration has "3" appended to its name to distinguish it from
// older versions.
- UMA_HISTOGRAM_CUSTOM_ENUMERATION(
+ UMA_HISTOGRAM_SPARSE_SLOWLY(
"Net.ErrorCodesForMainFrame3",
- -loader->request()->status().error(),
- base::CustomHistogram::ArrayToCustomRanges(
- kAllNetErrorCodes, arraysize(kAllNetErrorCodes)));
+ -loader->request()->status().error());
if (loader->request()->url().SchemeIsSecure() &&
loader->request()->url().host() == "www.google.com") {
- UMA_HISTOGRAM_CUSTOM_ENUMERATION(
+ UMA_HISTOGRAM_SPARSE_SLOWLY(
"Net.ErrorCodesForHTTPSGoogleMainFrame2",
- -loader->request()->status().error(),
- base::CustomHistogram::ArrayToCustomRanges(
- kAllNetErrorCodes, arraysize(kAllNetErrorCodes)));
+ -loader->request()->status().error());
}
} else {
+ if (info->GetResourceType() == ResourceType::IMAGE) {
+ UMA_HISTOGRAM_SPARSE_SLOWLY(
+ "Net.ErrorCodesForImages",
+ -loader->request()->status().error());
+ }
// This enumeration has "2" appended to distinguish it from older versions.
- UMA_HISTOGRAM_CUSTOM_ENUMERATION(
+ UMA_HISTOGRAM_SPARSE_SLOWLY(
"Net.ErrorCodesForSubresources2",
- -loader->request()->status().error(),
- base::CustomHistogram::ArrayToCustomRanges(
- kAllNetErrorCodes, arraysize(kAllNetErrorCodes)));
+ -loader->request()->status().error());
}
// Destroy the ResourceLoader.
@@ -787,17 +804,17 @@
// Note that we have to do this in 2 passes as we cannot call
// CancelBlockedRequestsForRoute while iterating over
// blocked_loaders_map_, as it modifies it.
- std::set<ProcessRouteIDs> ids;
+ std::set<GlobalRoutingID> ids;
for (BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.begin();
iter != blocked_loaders_map_.end(); ++iter) {
- std::pair<std::set<ProcessRouteIDs>::iterator, bool> result =
+ std::pair<std::set<GlobalRoutingID>::iterator, bool> result =
ids.insert(iter->first);
// We should not have duplicates.
DCHECK(result.second);
}
- for (std::set<ProcessRouteIDs>::const_iterator iter = ids.begin();
+ for (std::set<GlobalRoutingID>::const_iterator iter = ids.begin();
iter != ids.end(); ++iter) {
- CancelBlockedRequestsForRoute(iter->first, iter->second);
+ CancelBlockedRequestsForRoute(iter->child_id, iter->route_id);
}
scheduler_.reset();
@@ -934,6 +951,12 @@
int load_flags =
BuildLoadFlagsForRequest(request_data, child_id, is_sync_load);
+ GlobalRoutingID id(child_id, route_id);
+ if (!offline_policy_map_[id])
+ offline_policy_map_[id] = new OfflinePolicy();
+ load_flags |= offline_policy_map_[id]->GetAdditionalLoadFlags(
+ load_flags, request_data.resource_type == ResourceType::MAIN_FRAME);
+
// Construct the request.
scoped_ptr<net::URLRequest> new_request;
net::URLRequest* request;
@@ -951,7 +974,7 @@
request->set_method(request_data.method);
request->set_first_party_for_cookies(request_data.first_party_for_cookies);
- request->set_referrer(referrer.url.spec());
+ request->SetReferrer(referrer.url.spec());
webkit_glue::ConfigureURLRequestForReferrerPolicy(request,
referrer.policy);
net::HttpRequestHeaders headers;
@@ -1267,13 +1290,19 @@
scoped_ptr<net::URLRequest> request(
request_context->CreateRequest(url, NULL));
request->set_method("GET");
- request->set_referrer(MaybeStripReferrer(referrer.url).spec());
+ request->SetReferrer(MaybeStripReferrer(referrer.url).spec());
webkit_glue::ConfigureURLRequestForReferrerPolicy(request.get(),
referrer.policy);
// So far, for saving page, we need fetch content from cache, in the
// future, maybe we can use a configuration to configure this behavior.
request->set_load_flags(net::LOAD_PREFERRING_CACHE);
+ // No need to get offline load flags for save files, but make sure
+ // we have an OfflinePolicy to receive request completions.
+ GlobalRoutingID id(child_id, route_id);
+ if (!offline_policy_map_[id])
+ offline_policy_map_[id] = new OfflinePolicy();
+
// Since we're just saving some resources we need, disallow downloading.
ResourceRequestInfoImpl* extra_info =
CreateRequestInfo(child_id, route_id, false, context);
@@ -1324,7 +1353,8 @@
// Don't cancel navigations that are transferring to another process,
// since they belong to another process now.
- if (!info->is_download() && !IsTransferredNavigation(id) &&
+ if (!info->is_download() && !info->is_stream() &&
+ !IsTransferredNavigation(id) &&
(route_id == -1 || route_id == info->GetRouteID())) {
matching_requests.push_back(id);
}
@@ -1348,7 +1378,7 @@
// Now deal with blocked requests if any.
if (route_id != -1) {
- if (blocked_loaders_map_.find(ProcessRouteIDs(child_id, route_id)) !=
+ if (blocked_loaders_map_.find(GlobalRoutingID(child_id, route_id)) !=
blocked_loaders_map_.end()) {
CancelBlockedRequestsForRoute(child_id, route_id);
}
@@ -1360,14 +1390,35 @@
std::set<int> route_ids;
for (BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.begin();
iter != blocked_loaders_map_.end(); ++iter) {
- if (iter->first.first == child_id)
- route_ids.insert(iter->first.second);
+ if (iter->first.child_id == child_id)
+ route_ids.insert(iter->first.route_id);
}
for (std::set<int>::const_iterator iter = route_ids.begin();
iter != route_ids.end(); ++iter) {
CancelBlockedRequestsForRoute(child_id, *iter);
}
}
+
+ // Cleanup the offline state for the route.
+ if (-1 != route_id) {
+ OfflineMap::iterator it = offline_policy_map_.find(
+ GlobalRoutingID(child_id, route_id));
+ if (offline_policy_map_.end() != it) {
+ delete it->second;
+ offline_policy_map_.erase(it);
+ }
+ } else {
+ for (OfflineMap::iterator it = offline_policy_map_.begin();
+ offline_policy_map_.end() != it;) {
+ // Increment iterator so deletion doesn't invalidate it.
+ OfflineMap::iterator current_it = it++;
+
+ if (child_id == current_it->first.child_id) {
+ delete current_it->second;
+ offline_policy_map_.erase(current_it);
+ }
+ }
+ }
}
// Cancels the request and removes it from the list.
@@ -1394,7 +1445,7 @@
pending_loaders_.erase(iter);
// If we have no more pending requests, then stop the load state monitor
- if (pending_loaders_.empty() && update_load_states_timer_.get())
+ if (pending_loaders_.empty() && update_load_states_timer_)
update_load_states_timer_->Stop();
}
@@ -1499,8 +1550,8 @@
linked_ptr<ResourceLoader> loader(
new ResourceLoader(request.Pass(), handler.Pass(), this));
- ProcessRouteIDs pair_id(info->GetChildID(), info->GetRouteID());
- BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(pair_id);
+ GlobalRoutingID id(info->GetGlobalRoutingID());
+ BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(id);
if (iter != blocked_loaders_map_.end()) {
// The request should be blocked.
iter->second->push_back(loader);
@@ -1562,8 +1613,8 @@
uint64 upload_size;
};
-// Map from ProcessID+ViewID pair to LoadState
-typedef std::map<std::pair<int, int>, LoadInfo> LoadInfoMap;
+// Map from ProcessID+RouteID pair to LoadState
+typedef std::map<GlobalRoutingID, LoadInfo> LoadInfoMap;
// Used to marshal calls to LoadStateChanged from the IO to UI threads. We do
// them all as a single callback to avoid spamming the UI thread.
@@ -1571,7 +1622,7 @@
LoadInfoMap::const_iterator i;
for (i = info_map.begin(); i != info_map.end(); ++i) {
RenderViewHostImpl* view =
- RenderViewHostImpl::FromID(i->first.first, i->first.second);
+ RenderViewHostImpl::FromID(i->first.child_id, i->first.route_id);
if (view) // The view could be gone at this point.
view->LoadStateChanged(i->second.url, i->second.load_state,
i->second.upload_position,
@@ -1590,16 +1641,16 @@
// Determine the largest upload size of all requests
// in each View (good chance it's zero).
- std::map<std::pair<int, int>, uint64> largest_upload_size;
+ std::map<GlobalRoutingID, uint64> largest_upload_size;
for (i = pending_loaders_.begin(); i != pending_loaders_.end(); ++i) {
net::URLRequest* request = i->second->request();
ResourceRequestInfoImpl* info = i->second->GetRequestInfo();
uint64 upload_size = request->GetUploadProgress().size();
if (request->GetLoadState().state != net::LOAD_STATE_SENDING_REQUEST)
upload_size = 0;
- std::pair<int, int> key(info->GetChildID(), info->GetRouteID());
- if (upload_size && largest_upload_size[key] < upload_size)
- largest_upload_size[key] = upload_size;
+ GlobalRoutingID id(info->GetGlobalRoutingID());
+ if (upload_size && largest_upload_size[id] < upload_size)
+ largest_upload_size[id] = upload_size;
}
for (i = pending_loaders_.begin(); i != pending_loaders_.end(); ++i) {
@@ -1612,23 +1663,23 @@
// progress ipc messages to the plugin process.
i->second->ReportUploadProgress();
- std::pair<int, int> key(info->GetChildID(), info->GetRouteID());
+ GlobalRoutingID id(info->GetGlobalRoutingID());
// If a request is uploading data, ignore all other requests so that the
// upload progress takes priority for being shown in the status bar.
- if (largest_upload_size.find(key) != largest_upload_size.end() &&
- progress.size() < largest_upload_size[key])
+ if (largest_upload_size.find(id) != largest_upload_size.end() &&
+ progress.size() < largest_upload_size[id])
continue;
net::LoadStateWithParam to_insert = load_state;
- LoadInfoMap::iterator existing = info_map.find(key);
+ LoadInfoMap::iterator existing = info_map.find(id);
if (existing != info_map.end()) {
to_insert =
MoreInterestingLoadState(existing->second.load_state, load_state);
if (to_insert.state == existing->second.load_state.state)
continue;
}
- LoadInfo& load_info = info_map[key];
+ LoadInfo& load_info = info_map[id];
load_info.url = request->url();
load_info.load_state = to_insert;
load_info.upload_size = progress.size();
@@ -1646,7 +1697,7 @@
void ResourceDispatcherHostImpl::BlockRequestsForRoute(int child_id,
int route_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- ProcessRouteIDs key(child_id, route_id);
+ GlobalRoutingID key(child_id, route_id);
DCHECK(blocked_loaders_map_.find(key) == blocked_loaders_map_.end()) <<
"BlockRequestsForRoute called multiple time for the same RVH";
blocked_loaders_map_[key] = new BlockedLoadersList();
@@ -1667,7 +1718,7 @@
int route_id,
bool cancel_requests) {
BlockedLoadersMap::iterator iter = blocked_loaders_map_.find(
- std::pair<int, int>(child_id, route_id));
+ GlobalRoutingID(child_id, route_id));
if (iter == blocked_loaders_map_.end()) {
// It's possible to reach here if the renderer crashed while an interstitial
// page was showing.
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h
index 5dc36e6..b459ec8 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.h
+++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -25,6 +25,8 @@
#include "base/time.h"
#include "base/timer.h"
#include "content/browser/download/download_resource_handler.h"
+#include "content/browser/loader/global_routing_id.h"
+#include "content/browser/loader/offline_policy.h"
#include "content/browser/loader/render_view_host_tracker.h"
#include "content/browser/loader/resource_loader.h"
#include "content/browser/loader/resource_loader_delegate.h"
@@ -32,6 +34,7 @@
#include "content/common/content_export.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/download_id.h"
+#include "content/public/browser/global_request_id.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "ipc/ipc_message.h"
@@ -60,7 +63,6 @@
class SaveFileManager;
class WebContentsImpl;
struct DownloadSaveInfo;
-struct GlobalRequestID;
struct Referrer;
class CONTENT_EXPORT ResourceDispatcherHostImpl
@@ -409,8 +411,7 @@
bool is_shutdown_;
typedef std::vector<linked_ptr<ResourceLoader> > BlockedLoadersList;
- typedef std::pair<int, int> ProcessRouteIDs;
- typedef std::map<ProcessRouteIDs, BlockedLoadersList*> BlockedLoadersMap;
+ typedef std::map<GlobalRoutingID, BlockedLoadersList*> BlockedLoadersMap;
BlockedLoadersMap blocked_loaders_map_;
// Maps the child_ids to the approximate number of bytes
@@ -452,6 +453,10 @@
RenderViewHostTracker tracker_; // Lives on UI thread.
+ typedef std::map<GlobalRoutingID, OfflinePolicy*> OfflineMap;
+
+ OfflineMap offline_policy_map_;
+
DISALLOW_COPY_AND_ASSIGN(ResourceDispatcherHostImpl);
};
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc
index 329c939..5e1b440 100644
--- a/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -113,7 +113,7 @@
// Spin up the message loop to kick off the request.
static void KickOffRequest() {
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
}
// We may want to move this to a shared space if it is useful for something else
@@ -497,7 +497,7 @@
int route_id,
bool is_continuation_of_transferred_request,
ScopedVector<ResourceThrottle>* throttles) OVERRIDE {
- if (user_data_.get()) {
+ if (user_data_) {
const void* key = user_data_.get();
request->SetUserData(key, user_data_.release());
}
@@ -535,6 +535,14 @@
filter_ = new ForwardingFilter(
this, browser_context_->GetResourceContext());
}
+
+ virtual ~ResourceDispatcherHostTest() {
+ for (std::set<int>::iterator it = child_ids_.begin();
+ it != child_ids_.end(); ++it) {
+ host_.CancelRequestsForProcess(*it);
+ }
+ }
+
// IPC::Sender implementation
virtual bool Send(IPC::Message* msg) OVERRIDE {
accum_.AddMessage(*msg);
@@ -699,12 +707,12 @@
scoped_ptr<IPC::Message> ack(
new ResourceHostMsg_DataReceived_ACK(msg.routing_id(), request_id));
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&GenerateIPCMessage, filter_, base::Passed(&ack)));
}
- MessageLoopForIO message_loop_;
+ base::MessageLoopForIO message_loop_;
BrowserThreadImpl ui_thread_;
BrowserThreadImpl file_thread_;
BrowserThreadImpl cache_thread_;
@@ -719,6 +727,7 @@
net::URLRequest::ProtocolFactory* old_factory_;
ResourceType::Type resource_type_;
bool send_data_received_acks_;
+ std::set<int> child_ids_;
static ResourceDispatcherHostTest* test_fixture_;
static bool delay_start_;
static bool delay_complete_;
@@ -741,6 +750,9 @@
int render_view_id,
int request_id,
const GURL& url) {
+ // If it's already there, this'll be dropped on the floor, which is fine.
+ child_ids_.insert(filter->child_id());
+
ResourceHostMsg_Request request =
CreateResourceRequest("GET", resource_type_, url);
ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
@@ -865,7 +877,7 @@
// flush all the pending requests
while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
@@ -905,7 +917,7 @@
// flush all the pending requests
while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(was_deleted);
@@ -923,7 +935,7 @@
// flush all the pending requests
while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
ResourceIPCAccumulator::ClassifiedMessages msgs;
accum_.GetClassifiedMessages(&msgs);
@@ -950,7 +962,7 @@
// flush all the pending requests
while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(0, host_.pending_requests());
}
@@ -979,7 +991,7 @@
ASSERT_FALSE(GenericResourceThrottle::active_throttle());
// The request is started asynchronously.
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
// Flush all the pending requests.
while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
@@ -1009,7 +1021,7 @@
// flush all the pending requests
while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
@@ -1080,7 +1092,7 @@
// Make sure all requests have finished stage one. test_url_1 will have
// finished.
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
// TODO(mbelshe):
// Now that the async IO path is in place, the IO always completes on the
@@ -1288,7 +1300,7 @@
ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
// Add 9 bytes of referrer.
- req.set_referrer("123456789");
+ req.SetReferrer("123456789");
EXPECT_EQ(4436,
ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
@@ -1384,7 +1396,7 @@
// Flush all the pending requests.
while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id()));
@@ -1733,14 +1745,13 @@
// Temporarily replace ContentBrowserClient with one that will trigger the
// transfer navigation code paths.
- ContentBrowserClient* old_client = GetContentClient()->browser();
TransfersAllNavigationsContentBrowserClient new_client;
- GetContentClient()->set_browser_for_testing(&new_client);
+ ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
// Restore.
- GetContentClient()->set_browser_for_testing(old_client);
+ SetBrowserClientForTesting(old_client);
// This second filter is used to emulate a second process.
scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
@@ -1760,11 +1771,13 @@
request.transferred_request_child_id = filter_->child_id();
request.transferred_request_request_id = request_id;
+ // For cleanup.
+ child_ids_.insert(second_filter->child_id());
ResourceHostMsg_RequestResource transfer_request_msg(
new_render_view_id, new_request_id, request);
bool msg_was_ok;
host_.OnMessageReceived(transfer_request_msg, second_filter, &msg_was_ok);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
// Flush all the pending requests.
while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
@@ -1792,14 +1805,13 @@
// Temporarily replace ContentBrowserClient with one that will trigger the
// transfer navigation code paths.
- ContentBrowserClient* old_client = GetContentClient()->browser();
TransfersAllNavigationsContentBrowserClient new_client;
- GetContentClient()->set_browser_for_testing(&new_client);
+ ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
// Restore.
- GetContentClient()->set_browser_for_testing(old_client);
+ SetBrowserClientForTesting(old_client);
// This second filter is used to emulate a second process.
scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
@@ -1821,11 +1833,13 @@
request.transferred_request_child_id = filter_->child_id();
request.transferred_request_request_id = request_id;
+ // For cleanup.
+ child_ids_.insert(second_filter->child_id());
ResourceHostMsg_RequestResource transfer_request_msg(
new_render_view_id, new_request_id, request);
bool msg_was_ok;
host_.OnMessageReceived(transfer_request_msg, second_filter, &msg_was_ok);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
// Response data for "http://other.com/blerg":
const std::string kResponseBody = "hello world";
@@ -1836,7 +1850,7 @@
// OK, let the redirect happen.
SetDelayedStartJobGeneration(false);
CompleteStartRequest(second_filter, new_request_id);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
// Flush all the pending requests.
while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
@@ -1845,7 +1859,7 @@
ResourceHostMsg_FollowRedirect redirect_msg(
new_render_view_id, new_request_id, false, GURL());
host_.OnMessageReceived(redirect_msg, second_filter, &msg_was_ok);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
// Flush all the pending requests.
while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
@@ -1954,7 +1968,7 @@
host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
}
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
msgs.clear();
accum_.GetClassifiedMessages(&msgs);
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc
index a88aa05..6319512 100644
--- a/content/browser/loader/resource_loader.cc
+++ b/content/browser/loader/resource_loader.cc
@@ -437,14 +437,14 @@
request_->FollowDeferredRedirect();
break;
case DEFERRED_READ:
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&ResourceLoader::ResumeReading,
weak_ptr_factory_.GetWeakPtr()));
break;
case DEFERRED_FINISH:
// Delay self-destruction since we don't know how we were reached.
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&ResourceLoader::CallDidFinishLoading,
weak_ptr_factory_.GetWeakPtr()));
@@ -493,9 +493,10 @@
// If the request isn't in flight, then we won't get an asynchronous
// notification from the request, so we have to signal ourselves to finish
// this request.
- MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&ResourceLoader::ResponseCompleted,
- weak_ptr_factory_.GetWeakPtr()));
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&ResourceLoader::ResponseCompleted,
+ weak_ptr_factory_.GetWeakPtr()));
}
}
@@ -529,7 +530,7 @@
response->head.mime_type == "text/html" &&
!request_->url().SchemeIs(chrome::kChromeUIScheme) &&
!SiteInstance::IsSameWebSite(NULL, request_->url(),
- request_->GetSanitizedReferrer())) {
+ GURL(request_->referrer()))) {
response->head.mime_type = "application/browser-plugin";
}
@@ -572,11 +573,12 @@
} else {
// Else, trigger OnReadCompleted asynchronously to avoid starving the IO
// thread in case the URLRequest can provide data synchronously.
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&ResourceLoader::OnReadCompleted,
weak_ptr_factory_.GetWeakPtr(),
- request_.get(), bytes_read));
+ request_.get(),
+ bytes_read));
}
}
diff --git a/content/browser/loader/resource_loader_unittest.cc b/content/browser/loader/resource_loader_unittest.cc
index 781b62c..84e57a5 100644
--- a/content/browser/loader/resource_loader_unittest.cc
+++ b/content/browser/loader/resource_loader_unittest.cc
@@ -10,7 +10,7 @@
#include "content/public/browser/resource_request_info.h"
#include "content/public/test/mock_resource_context.h"
#include "content/test/test_content_browser_client.h"
-#include "net/base/x509_certificate.h"
+#include "net/cert/x509_certificate.h"
#include "net/ssl/client_cert_store.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/url_request/url_request.h"
@@ -146,9 +146,9 @@
protected:
// testing::Test:
virtual void SetUp() OVERRIDE {
- message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO));
- ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI,
- message_loop_.get()));
+ message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO));
+ ui_thread_.reset(
+ new BrowserThreadImpl(BrowserThread::UI, message_loop_.get()));
io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
message_loop_.get()));
}
@@ -179,7 +179,7 @@
virtual void DidReceiveResponse(ResourceLoader* loader) OVERRIDE {}
virtual void DidFinishLoading(ResourceLoader* loader) OVERRIDE {}
- scoped_ptr<MessageLoop> message_loop_;
+ scoped_ptr<base::MessageLoop> message_loop_;
scoped_ptr<BrowserThreadImpl> ui_thread_;
scoped_ptr<BrowserThreadImpl> io_thread_;
@@ -230,9 +230,8 @@
cert_request_info->cert_authorities = dummy_authority;
// Plug in test content browser client.
- ContentBrowserClient* old_client = GetContentClient()->browser();
SelectCertificateBrowserClient test_client;
- GetContentClient()->set_browser_for_testing(&test_client);
+ ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client);
// Everything is set up. Trigger the resource loader certificate request event
// and run the message loop.
@@ -240,7 +239,7 @@
message_loop_->RunUntilIdle();
// Restore the original content browser client.
- GetContentClient()->set_browser_for_testing(old_client);
+ SetBrowserClientForTesting(old_client);
// Check if the test store was queried against correct |cert_authorities|.
EXPECT_EQ(1, raw_ptr_to_store->request_count());
diff --git a/content/browser/loader/resource_request_info_impl.cc b/content/browser/loader/resource_request_info_impl.cc
index 8039a12..09b82ca 100644
--- a/content/browser/loader/resource_request_info_impl.cc
+++ b/content/browser/loader/resource_request_info_impl.cc
@@ -4,6 +4,7 @@
#include "content/browser/loader/resource_request_info_impl.h"
+#include "content/browser/loader/global_routing_id.h"
#include "content/browser/worker_host/worker_service_impl.h"
#include "content/common/net/url_request_user_data.h"
#include "content/public/browser/global_request_id.h"
@@ -221,6 +222,10 @@
return GlobalRequestID(child_id_, request_id_);
}
+GlobalRoutingID ResourceRequestInfoImpl::GetGlobalRoutingID() const {
+ return GlobalRoutingID(child_id_, route_id_);
+}
+
void ResourceRequestInfoImpl::set_requested_blob_data(
webkit_blob::BlobData* data) {
requested_blob_data_ = data;
diff --git a/content/browser/loader/resource_request_info_impl.h b/content/browser/loader/resource_request_info_impl.h
index 8b23b2a..1c663257 100644
--- a/content/browser/loader/resource_request_info_impl.h
+++ b/content/browser/loader/resource_request_info_impl.h
@@ -24,6 +24,7 @@
class CrossSiteResourceHandler;
class ResourceContext;
struct GlobalRequestID;
+struct GlobalRoutingID;
// Holds the data ResourceDispatcherHost associates with each request.
// Retrieve this data by calling ResourceDispatcherHost::InfoForRequest.
@@ -82,6 +83,7 @@
CONTENT_EXPORT void AssociateWithRequest(net::URLRequest* request);
CONTENT_EXPORT GlobalRequestID GetGlobalRequestID() const;
+ GlobalRoutingID GetGlobalRoutingID() const;
// CrossSiteResourceHandler for this request. May be null.
CrossSiteResourceHandler* cross_site_handler() {
diff --git a/content/browser/loader/resource_scheduler.cc b/content/browser/loader/resource_scheduler.cc
index 4f377dc..6e75c73 100644
--- a/content/browser/loader/resource_scheduler.cc
+++ b/content/browser/loader/resource_scheduler.cc
@@ -11,9 +11,12 @@
#include "content/public/browser/resource_request_info.h"
#include "content/public/browser/resource_throttle.h"
#include "ipc/ipc_message_macros.h"
+#include "net/base/host_port_pair.h"
#include "net/base/load_flags.h"
#include "net/base/request_priority.h"
+#include "net/http/http_server_properties.h"
#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
namespace content {
@@ -324,6 +327,7 @@
//
// * Higher priority requests (>= net::LOW).
// * Synchronous requests.
+// * Requests to SPDY-capable origin servers.
//
// 2. The remainder are delayable requests, which follow these rules:
//
@@ -333,8 +337,19 @@
// * Never exceed 10 delayable requests in flight per client.
bool ResourceScheduler::ShouldStartRequest(ScheduledResourceRequest* request,
Client* client) const {
- if (request->url_request()->priority() >= net::LOW ||
- !ResourceRequestInfo::ForRequest(request->url_request())->IsAsync()) {
+ const net::URLRequest& url_request = *request->url_request();
+ const net::HttpServerProperties& http_server_properties =
+ *url_request.context()->http_server_properties();
+
+ // TODO(willchan): We should really improve this algorithm as described in
+ // crbug.com/164101. Also, theoretically we should not count a SPDY request
+ // against the delayable requests limit.
+ bool origin_supports_spdy = http_server_properties.SupportsSpdy(
+ net::HostPortPair::FromURL(url_request.url()));
+
+ if (url_request.priority() >= net::LOW ||
+ !ResourceRequestInfo::ForRequest(&url_request)->IsAsync() ||
+ origin_supports_spdy) {
return true;
}
diff --git a/content/browser/loader/resource_scheduler_unittest.cc b/content/browser/loader/resource_scheduler_unittest.cc
index 428110f..cfaf459 100644
--- a/content/browser/loader/resource_scheduler_unittest.cc
+++ b/content/browser/loader/resource_scheduler_unittest.cc
@@ -16,6 +16,8 @@
#include "content/public/browser/resource_controller.h"
#include "content/public/browser/resource_throttle.h"
#include "content/public/common/process_type.h"
+#include "net/base/host_port_pair.h"
+#include "net/http/http_server_properties_impl.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -120,10 +122,11 @@
protected:
ResourceSchedulerTest()
: next_request_id_(0),
- message_loop_(MessageLoop::TYPE_IO),
+ message_loop_(base::MessageLoop::TYPE_IO),
ui_thread_(BrowserThread::UI, &message_loop_),
io_thread_(BrowserThread::IO, &message_loop_) {
scheduler_.OnClientCreated(kChildId, kRouteId);
+ context_.set_http_server_properties(&http_server_properties_);
}
virtual ~ResourceSchedulerTest() {
@@ -196,11 +199,12 @@
}
int next_request_id_;
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
BrowserThreadImpl ui_thread_;
BrowserThreadImpl io_thread_;
ResourceDispatcherHostImpl rdh_;
ResourceScheduler scheduler_;
+ net::HttpServerPropertiesImpl http_server_properties_;
net::TestURLRequestContext context_;
};
@@ -227,6 +231,20 @@
EXPECT_TRUE(low->started());
}
+TEST_F(ResourceSchedulerTest, LowBlocksUntilBodyInsertedExceptSpdy) {
+ http_server_properties_.SetSupportsSpdy(
+ net::HostPortPair("spdyhost", 443), true);
+ scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
+ scoped_ptr<TestRequest> low_spdy(
+ NewRequest("https://spdyhost/high", net::LOWEST));
+ scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
+ EXPECT_TRUE(high->started());
+ EXPECT_TRUE(low_spdy->started());
+ EXPECT_FALSE(low->started());
+ scheduler_.OnWillInsertBody(kChildId, kRouteId);
+ EXPECT_TRUE(low->started());
+}
+
TEST_F(ResourceSchedulerTest, NavigationResetsState) {
scheduler_.OnWillInsertBody(kChildId, kRouteId);
scheduler_.OnNavigate(kChildId, kRouteId);
diff --git a/content/browser/loader/sync_resource_handler.cc b/content/browser/loader/sync_resource_handler.cc
index 3b9ee1d..879c267 100644
--- a/content/browser/loader/sync_resource_handler.cc
+++ b/content/browser/loader/sync_resource_handler.cc
@@ -83,8 +83,6 @@
result_.download_file_path = response->head.download_file_path;
result_.request_time = response->head.request_time;
result_.response_time = response->head.response_time;
- result_.connection_id = response->head.connection_id;
- result_.connection_reused = response->head.connection_reused;
result_.load_timing = response->head.load_timing;
result_.devtools_info = response->head.devtools_info;
return true;
diff --git a/content/browser/mach_broker_mac.cc b/content/browser/mach_broker_mac.cc
deleted file mode 100644
index 325db75..0000000
--- a/content/browser/mach_broker_mac.cc
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/mach_broker_mac.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/mac/foundation_util.h"
-#include "base/mach_ipc_mac.h"
-#include "base/string_util.h"
-#include "base/stringprintf.h"
-#include "base/sys_string_conversions.h"
-#include "base/threading/platform_thread.h"
-#include "content/browser/renderer_host/render_process_host_impl.h"
-#include "content/public/browser/child_process_data.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_types.h"
-#include "content/public/common/content_switches.h"
-
-namespace content {
-
-namespace {
-// Prints a string representation of a Mach error code.
-std::string MachErrorCode(kern_return_t err) {
- return base::StringPrintf("0x%x %s", err, mach_error_string(err));
-}
-} // namespace
-
-class MachListenerThreadDelegate : public base::PlatformThread::Delegate {
- public:
- MachListenerThreadDelegate(MachBroker* broker) : broker_(broker) {
- DCHECK(broker_);
- std::string port_name = MachBroker::GetMachPortName();
-
- // Create the receive port in the constructor, not in ThreadMain(). It is
- // important to create and register the receive port before starting the
- // thread so that child processes will always have someone who's listening.
- receive_port_.reset(new base::ReceivePort(port_name.c_str()));
- }
-
- // Implement |PlatformThread::Delegate|.
- virtual void ThreadMain() OVERRIDE {
- base::MachReceiveMessage message;
- kern_return_t err;
- while ((err = receive_port_->WaitForMessage(&message,
- MACH_MSG_TIMEOUT_NONE)) ==
- KERN_SUCCESS) {
- // 0 was the secret message id. Reject any messages that don't have it.
- if (message.GetMessageID() != 0) {
- LOG(ERROR) << "Received message with incorrect id: "
- << message.GetMessageID();
- continue;
- }
-
- const task_t child_task = message.GetTranslatedPort(0);
- if (child_task == MACH_PORT_NULL) {
- LOG(ERROR) << "parent GetTranslatedPort(0) failed.";
- continue;
- }
-
- // It is possible for the child process to die after the call to
- // |pid_for_task()| but before the call to |FinalizePid()|. To prevent
- // leaking MachBroker map entries in this case, lock around both these
- // calls. If the child dies, the death notification will be processed
- // after the call to FinalizePid(), ensuring proper cleanup.
- base::AutoLock lock(broker_->GetLock());
-
- int pid;
- err = pid_for_task(child_task, &pid);
- if (err == KERN_SUCCESS) {
- broker_->FinalizePid(pid,
- MachBroker::MachInfo().SetTask(child_task));
- } else {
- LOG(ERROR) << "Error getting pid for task " << child_task
- << ": " << MachErrorCode(err);
- }
- }
-
- LOG(ERROR) << "Mach listener thread exiting; "
- << "parent WaitForMessage() likely failed: "
- << MachErrorCode(err);
- }
-
- private:
- // The Mach port to listen on. Created on thread startup.
- scoped_ptr<base::ReceivePort> receive_port_;
-
- // The MachBroker to use when new child task rights are received. Can be
- // NULL.
- MachBroker* broker_; // weak
-
- DISALLOW_COPY_AND_ASSIGN(MachListenerThreadDelegate);
-};
-
-// Returns the global MachBroker.
-MachBroker* MachBroker::GetInstance() {
- return Singleton<MachBroker, LeakySingletonTraits<MachBroker> >::get();
-}
-
-void MachBroker::EnsureRunning() {
- lock_.AssertAcquired();
-
- if (!listener_thread_started_) {
- listener_thread_started_ = true;
-
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&MachBroker::RegisterNotifications, base::Unretained(this)));
-
- // Intentional leak. This thread is never joined or reaped.
- base::PlatformThread::CreateNonJoinable(
- 0, new MachListenerThreadDelegate(this));
- }
-}
-
-// Adds a placeholder to the map for the given pid with MACH_PORT_NULL.
-void MachBroker::AddPlaceholderForPid(base::ProcessHandle pid) {
- lock_.AssertAcquired();
-
- MachInfo mach_info;
- DCHECK_EQ(0u, mach_map_.count(pid));
- mach_map_[pid] = mach_info;
-}
-
-// Updates the mapping for |pid| to include the given |mach_info|.
-void MachBroker::FinalizePid(base::ProcessHandle pid,
- const MachInfo& mach_info) {
- lock_.AssertAcquired();
-
- const int count = mach_map_.count(pid);
- if (count == 0) {
- // Do nothing for unknown pids.
- LOG(ERROR) << "Unknown process " << pid << " is sending Mach IPC messages!";
- return;
- }
-
- DCHECK_EQ(1, count);
- DCHECK(mach_map_[pid].mach_task_ == MACH_PORT_NULL);
- if (mach_map_[pid].mach_task_ == MACH_PORT_NULL)
- mach_map_[pid] = mach_info;
-}
-
-// Removes all mappings belonging to |pid| from the broker.
-void MachBroker::InvalidatePid(base::ProcessHandle pid) {
- base::AutoLock lock(lock_);
- MachBroker::MachMap::iterator it = mach_map_.find(pid);
- if (it == mach_map_.end())
- return;
-
- kern_return_t kr = mach_port_deallocate(mach_task_self(),
- it->second.mach_task_);
- LOG_IF(WARNING, kr != KERN_SUCCESS)
- << "Failed to mach_port_deallocate mach task " << it->second.mach_task_
- << ", error " << MachErrorCode(kr);
- mach_map_.erase(it);
-}
-
-base::Lock& MachBroker::GetLock() {
- return lock_;
-}
-
-// Returns the mach task belonging to |pid|.
-mach_port_t MachBroker::TaskForPid(base::ProcessHandle pid) const {
- base::AutoLock lock(lock_);
- MachBroker::MachMap::const_iterator it = mach_map_.find(pid);
- if (it == mach_map_.end())
- return MACH_PORT_NULL;
- return it->second.mach_task_;
-}
-
-void MachBroker::BrowserChildProcessHostDisconnected(
- const ChildProcessData& data) {
- InvalidatePid(data.handle);
-}
-
-void MachBroker::BrowserChildProcessCrashed(const ChildProcessData& data) {
- InvalidatePid(data.handle);
-}
-
-void MachBroker::Observe(int type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- // TODO(rohitrao): These notifications do not always carry the proper PIDs,
- // especially when the renderer is already gone or has crashed. Find a better
- // way to listen for child process deaths. http://crbug.com/55734
- base::ProcessHandle handle = 0;
- switch (type) {
- case NOTIFICATION_RENDERER_PROCESS_CLOSED:
- handle = Details<RenderProcessHost::RendererClosedDetails>(
- details)->handle;
- break;
- case NOTIFICATION_RENDERER_PROCESS_TERMINATED:
- handle = Source<RenderProcessHost>(source)->GetHandle();
- break;
- default:
- NOTREACHED() << "Unexpected notification";
- break;
- }
- InvalidatePid(handle);
-}
-
-// static
-std::string MachBroker::GetMachPortName() {
- const CommandLine* command_line = CommandLine::ForCurrentProcess();
- const bool is_child = command_line->HasSwitch(switches::kProcessType);
-
- // In non-browser (child) processes, use the parent's pid.
- const pid_t pid = is_child ? getppid() : getpid();
- return base::StringPrintf("%s.rohitfork.%d", base::mac::BaseBundleID(), pid);
-}
-
-MachBroker::MachBroker() : listener_thread_started_(false) {
-}
-
-MachBroker::~MachBroker() {}
-
-void MachBroker::RegisterNotifications() {
- registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSED,
- NotificationService::AllBrowserContextsAndSources());
- registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED,
- NotificationService::AllBrowserContextsAndSources());
-
- // No corresponding StopObservingBrowserChildProcesses,
- // we leak this singleton.
- BrowserChildProcessObserver::Add(this);
-}
-
-} // namespace content
diff --git a/content/browser/mach_broker_mac.h b/content/browser/mach_broker_mac.h
index 011df04..e38e86f 100644
--- a/content/browser/mach_broker_mac.h
+++ b/content/browser/mach_broker_mac.h
@@ -38,48 +38,30 @@
public BrowserChildProcessObserver,
public NotificationObserver {
public:
+ // For use in child processes. This will send the task port of the current
+ // process over Mach IPC to the port registered by name (via this class) in
+ // the parent process. Returns true if the message was sent successfully
+ // and false if otherwise.
+ static bool ChildSendTaskPortToParent();
+
// Returns the global MachBroker.
static MachBroker* GetInstance();
- // Performs any necessary setup that cannot happen in the constructor.
- // Callers MUST acquire the lock given by GetLock() before calling this
- // method (and release the lock afterwards).
- void EnsureRunning();
-
- struct MachInfo {
- MachInfo() : mach_task_(MACH_PORT_NULL) {}
-
- MachInfo& SetTask(mach_port_t task) {
- mach_task_ = task;
- return *this;
- }
-
- mach_port_t mach_task_;
- };
-
- // Adds a placeholder to the map for the given pid with MACH_PORT_NULL.
- // Callers are expected to later update the port with FinalizePid(). Callers
- // MUST acquire the lock given by GetLock() before calling this method (and
- // release the lock afterwards).
- void AddPlaceholderForPid(base::ProcessHandle pid);
-
- // Updates the mapping for |pid| to include the given |mach_info|. Does
- // nothing if PlaceholderForPid() has not already been called for the given
- // |pid|. Callers MUST acquire the lock given by GetLock() before calling
- // this method (and release the lock afterwards).
- void FinalizePid(base::ProcessHandle pid, const MachInfo& mach_info);
-
- // Removes all mappings belonging to |pid| from the broker.
- void InvalidatePid(base::ProcessHandle pid);
-
// The lock that protects this MachBroker object. Clients MUST acquire and
// release this lock around calls to EnsureRunning(), PlaceholderForPid(),
// and FinalizePid().
base::Lock& GetLock();
- // Returns the Mach port name to use when sending or receiving messages.
- // Does the Right Thing in the browser and in child processes.
- static std::string GetMachPortName();
+ // Performs any necessary setup that cannot happen in the constructor.
+ // Callers MUST acquire the lock given by GetLock() before calling this
+ // method (and release the lock afterwards).
+ void EnsureRunning();
+
+ // Adds a placeholder to the map for the given pid with MACH_PORT_NULL.
+ // Callers are expected to later update the port with FinalizePid(). Callers
+ // MUST acquire the lock given by GetLock() before calling this method (and
+ // release the lock afterwards).
+ void AddPlaceholderForPid(base::ProcessHandle pid);
// Implement |ProcessMetrics::PortProvider|.
virtual mach_port_t TaskForPid(base::ProcessHandle process) const OVERRIDE;
@@ -96,11 +78,24 @@
const NotificationDetails& details) OVERRIDE;
private:
friend class MachBrokerTest;
+ friend class MachListenerThreadDelegate;
friend struct DefaultSingletonTraits<MachBroker>;
MachBroker();
virtual ~MachBroker();
+ // Updates the mapping for |pid| to include the given |mach_info|. Does
+ // nothing if PlaceholderForPid() has not already been called for the given
+ // |pid|. Callers MUST acquire the lock given by GetLock() before calling
+ // this method (and release the lock afterwards).
+ void FinalizePid(base::ProcessHandle pid, mach_port_t task_port);
+
+ // Removes all mappings belonging to |pid| from the broker.
+ void InvalidatePid(base::ProcessHandle pid);
+
+ // Returns the Mach port name to use when sending or receiving messages.
+ // Does the Right Thing in the browser and in child processes.
+ static std::string GetMachPortName();
// Callback used to register notifications on the UI thread.
void RegisterNotifications();
@@ -112,7 +107,7 @@
NotificationRegistrar registrar_;
// Stores mach info for every process in the broker.
- typedef std::map<base::ProcessHandle, MachInfo> MachMap;
+ typedef std::map<base::ProcessHandle, mach_port_t> MachMap;
MachMap mach_map_;
// Mutex that guards |mach_map_|.
diff --git a/content/browser/mach_broker_mac.mm b/content/browser/mach_broker_mac.mm
new file mode 100644
index 0000000..783b708
--- /dev/null
+++ b/content/browser/mach_broker_mac.mm
@@ -0,0 +1,309 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/mach_broker_mac.h"
+
+#include <bsm/libbsm.h>
+#include <servers/bootstrap.h>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_mach_port.h"
+#include "base/string_util.h"
+#include "base/stringprintf.h"
+#include "base/strings/sys_string_conversions.h"
+#include "base/threading/platform_thread.h"
+#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/public/browser/child_process_data.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/common/content_switches.h"
+
+namespace content {
+
+namespace {
+
+// Prints a string representation of a Mach error code.
+std::string MachErrorCode(kern_return_t err) {
+ return base::StringPrintf("0x%x %s", err, mach_error_string(err));
+}
+
+// Mach message structure used in the child as a sending message.
+struct MachBroker_ChildSendMsg {
+ mach_msg_header_t header;
+ mach_msg_body_t body;
+ mach_msg_port_descriptor_t child_task_port;
+};
+
+// Complement to the ChildSendMsg, this is used in the parent for receiving
+// a message. Contains a message trailer with audit information.
+struct MachBroker_ParentRecvMsg : public MachBroker_ChildSendMsg {
+ mach_msg_audit_trailer_t trailer;
+};
+
+} // namespace
+
+class MachListenerThreadDelegate : public base::PlatformThread::Delegate {
+ public:
+ explicit MachListenerThreadDelegate(MachBroker* broker)
+ : broker_(broker),
+ server_port_(MACH_PORT_NULL) {
+ DCHECK(broker_);
+ }
+
+ bool Init() {
+ DCHECK(server_port_ == MACH_PORT_NULL);
+
+ mach_port_t port;
+ kern_return_t kr = mach_port_allocate(mach_task_self(),
+ MACH_PORT_RIGHT_RECEIVE,
+ &port);
+ if (kr != KERN_SUCCESS) {
+ LOG(ERROR) << "Failed to allocate MachBroker server port: "
+ << MachErrorCode(kr);
+ return false;
+ }
+
+ // Allocate a send right for the server port.
+ kr = mach_port_insert_right(
+ mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND);
+ if (kr != KERN_SUCCESS) {
+ LOG(ERROR) << "Failed to insert send right for MachBroker server port: "
+ << MachErrorCode(kr);
+ return false;
+ }
+
+ server_port_.reset(port);
+
+ // Register the port with the bootstrap server. Because bootstrap_register
+ // is deprecated, this has to be wraped in an ObjC interface.
+ NSPort* ns_port = [NSMachPort portWithMachPort:port
+ options:NSMachPortDeallocateNone];
+ NSString* name = base::SysUTF8ToNSString(broker_->GetMachPortName());
+ return [[NSMachBootstrapServer sharedInstance] registerPort:ns_port
+ name:name];
+ }
+
+ // Implement |PlatformThread::Delegate|.
+ virtual void ThreadMain() OVERRIDE {
+ MachBroker_ParentRecvMsg msg;
+ bzero(&msg, sizeof(msg));
+ msg.header.msgh_size = sizeof(msg);
+ msg.header.msgh_local_port = server_port_.get();
+
+ kern_return_t kr;
+ do {
+ // Use the kernel audit information to make sure this message is from
+ // a task that this process spawned. The kernel audit token contains the
+ // unspoofable pid of the task that sent the message.
+ mach_msg_option_t options = MACH_RCV_MSG |
+ MACH_RCV_TRAILER_TYPE(MACH_RCV_TRAILER_AUDIT) |
+ MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT);
+
+ kr = mach_msg(&msg.header, options, 0, sizeof(msg), server_port_,
+ MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+ if (kr == KERN_SUCCESS) {
+ // TODO(rsesek): In the 10.7 SDK, there's audit_token_to_pid().
+ pid_t child_pid;
+ audit_token_to_au32(msg.trailer.msgh_audit,
+ NULL, NULL, NULL, NULL, NULL, &child_pid, NULL, NULL);
+
+ mach_port_t child_task_port = msg.child_task_port.name;
+
+ // Take the lock and update the broker information.
+ base::AutoLock lock(broker_->GetLock());
+ broker_->FinalizePid(child_pid, child_task_port);
+ }
+ } while (kr == KERN_SUCCESS);
+
+ LOG(ERROR) << "MachBroker thread exiting; mach_msg() likely failed: "
+ << MachErrorCode(kr);
+ }
+
+ private:
+ // The MachBroker to use when new child task rights are received. Can be
+ // NULL.
+ MachBroker* broker_; // weak
+
+ base::mac::ScopedMachPort server_port_;
+
+ DISALLOW_COPY_AND_ASSIGN(MachListenerThreadDelegate);
+};
+
+bool MachBroker::ChildSendTaskPortToParent() {
+ // Look up the named MachBroker port that's been registered with the
+ // bootstrap server.
+ mach_port_t bootstrap_port;
+ kern_return_t kr = task_get_bootstrap_port(mach_task_self(), &bootstrap_port);
+ if (kr != KERN_SUCCESS) {
+ LOG(ERROR) << "Failed to look up bootstrap port: " << MachErrorCode(kr);
+ return false;
+ }
+
+ mach_port_t parent_port;
+ kr = bootstrap_look_up(bootstrap_port,
+ const_cast<char*>(GetMachPortName().c_str()), &parent_port);
+ if (kr != KERN_SUCCESS) {
+ LOG(ERROR) << "Failed to look up named parent port: " << MachErrorCode(kr);
+ return false;
+ }
+
+ // Create the check in message. This will copy a send right on this process'
+ // (the child's) task port and send it to the parent.
+ MachBroker_ChildSendMsg msg;
+ bzero(&msg, sizeof(msg));
+ msg.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND) |
+ MACH_MSGH_BITS_COMPLEX;
+ msg.header.msgh_remote_port = parent_port;
+ msg.header.msgh_size = sizeof(msg);
+ msg.body.msgh_descriptor_count = 1;
+ msg.child_task_port.name = mach_task_self();
+ msg.child_task_port.disposition = MACH_MSG_TYPE_PORT_SEND;
+ msg.child_task_port.type = MACH_MSG_PORT_DESCRIPTOR;
+
+ kr = mach_msg(&msg.header, MACH_SEND_MSG | MACH_SEND_TIMEOUT, sizeof(msg),
+ 0, MACH_PORT_NULL, 100 /*milliseconds*/, MACH_PORT_NULL);
+ if (kr != KERN_SUCCESS) {
+ LOG(ERROR) << "Failed to send task port to parent: " << MachErrorCode(kr);
+ return false;
+ }
+
+ return true;
+}
+
+MachBroker* MachBroker::GetInstance() {
+ return Singleton<MachBroker, LeakySingletonTraits<MachBroker> >::get();
+}
+
+base::Lock& MachBroker::GetLock() {
+ return lock_;
+}
+
+void MachBroker::EnsureRunning() {
+ lock_.AssertAcquired();
+
+ if (!listener_thread_started_) {
+ listener_thread_started_ = true;
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&MachBroker::RegisterNotifications, base::Unretained(this)));
+
+ // Intentional leak. This thread is never joined or reaped.
+ MachListenerThreadDelegate* thread = new MachListenerThreadDelegate(this);
+ if (thread->Init()) {
+ base::PlatformThread::CreateNonJoinable(0, thread);
+ } else {
+ LOG(ERROR) << "Failed to initialize the MachListenerThreadDelegate";
+ }
+ }
+}
+
+void MachBroker::AddPlaceholderForPid(base::ProcessHandle pid) {
+ lock_.AssertAcquired();
+
+ DCHECK_EQ(0u, mach_map_.count(pid));
+ mach_map_[pid] = MACH_PORT_NULL;
+}
+
+mach_port_t MachBroker::TaskForPid(base::ProcessHandle pid) const {
+ base::AutoLock lock(lock_);
+ MachBroker::MachMap::const_iterator it = mach_map_.find(pid);
+ if (it == mach_map_.end())
+ return MACH_PORT_NULL;
+ return it->second;
+}
+
+void MachBroker::BrowserChildProcessHostDisconnected(
+ const ChildProcessData& data) {
+ InvalidatePid(data.handle);
+}
+
+void MachBroker::BrowserChildProcessCrashed(const ChildProcessData& data) {
+ InvalidatePid(data.handle);
+}
+
+void MachBroker::Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ // TODO(rohitrao): These notifications do not always carry the proper PIDs,
+ // especially when the renderer is already gone or has crashed. Find a better
+ // way to listen for child process deaths. http://crbug.com/55734
+ base::ProcessHandle handle = 0;
+ switch (type) {
+ case NOTIFICATION_RENDERER_PROCESS_CLOSED:
+ handle = Details<RenderProcessHost::RendererClosedDetails>(
+ details)->handle;
+ break;
+ case NOTIFICATION_RENDERER_PROCESS_TERMINATED:
+ handle = Source<RenderProcessHost>(source)->GetHandle();
+ break;
+ default:
+ NOTREACHED() << "Unexpected notification";
+ break;
+ }
+ InvalidatePid(handle);
+}
+
+MachBroker::MachBroker() : listener_thread_started_(false) {
+}
+
+MachBroker::~MachBroker() {}
+
+void MachBroker::FinalizePid(base::ProcessHandle pid,
+ mach_port_t task_port) {
+ lock_.AssertAcquired();
+
+ MachMap::iterator it = mach_map_.find(pid);
+ if (it == mach_map_.end()) {
+ // Do nothing for unknown pids.
+ LOG(ERROR) << "Unknown process " << pid << " is sending Mach IPC messages!";
+ return;
+ }
+
+ DCHECK(it->second == MACH_PORT_NULL);
+ if (it->second == MACH_PORT_NULL)
+ it->second = task_port;
+}
+
+void MachBroker::InvalidatePid(base::ProcessHandle pid) {
+ base::AutoLock lock(lock_);
+ MachBroker::MachMap::iterator it = mach_map_.find(pid);
+ if (it == mach_map_.end())
+ return;
+
+ kern_return_t kr = mach_port_deallocate(mach_task_self(),
+ it->second);
+ LOG_IF(WARNING, kr != KERN_SUCCESS)
+ << "Failed to mach_port_deallocate mach task " << it->second
+ << ", error " << MachErrorCode(kr);
+ mach_map_.erase(it);
+}
+
+// static
+std::string MachBroker::GetMachPortName() {
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ const bool is_child = command_line->HasSwitch(switches::kProcessType);
+
+ // In non-browser (child) processes, use the parent's pid.
+ const pid_t pid = is_child ? getppid() : getpid();
+ return base::StringPrintf("%s.rohitfork.%d", base::mac::BaseBundleID(), pid);
+}
+
+void MachBroker::RegisterNotifications() {
+ registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSED,
+ NotificationService::AllBrowserContextsAndSources());
+ registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED,
+ NotificationService::AllBrowserContextsAndSources());
+
+ // No corresponding StopObservingBrowserChildProcesses,
+ // we leak this singleton.
+ BrowserChildProcessObserver::Add(this);
+}
+
+} // namespace content
diff --git a/content/browser/mach_broker_mac_unittest.cc b/content/browser/mach_broker_mac_unittest.cc
index 7bd88a5..a7eca4f 100644
--- a/content/browser/mach_broker_mac_unittest.cc
+++ b/content/browser/mach_broker_mac_unittest.cc
@@ -17,11 +17,15 @@
broker_.AddPlaceholderForPid(pid);
}
+ void InvalidatePid(base::ProcessHandle pid) {
+ broker_.InvalidatePid(pid);
+ }
+
// Helper function to acquire/release locks and call |FinalizePid()|.
void FinalizePid(base::ProcessHandle pid,
- const MachBroker::MachInfo& mach_info) {
+ mach_port_t task_port) {
base::AutoLock lock(broker_.GetLock());
- broker_.FinalizePid(pid, mach_info);
+ broker_.FinalizePid(pid, task_port);
}
protected:
@@ -39,7 +43,7 @@
EXPECT_EQ(0u, broker_.TaskForPid(1));
// Finalize PID 1.
- FinalizePid(1, MachBroker::MachInfo().SetTask(100u));
+ FinalizePid(1, 100u);
EXPECT_EQ(100u, broker_.TaskForPid(1));
// Should be no entry for PID 2.
@@ -48,16 +52,16 @@
TEST_F(MachBrokerTest, Invalidate) {
AddPlaceholderForPid(1);
- FinalizePid(1, MachBroker::MachInfo().SetTask(100u));
+ FinalizePid(1, 100u);
EXPECT_EQ(100u, broker_.TaskForPid(1));
- broker_.InvalidatePid(1u);
+ InvalidatePid(1u);
EXPECT_EQ(0u, broker_.TaskForPid(1));
}
TEST_F(MachBrokerTest, FinalizeUnknownPid) {
// Finalizing an entry for an unknown pid should not add it to the map.
- FinalizePid(1u, MachBroker::MachInfo().SetTask(100u));
+ FinalizePid(1u, 100u);
EXPECT_EQ(0u, broker_.TaskForPid(1u));
}
diff --git a/content/browser/media/encrypted_media_browsertest.cc b/content/browser/media/encrypted_media_browsertest.cc
index c41b955..34cbd65 100644
--- a/content/browser/media/encrypted_media_browsertest.cc
+++ b/content/browser/media/encrypted_media_browsertest.cc
@@ -21,13 +21,22 @@
#include "media/base/media_switches.h"
#include "webkit/media/crypto/key_systems.h"
+#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
+
+#if defined(WIDEVINE_CDM_AVAILABLE) && defined(OS_LINUX)
+#include <gnu/libc-version.h>
+#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(OS_LINUX)
+
// Platform-specific filename relative to the chrome executable.
#if defined(OS_WIN)
-static const wchar_t kLibraryName[] = L"clearkeycdmadapter.dll";
+static const char kClearKeyLibraryName[] = "clearkeycdmadapter.dll";
+static const char kWidevineLibraryName[] = "widevinecdmadapter.dll";
#elif defined(OS_MACOSX)
-static const char kLibraryName[] = "clearkeycdmadapter.plugin";
+static const char kClearKeyLibraryName[] = "clearkeycdmadapter.plugin";
+static const char kWidevineLibraryName[] = "widevinecdmadapter.plugin";
#elif defined(OS_POSIX)
-static const char kLibraryName[] = "libclearkeycdmadapter.so";
+static const char kClearKeyLibraryName[] = "libclearkeycdmadapter.so";
+static const char kWidevineLibraryName[] = "libwidevinecdmadapter.so";
#endif
// Available key systems.
@@ -35,12 +44,17 @@
static const char kExternalClearKeyKeySystem[] =
"org.chromium.externalclearkey";
+// Supported media types.
static const char kWebMAudioOnly[] = "audio/webm; codecs=\"vorbis\"";
static const char kWebMVideoOnly[] = "video/webm; codecs=\"vp8\"";
static const char kWebMAudioVideo[] = "video/webm; codecs=\"vorbis, vp8\"";
static const char kMP4AudioOnly[] = "audio/mp4; codecs=\"mp4a.40.2\"";
static const char kMP4VideoOnly[] = "video/mp4; codecs=\"avc1.4D4041\"";
+// Common test expectations.
+const string16 kExpectedEnded = ASCIIToUTF16("ENDED");
+const string16 kExpectedWebKitError = ASCIIToUTF16("WEBKITKEYERROR");
+
namespace content {
class EncryptedMediaTest : public testing::WithParamInterface<const char*>,
@@ -48,14 +62,16 @@
public:
void TestSimplePlayback(const char* encrypted_media, const char* media_type,
const char* key_system, const string16 expectation) {
- PlayEncryptedMedia("encrypted_media_player.html", encrypted_media,
- media_type, key_system, expectation);
+ ASSERT_NO_FATAL_FAILURE(
+ PlayEncryptedMedia("encrypted_media_player.html", encrypted_media,
+ media_type, key_system, expectation));
}
void TestFrameSizeChange(const char* key_system, const string16 expectation) {
- PlayEncryptedMedia("encrypted_frame_size_change.html",
- "frame_size_change-av-enc-v.webm", kWebMAudioVideo,
- key_system, expectation);
+ ASSERT_NO_FATAL_FAILURE(
+ PlayEncryptedMedia("encrypted_frame_size_change.html",
+ "frame_size_change-av-enc-v.webm", kWebMAudioVideo,
+ key_system, expectation));
}
void PlayEncryptedMedia(const char* html_page, const char* media_file,
@@ -91,28 +107,73 @@
protected:
// Registers any CDM plugins not registered by default.
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
- command_line->AppendSwitch(switches::kDisableAudio);
+ RegisterPepperPlugin(command_line, kClearKeyLibraryName,
+ kExternalClearKeyKeySystem);
+ }
- // Append the switch to register the Clear Key CDM plugin.
+ virtual void RegisterPepperPlugin(CommandLine* command_line,
+ const std::string& library_name,
+ const std::string& key_system) {
+ // Append the switch to register the Clear Key CDM Adapter.
base::FilePath plugin_dir;
EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &plugin_dir));
- base::FilePath plugin_lib = plugin_dir.Append(kLibraryName);
+#if defined(OS_WIN)
+ base::FilePath plugin_lib = plugin_dir.Append(ASCIIToWide(library_name));
+#else
+ base::FilePath plugin_lib = plugin_dir.Append(library_name);
+#endif
EXPECT_TRUE(file_util::PathExists(plugin_lib));
base::FilePath::StringType pepper_plugin = plugin_lib.value();
- pepper_plugin.append(FILE_PATH_LITERAL(
- "#Clear Key CDM#Clear Key CDM 0.1.0.0#0.1.0.0;"));
+ pepper_plugin.append(FILE_PATH_LITERAL("#CDM#0.1.0.0;"));
#if defined(OS_WIN)
- pepper_plugin.append(ASCIIToWide(
- webkit_media::GetPluginType(kExternalClearKeyKeySystem)));
+ pepper_plugin.append(ASCIIToWide(webkit_media::GetPluginType(key_system)));
#else
- pepper_plugin.append(
- webkit_media::GetPluginType(kExternalClearKeyKeySystem));
+ pepper_plugin.append(webkit_media::GetPluginType(key_system));
#endif
command_line->AppendSwitchNative(switches::kRegisterPepperPlugins,
pepper_plugin);
}
};
+#if defined(WIDEVINE_CDM_AVAILABLE)
+class WVEncryptedMediaTest : public EncryptedMediaTest {
+ public:
+ // Tests that the following happen after trying to play encrypted media:
+ // - webkitneedkey event is fired.
+ // - webkitGenerateKeyRequest() does not fail.
+ // - webkitkeymessage is fired
+ // - webkitAddKey() generates a WebKitKeyError since no real WV key is added.
+ void TestSimplePlayback(const char* encrypted_media, const char* media_type,
+ const char* key_system) {
+ // TODO(shadi): Remove after bots upgrade to precise.
+ // Don't run on lucid bots since the CDM is not compatible (glibc < 2.14)
+#if defined(OS_LINUX)
+ if(strcmp(gnu_get_libc_version(), "2.11.1") == 0) {
+ LOG(INFO) << "Skipping test; not supported on glibc version: "
+ << gnu_get_libc_version();
+ return;
+ }
+#endif // defined(OS_LINUX)
+ EncryptedMediaTest::TestSimplePlayback(encrypted_media, media_type,
+ key_system, kExpectedWebKitError);
+ bool receivedKeyMessage = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ shell()->web_contents(),
+ "window.domAutomationController.send(video.receivedKeyMessage);",
+ &receivedKeyMessage));
+ ASSERT_TRUE(receivedKeyMessage);
+ }
+
+ protected:
+ // Registers any CDM plugins not registered by default.
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ command_line->AppendSwitch(switches::kAllowFileAccessFromFiles);
+ RegisterPepperPlugin(command_line, kWidevineLibraryName,
+ kWidevineKeySystem);
+ }
+};
+#endif // defined(WIDEVINE_CDM_AVAILABLE)
+
INSTANTIATE_TEST_CASE_P(ClearKey, EncryptedMediaTest,
::testing::Values(kClearKeyKeySystem));
@@ -122,44 +183,33 @@
IN_PROC_BROWSER_TEST_F(EncryptedMediaTest, InvalidKeySystem) {
const string16 kExpected = ASCIIToUTF16(
StringToUpperASCII(std::string("GenerateKeyRequestException")));
- ASSERT_NO_FATAL_FAILURE(
- TestSimplePlayback("bear-320x240-av-enc_av.webm", kWebMAudioVideo,
- "com.example.invalid", kExpected));
+ TestSimplePlayback("bear-320x240-av-enc_av.webm", kWebMAudioVideo,
+ "com.example.invalid", kExpected);
}
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_AudioOnly_WebM) {
- const string16 kExpected = ASCIIToUTF16("ENDED");
- ASSERT_NO_FATAL_FAILURE(
- TestSimplePlayback("bear-a-enc_a.webm", kWebMAudioOnly,
- GetParam(), kExpected));
+ TestSimplePlayback("bear-a-enc_a.webm", kWebMAudioOnly, GetParam(),
+ kExpectedEnded);
}
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_AudioClearVideo_WebM) {
- const string16 kExpected = ASCIIToUTF16("ENDED");
- ASSERT_NO_FATAL_FAILURE(
- TestSimplePlayback("bear-320x240-av-enc_a.webm", kWebMAudioVideo,
- GetParam(), kExpected));
+ TestSimplePlayback("bear-320x240-av-enc_a.webm", kWebMAudioVideo, GetParam(),
+ kExpectedEnded);
}
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoAudio_WebM) {
- const string16 kExpected = ASCIIToUTF16("ENDED");
- ASSERT_NO_FATAL_FAILURE(
- TestSimplePlayback("bear-320x240-av-enc_av.webm", kWebMAudioVideo,
- GetParam(), kExpected));
+ TestSimplePlayback("bear-320x240-av-enc_av.webm", kWebMAudioVideo, GetParam(),
+ kExpectedEnded);
}
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoOnly_WebM) {
- const string16 kExpected = ASCIIToUTF16("ENDED");
- ASSERT_NO_FATAL_FAILURE(
- TestSimplePlayback("bear-320x240-v-enc_v.webm", kWebMVideoOnly,
- GetParam(), kExpected));
+ TestSimplePlayback("bear-320x240-v-enc_v.webm", kWebMVideoOnly, GetParam(),
+ kExpectedEnded);
}
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoClearAudio_WebM) {
- const string16 kExpected = ASCIIToUTF16("ENDED");
- ASSERT_NO_FATAL_FAILURE(
- TestSimplePlayback("bear-320x240-av-enc_v.webm", kWebMAudioVideo,
- GetParam(), kExpected));
+ TestSimplePlayback("bear-320x240-av-enc_v.webm", kWebMAudioVideo,GetParam(),
+ kExpectedEnded);
}
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, FrameChangeVideo) {
@@ -168,24 +218,61 @@
if (base::win::GetVersion() < base::win::VERSION_VISTA)
return;
#endif
- const string16 kExpected = ASCIIToUTF16("ENDED");
- ASSERT_NO_FATAL_FAILURE(TestFrameSizeChange(GetParam(), kExpected));
+ TestFrameSizeChange(GetParam(), kExpectedEnded);
}
#if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS)
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoOnly_MP4) {
- const string16 kExpected = ASCIIToUTF16("ENDED");
- ASSERT_NO_FATAL_FAILURE(
- TestSimplePlayback("bear-640x360-v_frag-cenc.mp4", kMP4VideoOnly,
- GetParam(), kExpected));
+ TestSimplePlayback("bear-640x360-v_frag-cenc.mp4", kMP4VideoOnly, GetParam(),
+ kExpectedEnded);
}
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_AudioOnly_MP4) {
- const string16 kExpected = ASCIIToUTF16("ENDED");
- ASSERT_NO_FATAL_FAILURE(
- TestSimplePlayback("bear-640x360-a_frag-cenc.mp4", kMP4AudioOnly,
- GetParam(), kExpected));
+ TestSimplePlayback("bear-640x360-a_frag-cenc.mp4", kMP4AudioOnly, GetParam(),
+ kExpectedEnded);
}
#endif
+// 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) {
+ TestSimplePlayback("bear-a-enc_a.webm", kWebMAudioOnly, kWidevineKeySystem);
+}
+
+IN_PROC_BROWSER_TEST_F(WVEncryptedMediaTest, Playback_AudioClearVideo_WebM) {
+ TestSimplePlayback("bear-320x240-av-enc_a.webm", kWebMAudioVideo,
+ kWidevineKeySystem);
+}
+
+IN_PROC_BROWSER_TEST_F(WVEncryptedMediaTest, Playback_VideoAudio_WebM) {
+ TestSimplePlayback("bear-320x240-av-enc_av.webm", kWebMAudioVideo,
+ kWidevineKeySystem);
+}
+
+IN_PROC_BROWSER_TEST_F(WVEncryptedMediaTest, Playback_VideoOnly_WebM) {
+ TestSimplePlayback("bear-320x240-v-enc_v.webm", kWebMVideoOnly,
+ kWidevineKeySystem);
+}
+
+IN_PROC_BROWSER_TEST_F(WVEncryptedMediaTest, Playback_VideoClearAudio_WebM) {
+ TestSimplePlayback("bear-320x240-av-enc_v.webm", kWebMAudioVideo,
+ kWidevineKeySystem);
+}
+
+#if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS)
+IN_PROC_BROWSER_TEST_F(WVEncryptedMediaTest, Playback_VideoOnly_MP4) {
+ TestSimplePlayback("bear-640x360-v_frag-cenc.mp4", kMP4VideoOnly,
+ kWidevineKeySystem);
+}
+
+IN_PROC_BROWSER_TEST_F(WVEncryptedMediaTest, Playback_AudioOnly_MP4) {
+ TestSimplePlayback("bear-640x360-a_frag-cenc.mp4", kMP4AudioOnly,
+ 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/media_internals.cc b/content/browser/media/media_internals.cc
index 6b55d2a..f69169e 100644
--- a/content/browser/media/media_internals.cc
+++ b/content/browser/media/media_internals.cc
@@ -48,18 +48,21 @@
"volume", new base::FundamentalValue(volume));
}
-void MediaInternals::OnMediaEvent(
- int render_process_id, const media::MediaLogEvent& event) {
+void MediaInternals::OnMediaEvents(
+ int render_process_id, const std::vector<media::MediaLogEvent>& events) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
// Notify observers that |event| has occured.
- base::DictionaryValue dict;
- dict.SetInteger("renderer", render_process_id);
- dict.SetInteger("player", event.id);
- dict.SetString("type", media::MediaLog::EventTypeToString(event.type));
- dict.SetDouble("time", event.time.ToDoubleT());
- dict.Set("params", event.params.DeepCopy());
- SendUpdate("media.onMediaEvent", &dict);
+ for (std::vector<media::MediaLogEvent>::const_iterator event = events.begin();
+ event != events.end(); ++event) {
+ base::DictionaryValue dict;
+ dict.SetInteger("renderer", render_process_id);
+ dict.SetInteger("player", event->id);
+ dict.SetString("type", media::MediaLog::EventTypeToString(event->type));
+ dict.SetDouble("time", event->time.ToDoubleT());
+ dict.Set("params", event->params.DeepCopy());
+ SendUpdate("media.onMediaEvent", &dict);
+ }
}
void MediaInternals::AddUpdateCallback(const UpdateCallback& callback) {
diff --git a/content/browser/media/media_internals.h b/content/browser/media/media_internals.h
index 5c901d5..170587a 100644
--- a/content/browser/media/media_internals.h
+++ b/content/browser/media/media_internals.h
@@ -39,8 +39,8 @@
virtual void OnSetAudioStreamPlaying(void* host, int stream_id,
bool playing);
- // Called when the status of an audio stream is set to "created", "flushed",
- // "closed", or "error".
+ // Called when the status of an audio stream is set to "created", "closed", or
+ // "error".
virtual void OnSetAudioStreamStatus(void* host, int stream_id,
const std::string& status);
@@ -49,8 +49,8 @@
double volume);
// Called when a MediaEvent occurs.
- virtual void OnMediaEvent(int render_process_id,
- const media::MediaLogEvent& event);
+ virtual void OnMediaEvents(int render_process_id,
+ const std::vector<media::MediaLogEvent>& events);
// Called with the update string.
typedef base::Callback<void(const string16&)> UpdateCallback;
diff --git a/content/browser/media/media_internals_proxy.cc b/content/browser/media/media_internals_proxy.cc
index 5d837d6..0c214d1 100644
--- a/content/browser/media/media_internals_proxy.cc
+++ b/content/browser/media/media_internals_proxy.cc
@@ -152,12 +152,11 @@
// Send the updates to the page in kMediaInternalsProxyEventDelayMilliseconds
// if an update is not already pending.
- if (!pending_net_updates_.get()) {
+ if (!pending_net_updates_) {
pending_net_updates_.reset(new base::ListValue());
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
- base::Bind(
- &MediaInternalsProxy::SendNetEventsOnUIThread, this),
+ base::Bind(&MediaInternalsProxy::SendNetEventsOnUIThread, this),
base::TimeDelta::FromMilliseconds(
kMediaInternalsProxyEventDelayMilliseconds));
}
diff --git a/content/browser/media/media_internals_ui.cc b/content/browser/media/media_internals_ui.cc
index f35395e..812825d 100644
--- a/content/browser/media/media_internals_ui.cc
+++ b/content/browser/media/media_internals_ui.cc
@@ -16,7 +16,7 @@
WebUIDataSource* CreateMediaInternalsHTMLSource() {
WebUIDataSource* source =
- WebUIDataSource::Create(chrome::kChromeUIMediaInternalsHost);
+ WebUIDataSource::Create(kChromeUIMediaInternalsHost);
source->SetJsonPath("strings.js");
source->AddResourcePath("media_internals.js", IDR_MEDIA_INTERNALS_JS);
diff --git a/content/browser/media/media_internals_unittest.cc b/content/browser/media/media_internals_unittest.cc
index 0db2580..5edd55d 100644
--- a/content/browser/media/media_internals_unittest.cc
+++ b/content/browser/media/media_internals_unittest.cc
@@ -41,7 +41,7 @@
void UpdateItem(const std::string& item, const std::string& property,
base::Value* value) {
- internals_->UpdateItem("", item, property, value);
+ internals_->UpdateItem(std::string(), item, property, value);
}
void SendUpdate(const std::string& function, base::Value* value) {
@@ -53,7 +53,7 @@
internals_.reset(new MediaInternals());
}
- MessageLoop loop_;
+ base::MessageLoop loop_;
TestBrowserThread io_thread_;
scoped_ptr<MediaInternals> internals_;
};
diff --git a/content/browser/media/webrtc_browsertest.cc b/content/browser/media/webrtc_browsertest.cc
index e0d086d..3ae9371 100644
--- a/content/browser/media/webrtc_browsertest.cc
+++ b/content/browser/media/webrtc_browsertest.cc
@@ -10,7 +10,7 @@
#include "content/shell/shell.h"
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"
-#include "net/test/test_server.h"
+#include "net/test/spawned_test_server.h"
#if defined(OS_WIN)
#include "base/win/windows_version.h"
@@ -47,7 +47,7 @@
// see that the success callback is called. If the error callback is called or
// none of the callbacks are called the tests will simply time out and fail.
IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetVideoStreamAndStop) {
- GURL url(test_server()->GetURL("files/media/getusermedia_and_stop.html"));
+ GURL url(test_server()->GetURL("files/media/getusermedia.html"));
NavigateToURL(shell(), url);
EXPECT_TRUE(ExecuteJavascript("getUserMedia({video: true});"));
@@ -56,7 +56,7 @@
}
IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetAudioAndVideoStreamAndStop) {
- GURL url(test_server()->GetURL("files/media/getusermedia_and_stop.html"));
+ GURL url(test_server()->GetURL("files/media/getusermedia.html"));
NavigateToURL(shell(), url);
EXPECT_TRUE(ExecuteJavascript("getUserMedia({video: true, audio: true});"));
@@ -64,6 +64,15 @@
ExpectTitle("OK");
}
+IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetAudioAndVideoStreamAndClone) {
+ GURL url(test_server()->GetURL("files/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+
+ EXPECT_TRUE(ExecuteJavascript("getUserMediaAndClone();"));
+
+ ExpectTitle("OK");
+}
+
// These tests will make a complete PeerConnection-based call and verify that
// video is playing for the call.
IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, CanSetupVideoCall) {
@@ -90,8 +99,7 @@
ExecuteJavascript("callAndSendDtmf('123,abc');"));
}
-// This test is flaky on Win XP, Win7 and Linux Precise. Disabling on all just
-// in case.
+// TODO(miu): Test is flaky. http://crbug.com/236102
IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
DISABLED_CanMakeEmptyCallThenAddStreamsAndRenegotiate) {
GURL url(test_server()->GetURL("files/media/peerconnection-call.html"));
@@ -108,8 +116,16 @@
// MSID and bundle attribute from the initial offer to verify that
// video is playing for the call even if the initiating client don't support
// MSID. http://tools.ietf.org/html/draft-alvestrand-rtcweb-msid-02
+// Disabled for win7_aura, see http://crbug.com/235089.
+#if defined(OS_WIN) && defined(USE_AURA)
+#define MAYBE_CanSetupAudioAndVideoCallWithoutMsidAndBundle\
+ DISABLED_CanSetupAudioAndVideoCallWithoutMsidAndBundle
+#else
+#define MAYBE_CanSetupAudioAndVideoCallWithoutMsidAndBundle\
+ CanSetupAudioAndVideoCallWithoutMsidAndBundle
+#endif
IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
- CanSetupAudioAndVideoCallWithoutMsidAndBundle) {
+ MAYBE_CanSetupAudioAndVideoCallWithoutMsidAndBundle) {
GURL url(test_server()->GetURL("files/media/peerconnection-call.html"));
NavigateToURL(shell(), url);
@@ -139,7 +155,7 @@
// This test will make a PeerConnection-based call and test an unreliable text
// dataChannel and later add an audio and video track.
-// Flaky. http://crbug.com/175683
+// TODO(perkj): Fix flakiness. See: http://crbug.com/227409
IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
DISABLED_CallWithDataAndLaterAddMedia) {
GURL url(test_server()->GetURL("files/media/peerconnection-call.html"));
@@ -149,5 +165,30 @@
ExpectTitle("OK");
}
-} // namespace content
+// This test will make a PeerConnection-based call and send a new Video
+// MediaStream that has been created based on a MediaStream created with
+// getUserMedia.
+IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, CallWithNewVideoMediaStream) {
+ GURL url(test_server()->GetURL("files/media/peerconnection-call.html"));
+ NavigateToURL(shell(), url);
+ EXPECT_TRUE(ExecuteJavascript("callWithNewVideoMediaStream();"));
+ ExpectTitle("OK");
+}
+
+// This test will make a PeerConnection-based call and send a new Video
+// MediaStream that has been created based on a MediaStream created with
+// getUserMedia. When video is flowing, the VideoTrack is removed and an
+// AudioTrack is added instead.
+// TODO(phoglund): This test is manual since not all buildbots has an audio
+// input.
+IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MANUAL_CallAndModifyStream) {
+ GURL url(test_server()->GetURL("files/media/peerconnection-call.html"));
+ NavigateToURL(shell(), url);
+
+ EXPECT_TRUE(
+ ExecuteJavascript("callWithNewVideoMediaStreamLaterSwitchToAudio();"));
+ ExpectTitle("OK");
+}
+
+} // namespace content
diff --git a/content/browser/media/webrtc_internals.cc b/content/browser/media/webrtc_internals.cc
index 34703f5..efdba58 100644
--- a/content/browser/media/webrtc_internals.cc
+++ b/content/browser/media/webrtc_internals.cc
@@ -32,7 +32,7 @@
} // namespace
-WebRTCInternals::WebRTCInternals() {
+WebRTCInternals::WebRTCInternals() : is_recording_rtp_(false) {
registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED,
NotificationService::AllBrowserContextsAndSources());
@@ -47,12 +47,12 @@
return Singleton<WebRTCInternals>::get();
}
-void WebRTCInternals::AddPeerConnection(int render_process_id,
- ProcessId pid,
- int lid,
- const string& url,
- const string& servers,
- const string& constraints) {
+void WebRTCInternals::OnAddPeerConnection(int render_process_id,
+ ProcessId pid,
+ int lid,
+ const string& url,
+ const string& servers,
+ const string& constraints) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DictionaryValue* dict = new DictionaryValue();
@@ -71,7 +71,7 @@
SendUpdate("addPeerConnection", dict);
}
-void WebRTCInternals::RemovePeerConnection(ProcessId pid, int lid) {
+void WebRTCInternals::OnRemovePeerConnection(ProcessId pid, int lid) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
for (size_t i = 0; i < peer_connection_data_.GetSize(); ++i) {
DictionaryValue* dict = NULL;
@@ -97,7 +97,7 @@
}
}
-void WebRTCInternals::UpdatePeerConnection(
+void WebRTCInternals::OnUpdatePeerConnection(
ProcessId pid, int lid, const string& type, const string& value) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -138,8 +138,8 @@
}
}
-void WebRTCInternals::AddStats(base::ProcessId pid, int lid,
- const base::ListValue& value) {
+void WebRTCInternals::OnAddStats(base::ProcessId pid, int lid,
+ const base::ListValue& value) {
if (observers_.size() == 0)
return;
@@ -171,6 +171,20 @@
SendUpdate("updateAllPeerConnections", &peer_connection_data_);
}
+void WebRTCInternals::StartRtpRecording() {
+ if (!is_recording_rtp_) {
+ is_recording_rtp_ = true;
+ // TODO(justinlin): start RTP recording.
+ }
+}
+
+void WebRTCInternals::StopRtpRecording() {
+ if (is_recording_rtp_) {
+ is_recording_rtp_ = false;
+ // TODO(justinlin): stop RTP recording.
+ }
+}
+
void WebRTCInternals::SendUpdate(const string& command, Value* value) {
DCHECK_GT(observers_.size(), (size_t)0);
@@ -219,4 +233,13 @@
}
}
+// TODO(justlin): Calls this method as necessary to update the recording status
+// UI.
+void WebRTCInternals::SendRtpRecordingUpdate() {
+ DCHECK(is_recording_rtp_);
+ DictionaryValue update;
+ // TODO(justinlin): Fill in |update| with values as appropriate.
+ SendUpdate("updateDumpStatus", &update);
+}
+
} // namespace content
diff --git a/content/browser/media/webrtc_internals.h b/content/browser/media/webrtc_internals.h
index 7baff52..c5b110e 100644
--- a/content/browser/media/webrtc_internals.h
+++ b/content/browser/media/webrtc_internals.h
@@ -22,7 +22,7 @@
// forwards the data to WebRTCInternalsUIObserver and
// sends data collecting commands to the renderers.
class CONTENT_EXPORT WebRTCInternals : public BrowserChildProcessObserver,
- public NotificationObserver{
+ public NotificationObserver {
public:
static WebRTCInternals* GetInstance();
@@ -34,29 +34,29 @@
// identify a PeerConnection, |url| is the url of the tab owning the
// PeerConnection, |servers| is the servers configuration, |constraints| is
// the media constraints used to initialize the PeerConnection.
- void AddPeerConnection(int render_process_id,
- base::ProcessId pid,
- int lid,
- const std::string& url,
- const std::string& servers,
- const std::string& constraints);
+ void OnAddPeerConnection(int render_process_id,
+ base::ProcessId pid,
+ int lid,
+ const std::string& url,
+ const std::string& servers,
+ const std::string& constraints);
// This method is called when PeerConnection is destroyed.
// |pid| is the renderer process id, |lid| is the renderer local id.
- void RemovePeerConnection(base::ProcessId pid, int lid);
+ void OnRemovePeerConnection(base::ProcessId pid, int lid);
// This method is called when a PeerConnection is updated.
// |pid| is the renderer process id, |lid| is the renderer local id,
// |type| is the update type, |value| is the detail of the update.
- void UpdatePeerConnection(base::ProcessId pid,
- int lid,
- const std::string& type,
- const std::string& value);
+ void OnUpdatePeerConnection(base::ProcessId pid,
+ int lid,
+ const std::string& type,
+ const std::string& value);
// This method is called when results from PeerConnectionInterface::GetStats
// are available. |pid| is the renderer process id, |lid| is the renderer
// local id, |value| is the list of stats reports.
- void AddStats(base::ProcessId pid, int lid, const base::ListValue& value);
+ void OnAddStats(base::ProcessId pid, int lid, const base::ListValue& value);
// Methods for adding or removing WebRTCInternalsUIObserver.
void AddObserver(WebRTCInternalsUIObserver *observer);
@@ -65,6 +65,10 @@
// Sends all update data to the observers.
void SendAllUpdates();
+ // Tells the renderer processes to start or stop recording RTP packets.
+ void StartRtpRecording();
+ void StopRtpRecording();
+
private:
friend struct DefaultSingletonTraits<WebRTCInternals>;
@@ -85,6 +89,8 @@
// Called when a renderer exits (including crashes).
void OnRendererExit(int render_process_id);
+ void SendRtpRecordingUpdate();
+
ObserverList<WebRTCInternalsUIObserver> observers_;
// |peer_connection_data_| is a list containing all the PeerConnection
@@ -102,6 +108,8 @@
base::ListValue peer_connection_data_;
NotificationRegistrar registrar_;
+
+ bool is_recording_rtp_;
};
} // namespace content
diff --git a/content/browser/media/webrtc_internals_browsertest.cc b/content/browser/media/webrtc_internals_browsertest.cc
index a497c3d..5dcb3a9 100644
--- a/content/browser/media/webrtc_internals_browsertest.cc
+++ b/content/browser/media/webrtc_internals_browsertest.cc
@@ -2,16 +2,47 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/command_line.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
+#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "content/shell/shell.h"
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"
+#include "net/test/spawned_test_server.h"
using std::string;
namespace content {
+struct SsrcEntry {
+ string GetSsrcAttributeString() const {
+ std::stringstream ss;
+ ss << "a=ssrc:" << id;
+ std::map<string, string>::const_iterator iter;
+ for (iter = properties.begin(); iter != properties.end(); ++iter) {
+ ss << " " << iter->first << ":" << iter->second;
+ }
+ return ss.str();
+ }
+
+ string GetAsJSON() const {
+ std::stringstream ss;
+ ss << "{";
+ std::map<string, string>::const_iterator iter;
+ for (iter = properties.begin(); iter != properties.end(); ++iter) {
+ if (iter != properties.begin())
+ ss << ",";
+ ss << "\"" << iter->first << "\":\"" << iter->second << "\"";
+ }
+ ss << "}";
+ return ss.str();
+ }
+
+ string id;
+ std::map<string, string> properties;
+};
+
struct EventEntry {
string type;
string value;
@@ -22,7 +53,7 @@
std::stringstream ss;
ss << "{timestamp:" << timestamp << ", values:[";
std::map<string, string>::const_iterator iter;
- for (iter = values.begin(); iter != values.end(); iter++) {
+ for (iter = values.begin(); iter != values.end(); ++iter) {
ss << "'" << iter->first << "','" << iter->second << "',";
}
ss << "]}";
@@ -36,8 +67,7 @@
struct StatsEntry {
string type;
string id;
- StatsUnit local;
- StatsUnit remote;
+ StatsUnit stats;
};
typedef std::map<string, std::vector<string> > StatsMap;
@@ -59,7 +89,7 @@
string getLogIdString() const {
std::stringstream ss;
- ss << pid_ << "-" << lid_ << "-log";
+ ss << pid_ << "-" << lid_ << "-update-log";
return ss.str();
}
@@ -91,11 +121,26 @@
WebRTCInternalsBrowserTest() {}
virtual ~WebRTCInternalsBrowserTest() {}
+ virtual void SetUpOnMainThread() OVERRIDE {
+ // We need fake devices in this test since we want to run on naked VMs. We
+ // assume this switch is set by default in content_browsertests.
+ ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kUseFakeDeviceForMediaStream));
+
+ ASSERT_TRUE(test_server()->Start());
+ }
+
protected:
bool ExecuteJavascript(const string& javascript) {
return ExecuteScript(shell()->web_contents(), javascript);
}
+ void ExpectTitle(const std::string& expected_title) const {
+ string16 expected_title16(ASCIIToUTF16(expected_title));
+ TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
+ EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
+ }
+
// Execute the javascript of addPeerConnection.
void ExecuteAddPeerConnectionJs(const PeerConnectionEntry& pc) {
std::stringstream ss;
@@ -145,12 +190,10 @@
std::stringstream ss;
ss << "var row = $('" << log_id << "').rows[" << (i + 1) << "];"
"var cell = row.lastChild;"
- "var type = cell.firstChild.textContent;"
- "var value = cell.lastChild.lastChild.value;"
- "window.domAutomationController.send(type + ':' + value);";
+ "window.domAutomationController.send(cell.firstChild.textContent);";
ASSERT_TRUE(ExecuteScriptAndExtractString(
shell()->web_contents(), ss.str(), &result));
- EXPECT_EQ(pc.events_[i].type + ":" + pc.events_[i].value, result);
+ EXPECT_EQ(pc.events_[i].type + pc.events_[i].value, result);
}
}
@@ -170,23 +213,18 @@
// Execute addStats and verifies that the stats table has the right content.
void ExecuteAndVerifyAddStats(
PeerConnectionEntry& pc, const string& type, const string& id,
- StatsUnit& local, StatsUnit& remote) {
- StatsEntry entry = {type, id, local, remote};
+ StatsUnit& stats) {
+ StatsEntry entry = {type, id, stats};
// Adds each new value to the map of stats history.
std::map<string, string>::iterator iter;
- for (iter = local.values.begin(); iter != local.values.end(); iter++) {
+ for (iter = stats.values.begin(); iter != stats.values.end(); iter++) {
pc.stats_[type + "-" + id][iter->first].push_back(iter->second);
}
- for (iter = remote.values.begin(); iter != remote.values.end(); iter++) {
- pc.stats_[type + "-" + id][iter->first].push_back(iter->second);
- }
-
std::stringstream ss;
ss << "{pid:" << pc.pid_ << ", lid:" << pc.lid_ << ","
"reports:[" << "{id:'" << id << "', type:'" << type << "', "
- "local:" << local.GetString() << ", "
- "remote:" << remote.GetString() << "}]}";
+ "stats:" << stats.GetString() << "}]}";
ASSERT_TRUE(ExecuteJavascript("addStats(" + ss.str() + ")"));
VerifyStatsTable(pc, entry);
@@ -195,18 +233,14 @@
// Verifies that the stats table has the right content.
void VerifyStatsTable(const PeerConnectionEntry& pc,
- const StatsEntry& report) {
+ const StatsEntry& report) {
string table_id =
pc.getIdString() + "-table-" + report.type + "-" + report.id;
VerifyElementWithId(table_id);
std::map<string, string>::const_iterator iter;
- for (iter = report.local.values.begin();
- iter != report.local.values.end(); iter++) {
- VerifyStatsTableRow(table_id, iter->first, iter->second);
- }
- for (iter = report.remote.values.begin();
- iter != report.remote.values.end(); iter++) {
+ for (iter = report.stats.values.begin();
+ iter != report.stats.values.end(); iter++) {
VerifyStatsTableRow(table_id, iter->first, iter->second);
}
}
@@ -254,7 +288,7 @@
ASSERT_TRUE(ExecuteScriptAndExtractBool(
shell()->web_contents(),
"window.domAutomationController.send("
- " graphViews['" + graph_id + "'] != null)",
+ "graphViews['" + graph_id + "'] != null)",
&result));
EXPECT_TRUE(result);
@@ -267,6 +301,17 @@
shell()->web_contents(), ss.str(), &actual_value));
EXPECT_EQ(value, actual_value);
}
+
+ // Get the JSON string of the ssrc info from the page.
+ string GetSsrcInfo(const string& ssrc_id) {
+ string result;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ shell()->web_contents(),
+ "window.domAutomationController.send(JSON.stringify("
+ "ssrcInfoManager.streamInfoContainer_['" + ssrc_id + "']))",
+ &result));
+ return result;
+ }
};
IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, AddAndRemovePeerConnection) {
@@ -321,8 +366,21 @@
PeerConnectionEntry pc_2(1, 1);
ExecuteAddPeerConnectionJs(pc_2);
- ExecuteAndVerifyUpdatePeerConnection(pc_2, "e2", "v2");
- ExecuteAndVerifyUpdatePeerConnection(pc_2, "e3", "v3");
+ SsrcEntry ssrc1, ssrc2;
+ ssrc1.id = "ssrcid1";
+ ssrc1.properties["msid"] = "mymsid";
+ ssrc2.id = "ssrcid2";
+ ssrc2.properties["label"] = "mylabel";
+ ssrc2.properties["cname"] = "mycname";
+
+ ExecuteAndVerifyUpdatePeerConnection(pc_2, "setRemoteDescription",
+ ssrc1.GetSsrcAttributeString());
+
+ ExecuteAndVerifyUpdatePeerConnection(pc_2, "setLocalDescription",
+ ssrc2.GetSsrcAttributeString());
+
+ EXPECT_EQ(ssrc1.GetAsJSON(), GetSsrcInfo(ssrc1.id));
+ EXPECT_EQ(ssrc2.GetAsJSON(), GetSsrcInfo(ssrc2.id));
}
// Tests that adding random named stats updates the dataSeries and graphs.
@@ -335,21 +393,18 @@
const string type = "ssrc";
const string id = "1234";
- StatsUnit local = {FAKE_TIME_STAMP};
- local.values["bitrate"] = "2000";
- local.values["framerate"] = "30";
- StatsUnit remote = {FAKE_TIME_STAMP};
- remote.values["jitter"] = "1";
- remote.values["rtt"] = "20";
+ StatsUnit stats = {FAKE_TIME_STAMP};
+ stats.values["bitrate"] = "2000";
+ stats.values["framerate"] = "30";
// Add new stats and verify the stats table and graphs.
- ExecuteAndVerifyAddStats(pc, type, id, local, remote);
+ ExecuteAndVerifyAddStats(pc, type, id, stats);
VerifyStatsGraph(pc);
// Update existing stats and verify the stats table and graphs.
- local.values["bitrate"] = "2001";
- local.values["framerate"] = "31";
- ExecuteAndVerifyAddStats(pc, type, id, local, remote);
+ stats.values["bitrate"] = "2001";
+ stats.values["framerate"] = "31";
+ ExecuteAndVerifyAddStats(pc, type, id, stats);
VerifyStatsGraph(pc);
}
@@ -361,15 +416,15 @@
PeerConnectionEntry pc(1, 0);
ExecuteAddPeerConnectionJs(pc);
- StatsUnit local = {FAKE_TIME_STAMP};
- local.values["googAvailableSendBandwidth"] = "1000000";
- local.values["googTargetEncBitrate"] = "1000";
- local.values["googActualEncBitrate"] = "1000000";
- local.values["googRetransmitBitrate"] = "10";
- local.values["googTransmitBitrate"] = "1000000";
+ StatsUnit stats = {FAKE_TIME_STAMP};
+ stats.values["googAvailableSendBandwidth"] = "1000000";
+ stats.values["googTargetEncBitrate"] = "1000";
+ stats.values["googActualEncBitrate"] = "1000000";
+ stats.values["googRetransmitBitrate"] = "10";
+ stats.values["googTransmitBitrate"] = "1000000";
const string stats_type = "bwe";
const string stats_id = "videobwe";
- ExecuteAndVerifyAddStats(pc, stats_type, stats_id, local, local);
+ ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);
string graph_id =
pc.getIdString() + "-" + stats_type + "-" + stats_id + "-bweCompound";
@@ -389,7 +444,7 @@
"window.domAutomationController.send("
" graphViews['" + graph_id + "'].getDataSeriesCount())",
&count));
- EXPECT_EQ((int)local.values.size(), count);
+ EXPECT_EQ((int)stats.values.size(), count);
}
// Tests that the total packet/byte count is converted to count per second,
@@ -414,18 +469,17 @@
const string converted_values[] = {"1000", "8000", "1000", "8000"};
// Send the first data point.
- StatsUnit remote = {FAKE_TIME_STAMP};
- StatsUnit local = {FAKE_TIME_STAMP};
+ StatsUnit stats = {FAKE_TIME_STAMP};
for (int i = 0; i < num_converted_stats; ++i)
- local.values[stats_names[i]] = first_value;
+ stats.values[stats_names[i]] = first_value;
- ExecuteAndVerifyAddStats(pc, stats_type, stats_id, local, remote);
+ ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);
// Send the second data point at 1000ms after the first data point.
- local.timestamp += 1000;
+ stats.timestamp += 1000;
for (int i = 0; i < num_converted_stats; ++i)
- local.values[stats_names[i]] = second_value;
- ExecuteAndVerifyAddStats(pc, stats_type, stats_id, local, remote);
+ stats.values[stats_names[i]] = second_value;
+ ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);
// Verifies the graph data matches converted_values.
string graph_id_prefix = pc.getIdString() + "-" + stats_type + "-" + stats_id;
@@ -435,4 +489,83 @@
}
}
+// Sanity check of the page content under a real PeerConnection call.
+IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, withRealPeerConnectionCall) {
+ // Start a peerconnection call in the first window.
+ GURL url(test_server()->GetURL("files/media/peerconnection-call.html"));
+ NavigateToURL(shell(), url);
+ ASSERT_TRUE(ExecuteJavascript("call({video:true});"));
+ ExpectTitle("OK");
+
+ // Open webrtc-internals in the second window.
+ GURL url2("chrome://webrtc-internals");
+ Shell* shell2 = CreateBrowser();
+ NavigateToURL(shell2, url2);
+
+ const int NUMBER_OF_PEER_CONNECTIONS = 2;
+
+ // Verifies the number of peerconnections.
+ int count = 0;
+ ASSERT_TRUE(ExecuteScriptAndExtractInt(
+ shell2->web_contents(),
+ "window.domAutomationController.send("
+ "$('peer-connections-list').getElementsByTagName('li').length);",
+ &count));
+ EXPECT_EQ(NUMBER_OF_PEER_CONNECTIONS, count);
+
+ // Verifies the the event tables.
+ ASSERT_TRUE(ExecuteScriptAndExtractInt(
+ shell2->web_contents(),
+ "window.domAutomationController.send($('peer-connections-list')"
+ ".getElementsByClassName('update-log-table').length);",
+ &count));
+ EXPECT_EQ(NUMBER_OF_PEER_CONNECTIONS, count);
+
+ ASSERT_TRUE(ExecuteScriptAndExtractInt(
+ shell2->web_contents(),
+ "window.domAutomationController.send($('peer-connections-list')"
+ ".getElementsByClassName('update-log-table')[0].rows.length);",
+ &count));
+ EXPECT_GT(count, 1);
+
+ ASSERT_TRUE(ExecuteScriptAndExtractInt(
+ shell2->web_contents(),
+ "window.domAutomationController.send($('peer-connections-list')"
+ ".getElementsByClassName('update-log-table')[1].rows.length);",
+ &count));
+ EXPECT_GT(count, 1);
+
+ // Wait until the stats table containers are created.
+ count = 0;
+ while (count != NUMBER_OF_PEER_CONNECTIONS) {
+ ASSERT_TRUE(ExecuteScriptAndExtractInt(
+ shell2->web_contents(),
+ "window.domAutomationController.send("
+ "$('peer-connections-list').getElementsByClassName("
+ "'stats-table-container').length);",
+ &count));
+ }
+
+ // Verifies each stats table having more than one rows.
+ bool result = false;
+ ASSERT_TRUE(ExecuteScriptAndExtractBool(
+ shell2->web_contents(),
+ "var tableContainers = $('peer-connections-list')"
+ ".getElementsByClassName('stats-table-container');"
+ "var result = true;"
+ "for (var i = 0; i < tableContainers.length && result; ++i) {"
+ "var tables = tableContainers[i].getElementsByTagName('table');"
+ "for (var j = 0; j < tables.length && result; ++j) {"
+ "result = (tables[j].rows.length > 1);"
+ "}"
+ "if (!result) {"
+ "console.log(tableContainers[i].innerHTML);"
+ "}"
+ "}"
+ "window.domAutomationController.send(result);",
+ &result));
+
+ EXPECT_TRUE(result);
+}
+
} // namespace content
diff --git a/content/browser/media/webrtc_internals_message_handler.cc b/content/browser/media/webrtc_internals_message_handler.cc
index 9545b9d..c89cfba 100644
--- a/content/browser/media/webrtc_internals_message_handler.cc
+++ b/content/browser/media/webrtc_internals_message_handler.cc
@@ -32,6 +32,14 @@
web_ui()->RegisterMessageCallback("getAllStats",
base::Bind(&WebRTCInternalsMessageHandler::OnGetAllStats,
base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback("startRtpRecording",
+ base::Bind(&WebRTCInternalsMessageHandler::OnStartRtpRecording,
+ base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback("stopRtpRecording",
+ base::Bind(&WebRTCInternalsMessageHandler::OnStopRtpRecording,
+ base::Unretained(this)));
}
void WebRTCInternalsMessageHandler::OnGetAllUpdates(
@@ -47,6 +55,16 @@
}
}
+void WebRTCInternalsMessageHandler::OnStartRtpRecording(
+ const base::ListValue* list) {
+ WebRTCInternals::GetInstance()->StartRtpRecording();
+}
+
+void WebRTCInternalsMessageHandler::OnStopRtpRecording(
+ const base::ListValue* list) {
+ WebRTCInternals::GetInstance()->StopRtpRecording();
+}
+
void WebRTCInternalsMessageHandler::OnUpdate(const std::string& command,
const base::Value* args) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
diff --git a/content/browser/media/webrtc_internals_message_handler.h b/content/browser/media/webrtc_internals_message_handler.h
index 9600a41..ee2059a 100644
--- a/content/browser/media/webrtc_internals_message_handler.h
+++ b/content/browser/media/webrtc_internals_message_handler.h
@@ -33,6 +33,8 @@
// Javascript message handler.
void OnGetAllUpdates(const base::ListValue* list);
void OnGetAllStats(const base::ListValue* list);
+ void OnStartRtpRecording(const base::ListValue* list);
+ void OnStopRtpRecording(const base::ListValue* list);
private:
DISALLOW_COPY_AND_ASSIGN(WebRTCInternalsMessageHandler);
diff --git a/content/browser/media/webrtc_internals_ui.cc b/content/browser/media/webrtc_internals_ui.cc
index 2137acb..5c4adc5 100644
--- a/content/browser/media/webrtc_internals_ui.cc
+++ b/content/browser/media/webrtc_internals_ui.cc
@@ -16,7 +16,7 @@
WebUIDataSource* CreateWebRTCInternalsHTMLSource() {
WebUIDataSource* source =
- WebUIDataSource::Create(chrome::kChromeUIWebRTCInternalsHost);
+ WebUIDataSource::Create(kChromeUIWebRTCInternalsHost);
source->SetJsonPath("strings.js");
source->AddResourcePath("webrtc_internals.js", IDR_WEBRTC_INTERNALS_JS);
diff --git a/content/browser/media/webrtc_internals_unittest.cc b/content/browser/media/webrtc_internals_unittest.cc
index c9237f0..58c7d8d 100644
--- a/content/browser/media/webrtc_internals_unittest.cc
+++ b/content/browser/media/webrtc_internals_unittest.cc
@@ -56,7 +56,7 @@
return prefix + kstatic_part1 + id + kstatic_part2 + suffix;
}
- MessageLoop io_loop_;
+ base::MessageLoop io_loop_;
TestBrowserThread io_thread_;
};
@@ -67,18 +67,18 @@
new MockWebRTCInternalsProxy());
WebRTCInternals::GetInstance()->AddObserver(observer.get());
WebRTCInternals::GetInstance()->RemoveObserver(observer.get());
- WebRTCInternals::GetInstance()->AddPeerConnection(
+ WebRTCInternals::GetInstance()->OnAddPeerConnection(
0, 3, 4, kUrl, kServers, kContraints);
EXPECT_EQ("", observer->command());
- WebRTCInternals::GetInstance()->RemovePeerConnection(3, 4);
+ WebRTCInternals::GetInstance()->OnRemovePeerConnection(3, 4);
}
TEST_F(WebRTCInternalsTest, SendAddPeerConnectionUpdate) {
scoped_ptr<MockWebRTCInternalsProxy> observer(
new MockWebRTCInternalsProxy());
WebRTCInternals::GetInstance()->AddObserver(observer.get());
- WebRTCInternals::GetInstance()->AddPeerConnection(
+ WebRTCInternals::GetInstance()->OnAddPeerConnection(
0, 1, 2, kUrl, kServers, kContraints);
EXPECT_EQ("addPeerConnection", observer->command());
@@ -100,16 +100,16 @@
EXPECT_EQ(kContraints, value);
WebRTCInternals::GetInstance()->RemoveObserver(observer.get());
- WebRTCInternals::GetInstance()->RemovePeerConnection(1, 2);
+ WebRTCInternals::GetInstance()->OnRemovePeerConnection(1, 2);
}
TEST_F(WebRTCInternalsTest, SendRemovePeerConnectionUpdate) {
scoped_ptr<MockWebRTCInternalsProxy> observer(
new MockWebRTCInternalsProxy());
WebRTCInternals::GetInstance()->AddObserver(observer.get());
- WebRTCInternals::GetInstance()->AddPeerConnection(
+ WebRTCInternals::GetInstance()->OnAddPeerConnection(
0, 1, 2, kUrl, kServers, kContraints);
- WebRTCInternals::GetInstance()->RemovePeerConnection(1, 2);
+ WebRTCInternals::GetInstance()->OnRemovePeerConnection(1, 2);
EXPECT_EQ("removePeerConnection", observer->command());
DictionaryValue* dict = NULL;
@@ -128,12 +128,12 @@
scoped_ptr<MockWebRTCInternalsProxy> observer(
new MockWebRTCInternalsProxy());
WebRTCInternals::GetInstance()->AddObserver(observer.get());
- WebRTCInternals::GetInstance()->AddPeerConnection(
+ WebRTCInternals::GetInstance()->OnAddPeerConnection(
0, 1, 2, kUrl, kServers, kContraints);
const string update_type = "fakeType";
const string update_value = "fakeValue";
- WebRTCInternals::GetInstance()->UpdatePeerConnection(
+ WebRTCInternals::GetInstance()->OnUpdatePeerConnection(
1, 2, update_type, update_value);
EXPECT_EQ("updatePeerConnection", observer->command());
@@ -153,7 +153,7 @@
EXPECT_TRUE(dict->GetString("value", &value));
EXPECT_EQ(update_value, value);
- WebRTCInternals::GetInstance()->RemovePeerConnection(1, 2);
+ WebRTCInternals::GetInstance()->OnRemovePeerConnection(1, 2);
WebRTCInternals::GetInstance()->RemoveObserver(observer.get());
}
diff --git a/content/browser/net/OWNERS b/content/browser/net/OWNERS
new file mode 100644
index 0000000..82e44d8
--- /dev/null
+++ b/content/browser/net/OWNERS
@@ -0,0 +1 @@
+erikwright@chromium.org
diff --git a/content/browser/net/sqlite_persistent_cookie_store.cc b/content/browser/net/sqlite_persistent_cookie_store.cc
new file mode 100644
index 0000000..2822e40
--- /dev/null
+++ b/content/browser/net/sqlite_persistent_cookie_store.cc
@@ -0,0 +1,1223 @@
+// 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/net/sqlite_persistent_cookie_store.h"
+
+#include <list>
+#include <map>
+#include <set>
+#include <utility>
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram.h"
+#include "base/sequenced_task_runner.h"
+#include "base/string_util.h"
+#include "base/stringprintf.h"
+#include "base/synchronization/lock.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "base/time.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/cookie_store_factory.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "net/cookies/canonical_cookie.h"
+#include "net/cookies/cookie_constants.h"
+#include "net/cookies/cookie_util.h"
+#include "sql/error_delegate_util.h"
+#include "sql/meta_table.h"
+#include "sql/statement.h"
+#include "sql/transaction.h"
+#include "third_party/sqlite/sqlite3.h"
+#include "webkit/quota/special_storage_policy.h"
+
+using base::Time;
+
+namespace content {
+
+// This class is designed to be shared between any client thread and the
+// background task runner. It batches operations and commits them on a timer.
+//
+// SQLitePersistentCookieStore::Load is called to load all cookies. It
+// delegates to Backend::Load, which posts a Backend::LoadAndNotifyOnDBThread
+// task to the background runner. This task calls Backend::ChainLoadCookies(),
+// which repeatedly posts itself to the BG runner to load each eTLD+1's cookies
+// in separate tasks. When this is complete, Backend::CompleteLoadOnIOThread is
+// posted to the client runner, which notifies the caller of
+// SQLitePersistentCookieStore::Load that the load is complete.
+//
+// If a priority load request is invoked via SQLitePersistentCookieStore::
+// LoadCookiesForKey, it is delegated to Backend::LoadCookiesForKey, which posts
+// Backend::LoadKeyAndNotifyOnDBThread to the BG runner. That routine loads just
+// that single domain key (eTLD+1)'s cookies, and posts a Backend::
+// CompleteLoadForKeyOnIOThread to the client runner to notify the caller of
+// SQLitePersistentCookieStore::LoadCookiesForKey that that load is complete.
+//
+// Subsequent to loading, mutations may be queued by any thread using
+// AddCookie, UpdateCookieAccessTime, and DeleteCookie. These are flushed to
+// disk on the BG runner every 30 seconds, 512 operations, or call to Flush(),
+// whichever occurs first.
+class SQLitePersistentCookieStore::Backend
+ : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> {
+ public:
+ Backend(
+ const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& client_task_runner,
+ const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
+ bool restore_old_session_cookies,
+ quota::SpecialStoragePolicy* special_storage_policy)
+ : path_(path),
+ db_(NULL),
+ num_pending_(0),
+ force_keep_session_state_(false),
+ initialized_(false),
+ corruption_detected_(false),
+ restore_old_session_cookies_(restore_old_session_cookies),
+ special_storage_policy_(special_storage_policy),
+ num_cookies_read_(0),
+ client_task_runner_(client_task_runner),
+ background_task_runner_(background_task_runner),
+ num_priority_waiting_(0),
+ total_priority_requests_(0) {
+ }
+
+ // Creates or loads the SQLite database.
+ void Load(const LoadedCallback& loaded_callback);
+
+ // Loads cookies for the domain key (eTLD+1).
+ void LoadCookiesForKey(const std::string& domain,
+ const LoadedCallback& loaded_callback);
+
+ // Batch a cookie addition.
+ void AddCookie(const net::CanonicalCookie& cc);
+
+ // Batch a cookie access time update.
+ void UpdateCookieAccessTime(const net::CanonicalCookie& cc);
+
+ // Batch a cookie deletion.
+ void DeleteCookie(const net::CanonicalCookie& cc);
+
+ // Commit pending operations as soon as possible.
+ void Flush(const base::Closure& callback);
+
+ // Commit any pending operations and close the database. This must be called
+ // before the object is destructed.
+ void Close();
+
+ void SetForceKeepSessionState();
+
+ private:
+ friend class base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend>;
+
+ class KillDatabaseErrorDelegate : public sql::ErrorDelegate {
+ public:
+ explicit KillDatabaseErrorDelegate(Backend* backend);
+
+ virtual ~KillDatabaseErrorDelegate() {}
+
+ // ErrorDelegate implementation.
+ virtual int OnError(int error,
+ sql::Connection* connection,
+ sql::Statement* stmt) OVERRIDE;
+
+ private:
+ // Do not increment the count on Backend, as that would create a circular
+ // reference (Backend -> Connection -> ErrorDelegate -> Backend).
+ Backend* backend_;
+
+ // True if the delegate has previously attempted to kill the database.
+ bool attempted_to_kill_database_;
+
+ DISALLOW_COPY_AND_ASSIGN(KillDatabaseErrorDelegate);
+ };
+
+ // You should call Close() before destructing this object.
+ ~Backend() {
+ DCHECK(!db_.get()) << "Close should have already been called.";
+ DCHECK(num_pending_ == 0 && pending_.empty());
+ }
+
+ // Database upgrade statements.
+ bool EnsureDatabaseVersion();
+
+ class PendingOperation {
+ public:
+ typedef enum {
+ COOKIE_ADD,
+ COOKIE_UPDATEACCESS,
+ COOKIE_DELETE,
+ } OperationType;
+
+ PendingOperation(OperationType op, const net::CanonicalCookie& cc)
+ : op_(op), cc_(cc) { }
+
+ OperationType op() const { return op_; }
+ const net::CanonicalCookie& cc() const { return cc_; }
+
+ private:
+ OperationType op_;
+ net::CanonicalCookie cc_;
+ };
+
+ private:
+ // Creates or loads the SQLite database on background runner.
+ void LoadAndNotifyInBackground(const LoadedCallback& loaded_callback,
+ const base::Time& posted_at);
+
+ // Loads cookies for the domain key (eTLD+1) on background runner.
+ void LoadKeyAndNotifyInBackground(const std::string& domains,
+ const LoadedCallback& loaded_callback,
+ const base::Time& posted_at);
+
+ // Notifies the CookieMonster when loading completes for a specific domain key
+ // or for all domain keys. Triggers the callback and passes it all cookies
+ // that have been loaded from DB since last IO notification.
+ void Notify(const LoadedCallback& loaded_callback, bool load_success);
+
+ // Sends notification when the entire store is loaded, and reports metrics
+ // for the total time to load and aggregated results from any priority loads
+ // that occurred.
+ void CompleteLoadInForeground(const LoadedCallback& loaded_callback,
+ bool load_success);
+
+ // Sends notification when a single priority load completes. Updates priority
+ // load metric data. The data is sent only after the final load completes.
+ void CompleteLoadForKeyInForeground(const LoadedCallback& loaded_callback,
+ bool load_success);
+
+ // Sends all metrics, including posting a ReportMetricsInBackground task.
+ // Called after all priority and regular loading is complete.
+ void ReportMetrics();
+
+ // Sends background-runner owned metrics (i.e., the combined duration of all
+ // BG-runner tasks).
+ void ReportMetricsInBackground();
+
+ // Initialize the data base.
+ bool InitializeDatabase();
+
+ // Loads cookies for the next domain key from the DB, then either reschedules
+ // itself or schedules the provided callback to run on the client runner (if
+ // all domains are loaded).
+ void ChainLoadCookies(const LoadedCallback& loaded_callback);
+
+ // Load all cookies for a set of domains/hosts
+ bool LoadCookiesForDomains(const std::set<std::string>& key);
+
+ // Batch a cookie operation (add or delete)
+ void BatchOperation(PendingOperation::OperationType op,
+ const net::CanonicalCookie& cc);
+ // Commit our pending operations to the database.
+ void Commit();
+ // Close() executed on the background runner.
+ void InternalBackgroundClose();
+
+ void DeleteSessionCookiesOnStartup();
+
+ void DeleteSessionCookiesOnShutdown();
+
+ void KillDatabase();
+ void ScheduleKillDatabase();
+
+ void PostBackgroundTask(const tracked_objects::Location& origin,
+ const base::Closure& task);
+ void PostClientTask(const tracked_objects::Location& origin,
+ const base::Closure& task);
+
+ base::FilePath path_;
+ scoped_ptr<sql::Connection> db_;
+ sql::MetaTable meta_table_;
+
+ typedef std::list<PendingOperation*> PendingOperationsList;
+ PendingOperationsList pending_;
+ PendingOperationsList::size_type num_pending_;
+ // True if the persistent store should skip delete on exit rules.
+ bool force_keep_session_state_;
+ // Guard |cookies_|, |pending_|, |num_pending_|, |force_keep_session_state_|
+ base::Lock lock_;
+
+ // Temporary buffer for cookies loaded from DB. Accumulates cookies to reduce
+ // the number of messages sent to the client runner. Sent back in response to
+ // individual load requests for domain keys or when all loading completes.
+ std::vector<net::CanonicalCookie*> cookies_;
+
+ // Map of domain keys(eTLD+1) to domains/hosts that are to be loaded from DB.
+ std::map<std::string, std::set<std::string> > keys_to_load_;
+
+ // Map of (domain keys(eTLD+1), is secure cookie) to number of cookies in the
+ // database.
+ typedef std::pair<std::string, bool> CookieOrigin;
+ typedef std::map<CookieOrigin, int> CookiesPerOriginMap;
+ CookiesPerOriginMap cookies_per_origin_;
+
+ // Indicates if DB has been initialized.
+ bool initialized_;
+
+ // Indicates if the kill-database callback has been scheduled.
+ bool corruption_detected_;
+
+ // If false, we should filter out session cookies when reading the DB.
+ bool restore_old_session_cookies_;
+
+ // Policy defining what data is deleted on shutdown.
+ scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
+
+ // The cumulative time spent loading the cookies on the background runner.
+ // Incremented and reported from the background runner.
+ base::TimeDelta cookie_load_duration_;
+
+ // The total number of cookies read. Incremented and reported on the
+ // background runner.
+ int num_cookies_read_;
+
+ scoped_refptr<base::SequencedTaskRunner> client_task_runner_;
+ scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
+
+ // Guards the following metrics-related properties (only accessed when
+ // starting/completing priority loads or completing the total load).
+ base::Lock metrics_lock_;
+ int num_priority_waiting_;
+ // The total number of priority requests.
+ int total_priority_requests_;
+ // The time when |num_priority_waiting_| incremented to 1.
+ base::Time current_priority_wait_start_;
+ // The cumulative duration of time when |num_priority_waiting_| was greater
+ // than 1.
+ base::TimeDelta priority_wait_duration_;
+
+ DISALLOW_COPY_AND_ASSIGN(Backend);
+};
+
+SQLitePersistentCookieStore::Backend::KillDatabaseErrorDelegate::
+KillDatabaseErrorDelegate(Backend* backend)
+ : backend_(backend),
+ attempted_to_kill_database_(false) {
+}
+
+int SQLitePersistentCookieStore::Backend::KillDatabaseErrorDelegate::OnError(
+ int error, sql::Connection* connection, sql::Statement* stmt) {
+ // Do not attempt to kill database more than once. If the first time failed,
+ // it is unlikely that a second time will be successful.
+ if (!attempted_to_kill_database_ && sql::IsErrorCatastrophic(error)) {
+ attempted_to_kill_database_ = true;
+
+ backend_->ScheduleKillDatabase();
+ }
+
+ return error;
+}
+
+namespace {
+
+// Version number of the database.
+//
+// Version 6 adds cookie priorities. This allows developers to influence the
+// order in which cookies are evicted in order to meet domain cookie limits.
+//
+// Version 5 adds the columns has_expires and is_persistent, so that the
+// database can store session cookies as well as persistent cookies. Databases
+// of version 5 are incompatible with older versions of code. If a database of
+// version 5 is read by older code, session cookies will be treated as normal
+// cookies. Currently, these fields are written, but not read anymore.
+//
+// In version 4, we migrated the time epoch. If you open the DB with an older
+// version on Mac or Linux, the times will look wonky, but the file will likely
+// be usable. On Windows version 3 and 4 are the same.
+//
+// Version 3 updated the database to include the last access time, so we can
+// expire them in decreasing order of use when we've reached the maximum
+// number of cookies.
+const int kCurrentVersionNumber = 6;
+const int kCompatibleVersionNumber = 5;
+
+// Possible values for the 'priority' column.
+enum DBCookiePriority {
+ kCookiePriorityLow = 0,
+ kCookiePriorityMedium = 1,
+ kCookiePriorityHigh = 2,
+};
+
+DBCookiePriority CookiePriorityToDBCookiePriority(net::CookiePriority value) {
+ switch (value) {
+ case net::COOKIE_PRIORITY_LOW:
+ return kCookiePriorityLow;
+ case net::COOKIE_PRIORITY_MEDIUM:
+ return kCookiePriorityMedium;
+ case net::COOKIE_PRIORITY_HIGH:
+ return kCookiePriorityHigh;
+ }
+
+ NOTREACHED();
+ return kCookiePriorityMedium;
+}
+
+net::CookiePriority DBCookiePriorityToCookiePriority(DBCookiePriority value) {
+ switch (value) {
+ case kCookiePriorityLow:
+ return net::COOKIE_PRIORITY_LOW;
+ case kCookiePriorityMedium:
+ return net::COOKIE_PRIORITY_MEDIUM;
+ case kCookiePriorityHigh:
+ return net::COOKIE_PRIORITY_HIGH;
+ }
+
+ NOTREACHED();
+ return net::COOKIE_PRIORITY_DEFAULT;
+}
+
+// Increments a specified TimeDelta by the duration between this object's
+// constructor and destructor. Not thread safe. Multiple instances may be
+// created with the same delta instance as long as their lifetimes are nested.
+// The shortest lived instances have no impact.
+class IncrementTimeDelta {
+ public:
+ explicit IncrementTimeDelta(base::TimeDelta* delta) :
+ delta_(delta),
+ original_value_(*delta),
+ start_(base::Time::Now()) {}
+
+ ~IncrementTimeDelta() {
+ *delta_ = original_value_ + base::Time::Now() - start_;
+ }
+
+ private:
+ base::TimeDelta* delta_;
+ base::TimeDelta original_value_;
+ base::Time start_;
+
+ DISALLOW_COPY_AND_ASSIGN(IncrementTimeDelta);
+};
+
+// Initializes the cookies table, returning true on success.
+bool InitTable(sql::Connection* db) {
+ if (!db->DoesTableExist("cookies")) {
+ std::string stmt(base::StringPrintf(
+ "CREATE TABLE cookies ("
+ "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY,"
+ "host_key TEXT NOT NULL,"
+ "name TEXT NOT NULL,"
+ "value TEXT NOT NULL,"
+ "path TEXT NOT NULL,"
+ "expires_utc INTEGER NOT NULL,"
+ "secure INTEGER NOT NULL,"
+ "httponly INTEGER NOT NULL,"
+ "last_access_utc INTEGER NOT NULL, "
+ "has_expires INTEGER NOT NULL DEFAULT 1, "
+ "persistent INTEGER NOT NULL DEFAULT 1,"
+ "priority INTEGER NOT NULL DEFAULT %d)",
+ CookiePriorityToDBCookiePriority(net::COOKIE_PRIORITY_DEFAULT)));
+ if (!db->Execute(stmt.c_str()))
+ return false;
+ }
+
+ // Older code created an index on creation_utc, which is already
+ // primary key for the table.
+ if (!db->Execute("DROP INDEX IF EXISTS cookie_times"))
+ return false;
+
+ if (!db->Execute("CREATE INDEX IF NOT EXISTS domain ON cookies(host_key)"))
+ return false;
+
+ return true;
+}
+
+} // namespace
+
+void SQLitePersistentCookieStore::Backend::Load(
+ const LoadedCallback& loaded_callback) {
+ // This function should be called only once per instance.
+ DCHECK(!db_.get());
+ PostBackgroundTask(FROM_HERE, base::Bind(
+ &Backend::LoadAndNotifyInBackground, this,
+ loaded_callback, base::Time::Now()));
+}
+
+void SQLitePersistentCookieStore::Backend::LoadCookiesForKey(
+ const std::string& key,
+ const LoadedCallback& loaded_callback) {
+ {
+ base::AutoLock locked(metrics_lock_);
+ if (num_priority_waiting_ == 0)
+ current_priority_wait_start_ = base::Time::Now();
+ num_priority_waiting_++;
+ total_priority_requests_++;
+ }
+
+ PostBackgroundTask(FROM_HERE, base::Bind(
+ &Backend::LoadKeyAndNotifyInBackground,
+ this, key, loaded_callback, base::Time::Now()));
+}
+
+void SQLitePersistentCookieStore::Backend::LoadAndNotifyInBackground(
+ const LoadedCallback& loaded_callback, const base::Time& posted_at) {
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
+ IncrementTimeDelta increment(&cookie_load_duration_);
+
+ UMA_HISTOGRAM_CUSTOM_TIMES(
+ "Cookie.TimeLoadDBQueueWait",
+ base::Time::Now() - posted_at,
+ base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
+ 50);
+
+ if (!InitializeDatabase()) {
+ PostClientTask(FROM_HERE, base::Bind(
+ &Backend::CompleteLoadInForeground, this, loaded_callback, false));
+ } else {
+ ChainLoadCookies(loaded_callback);
+ }
+}
+
+void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyInBackground(
+ const std::string& key,
+ const LoadedCallback& loaded_callback,
+ const base::Time& posted_at) {
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
+ IncrementTimeDelta increment(&cookie_load_duration_);
+
+ UMA_HISTOGRAM_CUSTOM_TIMES(
+ "Cookie.TimeKeyLoadDBQueueWait",
+ base::Time::Now() - posted_at,
+ base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
+ 50);
+
+ bool success = false;
+ if (InitializeDatabase()) {
+ std::map<std::string, std::set<std::string> >::iterator
+ it = keys_to_load_.find(key);
+ if (it != keys_to_load_.end()) {
+ success = LoadCookiesForDomains(it->second);
+ keys_to_load_.erase(it);
+ } else {
+ success = true;
+ }
+ }
+
+ PostClientTask(FROM_HERE, base::Bind(
+ &SQLitePersistentCookieStore::Backend::CompleteLoadForKeyInForeground,
+ this, loaded_callback, success));
+}
+
+void SQLitePersistentCookieStore::Backend::CompleteLoadForKeyInForeground(
+ const LoadedCallback& loaded_callback,
+ bool load_success) {
+ DCHECK(client_task_runner_->RunsTasksOnCurrentThread());
+
+ Notify(loaded_callback, load_success);
+
+ {
+ base::AutoLock locked(metrics_lock_);
+ num_priority_waiting_--;
+ if (num_priority_waiting_ == 0) {
+ priority_wait_duration_ +=
+ base::Time::Now() - current_priority_wait_start_;
+ }
+ }
+
+}
+
+void SQLitePersistentCookieStore::Backend::ReportMetricsInBackground() {
+ UMA_HISTOGRAM_CUSTOM_TIMES(
+ "Cookie.TimeLoad",
+ cookie_load_duration_,
+ base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
+ 50);
+}
+
+void SQLitePersistentCookieStore::Backend::ReportMetrics() {
+ PostBackgroundTask(FROM_HERE, base::Bind(
+ &SQLitePersistentCookieStore::Backend::ReportMetricsInBackground, this));
+
+ {
+ base::AutoLock locked(metrics_lock_);
+ UMA_HISTOGRAM_CUSTOM_TIMES(
+ "Cookie.PriorityBlockingTime",
+ priority_wait_duration_,
+ base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
+ 50);
+
+ UMA_HISTOGRAM_COUNTS_100(
+ "Cookie.PriorityLoadCount",
+ total_priority_requests_);
+
+ UMA_HISTOGRAM_COUNTS_10000(
+ "Cookie.NumberOfLoadedCookies",
+ num_cookies_read_);
+ }
+}
+
+void SQLitePersistentCookieStore::Backend::CompleteLoadInForeground(
+ const LoadedCallback& loaded_callback, bool load_success) {
+ Notify(loaded_callback, load_success);
+
+ if (load_success)
+ ReportMetrics();
+}
+
+void SQLitePersistentCookieStore::Backend::Notify(
+ const LoadedCallback& loaded_callback,
+ bool load_success) {
+ DCHECK(client_task_runner_->RunsTasksOnCurrentThread());
+
+ std::vector<net::CanonicalCookie*> cookies;
+ {
+ base::AutoLock locked(lock_);
+ cookies.swap(cookies_);
+ }
+
+ loaded_callback.Run(cookies);
+}
+
+bool SQLitePersistentCookieStore::Backend::InitializeDatabase() {
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
+
+ if (initialized_ || corruption_detected_) {
+ // Return false if we were previously initialized but the DB has since been
+ // closed, or if corruption caused a database reset during initialization.
+ return db_ != NULL;
+ }
+
+ base::Time start = base::Time::Now();
+
+ const base::FilePath dir = path_.DirName();
+ if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) {
+ return false;
+ }
+
+ int64 db_size = 0;
+ if (file_util::GetFileSize(path_, &db_size))
+ UMA_HISTOGRAM_COUNTS("Cookie.DBSizeInKB", db_size / 1024 );
+
+ db_.reset(new sql::Connection);
+ db_->set_error_histogram_name("Sqlite.Cookie.Error");
+ db_->set_error_delegate(new KillDatabaseErrorDelegate(this));
+
+ if (!db_->Open(path_)) {
+ NOTREACHED() << "Unable to open cookie DB.";
+ if (corruption_detected_)
+ db_->Raze();
+ meta_table_.Reset();
+ db_.reset();
+ return false;
+ }
+
+ if (!EnsureDatabaseVersion() || !InitTable(db_.get())) {
+ NOTREACHED() << "Unable to open cookie DB.";
+ if (corruption_detected_)
+ db_->Raze();
+ meta_table_.Reset();
+ db_.reset();
+ return false;
+ }
+
+ UMA_HISTOGRAM_CUSTOM_TIMES(
+ "Cookie.TimeInitializeDB",
+ base::Time::Now() - start,
+ base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
+ 50);
+
+ start = base::Time::Now();
+
+ // Retrieve all the domains
+ sql::Statement smt(db_->GetUniqueStatement(
+ "SELECT DISTINCT host_key FROM cookies"));
+
+ if (!smt.is_valid()) {
+ if (corruption_detected_)
+ db_->Raze();
+ meta_table_.Reset();
+ db_.reset();
+ return false;
+ }
+
+ // Build a map of domain keys (always eTLD+1) to domains.
+ while (smt.Step()) {
+ std::string domain = smt.ColumnString(0);
+ std::string key =
+ net::RegistryControlledDomainService::GetDomainAndRegistry(domain);
+
+ std::map<std::string, std::set<std::string> >::iterator it =
+ keys_to_load_.find(key);
+ if (it == keys_to_load_.end())
+ it = keys_to_load_.insert(std::make_pair
+ (key, std::set<std::string>())).first;
+ it->second.insert(domain);
+ }
+
+ UMA_HISTOGRAM_CUSTOM_TIMES(
+ "Cookie.TimeInitializeDomainMap",
+ base::Time::Now() - start,
+ base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
+ 50);
+
+ initialized_ = true;
+ return true;
+}
+
+void SQLitePersistentCookieStore::Backend::ChainLoadCookies(
+ const LoadedCallback& loaded_callback) {
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
+ IncrementTimeDelta increment(&cookie_load_duration_);
+
+ bool load_success = true;
+
+ if (!db_) {
+ // Close() has been called on this store.
+ load_success = false;
+ } else if (keys_to_load_.size() > 0) {
+ // Load cookies for the first domain key.
+ std::map<std::string, std::set<std::string> >::iterator
+ it = keys_to_load_.begin();
+ load_success = LoadCookiesForDomains(it->second);
+ keys_to_load_.erase(it);
+ }
+
+ // If load is successful and there are more domain keys to be loaded,
+ // then post a background task to continue chain-load;
+ // Otherwise notify on client runner.
+ if (load_success && keys_to_load_.size() > 0) {
+ PostBackgroundTask(FROM_HERE, base::Bind(
+ &Backend::ChainLoadCookies, this, loaded_callback));
+ } else {
+ PostClientTask(FROM_HERE, base::Bind(
+ &Backend::CompleteLoadInForeground, this,
+ loaded_callback, load_success));
+ if (load_success && !restore_old_session_cookies_)
+ DeleteSessionCookiesOnStartup();
+ }
+}
+
+bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains(
+ const std::set<std::string>& domains) {
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
+
+ sql::Statement smt;
+ if (restore_old_session_cookies_) {
+ smt.Assign(db_->GetCachedStatement(
+ SQL_FROM_HERE,
+ "SELECT creation_utc, host_key, name, value, path, expires_utc, "
+ "secure, httponly, last_access_utc, has_expires, persistent, priority "
+ "FROM cookies WHERE host_key = ?"));
+ } else {
+ smt.Assign(db_->GetCachedStatement(
+ SQL_FROM_HERE,
+ "SELECT creation_utc, host_key, name, value, path, expires_utc, "
+ "secure, httponly, last_access_utc, has_expires, persistent, priority "
+ "FROM cookies WHERE host_key = ? AND persistent = 1"));
+ }
+ if (!smt.is_valid()) {
+ smt.Clear(); // Disconnect smt_ref from db_.
+ meta_table_.Reset();
+ db_.reset();
+ return false;
+ }
+
+ std::vector<net::CanonicalCookie*> cookies;
+ std::set<std::string>::const_iterator it = domains.begin();
+ for (; it != domains.end(); ++it) {
+ smt.BindString(0, *it);
+ while (smt.Step()) {
+ scoped_ptr<net::CanonicalCookie> cc(new net::CanonicalCookie(
+ // The "source" URL is not used with persisted cookies.
+ GURL(), // Source
+ smt.ColumnString(2), // name
+ smt.ColumnString(3), // value
+ smt.ColumnString(1), // domain
+ smt.ColumnString(4), // path
+ Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc
+ Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc
+ Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc
+ smt.ColumnInt(6) != 0, // secure
+ smt.ColumnInt(7) != 0, // httponly
+ DBCookiePriorityToCookiePriority(
+ static_cast<DBCookiePriority>(smt.ColumnInt(11))))); // priority
+ DLOG_IF(WARNING,
+ cc->CreationDate() > Time::Now()) << L"CreationDate too recent";
+ cookies_per_origin_[CookieOrigin(cc->Domain(), cc->IsSecure())]++;
+ cookies.push_back(cc.release());
+ ++num_cookies_read_;
+ }
+ smt.Reset(true);
+ }
+ {
+ base::AutoLock locked(lock_);
+ cookies_.insert(cookies_.end(), cookies.begin(), cookies.end());
+ }
+ return true;
+}
+
+bool SQLitePersistentCookieStore::Backend::EnsureDatabaseVersion() {
+ // Version check.
+ if (!meta_table_.Init(
+ db_.get(), kCurrentVersionNumber, kCompatibleVersionNumber)) {
+ return false;
+ }
+
+ if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
+ LOG(WARNING) << "Cookie database is too new.";
+ return false;
+ }
+
+ int cur_version = meta_table_.GetVersionNumber();
+ if (cur_version == 2) {
+ sql::Transaction transaction(db_.get());
+ if (!transaction.Begin())
+ return false;
+ if (!db_->Execute("ALTER TABLE cookies ADD COLUMN last_access_utc "
+ "INTEGER DEFAULT 0") ||
+ !db_->Execute("UPDATE cookies SET last_access_utc = creation_utc")) {
+ LOG(WARNING) << "Unable to update cookie database to version 3.";
+ return false;
+ }
+ ++cur_version;
+ meta_table_.SetVersionNumber(cur_version);
+ meta_table_.SetCompatibleVersionNumber(
+ std::min(cur_version, kCompatibleVersionNumber));
+ transaction.Commit();
+ }
+
+ if (cur_version == 3) {
+ // The time epoch changed for Mac & Linux in this version to match Windows.
+ // This patch came after the main epoch change happened, so some
+ // developers have "good" times for cookies added by the more recent
+ // versions. So we have to be careful to only update times that are under
+ // the old system (which will appear to be from before 1970 in the new
+ // system). The magic number used below is 1970 in our time units.
+ sql::Transaction transaction(db_.get());
+ transaction.Begin();
+#if !defined(OS_WIN)
+ ignore_result(db_->Execute(
+ "UPDATE cookies "
+ "SET creation_utc = creation_utc + 11644473600000000 "
+ "WHERE rowid IN "
+ "(SELECT rowid FROM cookies WHERE "
+ "creation_utc > 0 AND creation_utc < 11644473600000000)"));
+ ignore_result(db_->Execute(
+ "UPDATE cookies "
+ "SET expires_utc = expires_utc + 11644473600000000 "
+ "WHERE rowid IN "
+ "(SELECT rowid FROM cookies WHERE "
+ "expires_utc > 0 AND expires_utc < 11644473600000000)"));
+ ignore_result(db_->Execute(
+ "UPDATE cookies "
+ "SET last_access_utc = last_access_utc + 11644473600000000 "
+ "WHERE rowid IN "
+ "(SELECT rowid FROM cookies WHERE "
+ "last_access_utc > 0 AND last_access_utc < 11644473600000000)"));
+#endif
+ ++cur_version;
+ meta_table_.SetVersionNumber(cur_version);
+ transaction.Commit();
+ }
+
+ if (cur_version == 4) {
+ const base::TimeTicks start_time = base::TimeTicks::Now();
+ sql::Transaction transaction(db_.get());
+ if (!transaction.Begin())
+ return false;
+ if (!db_->Execute("ALTER TABLE cookies "
+ "ADD COLUMN has_expires INTEGER DEFAULT 1") ||
+ !db_->Execute("ALTER TABLE cookies "
+ "ADD COLUMN persistent INTEGER DEFAULT 1")) {
+ LOG(WARNING) << "Unable to update cookie database to version 5.";
+ return false;
+ }
+ ++cur_version;
+ meta_table_.SetVersionNumber(cur_version);
+ meta_table_.SetCompatibleVersionNumber(
+ std::min(cur_version, kCompatibleVersionNumber));
+ transaction.Commit();
+ UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV5",
+ base::TimeTicks::Now() - start_time);
+ }
+
+ if (cur_version == 5) {
+ const base::TimeTicks start_time = base::TimeTicks::Now();
+ sql::Transaction transaction(db_.get());
+ if (!transaction.Begin())
+ return false;
+ // Alter the table to add the priority column with a default value.
+ std::string stmt(base::StringPrintf(
+ "ALTER TABLE cookies ADD COLUMN priority INTEGER DEFAULT %d",
+ CookiePriorityToDBCookiePriority(net::COOKIE_PRIORITY_DEFAULT)));
+ if (!db_->Execute(stmt.c_str())) {
+ LOG(WARNING) << "Unable to update cookie database to version 6.";
+ return false;
+ }
+ ++cur_version;
+ meta_table_.SetVersionNumber(cur_version);
+ meta_table_.SetCompatibleVersionNumber(
+ std::min(cur_version, kCompatibleVersionNumber));
+ transaction.Commit();
+ UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV6",
+ base::TimeTicks::Now() - start_time);
+ }
+
+ // Put future migration cases here.
+
+ if (cur_version < kCurrentVersionNumber) {
+ UMA_HISTOGRAM_COUNTS_100("Cookie.CorruptMetaTable", 1);
+
+ meta_table_.Reset();
+ db_.reset(new sql::Connection);
+ if (!file_util::Delete(path_, false) ||
+ !db_->Open(path_) ||
+ !meta_table_.Init(
+ db_.get(), kCurrentVersionNumber, kCompatibleVersionNumber)) {
+ UMA_HISTOGRAM_COUNTS_100("Cookie.CorruptMetaTableRecoveryFailed", 1);
+ NOTREACHED() << "Unable to reset the cookie DB.";
+ meta_table_.Reset();
+ db_.reset();
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void SQLitePersistentCookieStore::Backend::AddCookie(
+ const net::CanonicalCookie& cc) {
+ BatchOperation(PendingOperation::COOKIE_ADD, cc);
+}
+
+void SQLitePersistentCookieStore::Backend::UpdateCookieAccessTime(
+ const net::CanonicalCookie& cc) {
+ BatchOperation(PendingOperation::COOKIE_UPDATEACCESS, cc);
+}
+
+void SQLitePersistentCookieStore::Backend::DeleteCookie(
+ const net::CanonicalCookie& cc) {
+ BatchOperation(PendingOperation::COOKIE_DELETE, cc);
+}
+
+void SQLitePersistentCookieStore::Backend::BatchOperation(
+ PendingOperation::OperationType op,
+ const net::CanonicalCookie& cc) {
+ // Commit every 30 seconds.
+ static const int kCommitIntervalMs = 30 * 1000;
+ // Commit right away if we have more than 512 outstanding operations.
+ static const size_t kCommitAfterBatchSize = 512;
+ DCHECK(!background_task_runner_->RunsTasksOnCurrentThread());
+
+ // We do a full copy of the cookie here, and hopefully just here.
+ scoped_ptr<PendingOperation> po(new PendingOperation(op, cc));
+
+ PendingOperationsList::size_type num_pending;
+ {
+ base::AutoLock locked(lock_);
+ pending_.push_back(po.release());
+ num_pending = ++num_pending_;
+ }
+
+ if (num_pending == 1) {
+ // We've gotten our first entry for this batch, fire off the timer.
+ if (!background_task_runner_->PostDelayedTask(
+ FROM_HERE, base::Bind(&Backend::Commit, this),
+ base::TimeDelta::FromMilliseconds(kCommitIntervalMs))) {
+ NOTREACHED() << "background_task_runner_ is not running.";
+ }
+ } else if (num_pending == kCommitAfterBatchSize) {
+ // We've reached a big enough batch, fire off a commit now.
+ PostBackgroundTask(FROM_HERE, base::Bind(&Backend::Commit, this));
+ }
+}
+
+void SQLitePersistentCookieStore::Backend::Commit() {
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
+
+ PendingOperationsList ops;
+ {
+ base::AutoLock locked(lock_);
+ pending_.swap(ops);
+ num_pending_ = 0;
+ }
+
+ // Maybe an old timer fired or we are already Close()'ed.
+ if (!db_.get() || ops.empty())
+ return;
+
+ sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE,
+ "INSERT INTO cookies (creation_utc, host_key, name, value, path, "
+ "expires_utc, secure, httponly, last_access_utc, has_expires, "
+ "persistent, priority) "
+ "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"));
+ if (!add_smt.is_valid())
+ return;
+
+ sql::Statement update_access_smt(db_->GetCachedStatement(SQL_FROM_HERE,
+ "UPDATE cookies SET last_access_utc=? WHERE creation_utc=?"));
+ if (!update_access_smt.is_valid())
+ return;
+
+ sql::Statement del_smt(db_->GetCachedStatement(SQL_FROM_HERE,
+ "DELETE FROM cookies WHERE creation_utc=?"));
+ if (!del_smt.is_valid())
+ return;
+
+ sql::Transaction transaction(db_.get());
+ if (!transaction.Begin())
+ return;
+
+ for (PendingOperationsList::iterator it = ops.begin();
+ it != ops.end(); ++it) {
+ // Free the cookies as we commit them to the database.
+ scoped_ptr<PendingOperation> po(*it);
+ switch (po->op()) {
+ case PendingOperation::COOKIE_ADD:
+ cookies_per_origin_[
+ CookieOrigin(po->cc().Domain(), po->cc().IsSecure())]++;
+ add_smt.Reset(true);
+ add_smt.BindInt64(0, po->cc().CreationDate().ToInternalValue());
+ add_smt.BindString(1, po->cc().Domain());
+ add_smt.BindString(2, po->cc().Name());
+ add_smt.BindString(3, po->cc().Value());
+ add_smt.BindString(4, po->cc().Path());
+ add_smt.BindInt64(5, po->cc().ExpiryDate().ToInternalValue());
+ add_smt.BindInt(6, po->cc().IsSecure());
+ add_smt.BindInt(7, po->cc().IsHttpOnly());
+ add_smt.BindInt64(8, po->cc().LastAccessDate().ToInternalValue());
+ add_smt.BindInt(9, po->cc().IsPersistent());
+ add_smt.BindInt(10, po->cc().IsPersistent());
+ add_smt.BindInt(
+ 11, CookiePriorityToDBCookiePriority(po->cc().Priority()));
+ if (!add_smt.Run())
+ NOTREACHED() << "Could not add a cookie to the DB.";
+ break;
+
+ case PendingOperation::COOKIE_UPDATEACCESS:
+ update_access_smt.Reset(true);
+ update_access_smt.BindInt64(0,
+ po->cc().LastAccessDate().ToInternalValue());
+ update_access_smt.BindInt64(1,
+ po->cc().CreationDate().ToInternalValue());
+ if (!update_access_smt.Run())
+ NOTREACHED() << "Could not update cookie last access time in the DB.";
+ break;
+
+ case PendingOperation::COOKIE_DELETE:
+ cookies_per_origin_[
+ CookieOrigin(po->cc().Domain(), po->cc().IsSecure())]--;
+ del_smt.Reset(true);
+ del_smt.BindInt64(0, po->cc().CreationDate().ToInternalValue());
+ if (!del_smt.Run())
+ NOTREACHED() << "Could not delete a cookie from the DB.";
+ break;
+
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+ bool succeeded = transaction.Commit();
+ UMA_HISTOGRAM_ENUMERATION("Cookie.BackingStoreUpdateResults",
+ succeeded ? 0 : 1, 2);
+}
+
+void SQLitePersistentCookieStore::Backend::Flush(
+ const base::Closure& callback) {
+ DCHECK(!background_task_runner_->RunsTasksOnCurrentThread());
+ PostBackgroundTask(FROM_HERE, base::Bind(&Backend::Commit, this));
+
+ if (!callback.is_null()) {
+ // We want the completion task to run immediately after Commit() returns.
+ // Posting it from here means there is less chance of another task getting
+ // onto the message queue first, than if we posted it from Commit() itself.
+ PostBackgroundTask(FROM_HERE, callback);
+ }
+}
+
+// Fire off a close message to the background runner. We could still have a
+// pending commit timer or Load operations holding references on us, but if/when
+// this fires we will already have been cleaned up and it will be ignored.
+void SQLitePersistentCookieStore::Backend::Close() {
+ if (background_task_runner_->RunsTasksOnCurrentThread()) {
+ InternalBackgroundClose();
+ } else {
+ // Must close the backend on the background runner.
+ PostBackgroundTask(FROM_HERE,
+ base::Bind(&Backend::InternalBackgroundClose, this));
+ }
+}
+
+void SQLitePersistentCookieStore::Backend::InternalBackgroundClose() {
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
+ // Commit any pending operations
+ Commit();
+
+ if (!force_keep_session_state_ && special_storage_policy_.get() &&
+ special_storage_policy_->HasSessionOnlyOrigins()) {
+ DeleteSessionCookiesOnShutdown();
+ }
+
+ meta_table_.Reset();
+ db_.reset();
+}
+
+void SQLitePersistentCookieStore::Backend::DeleteSessionCookiesOnShutdown() {
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
+
+ if (!db_)
+ return;
+
+ if (!special_storage_policy_)
+ return;
+
+ sql::Statement del_smt(db_->GetCachedStatement(
+ SQL_FROM_HERE, "DELETE FROM cookies WHERE host_key=? AND secure=?"));
+ if (!del_smt.is_valid()) {
+ LOG(WARNING) << "Unable to delete cookies on shutdown.";
+ return;
+ }
+
+ sql::Transaction transaction(db_.get());
+ if (!transaction.Begin()) {
+ LOG(WARNING) << "Unable to delete cookies on shutdown.";
+ return;
+ }
+
+ for (CookiesPerOriginMap::iterator it = cookies_per_origin_.begin();
+ it != cookies_per_origin_.end(); ++it) {
+ if (it->second <= 0) {
+ DCHECK_EQ(0, it->second);
+ continue;
+ }
+ const GURL url(net::cookie_util::CookieOriginToURL(it->first.first,
+ it->first.second));
+ if (!url.is_valid() || !special_storage_policy_->IsStorageSessionOnly(url))
+ continue;
+
+ del_smt.Reset(true);
+ del_smt.BindString(0, it->first.first);
+ del_smt.BindInt(1, it->first.second);
+ if (!del_smt.Run())
+ NOTREACHED() << "Could not delete a cookie from the DB.";
+ }
+
+ if (!transaction.Commit())
+ LOG(WARNING) << "Unable to delete cookies on shutdown.";
+}
+
+void SQLitePersistentCookieStore::Backend::ScheduleKillDatabase() {
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
+
+ corruption_detected_ = true;
+
+ // Don't just do the close/delete here, as we are being called by |db| and
+ // that seems dangerous.
+ PostBackgroundTask(FROM_HERE, base::Bind(&Backend::KillDatabase, this));
+}
+
+void SQLitePersistentCookieStore::Backend::KillDatabase() {
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
+
+ if (db_) {
+ // This Backend will now be in-memory only. In a future run we will recreate
+ // the database. Hopefully things go better then!
+ bool success = db_->RazeAndClose();
+ UMA_HISTOGRAM_BOOLEAN("Cookie.KillDatabaseResult", success);
+ meta_table_.Reset();
+ db_.reset();
+ }
+}
+
+void SQLitePersistentCookieStore::Backend::SetForceKeepSessionState() {
+ base::AutoLock locked(lock_);
+ force_keep_session_state_ = true;
+}
+
+void SQLitePersistentCookieStore::Backend::DeleteSessionCookiesOnStartup() {
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
+ if (!db_->Execute("DELETE FROM cookies WHERE persistent == 0"))
+ LOG(WARNING) << "Unable to delete session cookies.";
+}
+
+void SQLitePersistentCookieStore::Backend::PostBackgroundTask(
+ const tracked_objects::Location& origin, const base::Closure& task) {
+ if (!background_task_runner_->PostTask(origin, task)) {
+ LOG(WARNING) << "Failed to post task from " << origin.ToString()
+ << " to background_task_runner_.";
+ }
+}
+
+void SQLitePersistentCookieStore::Backend::PostClientTask(
+ const tracked_objects::Location& origin, const base::Closure& task) {
+ if (!client_task_runner_->PostTask(origin, task)) {
+ LOG(WARNING) << "Failed to post task from " << origin.ToString()
+ << " to client_task_runner_.";
+ }
+}
+
+SQLitePersistentCookieStore::SQLitePersistentCookieStore(
+ const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& client_task_runner,
+ const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
+ bool restore_old_session_cookies,
+ quota::SpecialStoragePolicy* special_storage_policy)
+ : backend_(new Backend(path,
+ client_task_runner,
+ background_task_runner,
+ restore_old_session_cookies,
+ special_storage_policy)) {
+}
+
+void SQLitePersistentCookieStore::Load(const LoadedCallback& loaded_callback) {
+ backend_->Load(loaded_callback);
+}
+
+void SQLitePersistentCookieStore::LoadCookiesForKey(
+ const std::string& key,
+ const LoadedCallback& loaded_callback) {
+ backend_->LoadCookiesForKey(key, loaded_callback);
+}
+
+void SQLitePersistentCookieStore::AddCookie(const net::CanonicalCookie& cc) {
+ backend_->AddCookie(cc);
+}
+
+void SQLitePersistentCookieStore::UpdateCookieAccessTime(
+ const net::CanonicalCookie& cc) {
+ backend_->UpdateCookieAccessTime(cc);
+}
+
+void SQLitePersistentCookieStore::DeleteCookie(const net::CanonicalCookie& cc) {
+ backend_->DeleteCookie(cc);
+}
+
+void SQLitePersistentCookieStore::SetForceKeepSessionState() {
+ backend_->SetForceKeepSessionState();
+}
+
+void SQLitePersistentCookieStore::Flush(const base::Closure& callback) {
+ backend_->Flush(callback);
+}
+
+SQLitePersistentCookieStore::~SQLitePersistentCookieStore() {
+ backend_->Close();
+ // We release our reference to the Backend, though it will probably still have
+ // a reference if the background runner has not run Close() yet.
+}
+
+net::CookieStore* CreatePersistentCookieStore(
+ const base::FilePath& path,
+ bool restore_old_session_cookies,
+ quota::SpecialStoragePolicy* storage_policy,
+ net::CookieMonster::Delegate* cookie_monster_delegate) {
+ SQLitePersistentCookieStore* persistent_store =
+ new SQLitePersistentCookieStore(
+ path,
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
+ BrowserThread::GetBlockingPool()->GetSequencedTaskRunner(
+ BrowserThread::GetBlockingPool()->GetSequenceToken()),
+ restore_old_session_cookies,
+ storage_policy);
+ return new net::CookieMonster(persistent_store, cookie_monster_delegate);
+}
+
+} // namespace content
diff --git a/content/browser/net/sqlite_persistent_cookie_store.h b/content/browser/net/sqlite_persistent_cookie_store.h
new file mode 100644
index 0000000..65e3982
--- /dev/null
+++ b/content/browser/net/sqlite_persistent_cookie_store.h
@@ -0,0 +1,77 @@
+// 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.
+
+// A sqlite implementation of a cookie monster persistent store.
+
+#ifndef CONTENT_BROWSER_NET_SQLITE_PERSISTENT_COOKIE_STORE_H_
+#define CONTENT_BROWSER_NET_SQLITE_PERSISTENT_COOKIE_STORE_H_
+
+#include <string>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "content/common/content_export.h"
+#include "net/cookies/cookie_monster.h"
+
+class Task;
+
+namespace base {
+class FilePath;
+class SequencedTaskRunner;
+}
+
+namespace net {
+class CanonicalCookie;
+}
+
+namespace quota {
+class SpecialStoragePolicy;
+}
+
+namespace content {
+
+// Implements the PersistentCookieStore interface in terms of a SQLite database.
+// For documentation about the actual member functions consult the documentation
+// of the parent class |net::CookieMonster::PersistentCookieStore|.
+// If provided, a |SpecialStoragePolicy| is consulted when the SQLite database
+// is closed to decide which cookies to keep.
+class CONTENT_EXPORT SQLitePersistentCookieStore
+ : public net::CookieMonster::PersistentCookieStore {
+ public:
+ // All blocking database accesses will be performed on
+ // |background_task_runner|, while |client_task_runner| is used to invoke
+ // callbacks.
+ SQLitePersistentCookieStore(
+ const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& client_task_runner,
+ const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
+ bool restore_old_session_cookies,
+ quota::SpecialStoragePolicy* special_storage_policy);
+
+ // net::CookieMonster::PersistentCookieStore:
+ virtual void Load(const LoadedCallback& loaded_callback) OVERRIDE;
+ virtual void LoadCookiesForKey(const std::string& key,
+ const LoadedCallback& callback) OVERRIDE;
+ virtual void AddCookie(const net::CanonicalCookie& cc) OVERRIDE;
+ virtual void UpdateCookieAccessTime(const net::CanonicalCookie& cc) OVERRIDE;
+ virtual void DeleteCookie(const net::CanonicalCookie& cc) OVERRIDE;
+ virtual void SetForceKeepSessionState() OVERRIDE;
+ virtual void Flush(const base::Closure& callback) OVERRIDE;
+
+ protected:
+ virtual ~SQLitePersistentCookieStore();
+
+ private:
+ class Backend;
+
+ scoped_refptr<Backend> backend_;
+
+ DISALLOW_COPY_AND_ASSIGN(SQLitePersistentCookieStore);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_NET_SQLITE_PERSISTENT_COOKIE_STORE_H_
diff --git a/content/browser/net/sqlite_persistent_cookie_store_perftest.cc b/content/browser/net/sqlite_persistent_cookie_store_perftest.cc
new file mode 100644
index 0000000..d43a843
--- /dev/null
+++ b/content/browser/net/sqlite_persistent_cookie_store_perftest.cc
@@ -0,0 +1,142 @@
+// 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/net/sqlite_persistent_cookie_store.h"
+
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/perftimer.h"
+#include "base/sequenced_task_runner.h"
+#include "base/stringprintf.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/test/sequenced_worker_pool_owner.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "googleurl/src/gurl.h"
+#include "net/cookies/canonical_cookie.h"
+#include "net/cookies/cookie_constants.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+const base::FilePath::CharType cookie_filename[] = FILE_PATH_LITERAL("Cookies");
+
+} // namespace
+
+class SQLitePersistentCookieStorePerfTest : public testing::Test {
+ public:
+ SQLitePersistentCookieStorePerfTest()
+ : pool_owner_(new base::SequencedWorkerPoolOwner(1, "Background Pool")),
+ loaded_event_(false, false),
+ key_loaded_event_(false, false) {
+ }
+
+ void OnLoaded(const std::vector<net::CanonicalCookie*>& cookies) {
+ cookies_ = cookies;
+ loaded_event_.Signal();
+ }
+
+ void OnKeyLoaded(const std::vector<net::CanonicalCookie*>& cookies) {
+ cookies_ = cookies;
+ key_loaded_event_.Signal();
+ }
+
+ void Load() {
+ store_->Load(base::Bind(&SQLitePersistentCookieStorePerfTest::OnLoaded,
+ base::Unretained(this)));
+ loaded_event_.Wait();
+ }
+
+ scoped_refptr<base::SequencedTaskRunner> background_task_runner() {
+ return pool_owner_->pool()->GetSequencedTaskRunner(
+ pool_owner_->pool()->GetNamedSequenceToken("background"));
+ }
+
+ scoped_refptr<base::SequencedTaskRunner> client_task_runner() {
+ return pool_owner_->pool()->GetSequencedTaskRunner(
+ pool_owner_->pool()->GetNamedSequenceToken("client"));
+ }
+
+ virtual void SetUp() OVERRIDE {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ store_ = new SQLitePersistentCookieStore(
+ temp_dir_.path().Append(cookie_filename),
+ client_task_runner(),
+ background_task_runner(),
+ false, NULL);
+ std::vector<net::CanonicalCookie*> cookies;
+ Load();
+ ASSERT_EQ(0u, cookies_.size());
+ // Creates 15000 cookies from 300 eTLD+1s.
+ base::Time t = base::Time::Now();
+ for (int domain_num = 0; domain_num < 300; domain_num++) {
+ std::string domain_name(base::StringPrintf(".domain_%d.com", domain_num));
+ GURL gurl("www" + domain_name);
+ for (int cookie_num = 0; cookie_num < 50; ++cookie_num) {
+ t += base::TimeDelta::FromInternalValue(10);
+ store_->AddCookie(
+ net::CanonicalCookie(gurl,
+ base::StringPrintf("Cookie_%d", cookie_num), "1",
+ domain_name, "/", t, t, t, false, false,
+ net::COOKIE_PRIORITY_DEFAULT));
+ }
+ }
+ // Replace the store effectively destroying the current one and forcing it
+ // to write its data to disk.
+ store_ = NULL;
+
+ // Shut down the pool, causing deferred (no-op) commits to be discarded.
+ pool_owner_->pool()->Shutdown();
+ // ~SequencedWorkerPoolOwner blocks on pool shutdown.
+ pool_owner_.reset(new base::SequencedWorkerPoolOwner(1, "pool"));
+
+ store_ = new SQLitePersistentCookieStore(
+ temp_dir_.path().Append(cookie_filename),
+ client_task_runner(),
+ background_task_runner(),
+ false, NULL);
+ }
+
+ virtual void TearDown() OVERRIDE {
+ store_ = NULL;
+ pool_owner_->pool()->Shutdown();
+ }
+
+ protected:
+ scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_;
+ base::WaitableEvent loaded_event_;
+ base::WaitableEvent key_loaded_event_;
+ std::vector<net::CanonicalCookie*> cookies_;
+ base::ScopedTempDir temp_dir_;
+ scoped_refptr<SQLitePersistentCookieStore> store_;
+};
+
+// Test the performance of priority load of cookies for a specfic domain key
+TEST_F(SQLitePersistentCookieStorePerfTest, TestLoadForKeyPerformance) {
+ for (int domain_num = 0; domain_num < 3; ++domain_num) {
+ std::string domain_name(base::StringPrintf("domain_%d.com", domain_num));
+ PerfTimeLogger timer(
+ ("Load cookies for the eTLD+1 " + domain_name).c_str());
+ store_->LoadCookiesForKey(domain_name,
+ base::Bind(&SQLitePersistentCookieStorePerfTest::OnKeyLoaded,
+ base::Unretained(this)));
+ key_loaded_event_.Wait();
+ timer.Done();
+
+ ASSERT_EQ(50U, cookies_.size());
+ }
+}
+
+// Test the performance of load
+TEST_F(SQLitePersistentCookieStorePerfTest, TestLoadPerformance) {
+ PerfTimeLogger timer("Load all cookies");
+ Load();
+ timer.Done();
+
+ ASSERT_EQ(15000U, cookies_.size());
+}
+
+} // namespace content
diff --git a/content/browser/net/sqlite_persistent_cookie_store_unittest.cc b/content/browser/net/sqlite_persistent_cookie_store_unittest.cc
new file mode 100644
index 0000000..cd0e078
--- /dev/null
+++ b/content/browser/net/sqlite_persistent_cookie_store_unittest.cc
@@ -0,0 +1,488 @@
+// 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/net/sqlite_persistent_cookie_store.h"
+
+#include <map>
+#include <set>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop.h"
+#include "base/sequenced_task_runner.h"
+#include "base/stl_util.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/test/sequenced_worker_pool_owner.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "base/time.h"
+#include "googleurl/src/gurl.h"
+#include "net/cookies/canonical_cookie.h"
+#include "net/cookies/cookie_constants.h"
+#include "sql/connection.h"
+#include "sql/meta_table.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+const base::FilePath::CharType kCookieFilename[] = FILE_PATH_LITERAL("Cookies");
+
+} // namespace
+
+typedef std::vector<net::CanonicalCookie*> CanonicalCookieVector;
+
+class SQLitePersistentCookieStoreTest : public testing::Test {
+ public:
+ SQLitePersistentCookieStoreTest()
+ : pool_owner_(new base::SequencedWorkerPoolOwner(3, "Background Pool")),
+ loaded_event_(false, false),
+ key_loaded_event_(false, false),
+ db_thread_event_(false, false) {
+ }
+
+ void OnLoaded(const CanonicalCookieVector& cookies) {
+ cookies_ = cookies;
+ loaded_event_.Signal();
+ }
+
+ void OnKeyLoaded(const CanonicalCookieVector& cookies) {
+ cookies_ = cookies;
+ key_loaded_event_.Signal();
+ }
+
+ void Load(CanonicalCookieVector* cookies) {
+ EXPECT_FALSE(loaded_event_.IsSignaled());
+ store_->Load(base::Bind(&SQLitePersistentCookieStoreTest::OnLoaded,
+ base::Unretained(this)));
+ loaded_event_.Wait();
+ *cookies = cookies_;
+ }
+
+ void Flush() {
+ base::WaitableEvent event(false, false);
+ store_->Flush(base::Bind(&base::WaitableEvent::Signal,
+ base::Unretained(&event)));
+ event.Wait();
+ }
+
+ scoped_refptr<base::SequencedTaskRunner> background_task_runner() {
+ return pool_owner_->pool()->GetSequencedTaskRunner(
+ pool_owner_->pool()->GetNamedSequenceToken("background"));
+ }
+
+ scoped_refptr<base::SequencedTaskRunner> client_task_runner() {
+ return pool_owner_->pool()->GetSequencedTaskRunner(
+ pool_owner_->pool()->GetNamedSequenceToken("client"));
+ }
+
+ void DestroyStore() {
+ store_ = NULL;
+ // Make sure we wait until the destructor has run by shutting down the pool
+ // resetting the owner (whose destructor blocks on the pool completion).
+ pool_owner_->pool()->Shutdown();
+ // Create a new pool for the few tests that create multiple stores. In other
+ // cases this is wasted but harmless.
+ pool_owner_.reset(new base::SequencedWorkerPoolOwner(3, "Background Pool"));
+ }
+
+ void CreateAndLoad(bool restore_old_session_cookies,
+ CanonicalCookieVector* cookies) {
+ store_ = new SQLitePersistentCookieStore(
+ temp_dir_.path().Append(kCookieFilename),
+ client_task_runner(),
+ background_task_runner(),
+ restore_old_session_cookies,
+ NULL);
+ Load(cookies);
+ }
+
+ void InitializeStore(bool restore_old_session_cookies) {
+ CanonicalCookieVector cookies;
+ CreateAndLoad(restore_old_session_cookies, &cookies);
+ EXPECT_EQ(0U, cookies.size());
+ }
+
+ // We have to create this method to wrap WaitableEvent::Wait, since we cannot
+ // bind a non-void returning method as a Closure.
+ void WaitOnDBEvent() {
+ db_thread_event_.Wait();
+ }
+
+ // Adds a persistent cookie to store_.
+ void AddCookie(const std::string& name,
+ const std::string& value,
+ const std::string& domain,
+ const std::string& path,
+ const base::Time& creation) {
+ store_->AddCookie(
+ net::CanonicalCookie(GURL(), name, value, domain, path, creation,
+ creation, creation, false, false,
+ net::COOKIE_PRIORITY_DEFAULT));
+ }
+
+ virtual void SetUp() OVERRIDE {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ }
+
+ virtual void TearDown() OVERRIDE {
+ DestroyStore();
+ pool_owner_->pool()->Shutdown();
+ }
+
+ protected:
+ base::MessageLoop main_loop_;
+ scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_;
+ base::WaitableEvent loaded_event_;
+ base::WaitableEvent key_loaded_event_;
+ base::WaitableEvent db_thread_event_;
+ CanonicalCookieVector cookies_;
+ base::ScopedTempDir temp_dir_;
+ scoped_refptr<SQLitePersistentCookieStore> store_;
+};
+
+TEST_F(SQLitePersistentCookieStoreTest, TestInvalidMetaTableRecovery) {
+ InitializeStore(false);
+ AddCookie("A", "B", "foo.bar", "/", base::Time::Now());
+ DestroyStore();
+
+ // Load up the store and verify that it has good data in it.
+ CanonicalCookieVector cookies;
+ CreateAndLoad(false, &cookies);
+ ASSERT_EQ(1U, cookies.size());
+ ASSERT_STREQ("foo.bar", cookies[0]->Domain().c_str());
+ ASSERT_STREQ("A", cookies[0]->Name().c_str());
+ ASSERT_STREQ("B", cookies[0]->Value().c_str());
+ DestroyStore();
+ STLDeleteElements(&cookies);
+
+ // Now corrupt the meta table.
+ {
+ sql::Connection db;
+ ASSERT_TRUE(db.Open(temp_dir_.path().Append(kCookieFilename)));
+ sql::MetaTable meta_table_;
+ meta_table_.Init(&db, 1, 1);
+ ASSERT_TRUE(db.Execute("DELETE FROM meta"));
+ db.Close();
+ }
+
+ // Upon loading, the database should be reset to a good, blank state.
+ CreateAndLoad(false, &cookies);
+ ASSERT_EQ(0U, cookies.size());
+
+ // Verify that, after, recovery, the database persists properly.
+ AddCookie("X", "Y", "foo.bar", "/", base::Time::Now());
+ DestroyStore();
+ CreateAndLoad(false, &cookies);
+ ASSERT_EQ(1U, cookies.size());
+ ASSERT_STREQ("foo.bar", cookies[0]->Domain().c_str());
+ ASSERT_STREQ("X", cookies[0]->Name().c_str());
+ ASSERT_STREQ("Y", cookies[0]->Value().c_str());
+ STLDeleteElements(&cookies);
+}
+
+// Test if data is stored as expected in the SQLite database.
+TEST_F(SQLitePersistentCookieStoreTest, TestPersistance) {
+ InitializeStore(false);
+ AddCookie("A", "B", "foo.bar", "/", base::Time::Now());
+ // Replace the store effectively destroying the current one and forcing it
+ // to write its data to disk. Then we can see if after loading it again it
+ // is still there.
+ DestroyStore();
+ // Reload and test for persistence
+ CanonicalCookieVector cookies;
+ CreateAndLoad(false, &cookies);
+ ASSERT_EQ(1U, cookies.size());
+ ASSERT_STREQ("foo.bar", cookies[0]->Domain().c_str());
+ ASSERT_STREQ("A", cookies[0]->Name().c_str());
+ ASSERT_STREQ("B", cookies[0]->Value().c_str());
+
+ // Now delete the cookie and check persistence again.
+ store_->DeleteCookie(*cookies[0]);
+ DestroyStore();
+ STLDeleteElements(&cookies);
+
+ // Reload and check if the cookie has been removed.
+ CreateAndLoad(false, &cookies);
+ ASSERT_EQ(0U, cookies.size());
+}
+
+// Test that priority load of cookies for a specfic domain key could be
+// completed before the entire store is loaded
+TEST_F(SQLitePersistentCookieStoreTest, TestLoadCookiesForKey) {
+ InitializeStore(false);
+ base::Time t = base::Time::Now();
+ AddCookie("A", "B", "foo.bar", "/", t);
+ t += base::TimeDelta::FromInternalValue(10);
+ AddCookie("A", "B", "www.aaa.com", "/", t);
+ t += base::TimeDelta::FromInternalValue(10);
+ AddCookie("A", "B", "travel.aaa.com", "/", t);
+ t += base::TimeDelta::FromInternalValue(10);
+ AddCookie("A", "B", "www.bbb.com", "/", t);
+ DestroyStore();
+
+ store_ = new SQLitePersistentCookieStore(
+ temp_dir_.path().Append(kCookieFilename),
+ client_task_runner(),
+ background_task_runner(),
+ false, NULL);
+ // Posting a blocking task to db_thread_ makes sure that the DB thread waits
+ // until both Load and LoadCookiesForKey have been posted to its task queue.
+ background_task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&SQLitePersistentCookieStoreTest::WaitOnDBEvent,
+ base::Unretained(this)));
+ store_->Load(base::Bind(&SQLitePersistentCookieStoreTest::OnLoaded,
+ base::Unretained(this)));
+ store_->LoadCookiesForKey("aaa.com",
+ base::Bind(&SQLitePersistentCookieStoreTest::OnKeyLoaded,
+ base::Unretained(this)));
+ background_task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&SQLitePersistentCookieStoreTest::WaitOnDBEvent,
+ base::Unretained(this)));
+
+ // Now the DB-thread queue contains:
+ // (active:)
+ // 1. Wait (on db_event)
+ // (pending:)
+ // 2. "Init And Chain-Load First Domain"
+ // 3. Priority Load (aaa.com)
+ // 4. Wait (on db_event)
+ db_thread_event_.Signal();
+ key_loaded_event_.Wait();
+ ASSERT_EQ(loaded_event_.IsSignaled(), false);
+ std::set<std::string> cookies_loaded;
+ for (CanonicalCookieVector::const_iterator it = cookies_.begin();
+ it != cookies_.end();
+ ++it) {
+ cookies_loaded.insert((*it)->Domain().c_str());
+ }
+ STLDeleteElements(&cookies_);
+ ASSERT_GT(4U, cookies_loaded.size());
+ ASSERT_EQ(true, cookies_loaded.find("www.aaa.com") != cookies_loaded.end());
+ ASSERT_EQ(true,
+ cookies_loaded.find("travel.aaa.com") != cookies_loaded.end());
+
+ db_thread_event_.Signal();
+ loaded_event_.Wait();
+ for (CanonicalCookieVector::const_iterator it = cookies_.begin();
+ it != cookies_.end();
+ ++it) {
+ cookies_loaded.insert((*it)->Domain().c_str());
+ }
+ ASSERT_EQ(4U, cookies_loaded.size());
+ ASSERT_EQ(cookies_loaded.find("foo.bar") != cookies_loaded.end(),
+ true);
+ ASSERT_EQ(cookies_loaded.find("www.bbb.com") != cookies_loaded.end(), true);
+ STLDeleteElements(&cookies_);
+}
+
+// Test that we can force the database to be written by calling Flush().
+TEST_F(SQLitePersistentCookieStoreTest, TestFlush) {
+ InitializeStore(false);
+ // File timestamps don't work well on all platforms, so we'll determine
+ // whether the DB file has been modified by checking its size.
+ base::FilePath path = temp_dir_.path().Append(kCookieFilename);
+ base::PlatformFileInfo info;
+ ASSERT_TRUE(file_util::GetFileInfo(path, &info));
+ int64 base_size = info.size;
+
+ // Write some large cookies, so the DB will have to expand by several KB.
+ for (char c = 'a'; c < 'z'; ++c) {
+ // Each cookie needs a unique timestamp for creation_utc (see DB schema).
+ base::Time t = base::Time::Now() + base::TimeDelta::FromMicroseconds(c);
+ std::string name(1, c);
+ std::string value(1000, c);
+ AddCookie(name, value, "foo.bar", "/", t);
+ }
+
+ Flush();
+
+ // We forced a write, so now the file will be bigger.
+ ASSERT_TRUE(file_util::GetFileInfo(path, &info));
+ ASSERT_GT(info.size, base_size);
+}
+
+// Test loading old session cookies from the disk.
+TEST_F(SQLitePersistentCookieStoreTest, TestLoadOldSessionCookies) {
+ InitializeStore(true);
+
+ // Add a session cookie.
+ store_->AddCookie(
+ net::CanonicalCookie(
+ GURL(), "C", "D", "sessioncookie.com", "/", base::Time::Now(),
+ base::Time(), base::Time::Now(), false, false,
+ net::COOKIE_PRIORITY_DEFAULT));
+
+ // Force the store to write its data to the disk.
+ DestroyStore();
+
+ // Create a store that loads session cookies and test that the session cookie
+ // was loaded.
+ CanonicalCookieVector cookies;
+ CreateAndLoad(true, &cookies);
+
+ ASSERT_EQ(1U, cookies.size());
+ ASSERT_STREQ("sessioncookie.com", cookies[0]->Domain().c_str());
+ ASSERT_STREQ("C", cookies[0]->Name().c_str());
+ ASSERT_STREQ("D", cookies[0]->Value().c_str());
+ ASSERT_EQ(net::COOKIE_PRIORITY_DEFAULT, cookies[0]->Priority());
+
+ STLDeleteElements(&cookies);
+}
+
+// Test loading old session cookies from the disk.
+TEST_F(SQLitePersistentCookieStoreTest, TestDontLoadOldSessionCookies) {
+ InitializeStore(true);
+
+ // Add a session cookie.
+ store_->AddCookie(
+ net::CanonicalCookie(
+ GURL(), "C", "D", "sessioncookie.com", "/", base::Time::Now(),
+ base::Time(), base::Time::Now(), false, false,
+ net::COOKIE_PRIORITY_DEFAULT));
+
+ // Force the store to write its data to the disk.
+ DestroyStore();
+
+ // Create a store that doesn't load old session cookies and test that the
+ // session cookie was not loaded.
+ CanonicalCookieVector cookies;
+ CreateAndLoad(false, &cookies);
+ ASSERT_EQ(0U, cookies.size());
+
+ // The store should also delete the session cookie. Wait until that has been
+ // done.
+ DestroyStore();
+
+ // Create a store that loads old session cookies and test that the session
+ // cookie is gone.
+ CreateAndLoad(true, &cookies);
+ ASSERT_EQ(0U, cookies.size());
+}
+
+TEST_F(SQLitePersistentCookieStoreTest, PersistIsPersistent) {
+ InitializeStore(true);
+ static const char kSessionName[] = "session";
+ static const char kPersistentName[] = "persistent";
+
+ // Add a session cookie.
+ store_->AddCookie(
+ net::CanonicalCookie(
+ GURL(), kSessionName, "val", "sessioncookie.com", "/",
+ base::Time::Now(), base::Time(), base::Time::Now(), false, false,
+ net::COOKIE_PRIORITY_DEFAULT));
+ // Add a persistent cookie.
+ store_->AddCookie(
+ net::CanonicalCookie(
+ GURL(), kPersistentName, "val", "sessioncookie.com", "/",
+ base::Time::Now() - base::TimeDelta::FromDays(1),
+ base::Time::Now() + base::TimeDelta::FromDays(1),
+ base::Time::Now(), false, false,
+ net::COOKIE_PRIORITY_DEFAULT));
+
+ // Force the store to write its data to the disk.
+ DestroyStore();
+
+ // Create a store that loads session cookie and test that the IsPersistent
+ // attribute is restored.
+ CanonicalCookieVector cookies;
+ CreateAndLoad(true, &cookies);
+ ASSERT_EQ(2U, cookies.size());
+
+ std::map<std::string, net::CanonicalCookie*> cookie_map;
+ for (CanonicalCookieVector::const_iterator it = cookies.begin();
+ it != cookies.end();
+ ++it) {
+ cookie_map[(*it)->Name()] = *it;
+ }
+
+ std::map<std::string, net::CanonicalCookie*>::const_iterator it =
+ cookie_map.find(kSessionName);
+ ASSERT_TRUE(it != cookie_map.end());
+ EXPECT_FALSE(cookie_map[kSessionName]->IsPersistent());
+
+ it = cookie_map.find(kPersistentName);
+ ASSERT_TRUE(it != cookie_map.end());
+ EXPECT_TRUE(cookie_map[kPersistentName]->IsPersistent());
+
+ STLDeleteElements(&cookies);
+}
+
+TEST_F(SQLitePersistentCookieStoreTest, PriorityIsPersistent) {
+ static const char kLowName[] = "low";
+ static const char kMediumName[] = "medium";
+ static const char kHighName[] = "high";
+ static const char kCookieDomain[] = "sessioncookie.com";
+ static const char kCookieValue[] = "value";
+ static const char kCookiePath[] = "/";
+
+ InitializeStore(true);
+
+ // Add a low-priority persistent cookie.
+ store_->AddCookie(
+ net::CanonicalCookie(
+ GURL(), kLowName, kCookieValue, kCookieDomain, kCookiePath,
+ base::Time::Now() - base::TimeDelta::FromMinutes(1),
+ base::Time::Now() + base::TimeDelta::FromDays(1),
+ base::Time::Now(), false, false,
+ net::COOKIE_PRIORITY_LOW));
+
+ // Add a medium-priority persistent cookie.
+ store_->AddCookie(
+ net::CanonicalCookie(
+ GURL(), kMediumName, kCookieValue, kCookieDomain, kCookiePath,
+ base::Time::Now() - base::TimeDelta::FromMinutes(2),
+ base::Time::Now() + base::TimeDelta::FromDays(1),
+ base::Time::Now(), false, false,
+ net::COOKIE_PRIORITY_MEDIUM));
+
+ // Add a high-priority peristent cookie.
+ store_->AddCookie(
+ net::CanonicalCookie(
+ GURL(), kHighName, kCookieValue, kCookieDomain, kCookiePath,
+ base::Time::Now() - base::TimeDelta::FromMinutes(3),
+ base::Time::Now() + base::TimeDelta::FromDays(1),
+ base::Time::Now(), false, false,
+ net::COOKIE_PRIORITY_HIGH));
+
+ // Force the store to write its data to the disk.
+ DestroyStore();
+
+ // Create a store that loads session cookie and test that the priority
+ // attribute values are restored.
+ CanonicalCookieVector cookies;
+ CreateAndLoad(true, &cookies);
+ ASSERT_EQ(3U, cookies.size());
+
+ // Put the cookies into a map, by name, so we can easily find them.
+ std::map<std::string, net::CanonicalCookie*> cookie_map;
+ for (CanonicalCookieVector::const_iterator it = cookies.begin();
+ it != cookies.end();
+ ++it) {
+ cookie_map[(*it)->Name()] = *it;
+ }
+
+ // Validate that each cookie has the correct priority.
+ std::map<std::string, net::CanonicalCookie*>::const_iterator it =
+ cookie_map.find(kLowName);
+ ASSERT_TRUE(it != cookie_map.end());
+ EXPECT_EQ(net::COOKIE_PRIORITY_LOW, cookie_map[kLowName]->Priority());
+
+ it = cookie_map.find(kMediumName);
+ ASSERT_TRUE(it != cookie_map.end());
+ EXPECT_EQ(net::COOKIE_PRIORITY_MEDIUM, cookie_map[kMediumName]->Priority());
+
+ it = cookie_map.find(kHighName);
+ ASSERT_TRUE(it != cookie_map.end());
+ EXPECT_EQ(net::COOKIE_PRIORITY_HIGH, cookie_map[kHighName]->Priority());
+
+ STLDeleteElements(&cookies);
+}
+
+} // namespace content
diff --git a/content/browser/net/view_blob_internals_job_factory.cc b/content/browser/net/view_blob_internals_job_factory.cc
index eeb87fa..1eab44b 100644
--- a/content/browser/net/view_blob_internals_job_factory.cc
+++ b/content/browser/net/view_blob_internals_job_factory.cc
@@ -14,7 +14,7 @@
// static.
bool ViewBlobInternalsJobFactory::IsSupportedURL(const GURL& url) {
return url.SchemeIs(chrome::kChromeUIScheme) &&
- url.host() == chrome::kChromeUIBlobInternalsHost;
+ url.host() == kChromeUIBlobInternalsHost;
}
// static.
diff --git a/content/browser/net/view_http_cache_job_factory.cc b/content/browser/net/view_http_cache_job_factory.cc
index a1300e6..7738f8f 100644
--- a/content/browser/net/view_http_cache_job_factory.cc
+++ b/content/browser/net/view_http_cache_job_factory.cc
@@ -28,10 +28,9 @@
net::NetworkDelegate* network_delegate)
: net::URLRequestJob(request, network_delegate),
core_(new Core),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- callback_(base::Bind(&ViewHttpCacheJob::OnStartCompleted,
- base::Unretained(this)))) {
+ weak_factory_(this),
+ callback_(base::Bind(&ViewHttpCacheJob::OnStartCompleted,
+ base::Unretained(this))) {
}
// net::URLRequestJob implementation.
@@ -53,8 +52,7 @@
public:
Core()
: data_offset_(0),
- ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
- base::Bind(&Core::OnIOComplete, this))) {
+ callback_(base::Bind(&Core::OnIOComplete, this)) {
}
int Start(const net::URLRequest& request, const base::Closure& callback);
@@ -98,7 +96,7 @@
};
void ViewHttpCacheJob::Start() {
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&ViewHttpCacheJob::StartAsync, weak_factory_.GetWeakPtr()));
}
@@ -193,7 +191,7 @@
// Static.
bool ViewHttpCacheJobFactory::IsSupportedURL(const GURL& url) {
return url.SchemeIs(chrome::kChromeUIScheme) &&
- url.host() == chrome::kChromeUINetworkViewCacheHost;
+ url.host() == kChromeUINetworkViewCacheHost;
}
// Static.
diff --git a/content/browser/plugin_data_remover_impl_browsertest.cc b/content/browser/plugin_data_remover_impl_browsertest.cc
index f0b4ead..37672ee 100644
--- a/content/browser/plugin_data_remover_impl_browsertest.cc
+++ b/content/browser/plugin_data_remover_impl_browsertest.cc
@@ -25,7 +25,7 @@
PluginDataRemoverTest() {}
void OnWaitableEventSignaled(base::WaitableEvent* waitable_event) {
- MessageLoop::current()->Quit();
+ base::MessageLoop::current()->Quit();
}
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
diff --git a/content/browser/plugin_loader_posix_unittest.cc b/content/browser/plugin_loader_posix_unittest.cc
index 6944384..c623892 100644
--- a/content/browser/plugin_loader_posix_unittest.cc
+++ b/content/browser/plugin_loader_posix_unittest.cc
@@ -79,7 +79,7 @@
PluginServiceImpl::GetInstance()->Init();
}
- MessageLoop* message_loop() { return &message_loop_; }
+ base::MessageLoop* message_loop() { return &message_loop_; }
MockPluginLoaderPosix* plugin_loader() { return plugin_loader_.get(); }
void AddThreePlugins() {
@@ -97,7 +97,7 @@
private:
base::ShadowingAtExitManager at_exit_manager_; // Destroys PluginService.
- MessageLoopForIO message_loop_;
+ base::MessageLoopForIO message_loop_;
BrowserThreadImpl file_thread_;
BrowserThreadImpl io_thread_;
diff --git a/content/browser/plugin_process_host.cc b/content/browser/plugin_process_host.cc
index e3b5ac7..cad8d18 100644
--- a/content/browser/plugin_process_host.cc
+++ b/content/browser/plugin_process_host.cc
@@ -121,32 +121,22 @@
std::set<HWND>::iterator window_index;
for (window_index = plugin_parent_windows_set_.begin();
window_index != plugin_parent_windows_set_.end();
- window_index++) {
+ ++window_index) {
PostMessage(*window_index, WM_CLOSE, 0, 0);
}
#elif defined(OS_MACOSX)
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
// If the plugin process crashed but had fullscreen windows open at the time,
// make sure that the menu bar is visible.
- std::set<uint32>::iterator window_index;
- for (window_index = plugin_fullscreen_windows_set_.begin();
- window_index != plugin_fullscreen_windows_set_.end();
- window_index++) {
- if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- base::mac::ReleaseFullScreen(base::mac::kFullScreenModeHideAll);
- } else {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(base::mac::ReleaseFullScreen,
- base::mac::kFullScreenModeHideAll));
- }
+ for (size_t i = 0; i < plugin_fullscreen_windows_set_.size(); ++i) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(base::mac::ReleaseFullScreen,
+ base::mac::kFullScreenModeHideAll));
}
// If the plugin hid the cursor, reset that.
if (!plugin_cursor_visible_) {
- if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- base::mac::SetCursorVisibility(true);
- } else {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(base::mac::SetCursorVisibility, true));
- }
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(base::mac::SetCursorVisibility, true));
}
#endif
// Cancel all pending and sent requests.
diff --git a/content/browser/plugin_service_impl.cc b/content/browser/plugin_service_impl.cc
index 4ae318a..ff8aed4 100644
--- a/content/browser/plugin_service_impl.cc
+++ b/content/browser/plugin_service_impl.cc
@@ -16,13 +16,10 @@
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "base/utf_string_conversions.h"
-#include "base/values.h"
#include "content/browser/ppapi_plugin_process_host.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/common/pepper_plugin_registry.h"
-#include "content/common/plugin_messages.h"
-#include "content/common/utility_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
@@ -152,9 +149,9 @@
// Release the events since they're owned by RegKey, not WaitableEvent.
hkcu_watcher_.StopWatching();
hklm_watcher_.StopWatching();
- if (hkcu_event_.get())
+ if (hkcu_event_)
hkcu_event_->Release();
- if (hklm_event_.get())
+ if (hklm_event_)
hklm_event_->Release();
#endif
// Make sure no plugin channel requests have been leaked.
@@ -178,7 +175,7 @@
if (command_line->HasSwitch(switches::kSitePerProcess)) {
webkit::WebPluginInfo webview_plugin(
ASCIIToUTF16("WebView Tag"),
- base::FilePath(FILE_PATH_LITERAL("")),
+ base::FilePath(),
ASCIIToUTF16("1.2.3.4"),
ASCIIToUTF16("Browser Plugin."));
webview_plugin.type = webkit::WebPluginInfo::PLUGIN_TYPE_NPAPI;
@@ -584,7 +581,7 @@
void PluginServiceImpl::GetPlugins(const GetPluginsCallback& callback) {
scoped_refptr<base::MessageLoopProxy> target_loop(
- MessageLoop::current()->message_loop_proxy());
+ base::MessageLoop::current()->message_loop_proxy());
if (LoadPluginListInProcess()) {
BrowserThread::GetBlockingPool()->
@@ -606,7 +603,7 @@
} else {
// If we switch back to loading plugins in process, then we need to make
// sure g_thread_init() gets called since plugins may call glib at load.
- if (!plugin_loader_.get())
+ if (!plugin_loader_)
plugin_loader_ = new PluginLoaderPosix;
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&PluginLoaderPosix::LoadPlugins, plugin_loader_,
@@ -633,7 +630,7 @@
void PluginServiceImpl::OnWaitableEventSignaled(
base::WaitableEvent* waitable_event) {
#if defined(OS_WIN)
- if (waitable_event == hkcu_event_.get()) {
+ if (waitable_event == hkcu_event_) {
hkcu_key_.StartWatching();
} else {
hklm_key_.StartWatching();
@@ -743,10 +740,7 @@
return false;
}
base::TimeDelta delta = base::Time::Now() - i->second[0];
- if (delta.InSeconds() <= kCrashesInterval) {
- return true;
- }
- return false;
+ return delta.InSeconds() <= kCrashesInterval;
}
void PluginServiceImpl::RefreshPlugins() {
diff --git a/content/browser/plugin_service_impl_browsertest.cc b/content/browser/plugin_service_impl_browsertest.cc
index eaf5b66..102c492 100644
--- a/content/browser/plugin_service_impl_browsertest.cc
+++ b/content/browser/plugin_service_impl_browsertest.cc
@@ -106,8 +106,8 @@
}
void QuitMessageLoop() {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- MessageLoop::QuitClosure());
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure());
}
ResourceContext* context_;
@@ -218,8 +218,8 @@
};
void QuitUIMessageLoopFromIOThread() {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- MessageLoop::QuitClosure());
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure());
}
void OpenChannelAndThenCancel(PluginProcessHost::Client* client) {
@@ -271,13 +271,13 @@
set_host(host);
// This gets called right before we request the plugin<=>renderer channel,
// so we have to post a task to cancel it.
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&PluginProcessHost::CancelPendingRequest,
- base::Unretained(host), this));
- MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&QuitUIMessageLoopFromIOThread));
+ base::Unretained(host),
+ this));
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(&QuitUIMessageLoopFromIOThread));
}
bool set_plugin_info_called() const {
@@ -345,8 +345,8 @@
virtual void OnSentPluginChannelRequest() OVERRIDE {
on_sent_plugin_channel_request_called_ = true;
host()->CancelSentRequest(this);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- MessageLoop::QuitClosure());
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure());
}
bool on_sent_plugin_channel_request_called() const {
diff --git a/content/browser/power_save_blocker_chromeos.cc b/content/browser/power_save_blocker_chromeos.cc
index e19dfbc..9eda5c4 100644
--- a/content/browser/power_save_blocker_chromeos.cc
+++ b/content/browser/power_save_blocker_chromeos.cc
@@ -36,10 +36,10 @@
chromeos::DBusThreadManager::Get()->GetPowerPolicyController();
switch (type_) {
case kPowerSaveBlockPreventAppSuspension:
- block_id_ = controller->AddSuspendBlock(reason_);
+ block_id_ = controller->AddSystemWakeLock(reason_);
break;
case kPowerSaveBlockPreventDisplaySleep:
- block_id_ = controller->AddScreenBlock(reason_);
+ block_id_ = controller->AddScreenWakeLock(reason_);
break;
default:
NOTREACHED() << "Unhandled block type " << type_;
@@ -53,7 +53,7 @@
return;
}
chromeos::DBusThreadManager::Get()->GetPowerPolicyController()->
- RemoveBlock(block_id_);
+ RemoveWakeLock(block_id_);
}
private:
diff --git a/content/browser/power_save_blocker_mac.cc b/content/browser/power_save_blocker_mac.cc
index b5d47c0..113c4e9 100644
--- a/content/browser/power_save_blocker_mac.cc
+++ b/content/browser/power_save_blocker_mac.cc
@@ -9,7 +9,7 @@
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/mac/scoped_cftyperef.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
diff --git a/content/browser/power_save_blocker_linux.cc b/content/browser/power_save_blocker_x11.cc
similarity index 99%
rename from content/browser/power_save_blocker_linux.cc
rename to content/browser/power_save_blocker_x11.cc
index a0e3764..c7dba77 100644
--- a/content/browser/power_save_blocker_linux.cc
+++ b/content/browser/power_save_blocker_x11.cc
@@ -242,7 +242,7 @@
// We're on the FILE thread so it should be OK to block briefly here.
scoped_ptr<dbus::Response> response(object_proxy->CallMethodAndBlock(
method_call.get(), dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
- if (response.get()) {
+ if (response) {
// The method returns an inhibit_cookie, used to uniquely identify
// this request. It should be used as an argument to Uninhibit()
// in order to remove the request.
@@ -285,7 +285,7 @@
message_writer.AppendUint32(inhibit_cookie_);
scoped_ptr<dbus::Response> response(object_proxy->CallMethodAndBlock(
method_call.get(), dbus::ObjectProxy::TIMEOUT_USE_DEFAULT));
- if (!response.get())
+ if (!response)
LOG(ERROR) << "No response to Uninhibit() request!";
// We don't care about checking the result. We assume it works; we can't
// really do anything about it anyway if it fails.
diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc
index 2364efc..9956326 100644
--- a/content/browser/ppapi_plugin_process_host.cc
+++ b/content/browser/ppapi_plugin_process_host.cc
@@ -286,10 +286,9 @@
arraysize(kCommonForwardSwitches));
if (!is_broker_) {
- // TODO(vtl): Stop passing flash args in the command line, on windows is
+ // TODO(vtl): Stop passing flash args in the command line, or windows is
// going to explode.
static const char* kPluginForwardSwitches[] = {
- switches::kDisablePepperThreading,
switches::kDisableSeccompFilterSandbox,
#if defined(OS_MACOSX)
switches::kEnableSandboxLogging,
@@ -318,7 +317,7 @@
#if defined(OS_POSIX)
bool use_zygote = !is_broker_ && plugin_launcher.empty() && info.is_sandboxed;
if (!info.is_sandboxed)
- cmd_line->AppendSwitchASCII(switches::kNoSandbox, "");
+ cmd_line->AppendSwitchASCII(switches::kNoSandbox, std::string());
#endif // OS_POSIX
process_->Launch(
#if defined(OS_WIN)
diff --git a/content/browser/renderer_host/OWNERS b/content/browser/renderer_host/OWNERS
index 1828f18..e74505d 100644
--- a/content/browser/renderer_host/OWNERS
+++ b/content/browser/renderer_host/OWNERS
@@ -1,16 +1,18 @@
-# for *aura.*
-ben@chromium.org
-
-# for *mac*
-thakis@chromium.org
-
-# for GPU-related stuff in *mac*
-kbr@chromium.org
-
-# for *android*
-sievers@chromium.org
-aelias@chromium.org
-
-# For touch/gesture specific changes
-rjkroege@chromium.org
-sadrul@chromium.org
+# for *aura*
+per-file *aura*=ben@chromium.org
+
+# for *mac*
+thakis@chromium.org
+
+# for GPU-related stuff in *mac*
+kbr@chromium.org
+per-file compositing_iosurface*=hclam@chromium.org
+per-file compositing_iosurface*=miu@chromium.org
+
+# for *android*
+sievers@chromium.org
+aelias@chromium.org
+
+# For touch/gesture specific changes
+rjkroege@chromium.org
+sadrul@chromium.org
diff --git a/content/browser/renderer_host/basic_mouse_wheel_smooth_scroll_gesture.cc b/content/browser/renderer_host/basic_mouse_wheel_smooth_scroll_gesture.cc
index af93b7c..b4eaa49 100644
--- a/content/browser/renderer_host/basic_mouse_wheel_smooth_scroll_gesture.cc
+++ b/content/browser/renderer_host/basic_mouse_wheel_smooth_scroll_gesture.cc
@@ -26,21 +26,22 @@
if (pixels_scrolled_ >= pixels_to_scroll_)
return false;
- double positionDelta = 10;
+ double position_delta = 10;
if (!last_tick_time_.is_null()) {
- RenderWidgetHostImpl* hostImpl = RenderWidgetHostImpl::From(host);
- double desiredIntervalMs = hostImpl->SyntheticScrollMessageInterval();
- double velocity = 10 / desiredIntervalMs;
- double timeDelta = (now - last_tick_time_).InMillisecondsF();
- positionDelta = velocity * timeDelta;
+ RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(host);
+ base::TimeDelta desired_interval =
+ rwhi->GetSyntheticScrollMessageInterval();
+ double velocity = 10 / desired_interval.InMillisecondsF();
+ double time_delta = (now - last_tick_time_).InMillisecondsF();
+ position_delta = velocity * time_delta;
}
last_tick_time_ = now;
WebKit::WebMouseWheelEvent event;
event.type = WebKit::WebInputEvent::MouseWheel;
- event.hasPreciseScrollingDeltas = 1;
- event.deltaY = scroll_down_ ? -positionDelta : positionDelta;
+ event.hasPreciseScrollingDeltas = 0;
+ event.deltaY = scroll_down_ ? -position_delta : position_delta;
// TODO(vollick): find a proper way to access
// WebCore::WheelEvent::tickMultiplier.
event.wheelTicksY = event.deltaY / 120;
diff --git a/content/browser/renderer_host/clipboard_message_filter.cc b/content/browser/renderer_host/clipboard_message_filter.cc
index 0708971..0b9dbff 100644
--- a/content/browser/renderer_host/clipboard_message_filter.cc
+++ b/content/browser/renderer_host/clipboard_message_filter.cc
@@ -25,7 +25,7 @@
void WriteObjectsWrapper(ui::Clipboard* clipboard,
const ui::Clipboard::ObjectMap& objects,
BrowserContext* browser_context) {
- ui::Clipboard::SourceTag source_tag =
+ ui::SourceTag source_tag =
BrowserContext::GetMarkerForOffTheRecordContext(browser_context);
clipboard->WriteObjects(ui::Clipboard::BUFFER_STANDARD,
objects,
diff --git a/content/browser/renderer_host/clipboard_message_filter_mac.mm b/content/browser/renderer_host/clipboard_message_filter_mac.mm
index 4105458..cdeabe6 100644
--- a/content/browser/renderer_host/clipboard_message_filter_mac.mm
+++ b/content/browser/renderer_host/clipboard_message_filter_mac.mm
@@ -9,7 +9,7 @@
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "content/public/browser/browser_thread.h"
#import "ui/base/cocoa/find_pasteboard.h"
diff --git a/content/browser/renderer_host/compositing_iosurface_context_mac.h b/content/browser/renderer_host/compositing_iosurface_context_mac.h
new file mode 100644
index 0000000..0b67af1
--- /dev/null
+++ b/content/browser/renderer_host/compositing_iosurface_context_mac.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_CONTEXT_MAC_H_
+#define CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_CONTEXT_MAC_H_
+
+#import <AppKit/NSOpenGL.h>
+#include <OpenGL/OpenGL.h>
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/lazy_instance.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_nsobject.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/browser/renderer_host/compositing_iosurface_mac.h"
+
+namespace content {
+
+class CompositingIOSurfaceShaderPrograms;
+
+class CompositingIOSurfaceContext
+ : public base::RefCounted<CompositingIOSurfaceContext> {
+ public:
+ // Get or create a GL context for the specified window with the specified
+ // surface ordering. Share these GL contexts as much as possible because
+ // creating and destroying them can be expensive
+ // http://crbug.com/180463
+ static scoped_refptr<CompositingIOSurfaceContext> Get(
+ int window_number,
+ CompositingIOSurfaceMac::SurfaceOrder surface_order);
+
+ CompositingIOSurfaceShaderPrograms* shader_program_cache() const {
+ return shader_program_cache_.get();
+ }
+ NSOpenGLContext* nsgl_context() const { return nsgl_context_; }
+ CGLContextObj cgl_context() const { return cgl_context_; }
+ bool is_vsync_disabled() const { return is_vsync_disabled_; }
+ int window_number() const { return window_number_; }
+ CompositingIOSurfaceMac::SurfaceOrder surface_order() const {
+ return surface_order_;
+ }
+
+ private:
+ friend class base::RefCounted<CompositingIOSurfaceContext>;
+
+ CompositingIOSurfaceContext(
+ int window_number,
+ CompositingIOSurfaceMac::SurfaceOrder surface_order,
+ NSOpenGLContext* nsgl_context,
+ CGLContextObj clg_context,
+ bool is_vsync_disabled_,
+ scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache);
+ ~CompositingIOSurfaceContext();
+
+ // The value for NSOpenGLCPSurfaceOrder for this GL context, 1 will
+ // render above the window and -1 will render below the window.
+ int window_number_;
+ CompositingIOSurfaceMac::SurfaceOrder surface_order_;
+ scoped_nsobject<NSOpenGLContext> nsgl_context_;
+ CGLContextObj cgl_context_; // weak, backed by |nsgl_context_|
+ bool is_vsync_disabled_;
+ scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache_;
+
+ // The global map from window number and window ordering to
+ // context data.
+ typedef std::map<std::pair<int,GLint>, CompositingIOSurfaceContext*>
+ WindowMap;
+ static base::LazyInstance<WindowMap> window_map_;
+ static WindowMap* window_map();
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_CONTEXT_MAC_H_
diff --git a/content/browser/renderer_host/compositing_iosurface_context_mac.mm b/content/browser/renderer_host/compositing_iosurface_context_mac.mm
new file mode 100644
index 0000000..2974d01
--- /dev/null
+++ b/content/browser/renderer_host/compositing_iosurface_context_mac.mm
@@ -0,0 +1,146 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/compositing_iosurface_context_mac.h"
+
+#include <OpenGL/gl.h>
+#include <OpenGL/OpenGL.h>
+#include <vector>
+
+#include "base/command_line.h"
+#include "base/debug/trace_event.h"
+#include "base/logging.h"
+#include "content/browser/renderer_host/compositing_iosurface_shader_programs_mac.h"
+#include "ui/gl/gl_switches.h"
+#include "ui/gl/gpu_switching_manager.h"
+
+namespace content {
+
+scoped_refptr<CompositingIOSurfaceContext>
+ CompositingIOSurfaceContext::Get(
+ int window_number,
+ CompositingIOSurfaceMac::SurfaceOrder surface_order) {
+ TRACE_EVENT0("browser", "CompositingIOSurfaceContext::Get");
+
+ // Return the context for this window_number and order, if it exists.
+ std::pair<int, int> key = std::make_pair(
+ window_number, static_cast<int>(surface_order));
+ WindowMap::iterator found = window_map()->find(key);
+ if (found != window_map()->end())
+ return found->second;
+
+ std::vector<NSOpenGLPixelFormatAttribute> attributes;
+ attributes.push_back(NSOpenGLPFADoubleBuffer);
+ // We don't need a depth buffer - try setting its size to 0...
+ attributes.push_back(NSOpenGLPFADepthSize); attributes.push_back(0);
+ if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus())
+ attributes.push_back(NSOpenGLPFAAllowOfflineRenderers);
+ attributes.push_back(0);
+
+ scoped_nsobject<NSOpenGLPixelFormat> glPixelFormat(
+ [[NSOpenGLPixelFormat alloc] initWithAttributes:&attributes.front()]);
+ if (!glPixelFormat) {
+ LOG(ERROR) << "NSOpenGLPixelFormat initWithAttributes failed";
+ return NULL;
+ }
+
+ // Create all contexts in the same share group so that the textures don't
+ // need to be recreated when transitioning contexts.
+ NSOpenGLContext* share_context = nil;
+ if (!window_map()->empty())
+ share_context = window_map()->begin()->second->nsgl_context();
+ scoped_nsobject<NSOpenGLContext> nsgl_context(
+ [[NSOpenGLContext alloc] initWithFormat:glPixelFormat
+ shareContext:share_context]);
+ if (!nsgl_context) {
+ LOG(ERROR) << "NSOpenGLContext initWithFormat failed";
+ return NULL;
+ }
+
+ // If requested, ask the WindowServer to render the OpenGL surface underneath
+ // the window. This, combined with a hole punched in the window, will allow
+ // for views to "overlap" the GL surface from the user's point of view.
+ if (surface_order == CompositingIOSurfaceMac::SURFACE_ORDER_BELOW_WINDOW) {
+ GLint gl_surface_order = -1;
+ [nsgl_context setValues:&gl_surface_order
+ forParameter:NSOpenGLCPSurfaceOrder];
+ }
+
+ CGLContextObj cgl_context = (CGLContextObj)[nsgl_context CGLContextObj];
+ if (!cgl_context) {
+ LOG(ERROR) << "CGLContextObj failed";
+ return NULL;
+ }
+
+ // Draw at beam vsync.
+ bool is_vsync_disabled =
+ CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync);
+ GLint swapInterval = is_vsync_disabled ? 0 : 1;
+ [nsgl_context setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
+
+ // Prepare the shader program cache. Precompile only the shader programs
+ // needed to draw the IO Surface.
+ CGLSetCurrentContext(cgl_context);
+ scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache(
+ new CompositingIOSurfaceShaderPrograms());
+ const bool prepared = (
+ shader_program_cache->UseBlitProgram() &&
+ shader_program_cache->UseSolidWhiteProgram());
+ glUseProgram(0u);
+ CGLSetCurrentContext(0);
+ if (!prepared) {
+ LOG(ERROR) << "IOSurface failed to compile/link required shader programs.";
+ return NULL;
+ }
+
+ return new CompositingIOSurfaceContext(
+ window_number,
+ surface_order,
+ nsgl_context.release(),
+ cgl_context,
+ is_vsync_disabled,
+ shader_program_cache.Pass());
+}
+
+CompositingIOSurfaceContext::CompositingIOSurfaceContext(
+ int window_number,
+ CompositingIOSurfaceMac::SurfaceOrder surface_order,
+ NSOpenGLContext* nsgl_context,
+ CGLContextObj cgl_context,
+ bool is_vsync_disabled,
+ scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache)
+ : window_number_(window_number),
+ surface_order_(surface_order),
+ nsgl_context_(nsgl_context),
+ cgl_context_(cgl_context),
+ is_vsync_disabled_(is_vsync_disabled),
+ shader_program_cache_(shader_program_cache.Pass()) {
+ std::pair<int, int> key = std::make_pair(
+ window_number_, static_cast<int>(surface_order_));
+ DCHECK(window_map()->find(key) == window_map()->end());
+ window_map()->insert(std::make_pair(key, this));
+}
+
+CompositingIOSurfaceContext::~CompositingIOSurfaceContext() {
+ CGLSetCurrentContext(cgl_context_);
+ shader_program_cache_->Reset();
+ CGLSetCurrentContext(0);
+ std::pair<int, int> key = std::make_pair(
+ window_number_, static_cast<int>(surface_order_));
+ DCHECK(window_map()->find(key) != window_map()->end());
+ DCHECK(window_map()->find(key)->second == this);
+ window_map()->erase(key);
+}
+
+// static
+CompositingIOSurfaceContext::WindowMap*
+ CompositingIOSurfaceContext::window_map() {
+ return window_map_.Pointer();
+}
+
+// static
+base::LazyInstance<CompositingIOSurfaceContext::WindowMap>
+ CompositingIOSurfaceContext::window_map_;
+
+} // namespace content
diff --git a/content/browser/renderer_host/compositing_iosurface_mac.h b/content/browser/renderer_host/compositing_iosurface_mac.h
index 4dcaac5..b6f734b 100644
--- a/content/browser/renderer_host/compositing_iosurface_mac.h
+++ b/content/browser/renderer_host/compositing_iosurface_mac.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_MAC_H_
#include <deque>
+#include <vector>
#import <Cocoa/Cocoa.h>
#import <QuartzCore/CVDisplayLink.h>
@@ -13,7 +14,6 @@
#include "base/callback.h"
#include "base/mac/scoped_cftyperef.h"
-#include "base/memory/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "base/time.h"
@@ -33,6 +33,7 @@
namespace content {
+class CompositingIOSurfaceContext;
class CompositingIOSurfaceShaderPrograms;
class CompositingIOSurfaceTransformer;
class RenderWidgetHostViewFrameSubscriber;
@@ -45,14 +46,15 @@
// Passed to Create() to specify the ordering of the surface relative to the
// containing window.
enum SurfaceOrder {
- SURFACE_ORDER_ABOVE_WINDOW,
- SURFACE_ORDER_BELOW_WINDOW
+ SURFACE_ORDER_ABOVE_WINDOW = 0,
+ SURFACE_ORDER_BELOW_WINDOW = 1,
};
// Returns NULL if IOSurface support is missing or GL APIs fail. Specify in
// |order| the desired ordering relationship of the surface to the containing
// window.
- static CompositingIOSurfaceMac* Create(SurfaceOrder order);
+ static CompositingIOSurfaceMac* Create(int window_number,
+ SurfaceOrder order);
~CompositingIOSurfaceMac();
// Set IOSurface that will be drawn on the next NSView drawRect.
@@ -67,7 +69,9 @@
// will be white. |scaleFactor| is 1 in normal views, 2 in HiDPI views.
// |frame_subscriber| listens to this draw event and provides output buffer
// for copying this frame into.
- void DrawIOSurface(NSView* view, float scale_factor,
+ void DrawIOSurface(NSView* view,
+ float scale_factor,
+ int window_number,
RenderWidgetHostViewFrameSubscriber* frame_subscriber);
// Copy the data of the "live" OpenGL texture referring to this IOSurfaceRef
@@ -110,7 +114,7 @@
// In cocoa view units / DIPs.
const gfx::Size& io_surface_size() const { return io_surface_size_; }
- bool is_vsync_disabled() const { return is_vsync_disabled_; }
+ bool is_vsync_disabled() const;
// Get vsync scheduling parameters.
// |interval_numerator/interval_denominator| equates to fractional number of
@@ -185,13 +189,26 @@
};
// Keeps track of states and buffers for readback of IOSurface.
+ //
+ // TODO(miu): Major code refactoring is badly needed! To be done in a
+ // soon-upcoming change. For now, we blatantly violate the style guide with
+ // respect to struct vs. class usage:
struct CopyContext {
- CopyContext();
+ explicit CopyContext(const scoped_refptr<CompositingIOSurfaceContext>& ctx);
~CopyContext();
- void CleanUp();
+ // Delete any references to owned OpenGL objects. This must be called
+ // within the OpenGL context just before destruction.
+ void ReleaseCachedGLObjects();
+
+ // The following two methods assume |num_outputs| has been set, and are
+ // being called within the OpenGL context.
+ void PrepareReadbackFramebuffers();
+ void PrepareForAsynchronousReadback();
+
+ const scoped_ptr<CompositingIOSurfaceTransformer> transformer;
int num_outputs;
- GLuint output_textures[3];
+ GLuint output_textures[3]; // Not owned.
// Note: For YUV, the |output_texture_sizes| widths are in terms of 4-byte
// quads, not pixels.
gfx::Size output_texture_sizes[3];
@@ -205,12 +222,14 @@
CompositingIOSurfaceMac(
IOSurfaceSupport* io_surface_support,
- NSOpenGLContext* glContext,
- CGLContextObj cglContext,
- scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache,
- bool is_vsync_disabled,
+ scoped_refptr<CompositingIOSurfaceContext> context,
CVDisplayLinkRef display_link);
+ // If this IOSurface has moved to a different window, use that window's
+ // GL context (if multiple visible windows are using the same GL context
+ // then call to setView call can stall and prevent reaching 60fps).
+ void SwitchToContextOnNewWindow(NSView* view, int window_number);
+
bool IsVendorIntel();
// Returns true if IOSurface is ready to render. False otherwise.
@@ -276,8 +295,8 @@
void FinishAllCopiesWithinContext(
std::vector<base::Closure>* done_callbacks);
- void CleanupAllCopiesWithinContext();
void FailAllCopies();
+ void DestroyAllCopyContextsWithinContext();
gfx::Rect IntersectWithIOSurface(const gfx::Rect& rect,
float scale_factor) const;
@@ -285,9 +304,9 @@
// Cached pointer to IOSurfaceSupport Singleton.
IOSurfaceSupport* io_surface_support_;
- // GL context
- scoped_nsobject<NSOpenGLContext> glContext_;
- CGLContextObj cglContext_; // weak, backed by |glContext_|.
+ // GL context, and parameters for context sharing. This may change when
+ // moving between windows, but will never be NULL.
+ scoped_refptr<CompositingIOSurfaceContext> context_;
// IOSurface data.
uint64 io_surface_handle_;
@@ -304,18 +323,18 @@
// with it.
GLuint texture_;
- std::deque<CopyContext> copy_requests_;
+ // A pool of CopyContexts with OpenGL objects ready for re-use. Prefer to
+ // pull one from the pool before creating a new CopyContext.
+ std::vector<CopyContext*> copy_context_pool_;
+
+ // CopyContexts being used for in-flight copy operations.
+ std::deque<CopyContext*> copy_requests_;
// Timer for finishing a copy operation.
base::Timer finish_copy_timer_;
- scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache_;
- scoped_ptr<CompositingIOSurfaceTransformer> transformer_;
-
SurfaceQuad quad_;
- bool is_vsync_disabled_;
-
// CVDisplayLink for querying Vsync timing info and throttling swaps.
CVDisplayLinkRef display_link_;
diff --git a/content/browser/renderer_host/compositing_iosurface_mac.mm b/content/browser/renderer_host/compositing_iosurface_mac.mm
index c433286..510e479 100644
--- a/content/browser/renderer_host/compositing_iosurface_mac.mm
+++ b/content/browser/renderer_host/compositing_iosurface_mac.mm
@@ -6,7 +6,6 @@
#include <OpenGL/CGLRenderers.h>
#include <OpenGL/OpenGL.h>
-#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -16,6 +15,7 @@
#include "base/mac/mac_util.h"
#include "base/message_loop.h"
#include "base/threading/platform_thread.h"
+#include "content/browser/renderer_host/compositing_iosurface_context_mac.h"
#include "content/browser/renderer_host/compositing_iosurface_shader_programs_mac.h"
#include "content/browser/renderer_host/compositing_iosurface_transformer_mac.h"
#include "content/common/content_constants_internal.h"
@@ -26,8 +26,6 @@
#include "ui/gfx/rect.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_switches.h"
-#include "ui/gl/gpu_switching_manager.h"
#include "ui/gfx/size_conversions.h"
#include "ui/surface/io_surface_support_mac.h"
@@ -51,9 +49,6 @@
// This value is shorter than 16ms such that copy can complete within a vsync.
const int kFinishCopyPollingPeriodMs = 10;
-// Everything uses only the GL_TEXTURE0 texture unit.
-const int kTextureUnit = 0;
-
bool HasAppleFenceExtension() {
static bool initialized_has_fence = false;
static bool has_fence = false;
@@ -92,7 +87,7 @@
// the snapshot path, we just memcpy the data into our output bitmap since the
// width, height, and stride should all be equal.
bool MapBufferToSkBitmap(const SkBitmap* output, const void* buf, int ignored) {
- TRACE_EVENT0("browser", "MapBufferToSkBitmap()");
+ TRACE_EVENT0("browser", "MapBufferToSkBitmap");
if (buf) {
SkAutoLockPixels output_lock(*output);
@@ -116,7 +111,7 @@
COMPILE_ASSERT(media::VideoFrame::kUPlane == 1, VideoFrame_kUPlane_mismatch);
COMPILE_ASSERT(media::VideoFrame::kVPlane == 2, VideoFrame_kVPlane_mismatch);
- TRACE_EVENT1("browser", "MapBufferToVideoFrame()", "plane", plane);
+ TRACE_EVENT1("browser", "MapBufferToVideoFrame", "plane", plane);
// Apply black-out in the regions surrounding the view area (for
// letterboxing/pillarboxing). Only do this once, since this is performed on
@@ -167,8 +162,11 @@
return kCVReturnSuccess;
}
-CompositingIOSurfaceMac::CopyContext::CopyContext()
- : num_outputs(0),
+CompositingIOSurfaceMac::CopyContext::CopyContext(
+ const scoped_refptr<CompositingIOSurfaceContext>& context)
+ : transformer(new CompositingIOSurfaceTransformer(
+ GL_TEXTURE_RECTANGLE_ARB, true, context->shader_program_cache())),
+ num_outputs(0),
fence(0),
cycles_elapsed(0) {
memset(output_textures, 0, sizeof(output_textures));
@@ -177,23 +175,56 @@
}
CompositingIOSurfaceMac::CopyContext::~CopyContext() {
+ DCHECK_EQ(frame_buffers[0], 0u) << "Failed to call ReleaseCachedGLObjects().";
}
-void CompositingIOSurfaceMac::CopyContext::CleanUp() {
- glDeleteFramebuffersEXT(num_outputs, frame_buffers); CHECK_GL_ERROR();
- glDeleteTextures(num_outputs, output_textures);
- CHECK_GL_ERROR();
+void CompositingIOSurfaceMac::CopyContext::ReleaseCachedGLObjects() {
+ // No outstanding callbacks should be pending.
+ DCHECK(map_buffer_callback.is_null());
+ DCHECK(done_callback.is_null());
// For an asynchronous read-back, there are more objects to delete:
if (fence) {
- glDeleteBuffers(num_outputs, pixel_buffers);
- CHECK_GL_ERROR();
+ glDeleteBuffers(arraysize(pixel_buffers), pixel_buffers); CHECK_GL_ERROR();
+ memset(pixel_buffers, 0, sizeof(pixel_buffers));
glDeleteFencesAPPLE(1, &fence); CHECK_GL_ERROR();
+ fence = 0;
+ }
+
+ glDeleteFramebuffersEXT(arraysize(frame_buffers), frame_buffers);
+ CHECK_GL_ERROR();
+ memset(frame_buffers, 0, sizeof(frame_buffers));
+
+ // Note: |output_textures| are owned by the transformer.
+ if (transformer)
+ transformer->ReleaseCachedGLObjects();
+}
+
+void CompositingIOSurfaceMac::CopyContext::PrepareReadbackFramebuffers() {
+ for (int i = 0; i < num_outputs; ++i) {
+ if (!frame_buffers[i]) {
+ glGenFramebuffersEXT(1, &frame_buffers[i]); CHECK_GL_ERROR();
+ }
}
}
+void CompositingIOSurfaceMac::CopyContext::PrepareForAsynchronousReadback() {
+ PrepareReadbackFramebuffers();
+ if (!fence) {
+ glGenFencesAPPLE(1, &fence); CHECK_GL_ERROR();
+ }
+ for (int i = 0; i < num_outputs; ++i) {
+ if (!pixel_buffers[i]) {
+ glGenBuffersARB(1, &pixel_buffers[i]); CHECK_GL_ERROR();
+ }
+ }
+}
+
+
// static
-CompositingIOSurfaceMac* CompositingIOSurfaceMac::Create(SurfaceOrder order) {
+CompositingIOSurfaceMac* CompositingIOSurfaceMac::Create(
+ int window_number,
+ SurfaceOrder surface_order) {
TRACE_EVENT0("browser", "CompositingIOSurfaceMac::Create");
IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
if (!io_surface_support) {
@@ -201,62 +232,8 @@
return NULL;
}
- std::vector<NSOpenGLPixelFormatAttribute> attributes;
- attributes.push_back(NSOpenGLPFADoubleBuffer);
- // We don't need a depth buffer - try setting its size to 0...
- attributes.push_back(NSOpenGLPFADepthSize); attributes.push_back(0);
- if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus())
- attributes.push_back(NSOpenGLPFAAllowOfflineRenderers);
- attributes.push_back(0);
-
- scoped_nsobject<NSOpenGLPixelFormat> glPixelFormat(
- [[NSOpenGLPixelFormat alloc] initWithAttributes:&attributes.front()]);
- if (!glPixelFormat) {
- LOG(ERROR) << "NSOpenGLPixelFormat initWithAttributes failed";
- return NULL;
- }
-
- scoped_nsobject<NSOpenGLContext> glContext(
- [[NSOpenGLContext alloc] initWithFormat:glPixelFormat
- shareContext:nil]);
- if (!glContext) {
- LOG(ERROR) << "NSOpenGLContext initWithFormat failed";
- return NULL;
- }
-
- // If requested, ask the WindowServer to render the OpenGL surface underneath
- // the window. This, combined with a hole punched in the window, will allow
- // for views to "overlap" the GL surface from the user's point of view.
- if (order == SURFACE_ORDER_BELOW_WINDOW) {
- GLint belowWindow = -1;
- [glContext setValues:&belowWindow forParameter:NSOpenGLCPSurfaceOrder];
- }
-
- CGLContextObj cglContext = (CGLContextObj)[glContext CGLContextObj];
- if (!cglContext) {
- LOG(ERROR) << "CGLContextObj failed";
- return NULL;
- }
-
- // Draw at beam vsync.
- bool is_vsync_disabled =
- CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync);
- GLint swapInterval = is_vsync_disabled ? 0 : 1;
- [glContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
-
- // Prepare the shader program cache. Precompile only the shader programs
- // needed to draw the IO Surface.
- CGLSetCurrentContext(cglContext);
- scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache(
- new CompositingIOSurfaceShaderPrograms());
- const bool prepared = (shader_program_cache->UseBlitProgram(kTextureUnit) &&
- shader_program_cache->UseSolidWhiteProgram());
- glUseProgram(0u);
- CGLSetCurrentContext(0);
- if (!prepared) {
- LOG(ERROR) << "IOSurface failed to compile/link required shader programs.";
- return NULL;
- }
+ scoped_refptr<CompositingIOSurfaceContext> context =
+ CompositingIOSurfaceContext::Get(window_number, surface_order);
CVDisplayLinkRef display_link;
CVReturn ret = CVDisplayLinkCreateWithActiveCGDisplays(&display_link);
@@ -265,23 +242,17 @@
return NULL;
}
- return new CompositingIOSurfaceMac(io_surface_support, glContext.release(),
- cglContext,
- shader_program_cache.Pass(),
- is_vsync_disabled,
+ return new CompositingIOSurfaceMac(io_surface_support,
+ context,
display_link);
}
CompositingIOSurfaceMac::CompositingIOSurfaceMac(
IOSurfaceSupport* io_surface_support,
- NSOpenGLContext* glContext,
- CGLContextObj cglContext,
- scoped_ptr<CompositingIOSurfaceShaderPrograms> shader_program_cache,
- bool is_vsync_disabled,
+ scoped_refptr<CompositingIOSurfaceContext> context,
CVDisplayLinkRef display_link)
: io_surface_support_(io_surface_support),
- glContext_(glContext),
- cglContext_(cglContext),
+ context_(context),
io_surface_handle_(0),
texture_(0),
finish_copy_timer_(
@@ -290,8 +261,6 @@
base::Bind(&CompositingIOSurfaceMac::FinishAllCopies,
base::Unretained(this)),
true),
- shader_program_cache_(shader_program_cache.Pass()),
- is_vsync_disabled_(is_vsync_disabled),
display_link_(display_link),
display_link_stop_timer_(FROM_HERE, base::TimeDelta::FromSeconds(1),
this, &CompositingIOSurfaceMac::StopDisplayLink),
@@ -323,6 +292,42 @@
StopDisplayLink();
}
+void CompositingIOSurfaceMac::SwitchToContextOnNewWindow(
+ NSView* view, int window_number) {
+ if (window_number == context_->window_number())
+ return;
+
+ // Asynchronous copies must complete in the same context they started in,
+ // defer updating the GL context to the new window until the copy finishes and
+ // all outstanding CopyContexts are destroyed.
+ if (!copy_requests_.empty())
+ return;
+ if (!copy_context_pool_.empty()) {
+ CGLSetCurrentContext(context_->cgl_context());
+ DestroyAllCopyContextsWithinContext();
+ CGLSetCurrentContext(0);
+ }
+
+ scoped_refptr<CompositingIOSurfaceContext> new_context =
+ CompositingIOSurfaceContext::Get(window_number,
+ context_->surface_order());
+ if (!new_context)
+ return;
+
+ // Having two NSOpenGLContexts bound to an NSView concurrently will cause
+ // artifacts and crashes. If |context_| is bound to |view|, then unbind
+ // |context_| before |new_context| gets bound to |view|.
+ // http://crbug.com/230883
+ if ([context_->nsgl_context() view] == view)
+ [context_->nsgl_context() clearDrawable];
+
+ context_ = new_context;
+}
+
+bool CompositingIOSurfaceMac::is_vsync_disabled() const {
+ return context_->is_vsync_disabled();
+}
+
void CompositingIOSurfaceMac::GetVSyncParameters(base::TimeTicks* timebase,
uint32* interval_numerator,
uint32* interval_denominator) {
@@ -335,24 +340,24 @@
CompositingIOSurfaceMac::~CompositingIOSurfaceMac() {
FailAllCopies();
CVDisplayLinkRelease(display_link_);
- CGLSetCurrentContext(cglContext_);
- CleanupAllCopiesWithinContext();
+ CGLSetCurrentContext(context_->cgl_context());
+ DestroyAllCopyContextsWithinContext();
UnrefIOSurfaceWithContextCurrent();
- shader_program_cache_->Reset();
CGLSetCurrentContext(0);
+ context_ = nil;
}
void CompositingIOSurfaceMac::SetIOSurface(uint64 io_surface_handle,
const gfx::Size& size) {
pixel_io_surface_size_ = size;
- CGLSetCurrentContext(cglContext_);
+ CGLSetCurrentContext(context_->cgl_context());
MapIOSurfaceToTexture(io_surface_handle);
CGLSetCurrentContext(0);
}
int CompositingIOSurfaceMac::GetRendererID() {
GLint current_renderer_id = -1;
- if (CGLGetParameter(cglContext_,
+ if (CGLGetParameter(context_->cgl_context(),
kCGLCPCurrentRendererID,
¤t_renderer_id) == kCGLNoError)
return current_renderer_id & kCGLRendererIDMatchingMask;
@@ -360,16 +365,20 @@
}
void CompositingIOSurfaceMac::DrawIOSurface(
- NSView* view, float scale_factor,
+ NSView* view,
+ float scale_factor,
+ int window_number,
RenderWidgetHostViewFrameSubscriber* frame_subscriber) {
- CGLSetCurrentContext(cglContext_);
+ SwitchToContextOnNewWindow(view, window_number);
+
+ CGLSetCurrentContext(context_->cgl_context());
bool has_io_surface = MapIOSurfaceToTexture(io_surface_handle_);
TRACE_EVENT1("browser", "CompositingIOSurfaceMac::DrawIOSurface",
"has_io_surface", has_io_surface);
- [glContext_ setView:view];
+ [context_->nsgl_context() setView:view];
gfx::Size window_size(NSSizeToCGSize([view frame].size));
gfx::Size pixel_window_size = gfx::ToFlooredSize(
gfx::ScaleSize(window_size, scale_factor));
@@ -395,8 +404,8 @@
glDisable(GL_BLEND);
if (has_io_surface) {
- shader_program_cache_->UseBlitProgram(kTextureUnit);
- glActiveTexture(GL_TEXTURE0 + kTextureUnit);
+ context_->shader_program_cache()->UseBlitProgram();
+ glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_);
DrawQuad(quad_);
@@ -406,7 +415,7 @@
// Fill the resize gutters with white.
if (window_size.width() > io_surface_size_.width() ||
window_size.height() > io_surface_size_.height()) {
- shader_program_cache_->UseSolidWhiteProgram();
+ context_->shader_program_cache()->UseSolidWhiteProgram();
SurfaceQuad filler_quad;
if (window_size.width() > io_surface_size_.width()) {
// Draw right-side gutter down to the bottom of the window.
@@ -464,19 +473,21 @@
base::Closure copy_done_callback;
if (frame_subscriber) {
+ const base::Time present_time = base::Time::Now();
scoped_refptr<media::VideoFrame> frame;
RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback;
- if (frame_subscriber->ShouldCaptureFrame(&frame, &callback)) {
+ if (frame_subscriber->ShouldCaptureFrame(present_time, &frame, &callback)) {
copy_done_callback = CopyToVideoFrameWithinContext(
- gfx::Rect(io_surface_size_), scale_factor, true, frame,
- base::Bind(callback, base::Time::Now()));
+ gfx::Rect(pixel_io_surface_size_), scale_factor, true, frame,
+ base::Bind(callback, present_time));
}
}
- CGLFlushDrawable(cglContext_);
+ CGLFlushDrawable(context_->cgl_context());
// For latency_tests.cc:
- UNSHIPPED_TRACE_EVENT_INSTANT0("test_gpu", "CompositorSwapBuffersComplete");
+ UNSHIPPED_TRACE_EVENT_INSTANT0("test_gpu", "CompositorSwapBuffersComplete",
+ TRACE_EVENT_SCOPE_THREAD);
// Try to finish previous copy requests after flush to get better pipelining.
std::vector<base::Closure> copy_done_callbacks;
@@ -491,7 +502,7 @@
StartOrContinueDisplayLink();
- if (!is_vsync_disabled_)
+ if (!is_vsync_disabled())
RateLimitDraws();
}
@@ -512,7 +523,7 @@
<< "Stride is required to be equal to width for GPU readback.";
output->setIsOpaque(true);
- CGLSetCurrentContext(cglContext_);
+ CGLSetCurrentContext(context_->cgl_context());
const base::Closure copy_done_callback = CopyToSelectedOutputWithinContext(
src_pixel_subrect, src_scale_factor, gfx::Rect(dst_pixel_size), false,
output.get(), NULL,
@@ -527,7 +538,7 @@
float src_scale_factor,
const scoped_refptr<media::VideoFrame>& target,
const base::Callback<void(bool)>& callback) {
- CGLSetCurrentContext(cglContext_);
+ CGLSetCurrentContext(context_->cgl_context());
const base::Closure copy_done_callback = CopyToVideoFrameWithinContext(
src_pixel_subrect, src_scale_factor, false, target, callback);
CGLSetCurrentContext(0);
@@ -571,7 +582,7 @@
static_cast<uint32>(io_surface_handle)));
// Can fail if IOSurface with that ID was already released by the gpu
// process.
- if (!io_surface_.get()) {
+ if (!io_surface_) {
io_surface_handle_ = 0;
return false;
}
@@ -595,7 +606,7 @@
glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); CHECK_GL_ERROR();
GLuint plane = 0;
CGLError cglerror = io_surface_support_->CGLTexImageIOSurface2D(
- cglContext_,
+ context_->cgl_context(),
target,
GL_RGBA,
rounded_size.width(),
@@ -614,7 +625,7 @@
}
void CompositingIOSurfaceMac::UnrefIOSurface() {
- CGLSetCurrentContext(cglContext_);
+ CGLSetCurrentContext(context_->cgl_context());
UnrefIOSurfaceWithContextCurrent();
CGLSetCurrentContext(0);
}
@@ -633,7 +644,7 @@
bool CompositingIOSurfaceMac::IsVendorIntel() {
GLint screen;
- CGLGetVirtualScreen(cglContext_, &screen);
+ CGLGetVirtualScreen(context_->cgl_context(), &screen);
if (screen != screen_)
initialized_is_intel_ = false;
screen_ = screen;
@@ -660,11 +671,11 @@
}
void CompositingIOSurfaceMac::GlobalFrameDidChange() {
- [glContext_ update];
+ [context_->nsgl_context() update];
}
void CompositingIOSurfaceMac::ClearDrawable() {
- [glContext_ clearDrawable];
+ [context_->nsgl_context() clearDrawable];
UnrefIOSurface();
}
@@ -733,7 +744,10 @@
bool CompositingIOSurfaceMac::IsAsynchronousReadbackSupported() {
// Using PBO crashes on Intel drivers but not on newer Mountain Lion
// systems. See bug http://crbug.com/152225.
- return (HasAppleFenceExtension() &&
+ const bool forced_synchronous = CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kForceSynchronousGLReadPixels);
+ return (!forced_synchronous &&
+ HasAppleFenceExtension() &&
HasPixelBufferObjectExtension() &&
(base::mac::IsOSMountainLionOrLater() || !IsVendorIntel()));
}
@@ -751,54 +765,65 @@
const bool async_copy = IsAsynchronousReadbackSupported();
TRACE_EVENT2(
- "browser", "CompositingIOSurfaceMac::CopyToSelectedOutputWithinContext()",
+ "browser", "CompositingIOSurfaceMac::CopyToSelectedOutputWithinContext",
"output", bitmap_output ? "SkBitmap (ARGB)" : "VideoFrame (YV12)",
"async_readback", async_copy);
+ CopyContext* copy_context;
+ if (copy_context_pool_.empty()) {
+ // Limit the maximum number of simultaneous copies to two. Rationale:
+ // Really, only one should ever be in-progress at a time, as we should
+ // depend on the speed of the hardware to rate-limit the copying naturally.
+ // In the asynchronous read-back case, the one currently in-flight copy is
+ // highly likely to have finished by this point (i.e., it's just waiting for
+ // us to make a glMapBuffer() call). Therefore, we allow a second copy to
+ // be started here.
+ if (copy_requests_.size() >= 2)
+ return base::Bind(done_callback, false);
+ copy_context = new CopyContext(context_);
+ } else {
+ copy_context = copy_context_pool_.back();
+ copy_context_pool_.pop_back();
+ }
+
// Set up source texture, bound to the GL_TEXTURE_RECTANGLE_ARB target.
if (!MapIOSurfaceToTexture(io_surface_handle_))
return base::Bind(done_callback, false);
- // Create the transformer_ on first use.
- if (!transformer_) {
- transformer_.reset(new CompositingIOSurfaceTransformer(
- GL_TEXTURE_RECTANGLE_ARB, kTextureUnit, true,
- shader_program_cache_.get()));
- }
-
// Send transform commands to the GPU.
const gfx::Rect src_rect = IntersectWithIOSurface(src_pixel_subrect,
src_scale_factor);
- CopyContext copy_context;
+ copy_context->num_outputs = 0;
if (bitmap_output) {
- if (transformer_->ResizeBilinear(texture_, src_rect, dst_pixel_rect.size(),
- ©_context.output_textures[0])) {
- copy_context.num_outputs = 1;
- copy_context.output_texture_sizes[0] = dst_pixel_rect.size();
+ if (copy_context->transformer->ResizeBilinear(
+ texture_, src_rect, dst_pixel_rect.size(),
+ ©_context->output_textures[0])) {
+ copy_context->num_outputs = 1;
+ copy_context->output_texture_sizes[0] = dst_pixel_rect.size();
}
} else {
- if (transformer_->TransformRGBToYV12(
+ if (copy_context->transformer->TransformRGBToYV12(
texture_, src_rect, dst_pixel_rect.size(),
- ©_context.output_textures[0],
- ©_context.output_textures[1],
- ©_context.output_textures[2],
- ©_context.output_texture_sizes[0],
- ©_context.output_texture_sizes[1])) {
- copy_context.num_outputs = 3;
- copy_context.output_texture_sizes[2] =
- copy_context.output_texture_sizes[1];
+ ©_context->output_textures[0],
+ ©_context->output_textures[1],
+ ©_context->output_textures[2],
+ ©_context->output_texture_sizes[0],
+ ©_context->output_texture_sizes[1])) {
+ copy_context->num_outputs = 3;
+ copy_context->output_texture_sizes[2] =
+ copy_context->output_texture_sizes[1];
}
}
- if (!copy_context.num_outputs)
+ if (!copy_context->num_outputs)
return base::Bind(done_callback, false);
// In the asynchronous case, issue commands to the GPU and return a null
// closure here. In the synchronous case, perform a blocking readback and
// return a callback to be run outside the CGL context to indicate success.
if (async_copy) {
- copy_context.done_callback = done_callback;
+ copy_context->done_callback = done_callback;
AsynchronousReadbackForCopy(
- dst_pixel_rect, called_within_draw, ©_context, bitmap_output,
+ dst_pixel_rect, called_within_draw, copy_context, bitmap_output,
video_frame_output);
copy_requests_.push_back(copy_context);
if (!finish_copy_timer_.IsRunning())
@@ -806,7 +831,7 @@
return base::Closure();
} else {
const bool success = SynchronousReadbackForCopy(
- dst_pixel_rect, ©_context, bitmap_output, video_frame_output);
+ dst_pixel_rect, copy_context, bitmap_output, video_frame_output);
return base::Bind(done_callback, success);
}
}
@@ -817,16 +842,12 @@
CopyContext* copy_context,
const SkBitmap* bitmap_output,
const scoped_refptr<media::VideoFrame>& video_frame_output) {
- glGenFencesAPPLE(1, ©_context->fence); CHECK_GL_ERROR();
+ copy_context->PrepareForAsynchronousReadback();
- // Copy the textures to a PBO.
- glGenFramebuffersEXT(copy_context->num_outputs, copy_context->frame_buffers);
- CHECK_GL_ERROR();
- glGenBuffersARB(copy_context->num_outputs, copy_context->pixel_buffers);
- CHECK_GL_ERROR();
+ // Copy the textures to their corresponding PBO.
for (int i = 0; i < copy_context->num_outputs; ++i) {
TRACE_EVENT1(
- "browser", "CompositingIOSurfaceMac::AsynchronousReadbackForCopy()",
+ "browser", "CompositingIOSurfaceMac::AsynchronousReadbackForCopy",
"plane", i);
// Attach the output texture to the FBO.
@@ -854,8 +875,9 @@
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); CHECK_GL_ERROR();
glSetFenceAPPLE(copy_context->fence); CHECK_GL_ERROR();
+ copy_context->cycles_elapsed = 0;
- // When this asynchronous copy happens in a draw operaton there is not need
+ // When this asynchronous copy happens in a draw operaton there is no need
// to explicitly flush because there will be a swap buffer and this flush
// hurts performance.
if (!called_within_draw) {
@@ -869,7 +891,7 @@
void CompositingIOSurfaceMac::FinishAllCopies() {
std::vector<base::Closure> done_callbacks;
- CGLSetCurrentContext(cglContext_);
+ CGLSetCurrentContext(context_->cgl_context());
FinishAllCopiesWithinContext(&done_callbacks);
CGLSetCurrentContext(0);
for (size_t i = 0; i < done_callbacks.size(); ++i)
@@ -879,15 +901,15 @@
void CompositingIOSurfaceMac::FinishAllCopiesWithinContext(
std::vector<base::Closure>* done_callbacks) {
while (!copy_requests_.empty()) {
- CopyContext& copy_context = copy_requests_.front();
+ CopyContext* const copy_context = copy_requests_.front();
- if (copy_context.fence) {
- const bool copy_completed = glTestFenceAPPLE(copy_context.fence);
+ if (copy_context->fence) {
+ const bool copy_completed = glTestFenceAPPLE(copy_context->fence);
CHECK_GL_ERROR();
if (!copy_completed &&
- copy_context.cycles_elapsed < kFinishCopyRetryCycles) {
- ++copy_context.cycles_elapsed;
+ copy_context->cycles_elapsed < kFinishCopyRetryCycles) {
+ ++copy_context->cycles_elapsed;
// This copy has not completed there is no need to test subsequent
// requests.
break;
@@ -895,24 +917,26 @@
}
bool success = true;
- for (int i = 0; success && i < copy_context.num_outputs; ++i) {
+ for (int i = 0; success && i < copy_context->num_outputs; ++i) {
TRACE_EVENT1(
- "browser", "CompositingIOSurfaceMac::FinishAllCopyWithinContext()",
+ "browser", "CompositingIOSurfaceMac::FinishAllCopiesWithinContext",
"plane", i);
- glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, copy_context.pixel_buffers[i]);
+ glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, copy_context->pixel_buffers[i]);
CHECK_GL_ERROR();
void* buf = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
CHECK_GL_ERROR();
- success &= copy_context.map_buffer_callback.Run(buf, i);
+ success &= copy_context->map_buffer_callback.Run(buf, i);
glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB); CHECK_GL_ERROR();
}
-
+ copy_context->map_buffer_callback.Reset();
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); CHECK_GL_ERROR();
- copy_context.CleanUp();
- done_callbacks->push_back(base::Bind(copy_context.done_callback, success));
+
copy_requests_.pop_front();
+ done_callbacks->push_back(base::Bind(copy_context->done_callback, success));
+ copy_context->done_callback.Reset();
+ copy_context_pool_.push_back(copy_context);
}
if (copy_requests_.empty())
finish_copy_timer_.Stop();
@@ -924,11 +948,10 @@
const SkBitmap* bitmap_output,
const scoped_refptr<media::VideoFrame>& video_frame_output) {
bool success = true;
- glGenFramebuffersEXT(copy_context->num_outputs, copy_context->frame_buffers);
- CHECK_GL_ERROR();
+ copy_context->PrepareReadbackFramebuffers();
for (int i = 0; i < copy_context->num_outputs; ++i) {
TRACE_EVENT1(
- "browser", "CompositingIOSurfaceMac::SynchronousReadbackForCopy()",
+ "browser", "CompositingIOSurfaceMac::SynchronousReadbackForCopy",
"plane", i);
// Attach the output texture to the FBO.
@@ -992,19 +1015,34 @@
}
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); CHECK_GL_ERROR();
- copy_context->CleanUp();
+ copy_context_pool_.push_back(copy_context);
return success;
}
-void CompositingIOSurfaceMac::CleanupAllCopiesWithinContext() {
- for (size_t i = 0; i < copy_requests_.size(); ++i)
- copy_requests_[i].CleanUp();
- copy_requests_.clear();
+void CompositingIOSurfaceMac::FailAllCopies() {
+ for (size_t i = 0; i < copy_requests_.size(); ++i) {
+ copy_requests_[i]->map_buffer_callback.Reset();
+
+ base::Callback<void(bool)>& done_callback =
+ copy_requests_[i]->done_callback;
+ if (!done_callback.is_null()) {
+ done_callback.Run(false);
+ done_callback.Reset();
+ }
+ }
}
-void CompositingIOSurfaceMac::FailAllCopies() {
- for (size_t i = 0; i < copy_requests_.size(); ++i)
- copy_requests_[i].done_callback.Run(false);
+void CompositingIOSurfaceMac::DestroyAllCopyContextsWithinContext() {
+ // Move all in-flight copies, if any, back into the pool. Then, destroy all
+ // the CopyContexts in the pool.
+ copy_context_pool_.insert(copy_context_pool_.end(),
+ copy_requests_.begin(), copy_requests_.end());
+ copy_requests_.clear();
+ while (!copy_context_pool_.empty()) {
+ scoped_ptr<CopyContext> copy_context(copy_context_pool_.back());
+ copy_context_pool_.pop_back();
+ copy_context->ReleaseCachedGLObjects();
+ }
}
gfx::Rect CompositingIOSurfaceMac::IntersectWithIOSurface(
diff --git a/content/browser/renderer_host/compositing_iosurface_shader_programs_mac.cc b/content/browser/renderer_host/compositing_iosurface_shader_programs_mac.cc
index 40575df..12988a1 100644
--- a/content/browser/renderer_host/compositing_iosurface_shader_programs_mac.cc
+++ b/content/browser/renderer_host/compositing_iosurface_shader_programs_mac.cc
@@ -332,13 +332,12 @@
texel_scale_x_var_locations_[i] = -1;
}
-bool CompositingIOSurfaceShaderPrograms::UseBlitProgram(
- int texture_unit_offset) {
+bool CompositingIOSurfaceShaderPrograms::UseBlitProgram() {
const GLuint program = GetShaderProgram(SHADER_PROGRAM_BLIT);
if (program == 0u)
return false;
glUseProgram(program);
- BindUniformTextureVariable(SHADER_PROGRAM_BLIT, texture_unit_offset);
+ BindUniformTextureVariable(SHADER_PROGRAM_BLIT, 0);
return true;
}
@@ -351,7 +350,7 @@
}
bool CompositingIOSurfaceShaderPrograms::UseRGBToYV12Program(
- int pass_number, int texture_unit_offset, float texel_scale_x) {
+ int pass_number, float texel_scale_x) {
const int which = SHADER_PROGRAM_RGB_TO_YV12__1_OF_2 + pass_number - 1;
DCHECK_GE(which, SHADER_PROGRAM_RGB_TO_YV12__1_OF_2);
DCHECK_LE(which, SHADER_PROGRAM_RGB_TO_YV12__2_OF_2);
@@ -360,7 +359,7 @@
if (program == 0u)
return false;
glUseProgram(program);
- BindUniformTextureVariable(which, texture_unit_offset);
+ BindUniformTextureVariable(which, 0);
if (which == SHADER_PROGRAM_RGB_TO_YV12__1_OF_2) {
BindUniformTexelScaleXVariable(which, texel_scale_x);
} else {
diff --git a/content/browser/renderer_host/compositing_iosurface_shader_programs_mac.h b/content/browser/renderer_host/compositing_iosurface_shader_programs_mac.h
index ce6bfa9..152858c 100644
--- a/content/browser/renderer_host/compositing_iosurface_shader_programs_mac.h
+++ b/content/browser/renderer_host/compositing_iosurface_shader_programs_mac.h
@@ -26,8 +26,8 @@
void Reset();
// Begin using the "blit" program, which is set up to sample the texture at
- // GL_TEXTURE_0 + |texture_unit_offset|. Returns false on error.
- bool UseBlitProgram(int texture_unit_offset);
+ // GL_TEXTURE_0. Returns false on error.
+ bool UseBlitProgram();
// Begin using the program that just draws solid white very efficiently.
// Returns false on error.
@@ -35,10 +35,9 @@
// Begin using one of the two RGB-to-YV12 color conversion programs, as
// specified by |pass_number| 1 or 2. The programs will sample the texture at
- // GL_TEXTURE0 + |texture_unit_offset|, and account for scaling in the X
- // direction by |texel_scale_x|. Returns false on error.
- bool UseRGBToYV12Program(
- int pass_number, int texture_unit_offset, float texel_scale_x);
+ // GL_TEXTURE0, and account for scaling in the X direction by |texel_scale_x|.
+ // Returns false on error.
+ bool UseRGBToYV12Program(int pass_number, float texel_scale_x);
private:
enum { kNumShaderPrograms = 4 };
diff --git a/content/browser/renderer_host/compositing_iosurface_transformer_mac.cc b/content/browser/renderer_host/compositing_iosurface_transformer_mac.cc
index be9d264..2e0401f 100644
--- a/content/browser/renderer_host/compositing_iosurface_transformer_mac.cc
+++ b/content/browser/renderer_host/compositing_iosurface_transformer_mac.cc
@@ -17,68 +17,11 @@
namespace {
-// Simple auto-delete scoping support for an owned Framebuffer object.
-class ScopedFramebuffer {
- public:
- ScopedFramebuffer() {
- glGenFramebuffersEXT(1, &name_);
- }
-
- ~ScopedFramebuffer() {
- if (name_ != 0u)
- glDeleteFramebuffersEXT(1, &name_);
- }
-
- bool is_valid() const { return name_ != 0u; }
- GLuint name() const { return name_; }
-
- private:
- GLuint name_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedFramebuffer);
+const GLenum kColorAttachments[] = {
+ GL_COLOR_ATTACHMENT0_EXT,
+ GL_COLOR_ATTACHMENT1_EXT
};
-// Simple auto-delete scoping support for an owned texture object.
-class ScopedTexture {
- public:
- ScopedTexture() : name_(0u) {}
- ScopedTexture(GLenum target, const gfx::Size& size);
-
- ~ScopedTexture() {
- if (name_ != 0u)
- glDeleteTextures(1, &name_);
- }
-
- bool is_valid() const { return name_ != 0u; }
- GLuint name() const { return name_; }
-
- void Reset(GLuint texture) {
- if (name_ != 0u)
- glDeleteTextures(1, &name_);
- name_ = texture;
- }
-
- GLuint Release() {
- GLuint ret = name_;
- name_ = 0u;
- return ret;
- }
-
- private:
- GLuint name_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedTexture);
-};
-
-ScopedTexture::ScopedTexture(GLenum target, const gfx::Size& size) {
- glGenTextures(1, &name_);
- glBindTexture(target, name_);
- glTexImage2D(target, 0, GL_RGBA, size.width(), size.height(), 0, GL_BGRA,
- GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
- DCHECK(glGetError() == GL_NO_ERROR);
- glBindTexture(target, 0u);
-}
-
// Set viewport and model/projection matrices for drawing to a framebuffer of
// size dst_size, with coordinates starting at (0, 0).
void SetTransformationsForOffScreenRendering(const gfx::Size& dst_size) {
@@ -142,16 +85,18 @@
} // namespace
CompositingIOSurfaceTransformer::CompositingIOSurfaceTransformer(
- GLenum texture_target, GLint texture_unit, bool src_texture_needs_y_flip,
+ GLenum texture_target, bool src_texture_needs_y_flip,
CompositingIOSurfaceShaderPrograms* shader_program_cache)
: texture_target_(texture_target),
- texture_unit_(texture_unit),
src_texture_needs_y_flip_(src_texture_needs_y_flip),
- shader_program_cache_(shader_program_cache) {
+ shader_program_cache_(shader_program_cache),
+ frame_buffer_(0) {
DCHECK(texture_target_ == GL_TEXTURE_RECTANGLE_ARB)
<< "Fragment shaders currently only support RECTANGLE textures.";
DCHECK(shader_program_cache_);
+ memset(textures_, 0, sizeof(textures_));
+
// The RGB-to-YV12 transform requires that the driver/hardware supports
// multiple draw buffers.
GLint max_draw_buffers = 1;
@@ -160,6 +105,23 @@
}
CompositingIOSurfaceTransformer::~CompositingIOSurfaceTransformer() {
+ for (int i = 0; i < NUM_CACHED_TEXTURES; ++i)
+ DCHECK_EQ(textures_[i], 0u) << "Failed to call ReleaseCachedGLObjects().";
+ DCHECK_EQ(frame_buffer_, 0u) << "Failed to call ReleaseCachedGLObjects().";
+}
+
+void CompositingIOSurfaceTransformer::ReleaseCachedGLObjects() {
+ for (int i = 0; i < NUM_CACHED_TEXTURES; ++i) {
+ if (textures_[i]) {
+ glDeleteTextures(1, &textures_[i]);
+ textures_[i] = 0;
+ texture_sizes_[i] = gfx::Size();
+ }
+ }
+ if (frame_buffer_) {
+ glDeleteFramebuffersEXT(1, &frame_buffer_);
+ frame_buffer_ = 0;
+ }
}
bool CompositingIOSurfaceTransformer::ResizeBilinear(
@@ -168,18 +130,15 @@
if (src_subrect.IsEmpty() || dst_size.IsEmpty())
return false;
- glActiveTexture(GL_TEXTURE0 + texture_unit_);
+ glActiveTexture(GL_TEXTURE0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
- ScopedTexture dst_texture(texture_target_, dst_size);
- if (!dst_texture.is_valid())
- return false;
-
- ScopedFramebuffer temp_frame_buffer;
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, temp_frame_buffer.name());
+ PrepareTexture(RGBA_OUTPUT, dst_size);
+ PrepareFramebuffer();
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame_buffer_);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- texture_target_, dst_texture.name(), 0);
+ texture_target_, textures_[RGBA_OUTPUT], 0);
DCHECK(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) ==
GL_FRAMEBUFFER_COMPLETE_EXT);
@@ -188,7 +147,7 @@
texture_target_, src_subrect.size() == dst_size ? GL_NEAREST : GL_LINEAR,
GL_CLAMP_TO_EDGE);
- const bool prepared = shader_program_cache_->UseBlitProgram(texture_unit_);
+ const bool prepared = shader_program_cache_->UseBlitProgram();
DCHECK(prepared);
SetTransformationsForOffScreenRendering(dst_size);
DrawQuad(src_subrect.x(), src_subrect.y(),
@@ -196,9 +155,11 @@
src_texture_needs_y_flip_,
dst_size.width(), dst_size.height());
glUseProgram(0);
- glBindTexture(texture_target_, 0u);
- *texture = dst_texture.Release();
+ glBindTexture(texture_target_, 0);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+ *texture = textures_[RGBA_OUTPUT];
return true;
}
@@ -218,11 +179,11 @@
TRACE_EVENT0("gpu", "TransformRGBToYV12");
- glActiveTexture(GL_TEXTURE0 + texture_unit_);
+ glActiveTexture(GL_TEXTURE0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
- // Allocate output textures for each plane, and the temporary one for the UUVV
+ // Resize output textures for each plane, and for the intermediate UUVV one
// that becomes an input into pass #2. |packed_y_size| is the size of the Y
// output texture, where its width is 1/4 the number of Y pixels because 4 Y
// pixels are packed into a single quad. |packed_uv_size| is half the size of
@@ -230,36 +191,22 @@
*packed_y_size = gfx::Size((dst_size.width() + 3) / 4, dst_size.height());
*packed_uv_size = gfx::Size((packed_y_size->width() + 1) / 2,
(packed_y_size->height() + 1) / 2);
- ScopedTexture temp_texture_y(texture_target_, *packed_y_size);
- if (!temp_texture_y.is_valid())
- return false;
- ScopedTexture temp_texture_u(texture_target_, *packed_uv_size);
- if (!temp_texture_u.is_valid())
- return false;
- ScopedTexture temp_texture_v(texture_target_, *packed_uv_size);
- if (!temp_texture_v.is_valid())
- return false;
-
- // Create a temporary texture for the UUVV that becomes an input into pass #2.
- ScopedTexture temp_texture_uuvv(texture_target_, *packed_y_size);
- if (!temp_texture_uuvv.is_valid())
- return false;
-
- // Create a temporary FBO for writing to the textures off-screen.
- ScopedFramebuffer temp_frame_buffer;
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, temp_frame_buffer.name());
+ PrepareTexture(Y_PLANE_OUTPUT, *packed_y_size);
+ PrepareTexture(UUVV_INTERMEDIATE, *packed_y_size);
+ PrepareTexture(U_PLANE_OUTPUT, *packed_uv_size);
+ PrepareTexture(V_PLANE_OUTPUT, *packed_uv_size);
/////////////////////////////////////////
// Pass 1: RGB --(scaled)--> YYYY + UUVV
+ PrepareFramebuffer();
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame_buffer_);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- texture_target_, temp_texture_y.name(), 0);
+ texture_target_, textures_[Y_PLANE_OUTPUT], 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT,
- texture_target_, temp_texture_uuvv.name(), 0);
+ texture_target_, textures_[UUVV_INTERMEDIATE], 0);
DCHECK(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) ==
GL_FRAMEBUFFER_COMPLETE_EXT);
- static const GLenum kAttachments[] =
- { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
- glDrawBuffers(2, kAttachments);
+ glDrawBuffers(2, kColorAttachments);
// Read from |src_texture|. Enable bilinear filtering only if scaling is
// required. The filtering will take place entirely in the first pass.
@@ -270,7 +217,7 @@
// Use the first-pass shader program and draw the scene.
const bool prepared_pass_1 = shader_program_cache_->UseRGBToYV12Program(
- 1, texture_unit_,
+ 1,
static_cast<float>(src_subrect.width()) / dst_size.width());
DCHECK(prepared_pass_1);
SetTransformationsForOffScreenRendering(*packed_y_size);
@@ -284,20 +231,20 @@
/////////////////////////////////////////
// Pass 2: UUVV -> UUUU + VVVV
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- texture_target_, temp_texture_u.name(), 0);
+ texture_target_, textures_[U_PLANE_OUTPUT], 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT,
- texture_target_, temp_texture_v.name(), 0);
+ texture_target_, textures_[V_PLANE_OUTPUT], 0);
DCHECK(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) ==
GL_FRAMEBUFFER_COMPLETE_EXT);
- // Read from texture_uuvv. The second pass uses bilinear minification to
- // achieve vertical scaling, so enable it always.
- glBindTexture(texture_target_, temp_texture_uuvv.name());
+ // Read from the intermediate UUVV texture. The second pass uses bilinear
+ // minification to achieve vertical scaling, so enable it always.
+ glBindTexture(texture_target_, textures_[UUVV_INTERMEDIATE]);
SetTextureParameters(texture_target_, GL_LINEAR, GL_CLAMP_TO_EDGE);
// Use the second-pass shader program and draw the scene.
const bool prepared_pass_2 =
- shader_program_cache_->UseRGBToYV12Program(2, texture_unit_, 1.0f);
+ shader_program_cache_->UseRGBToYV12Program(2, 1.0f);
DCHECK(prepared_pass_2);
SetTransformationsForOffScreenRendering(*packed_uv_size);
DrawQuad(0.0f, 0.0f,
@@ -306,15 +253,48 @@
false,
packed_uv_size->width(), packed_uv_size->height());
glUseProgram(0);
- glBindTexture(texture_target_, 0);
// Before leaving, put back to drawing to a single rendering output.
- glDrawBuffers(1, kAttachments);
+ glDrawBuffers(1, kColorAttachments);
- *texture_y = temp_texture_y.Release();
- *texture_u = temp_texture_u.Release();
- *texture_v = temp_texture_v.Release();
+ glBindTexture(texture_target_, 0);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+ *texture_y = textures_[Y_PLANE_OUTPUT];
+ *texture_u = textures_[U_PLANE_OUTPUT];
+ *texture_v = textures_[V_PLANE_OUTPUT];
return true;
}
+void CompositingIOSurfaceTransformer::PrepareTexture(
+ CachedTexture which, const gfx::Size& size) {
+ DCHECK_GE(which, 0);
+ DCHECK_LT(which, NUM_CACHED_TEXTURES);
+ DCHECK(!size.IsEmpty());
+
+ if (!textures_[which]) {
+ glGenTextures(1, &textures_[which]);
+ DCHECK_NE(textures_[which], 0u);
+ texture_sizes_[which] = gfx::Size();
+ }
+
+ // Re-allocate the texture if its size has changed since last use.
+ if (texture_sizes_[which] != size) {
+ TRACE_EVENT2("gpu", "Resize Texture",
+ "which", which,
+ "new_size", size.ToString());
+ glBindTexture(texture_target_, textures_[which]);
+ glTexImage2D(texture_target_, 0, GL_RGBA, size.width(), size.height(), 0,
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
+ texture_sizes_[which] = size;
+ }
+}
+
+void CompositingIOSurfaceTransformer::PrepareFramebuffer() {
+ if (!frame_buffer_) {
+ glGenFramebuffersEXT(1, &frame_buffer_);
+ DCHECK_NE(frame_buffer_, 0u);
+ }
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/compositing_iosurface_transformer_mac.h b/content/browser/renderer_host/compositing_iosurface_transformer_mac.h
index c38c0e0..4890074 100644
--- a/content/browser/renderer_host/compositing_iosurface_transformer_mac.h
+++ b/content/browser/renderer_host/compositing_iosurface_transformer_mac.h
@@ -9,10 +9,10 @@
#include "base/basictypes.h"
#include "content/browser/renderer_host/compositing_iosurface_shader_programs_mac.h"
+#include "ui/gfx/size.h"
namespace gfx {
class Rect;
-class Size;
} // namespace gfx
namespace content {
@@ -25,20 +25,25 @@
public:
// Construct a transformer that always uses the given parameters for texture
// bindings. |texture_target| is one of the valid enums to use with
- // glBindTexture(). |texture_unit| selects the texture unit to be used when
- // running the shader programs (i.e., specify 0 for GL_TEXTURE0).
+ // glBindTexture().
// |src_texture_needs_y_flip| is true when the |src_texture| argument to any
// of the methods below uses upside-down Y coordinates.
// |shader_program_cache| is not owned by this instance.
CompositingIOSurfaceTransformer(
- GLenum texture_target, int texture_unit, bool src_texture_needs_y_flip,
+ GLenum texture_target, bool src_texture_needs_y_flip,
CompositingIOSurfaceShaderPrograms* shader_program_cache);
~CompositingIOSurfaceTransformer();
+ // Delete any references to currently-cached OpenGL objects. This must be
+ // called within the OpenGL context just before destruction.
+ void ReleaseCachedGLObjects();
+
// Resize using bilinear interpolation. Returns false on error. Otherwise,
- // the |texture| argument will point to the result and the caller is
- // responsible for calling glDeleteTexture(*texture).
+ // the |texture| argument will point to the result. Ownership of the returned
+ // |texture| remains with CompositingIOSurfaceTransformer (i.e., the caller
+ // must not delete this texture). The |texture| remains valid until the next
+ // call to ResizeBilinear() or ReleaseCachedGLObjects().
//
// If the src and dst sizes are identical, this becomes a simple copy into a
// new texture.
@@ -52,15 +57,20 @@
//
// YV12 is effectively a twelve bit per pixel format consisting of a full-
// size y (luminance) plane and half-width, half-height u and v (blue and
- // red chrominance) planes. This method will allocate three off-screen
- // textures, one for each plane, and return them via the output arguments
- // |texture_y|, |texture_u|, and |texture_v|. While the textures are in
- // GL_RGBA format, they should be interpreted as the appropriate single-byte,
- // planar format after reading the pixel data. The output arguments
- // |packed_y_size| and |packed_uv_size| follow from these special semantics:
- // They represent the size of their corresponding texture, if it was to be
- // treated like RGBA pixel data. That means their widths are in terms of
- // "quads," where one quad contains 4 Y (or U or V) pixels.
+ // red chrominance) planes. This method will return three off-screen
+ // textures, one for each plane, via the output arguments |texture_y|,
+ // |texture_u|, and |texture_v|. While the textures are in GL_RGBA format,
+ // they should be interpreted as the appropriate single-byte, planar format
+ // after reading the pixel data. The output arguments |packed_y_size| and
+ // |packed_uv_size| follow from these special semantics: They represent the
+ // size of their corresponding texture, if it was to be treated like RGBA
+ // pixel data. That means their widths are in terms of "quads," where one
+ // quad contains 4 Y (or U or V) pixels.
+ //
+ // Ownership of the returned textures remains with
+ // CompositingIOSurfaceTransformer (i.e., the caller must not delete the
+ // textures). The textures remain valid until the next call to
+ // TransformRGBToYV12() or ReleaseCachedGLObjects().
//
// If |src_subrect|'s size does not match |dst_size|, the source will be
// bilinearly interpolated during conversion.
@@ -74,14 +84,34 @@
gfx::Size* packed_y_size, gfx::Size* packed_uv_size);
private:
+ enum CachedTexture {
+ RGBA_OUTPUT = 0,
+ Y_PLANE_OUTPUT,
+ UUVV_INTERMEDIATE,
+ U_PLANE_OUTPUT,
+ V_PLANE_OUTPUT,
+ NUM_CACHED_TEXTURES
+ };
+
+ // If necessary, generate the texture and/or resize it to the given |size|.
+ void PrepareTexture(CachedTexture which, const gfx::Size& size);
+
+ // If necessary, generate a framebuffer object to be used as an intermediate
+ // destination for drawing.
+ void PrepareFramebuffer();
+
// Target to bind all input and output textures to (which defines the type of
// textures being created and read). Generally, this is
// GL_TEXTURE_RECTANGLE_ARB.
const GLenum texture_target_;
- const int texture_unit_;
const bool src_texture_needs_y_flip_;
CompositingIOSurfaceShaderPrograms* const shader_program_cache_;
+ // Cached OpenGL objects.
+ GLuint textures_[NUM_CACHED_TEXTURES];
+ gfx::Size texture_sizes_[NUM_CACHED_TEXTURES];
+ GLuint frame_buffer_;
+
// Auto-detected and set once in the constructor.
bool system_supports_multiple_draw_buffers_;
diff --git a/content/browser/renderer_host/compositing_iosurface_transformer_mac_unittest.cc b/content/browser/renderer_host/compositing_iosurface_transformer_mac_unittest.cc
index 110d79a..6f2562c 100644
--- a/content/browser/renderer_host/compositing_iosurface_transformer_mac_unittest.cc
+++ b/content/browser/renderer_host/compositing_iosurface_transformer_mac_unittest.cc
@@ -276,10 +276,11 @@
CGLSetCurrentContext(context_);
shader_program_cache_.reset(new CompositingIOSurfaceShaderPrograms());
transformer_.reset(new CompositingIOSurfaceTransformer(
- kGLTextureTarget, 0, false, shader_program_cache_.get()));
+ kGLTextureTarget, false, shader_program_cache_.get()));
}
virtual ~CompositingIOSurfaceTransformerTest() {
+ transformer_->ReleaseCachedGLObjects();
shader_program_cache_->Reset();
CGLSetCurrentContext(NULL);
CGLDestroyContext(context_);
@@ -289,25 +290,21 @@
void RunResizeTest(const SkBitmap& src_bitmap, const gfx::Rect& src_rect,
const gfx::Size& dst_size) {
SCOPED_TRACE(::testing::Message()
- << "src_rect=" << src_rect.x() << ',' << src_rect.y()
+ << "src_rect=(" << src_rect.x() << ',' << src_rect.y()
<< ")x[" << src_rect.width() << 'x' << src_rect.height()
<< "]; dst_size=[" << dst_size.width() << 'x'
<< dst_size.height() << ']');
- const GLuint original_texture = CreateTextureWithImage(src_bitmap);
- EXPECT_NE(0u, original_texture);
-
// Do the scale operation on the GPU.
+ const GLuint original_texture = CreateTextureWithImage(src_bitmap);
+ ASSERT_NE(0u, original_texture);
GLuint scaled_texture = 0u;
- EXPECT_TRUE(transformer_->ResizeBilinear(
+ ASSERT_TRUE(transformer_->ResizeBilinear(
original_texture, src_rect, dst_size, &scaled_texture));
EXPECT_NE(0u, scaled_texture);
CGLFlushDrawable(context_); // Account for some buggy driver impls.
const SkBitmap result_bitmap = ReadBackTexture(scaled_texture, dst_size);
-
- // Delete the textures.
EXPECT_NO_GL_ERROR(glDeleteTextures(1, &original_texture));
- EXPECT_NO_GL_ERROR(glDeleteTextures(1, &scaled_texture));
// Compare the image read back to the version produced by a known-working
// software implementation. Allow up to 2 lines of mismatch due to how
@@ -322,21 +319,20 @@
const SkBitmap& src_bitmap, const gfx::Rect& src_rect,
const gfx::Size& dst_size) {
SCOPED_TRACE(::testing::Message()
- << "src_rect=" << src_rect.x() << ',' << src_rect.y()
+ << "src_rect=(" << src_rect.x() << ',' << src_rect.y()
<< ")x[" << src_rect.width() << 'x' << src_rect.height()
<< "]; dst_size=[" << dst_size.width() << 'x'
<< dst_size.height() << ']');
- const GLuint original_texture = CreateTextureWithImage(src_bitmap);
- EXPECT_NE(0u, original_texture);
-
// Perform the RGB to YV12 conversion.
+ const GLuint original_texture = CreateTextureWithImage(src_bitmap);
+ ASSERT_NE(0u, original_texture);
GLuint texture_y = 0u;
GLuint texture_u = 0u;
GLuint texture_v = 0u;
gfx::Size packed_y_size;
gfx::Size packed_uv_size;
- EXPECT_TRUE(transformer_->TransformRGBToYV12(
+ ASSERT_TRUE(transformer_->TransformRGBToYV12(
original_texture, src_rect, dst_size,
&texture_y, &texture_u, &texture_v, &packed_y_size, &packed_uv_size));
EXPECT_NE(0u, texture_y);
@@ -344,6 +340,7 @@
EXPECT_NE(0u, texture_v);
EXPECT_FALSE(packed_y_size.IsEmpty());
EXPECT_FALSE(packed_uv_size.IsEmpty());
+ EXPECT_NO_GL_ERROR(glDeleteTextures(1, &original_texture));
// Read-back the texture for each plane.
CGLFlushDrawable(context_); // Account for some buggy driver impls.
@@ -351,12 +348,6 @@
const SkBitmap result_u_bitmap = ReadBackTexture(texture_u, packed_uv_size);
const SkBitmap result_v_bitmap = ReadBackTexture(texture_v, packed_uv_size);
- // Delete the textures.
- EXPECT_NO_GL_ERROR(glDeleteTextures(1, &original_texture));
- EXPECT_NO_GL_ERROR(glDeleteTextures(1, &texture_y));
- EXPECT_NO_GL_ERROR(glDeleteTextures(1, &texture_u));
- EXPECT_NO_GL_ERROR(glDeleteTextures(1, &texture_v));
-
// Compare the Y, U, and V planes read-back to the version produced by a
// known-working software implementation. Allow up to 2 lines of mismatch
// due to how implementations disagree on resolving the processing of edges.
@@ -409,16 +400,12 @@
DISALLOW_COPY_AND_ASSIGN(CompositingIOSurfaceTransformerTest);
};
-// TODO(miu): Enable ALL the tests after the initial change lands. These were
-// started out DISABLED since unit tests executing on GPUs have been known to
-// sometimes cause messy flakiness problems.
-TEST_F(CompositingIOSurfaceTransformerTest,
- DISABLED_ShaderProgramsCompileAndLink) {
+TEST_F(CompositingIOSurfaceTransformerTest, ShaderProgramsCompileAndLink) {
// Attempt to use each program, binding its required uniform variables.
- EXPECT_NO_GL_ERROR(shader_program_cache()->UseBlitProgram(0));
+ EXPECT_NO_GL_ERROR(shader_program_cache()->UseBlitProgram());
EXPECT_NO_GL_ERROR(shader_program_cache()->UseSolidWhiteProgram());
- EXPECT_NO_GL_ERROR(shader_program_cache()->UseRGBToYV12Program(1, 0, 1.0f));
- EXPECT_NO_GL_ERROR(shader_program_cache()->UseRGBToYV12Program(2, 0, 1.0f));
+ EXPECT_NO_GL_ERROR(shader_program_cache()->UseRGBToYV12Program(1, 1.0f));
+ EXPECT_NO_GL_ERROR(shader_program_cache()->UseRGBToYV12Program(2, 1.0f));
EXPECT_NO_GL_ERROR(glUseProgram(0));
}
@@ -467,7 +454,7 @@
} // namespace
-TEST_F(CompositingIOSurfaceTransformerTest, DISABLED_ResizesTexturesCorrectly) {
+TEST_F(CompositingIOSurfaceTransformerTest, ResizesTexturesCorrectly) {
for (size_t i = 0; i < arraysize(kTestParameters); ++i) {
SCOPED_TRACE(::testing::Message() << "kTestParameters[" << i << ']');
@@ -497,7 +484,7 @@
}
}
-TEST_F(CompositingIOSurfaceTransformerTest, DISABLED_TransformsRGBToYV12) {
+TEST_F(CompositingIOSurfaceTransformerTest, TransformsRGBToYV12) {
for (size_t i = 0; i < arraysize(kTestParameters); ++i) {
SCOPED_TRACE(::testing::Message() << "kTestParameters[" << i << ']');
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index f81a876..6d4aba1 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -49,8 +49,8 @@
: cc::OutputSurface(context3d.Pass()) {}
virtual void Reshape(gfx::Size size) OVERRIDE {}
- virtual void PostSubBuffer(gfx::Rect rect) OVERRIDE {}
- virtual void SwapBuffers() OVERRIDE {}
+ virtual void PostSubBuffer(gfx::Rect rect, const cc::LatencyInfo&) OVERRIDE {}
+ virtual void SwapBuffers(const cc::LatencyInfo&) OVERRIDE {}
};
static bool g_initialized = false;
@@ -82,7 +82,8 @@
void Compositor::InitializeWithFlags(uint32 flags) {
g_use_direct_gl = flags & DIRECT_CONTEXT_ON_DRAW_THREAD;
if (flags & ENABLE_COMPOSITOR_THREAD) {
- TRACE_EVENT_INSTANT0("test_gpu", "ThreadedCompositingInitialization");
+ TRACE_EVENT_INSTANT0("test_gpu", "ThreadedCompositingInitialization",
+ TRACE_EVENT_SCOPE_THREAD);
g_impl_thread = new webkit_glue::WebThreadImpl("Browser Compositor");
}
Compositor::Initialize();
@@ -120,15 +121,22 @@
window_(NULL),
surface_id_(0),
client_(client),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ weak_factory_(this) {
DCHECK(client);
}
CompositorImpl::~CompositorImpl() {
+ // Clean-up any surface references.
+ SetSurface(NULL);
+}
+
+void CompositorImpl::SetNeedsRedraw() {
+ if (host_)
+ host_->SetNeedsRedraw();
}
void CompositorImpl::Composite() {
- if (host_.get())
+ if (host_)
host_->Composite(base::TimeTicks::Now());
}
@@ -162,33 +170,41 @@
void CompositorImpl::SetSurface(jobject surface) {
JNIEnv* env = base::android::AttachCurrentThread();
base::android::ScopedJavaLocalRef<jobject> j_surface(env, surface);
- if (surface) {
- ANativeWindow* window = ANativeWindow_fromSurface(env, surface);
+
+ // First, cleanup any existing surface references.
+ if (surface_id_) {
+ DCHECK(g_surface_map.Get().find(surface_id_) !=
+ g_surface_map.Get().end());
+ base::AutoLock lock(g_surface_map_lock.Get());
+ g_surface_map.Get().erase(surface_id_);
+ }
+ SetWindowSurface(NULL);
+
+ // Now, set the new surface if we have one.
+ ANativeWindow* window = NULL;
+ if (surface)
+ window = ANativeWindow_fromSurface(env, surface);
+ if (window) {
SetWindowSurface(window);
ANativeWindow_release(window);
{
base::AutoLock lock(g_surface_map_lock.Get());
g_surface_map.Get().insert(std::make_pair(surface_id_, j_surface));
}
- } else {
- {
- base::AutoLock lock(g_surface_map_lock.Get());
- g_surface_map.Get().erase(surface_id_);
- }
- SetWindowSurface(NULL);
}
}
void CompositorImpl::SetVisible(bool visible) {
if (!visible) {
host_.reset();
- } else if (!host_.get()) {
+ } else if (!host_) {
cc::LayerTreeSettings settings;
settings.refresh_rate = 60.0;
settings.impl_side_painting = false;
settings.calculate_top_controls_position = false;
settings.top_controls_height = 0.f;
settings.use_memory_management = false;
+ settings.highp_threshold_min = 2048;
// Do not clear the framebuffer when rendering into external GL contexts
// like Android View System's.
@@ -205,7 +221,7 @@
host_->SetVisible(true);
host_->SetSurfaceReady();
- host_->SetViewportSize(size_, size_);
+ host_->SetViewportSize(size_);
host_->set_has_transparent_background(has_transparent_background_);
}
}
@@ -221,18 +237,18 @@
size_ = size;
if (host_)
- host_->SetViewportSize(size, size);
+ host_->SetViewportSize(size);
root_layer_->SetBounds(size);
}
void CompositorImpl::SetHasTransparentBackground(bool flag) {
has_transparent_background_ = flag;
- if (host_.get())
+ if (host_)
host_->set_has_transparent_background(flag);
}
bool CompositorImpl::CompositeAndReadback(void *pixels, const gfx::Rect& rect) {
- if (host_.get())
+ if (host_)
return host_->CompositeAndReadback(pixels, rect);
else
return false;
@@ -354,8 +370,8 @@
}
}
-scoped_ptr<cc::InputHandler> CompositorImpl::CreateInputHandler() {
- return scoped_ptr<cc::InputHandler>();
+scoped_ptr<cc::InputHandlerClient> CompositorImpl::CreateInputHandlerClient() {
+ return scoped_ptr<cc::InputHandlerClient>();
}
void CompositorImpl::DidCompleteSwapBuffers() {
@@ -386,6 +402,7 @@
void CompositorImpl::OnViewContextSwapBuffersPosted() {
TRACE_EVENT0("compositor", "CompositorImpl::OnViewContextSwapBuffersPosted");
+ client_->OnSwapBuffersPosted();
}
void CompositorImpl::OnViewContextSwapBuffersComplete() {
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h
index d984547..fc5361a 100644
--- a/content/browser/renderer_host/compositor_impl_android.h
+++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -17,7 +17,7 @@
struct ANativeWindow;
namespace cc {
-class InputHandler;
+class InputHandlerClient;
class Layer;
class LayerTreeHost;
}
@@ -55,6 +55,7 @@
virtual void SetHasTransparentBackground(bool flag) OVERRIDE;
virtual bool CompositeAndReadback(
void *pixels, const gfx::Rect& rect) OVERRIDE;
+ virtual void SetNeedsRedraw() OVERRIDE;
virtual void Composite() OVERRIDE;
virtual WebKit::WebGLId GenerateTexture(gfx::JavaBitmap& bitmap) OVERRIDE;
virtual WebKit::WebGLId GenerateCompressedTexture(
@@ -74,7 +75,8 @@
virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
float page_scale) OVERRIDE {}
virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface() OVERRIDE;
- virtual scoped_ptr<cc::InputHandler> CreateInputHandler() OVERRIDE;
+ virtual scoped_ptr<cc::InputHandlerClient> CreateInputHandlerClient()
+ OVERRIDE;
virtual void DidRecreateOutputSurface(bool success) OVERRIDE {}
virtual void WillCommit() OVERRIDE {}
virtual void DidCommit() OVERRIDE {}
diff --git a/content/browser/renderer_host/database_message_filter.cc b/content/browser/renderer_host/database_message_filter.cc
index f364ce2..da667ea 100644
--- a/content/browser/renderer_host/database_message_filter.cc
+++ b/content/browser/renderer_host/database_message_filter.cc
@@ -15,7 +15,6 @@
#include "content/public/browser/user_metrics.h"
#include "content/public/common/result_codes.h"
#include "googleurl/src/gurl.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
#include "third_party/sqlite/sqlite3.h"
#include "webkit/database/database_util.h"
#include "webkit/database/vfs_backend.h"
@@ -28,7 +27,6 @@
using quota::QuotaManager;
using quota::QuotaManagerProxy;
using quota::QuotaStatusCode;
-using WebKit::WebSecurityOrigin;
using webkit_database::DatabaseTracker;
using webkit_database::DatabaseUtil;
using webkit_database::VfsBackend;
diff --git a/content/browser/renderer_host/gtk_im_context_wrapper.cc b/content/browser/renderer_host/gtk_im_context_wrapper.cc
index fb5669a..e3fa26f 100644
--- a/content/browser/renderer_host/gtk_im_context_wrapper.cc
+++ b/content/browser/renderer_host/gtk_im_context_wrapper.cc
@@ -484,10 +484,8 @@
}
void GtkIMContextWrapper::HandleCommit(const string16& text) {
- if (suppress_next_commit_) {
- suppress_next_commit_ = false;
+ if (suppress_next_commit_)
return;
- }
// Append the text to the buffer, because commit signal might be fired
// multiple times when processing a key event.
diff --git a/content/browser/renderer_host/gtk_key_bindings_handler.cc b/content/browser/renderer_host/gtk_key_bindings_handler.cc
index 756bcc3..e86ea60 100644
--- a/content/browser/renderer_host/gtk_key_bindings_handler.cc
+++ b/content/browser/renderer_host/gtk_key_bindings_handler.cc
@@ -132,15 +132,16 @@
}
void GtkKeyBindingsHandler::BackSpace(GtkTextView* text_view) {
- GetHandlerOwner(text_view)->EditCommandMatched("DeleteBackward", "");
+ GetHandlerOwner(text_view)
+ ->EditCommandMatched("DeleteBackward", std::string());
}
void GtkKeyBindingsHandler::CopyClipboard(GtkTextView* text_view) {
- GetHandlerOwner(text_view)->EditCommandMatched("Copy", "");
+ GetHandlerOwner(text_view)->EditCommandMatched("Copy", std::string());
}
void GtkKeyBindingsHandler::CutClipboard(GtkTextView* text_view) {
- GetHandlerOwner(text_view)->EditCommandMatched("Cut", "");
+ GetHandlerOwner(text_view)->EditCommandMatched("Cut", std::string());
}
void GtkKeyBindingsHandler::DeleteFromCursor(
@@ -191,7 +192,7 @@
count = -count;
for (; count > 0; --count) {
for (const char* const* p = commands; *p; ++p)
- owner->EditCommandMatched(*p, "");
+ owner->EditCommandMatched(*p, std::string());
}
}
@@ -247,7 +248,7 @@
if (count < 0)
count = -count;
for (; count > 0; --count)
- owner->EditCommandMatched(command, "");
+ owner->EditCommandMatched(command, std::string());
}
void GtkKeyBindingsHandler::MoveViewport(
@@ -256,18 +257,18 @@
}
void GtkKeyBindingsHandler::PasteClipboard(GtkTextView* text_view) {
- GetHandlerOwner(text_view)->EditCommandMatched("Paste", "");
+ GetHandlerOwner(text_view)->EditCommandMatched("Paste", std::string());
}
void GtkKeyBindingsHandler::SelectAll(GtkTextView* text_view, gboolean select) {
if (select)
- GetHandlerOwner(text_view)->EditCommandMatched("SelectAll", "");
+ GetHandlerOwner(text_view)->EditCommandMatched("SelectAll", std::string());
else
- GetHandlerOwner(text_view)->EditCommandMatched("Unselect", "");
+ GetHandlerOwner(text_view)->EditCommandMatched("Unselect", std::string());
}
void GtkKeyBindingsHandler::SetAnchor(GtkTextView* text_view) {
- GetHandlerOwner(text_view)->EditCommandMatched("SetMark", "");
+ GetHandlerOwner(text_view)->EditCommandMatched("SetMark", std::string());
}
void GtkKeyBindingsHandler::ToggleCursorVisible(GtkTextView* text_view) {
diff --git a/content/browser/renderer_host/image_transport_factory.cc b/content/browser/renderer_host/image_transport_factory.cc
index be01420..1e566ac 100644
--- a/content/browser/renderer_host/image_transport_factory.cc
+++ b/content/browser/renderer_host/image_transport_factory.cc
@@ -231,7 +231,8 @@
// Recreating contexts directly from here causes issues, so post a task
// instead.
// TODO(piman): Fix the underlying issues.
- MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
base::Bind(&CompositorSwapClient::OnLostContext, this->AsWeakPtr()));
}
@@ -261,7 +262,7 @@
arraysize(messages_to_filter),
base::Bind(&BrowserCompositorOutputSurfaceProxy::OnMessageReceived,
this),
- MessageLoop::current()->message_loop_proxy());
+ base::MessageLoop::current()->message_loop_proxy());
message_handler_set_ = true;
}
surface_map_.AddWithID(surface, surface_id);
@@ -372,7 +373,7 @@
public ImageTransportFactory {
public:
GpuProcessTransportFactory()
- : ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) {
+ : callback_factory_(this) {
output_surface_proxy_ = new BrowserCompositorOutputSurfaceProxy();
}
@@ -462,17 +463,11 @@
}
virtual GLHelper* GetGLHelper() OVERRIDE {
- if (!gl_helper_.get()) {
+ if (!gl_helper_) {
CreateSharedContextLazy();
- WebKit::WebGraphicsContext3D* context_for_main_thread =
+ WebGraphicsContext3DCommandBufferImpl* context_for_main_thread =
shared_contexts_main_thread_->Context3d();
- WebKit::WebGraphicsContext3D* context_for_thread =
- CreateOffscreenContext();
- if (!context_for_thread)
- return NULL;
-
- gl_helper_.reset(new GLHelper(context_for_main_thread,
- context_for_thread));
+ gl_helper_.reset(new GLHelper(context_for_main_thread));
}
return gl_helper_.get();
}
@@ -601,7 +596,7 @@
}
virtual void OnLostContext() OVERRIDE {
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&GpuProcessTransportFactory::OnLostMainThreadSharedContext,
factory_->callback_factory_.GetWeakPtr()));
diff --git a/content/browser/renderer_host/image_transport_factory_android.cc b/content/browser/renderer_host/image_transport_factory_android.cc
index 9648970..bfb6dbb 100644
--- a/content/browser/renderer_host/image_transport_factory_android.cc
+++ b/content/browser/renderer_host/image_transport_factory_android.cc
@@ -160,8 +160,8 @@
}
GLHelper* CmdBufferImageTransportFactory::GetGLHelper() {
- if (!gl_helper_.get())
- gl_helper_.reset(new GLHelper(GetContext3D(), NULL));
+ if (!gl_helper_)
+ gl_helper_.reset(new GLHelper(context_.get()));
return gl_helper_.get();
}
diff --git a/content/browser/renderer_host/ime_adapter_android.cc b/content/browser/renderer_host/ime_adapter_android.cc
index 3eab2b0..6de2598 100644
--- a/content/browser/renderer_host/ime_adapter_android.cc
+++ b/content/browser/renderer_host/ime_adapter_android.cc
@@ -13,6 +13,7 @@
#include "base/utf_string_conversions.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h"
+#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "jni/ImeAdapter_jni.h"
@@ -227,7 +228,7 @@
if (!rwhi)
return;
- rwhi->Send(new ViewMsg_Unselect(rwhi->GetRoutingID()));
+ rwhi->Send(new InputMsg_Unselect(rwhi->GetRoutingID()));
}
void ImeAdapterAndroid::SelectAll(JNIEnv* env, jobject) {
@@ -236,7 +237,7 @@
if (!rwhi)
return;
- rwhi->Send(new ViewMsg_SelectAll(rwhi->GetRoutingID()));
+ rwhi->Send(new InputMsg_SelectAll(rwhi->GetRoutingID()));
}
void ImeAdapterAndroid::Cut(JNIEnv* env, jobject) {
@@ -245,7 +246,7 @@
if (!rwhi)
return;
- rwhi->Send(new ViewMsg_Cut(rwhi->GetRoutingID()));
+ rwhi->Send(new InputMsg_Cut(rwhi->GetRoutingID()));
}
void ImeAdapterAndroid::Copy(JNIEnv* env, jobject) {
@@ -254,7 +255,7 @@
if (!rwhi)
return;
- rwhi->Send(new ViewMsg_Copy(rwhi->GetRoutingID()));
+ rwhi->Send(new InputMsg_Copy(rwhi->GetRoutingID()));
}
void ImeAdapterAndroid::Paste(JNIEnv* env, jobject) {
@@ -263,7 +264,11 @@
if (!rwhi)
return;
- rwhi->Send(new ViewMsg_Paste(rwhi->GetRoutingID()));
+ rwhi->Send(new InputMsg_Paste(rwhi->GetRoutingID()));
+}
+
+void ImeAdapterAndroid::ResetImeAdapter(JNIEnv* env, jobject) {
+ java_ime_adapter_.reset();
}
} // namespace content
diff --git a/content/browser/renderer_host/ime_adapter_android.h b/content/browser/renderer_host/ime_adapter_android.h
index f990498..1c1669e 100644
--- a/content/browser/renderer_host/ime_adapter_android.h
+++ b/content/browser/renderer_host/ime_adapter_android.h
@@ -51,6 +51,7 @@
void Cut(JNIEnv*, jobject);
void Copy(JNIEnv*, jobject);
void Paste(JNIEnv*, jobject);
+ void ResetImeAdapter(JNIEnv*, jobject);
// Called from native -> java
void CancelComposition();
diff --git a/content/browser/renderer_host/java/java_bound_object.cc b/content/browser/renderer_host/java/java_bound_object.cc
index 4a239a5..008cee1 100644
--- a/content/browser/renderer_host/java/java_bound_object.cc
+++ b/content/browser/renderer_host/java/java_bound_object.cc
@@ -223,35 +223,79 @@
return !base::android::ClearException(env);
}
+double RoundDoubleTowardsZero(const double& x) {
+ if (std::isnan(x)) {
+ return 0.0;
+ }
+ return x > 0.0 ? floor(x) : ceil(x);
+}
+
+// Rounds to jlong using Java's type conversion rules.
+jlong RoundDoubleToLong(const double& x) {
+ double intermediate = RoundDoubleTowardsZero(x);
+ // The int64 limits can not be converted exactly to double values, so we
+ // compare to custom constants. kint64max is 2^63 - 1, but the spacing
+ // between double values in the the range 2^62 to 2^63 is 2^10. The cast is
+ // required to silence a spurious gcc warning for integer overflow.
+ const int64 limit = (GG_INT64_C(1) << 63) - static_cast<uint64>(1 << 10);
+ DCHECK(limit > 0);
+ const double kLargestDoubleLessThanInt64Max = limit;
+ const double kSmallestDoubleGreaterThanInt64Min = -limit;
+ if (intermediate > kLargestDoubleLessThanInt64Max) {
+ return kint64max;
+ }
+ if (intermediate < kSmallestDoubleGreaterThanInt64Min) {
+ return kint64min;
+ }
+ return static_cast<jlong>(intermediate);
+}
+
+// Rounds to jint using Java's type conversion rules.
+jint RoundDoubleToInt(const double& x) {
+ double intermediate = RoundDoubleTowardsZero(x);
+ // The int32 limits cast exactly to double values.
+ intermediate = std::min(intermediate, static_cast<double>(kint32max));
+ intermediate = std::max(intermediate, static_cast<double>(kint32min));
+ return static_cast<jint>(intermediate);
+}
+
jvalue CoerceJavaScriptNumberToJavaValue(const NPVariant& variant,
const JavaType& target_type,
bool coerce_to_string) {
// See http://jdk6.java.net/plugin2/liveconnect/#JS_NUMBER_VALUES.
+
+ // For conversion to numeric types, we need to replicate Java's type
+ // conversion rules. This requires that for integer values, we simply discard
+ // all but the lowest n buts, where n is the number of bits in the target
+ // type. For double values, the logic is more involved.
jvalue result;
DCHECK(variant.type == NPVariantType_Int32 ||
variant.type == NPVariantType_Double);
bool is_double = variant.type == NPVariantType_Double;
switch (target_type.type) {
case JavaType::TypeByte:
- result.b = is_double ? static_cast<jbyte>(NPVARIANT_TO_DOUBLE(variant)) :
- static_cast<jbyte>(NPVARIANT_TO_INT32(variant));
+ result.b = is_double ?
+ static_cast<jbyte>(RoundDoubleToInt(NPVARIANT_TO_DOUBLE(variant))) :
+ static_cast<jbyte>(NPVARIANT_TO_INT32(variant));
break;
case JavaType::TypeChar:
// LIVECONNECT_COMPLIANCE: Existing behavior is to convert double to 0.
- // Spec requires converting doubles the same as int32.
+ // Spec requires converting doubles similarly to how we convert doubles to
+ // other numeric types.
result.c = is_double ? 0 :
static_cast<jchar>(NPVARIANT_TO_INT32(variant));
break;
case JavaType::TypeShort:
- result.s = is_double ? static_cast<jshort>(NPVARIANT_TO_DOUBLE(variant)) :
- static_cast<jshort>(NPVARIANT_TO_INT32(variant));
+ result.s = is_double ?
+ static_cast<jshort>(RoundDoubleToInt(NPVARIANT_TO_DOUBLE(variant))) :
+ static_cast<jshort>(NPVARIANT_TO_INT32(variant));
break;
case JavaType::TypeInt:
- result.i = is_double ? static_cast<jint>(NPVARIANT_TO_DOUBLE(variant)) :
+ result.i = is_double ? RoundDoubleToInt(NPVARIANT_TO_DOUBLE(variant)) :
NPVARIANT_TO_INT32(variant);
break;
case JavaType::TypeLong:
- result.j = is_double ? static_cast<jlong>(NPVARIANT_TO_DOUBLE(variant)) :
+ result.j = is_double ? RoundDoubleToLong(NPVARIANT_TO_DOUBLE(variant)) :
NPVARIANT_TO_INT32(variant);
break;
case JavaType::TypeFloat:
diff --git a/content/browser/renderer_host/java/java_bridge_dispatcher_host.cc b/content/browser/renderer_host/java/java_bridge_dispatcher_host.cc
index 9285007..e3d2cd2 100644
--- a/content/browser/renderer_host/java/java_bridge_dispatcher_host.cc
+++ b/content/browser/renderer_host/java/java_bridge_dispatcher_host.cc
@@ -138,7 +138,8 @@
void JavaBridgeDispatcherHost::CreateObjectStub(NPObject* object,
int route_id) {
- DCHECK_EQ(g_background_thread.Get().message_loop(), MessageLoop::current());
+ DCHECK_EQ(g_background_thread.Get().message_loop(),
+ base::MessageLoop::current());
if (!channel_) {
channel_ = JavaBridgeChannelHost::GetJavaBridgeChannelHost(
render_view_host()->GetProcess()->GetID(),
diff --git a/content/browser/renderer_host/java/java_type.cc b/content/browser/renderer_host/java/java_type.cc
index e68f6db..b590e77 100644
--- a/content/browser/renderer_host/java/java_type.cc
+++ b/content/browser/renderer_host/java/java_type.cc
@@ -68,7 +68,7 @@
JavaType& JavaType::operator=(const JavaType& other) {
type = other.type;
- if (other.inner_type.get()) {
+ if (other.inner_type) {
DCHECK_EQ(JavaType::TypeArray, type);
inner_type.reset(new JavaType(*other.inner_type));
} else {
diff --git a/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc b/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
index c5294dc..decc71a 100644
--- a/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
+++ b/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
@@ -15,11 +15,6 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#if defined(OS_ANDROID)
-#include "base/android/jni_android.h"
-#include "media/audio/audio_manager_base.h"
-#endif
-
using testing::_;
using testing::InSequence;
using testing::SaveArg;
@@ -57,15 +52,9 @@
protected:
virtual void SetUp() OVERRIDE {
// The test must run on Browser::IO.
- message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO));
+ message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO));
io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
message_loop_.get()));
-
-#if defined(OS_ANDROID)
- media::AudioManagerBase::RegisterAudioManager(
- base::android::AttachCurrentThread());
-#endif
-
audio_manager_.reset(media::AudioManager::Create());
manager_ = new AudioInputDeviceManager(audio_manager_.get());
audio_input_listener_.reset(new MockAudioInputDeviceManagerListener());
@@ -88,7 +77,7 @@
io_thread_.reset();
}
- scoped_ptr<MessageLoop> message_loop_;
+ scoped_ptr<base::MessageLoop> message_loop_;
scoped_ptr<BrowserThreadImpl> io_thread_;
scoped_refptr<AudioInputDeviceManager> manager_;
scoped_ptr<MockAudioInputDeviceManagerListener> audio_input_listener_;
@@ -140,7 +129,7 @@
InSequence s;
int index = 0;
- scoped_array<int> session_id(new int[devices_.size()]);
+ scoped_ptr<int[]> session_id(new int[devices_.size()]);
// Opens the devices in a loop.
for (StreamDeviceInfoArray::const_iterator iter = devices_.begin();
@@ -245,7 +234,7 @@
InSequence s;
int index = 0;
- scoped_array<int> session_id(new int[devices_.size()]);
+ scoped_ptr<int[]> session_id(new int[devices_.size()]);
// Loops through the devices and calls Open()/Close()/GetOpenedDeviceInfoById
// for each device.
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 750661c..38a45f2 100644
--- a/content/browser/renderer_host/media/audio_input_renderer_host.cc
+++ b/content/browser/renderer_host/media/audio_input_renderer_host.cc
@@ -13,7 +13,6 @@
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/web_contents_audio_input_stream.h"
#include "content/browser/renderer_host/media/web_contents_capture_util.h"
-#include "content/common/media/audio_messages.h"
#include "media/audio/audio_manager_base.h"
namespace content {
@@ -159,7 +158,7 @@
Send(new AudioInputMsg_NotifyStreamCreated(entry->stream_id,
foreign_memory_handle, foreign_socket_handle,
- entry->shared_memory.created_size(),
+ entry->shared_memory.requested_size(),
entry->shared_memory_segment_count));
}
@@ -186,8 +185,6 @@
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_EX(AudioInputRendererHost, message, *message_was_ok)
IPC_MESSAGE_HANDLER(AudioInputHostMsg_CreateStream, OnCreateStream)
- IPC_MESSAGE_HANDLER(AudioInputHostMsg_AssociateStreamWithConsumer,
- OnAssociateStreamWithConsumer)
IPC_MESSAGE_HANDLER(AudioInputHostMsg_RecordStream, OnRecordStream)
IPC_MESSAGE_HANDLER(AudioInputHostMsg_CloseStream, OnCloseStream)
IPC_MESSAGE_HANDLER(AudioInputHostMsg_SetVolume, OnSetVolume)
@@ -199,13 +196,17 @@
void AudioInputRendererHost::OnCreateStream(
int stream_id,
+ int render_view_id,
int session_id,
- const media::AudioParameters& params,
- bool automatic_gain_control,
- int shared_memory_count) {
- VLOG(1) << "AudioInputRendererHost::OnCreateStream(stream_id="
- << stream_id << ", session_id=" << session_id << ")";
+ const AudioInputHostMsg_CreateStream_Config& config) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ DVLOG(1) << "AudioInputRendererHost@" << this
+ << "::OnCreateStream(stream_id=" << stream_id
+ << ", render_view_id=" << render_view_id
+ << ", session_id=" << session_id << ")";
+ DCHECK_GT(render_view_id, 0);
+
// media::AudioParameters is validated in the deserializer.
if (LookupById(stream_id) != NULL) {
SendErrorMessage(stream_id);
@@ -227,23 +228,22 @@
device_id = info->device.id;
}
- media::AudioParameters audio_params(params);
+ media::AudioParameters audio_params(config.params);
if (media_stream_manager_->audio_input_device_manager()->
ShouldUseFakeDevice()) {
- audio_params.Reset(media::AudioParameters::AUDIO_FAKE,
- params.channel_layout(), params.channels(), 0,
- params.sample_rate(),
- params.bits_per_sample(), params.frames_per_buffer());
+ audio_params.Reset(
+ media::AudioParameters::AUDIO_FAKE,
+ config.params.channel_layout(), config.params.channels(), 0,
+ config.params.sample_rate(), config.params.bits_per_sample(),
+ config.params.frames_per_buffer());
}
- uint32 buffer_size = audio_params.GetBytesPerBuffer();
-
// Create a new AudioEntry structure.
scoped_ptr<AudioEntry> entry(new AudioEntry());
- uint32 segment_size =
- sizeof(media::AudioInputBufferParameters) + buffer_size;
- entry->shared_memory_segment_count = shared_memory_count;
+ const uint32 segment_size = (sizeof(media::AudioInputBufferParameters) +
+ audio_params.GetBytesPerBuffer());
+ entry->shared_memory_segment_count = config.shared_memory_count;
// Create the shared memory and share it with the renderer process
// using a new SyncWriter object.
@@ -292,24 +292,15 @@
// Set the initial AGC state for the audio input stream. Note that, the AGC
// is only supported in AUDIO_PCM_LOW_LATENCY mode.
- if (params.format() == media::AudioParameters::AUDIO_PCM_LOW_LATENCY)
- entry->controller->SetAutomaticGainControl(automatic_gain_control);
+ if (config.params.format() == media::AudioParameters::AUDIO_PCM_LOW_LATENCY)
+ entry->controller->SetAutomaticGainControl(config.automatic_gain_control);
- // If we have created the controller successfully create a entry and add it
+ // Since the controller was created successfully, create an entry and add it
// to the map.
entry->stream_id = stream_id;
-
audio_entries_.insert(std::make_pair(stream_id, entry.release()));
}
-void AudioInputRendererHost::OnAssociateStreamWithConsumer(int stream_id,
- int render_view_id) {
- // TODO(miu): Will use render_view_id in upcoming change.
- DVLOG(1) << "AudioInputRendererHost@" << this
- << "::OnAssociateStreamWithConsumer(stream_id=" << stream_id
- << ", render_view_id=" << render_view_id << ")";
-}
-
void AudioInputRendererHost::OnRecordStream(int stream_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -404,7 +395,7 @@
// TODO(hclam): Implement a faster look up method.
for (AudioEntryMap::iterator i = audio_entries_.begin();
i != audio_entries_.end(); ++i) {
- if (controller == i->second->controller.get())
+ if (controller == i->second->controller)
return i->second;
}
return NULL;
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.h b/content/browser/renderer_host/media/audio_input_renderer_host.h
index e3b0453..077a1cc 100644
--- a/content/browser/renderer_host/media/audio_input_renderer_host.h
+++ b/content/browser/renderer_host/media/audio_input_renderer_host.h
@@ -34,6 +34,7 @@
#include "base/process.h"
#include "base/sequenced_task_runner_helpers.h"
#include "base/shared_memory.h"
+#include "content/common/media/audio_messages.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/browser_thread.h"
#include "media/audio/audio_input_controller.h"
@@ -84,20 +85,17 @@
// Methods called on IO thread ----------------------------------------------
// Audio related IPC message handlers.
- // Creates an audio input stream with the specified session id and format.
- // |session_id| is used to find out which device to be used for the stream,
- // when it is AudioInputDeviceManager::kFakeOpenSessionId, it uses the
- // the default device. If this call is successful this object would keep an
- // internal entry of the stream for the required properties.
- void OnCreateStream(int stream_id,
- int session_id,
- const media::AudioParameters& params,
- bool automatic_gain_control,
- int shared_memory_count);
- // Track that the data for the audio stream referenced by |stream_id| is
+ // Creates an audio input stream with the specified format whose data is
// consumed by an entity in the render view referenced by |render_view_id|.
- void OnAssociateStreamWithConsumer(int stream_id, int render_view_id);
+ // |session_id| is used to find out which device to be used for the stream.
+ // When it is AudioInputDeviceManager::kFakeOpenSessionId, it uses the the
+ // default device. Upon success/failure, the peer is notified via the
+ // NotifyStreamCreated message.
+ void OnCreateStream(int stream_id,
+ int render_view_id,
+ int session_id,
+ const AudioInputHostMsg_CreateStream_Config& config);
// Record the audio input stream referenced by |stream_id|.
void OnRecordStream(int stream_id);
@@ -109,7 +107,8 @@
void OnSetVolume(int stream_id, double volume);
// Complete the process of creating an audio input stream. This will set up
- // the shared memory or shared socket in low latency mode.
+ // the shared memory or shared socket in low latency mode and send the
+ // NotifyStreamCreated message to the peer.
void DoCompleteCreation(media::AudioInputController* controller);
// Send a state change message to the renderer.
diff --git a/content/browser/renderer_host/media/audio_input_sync_writer.cc b/content/browser/renderer_host/media/audio_input_sync_writer.cc
index 2af937d..18a85ab 100644
--- a/content/browser/renderer_host/media/audio_input_sync_writer.cc
+++ b/content/browser/renderer_host/media/audio_input_sync_writer.cc
@@ -18,9 +18,9 @@
shared_memory_segment_count_(shared_memory_segment_count),
current_segment_id_(0) {
DCHECK_GT(shared_memory_segment_count, 0);
- DCHECK_EQ(shared_memory->created_size() % shared_memory_segment_count, 0u);
+ DCHECK_EQ(shared_memory->requested_size() % shared_memory_segment_count, 0u);
shared_memory_segment_size_ =
- shared_memory->created_size() / shared_memory_segment_count;
+ shared_memory->requested_size() / shared_memory_segment_count;
}
AudioInputSyncWriter::~AudioInputSyncWriter() {}
diff --git a/content/browser/renderer_host/media/audio_mirroring_manager_unittest.cc b/content/browser/renderer_host/media/audio_mirroring_manager_unittest.cc
index 3cf38ed..b05fd71 100644
--- a/content/browser/renderer_host/media/audio_mirroring_manager_unittest.cc
+++ b/content/browser/renderer_host/media/audio_mirroring_manager_unittest.cc
@@ -46,7 +46,7 @@
class AudioMirroringManagerTest : public testing::Test {
public:
AudioMirroringManagerTest()
- : message_loop_(MessageLoop::TYPE_IO),
+ : message_loop_(base::MessageLoop::TYPE_IO),
io_thread_(BrowserThread::IO, &message_loop_),
params_(AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO,
AudioParameters::kAudioCDSampleRate, 16,
@@ -102,7 +102,7 @@
}
private:
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
BrowserThreadImpl io_thread_;
AudioParameters params_;
AudioMirroringManager mirroring_manager_;
diff --git a/content/browser/renderer_host/media/audio_renderer_host.cc b/content/browser/renderer_host/media/audio_renderer_host.cc
index b652183..3b21720 100644
--- a/content/browser/renderer_host/media/audio_renderer_host.cc
+++ b/content/browser/renderer_host/media/audio_renderer_host.cc
@@ -5,6 +5,8 @@
#include "content/browser/renderer_host/media/audio_renderer_host.h"
#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/command_line.h"
#include "base/metrics/histogram.h"
#include "base/process.h"
#include "base/shared_memory.h"
@@ -15,46 +17,85 @@
#include "content/common/media/audio_messages.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/media_observer.h"
+#include "content/public/common/content_switches.h"
#include "media/audio/shared_memory_util.h"
#include "media/base/audio_bus.h"
#include "media/base/limits.h"
-// TODO(miu): Re-enable after M27 branch cut. This feature is scheduled for
-// release in M28.
-#define DISABLED_AUDIO_INDICATOR_TRIGGERS_FOR_M27_ONLY
-
using media::AudioBus;
namespace content {
-struct AudioRendererHost::AudioEntry {
- AudioEntry();
- ~AudioEntry();
+class AudioRendererHost::AudioEntry
+ : public media::AudioOutputController::EventHandler {
+ public:
+ AudioEntry(AudioRendererHost* host,
+ int stream_id,
+ int render_view_id,
+ const media::AudioParameters& params,
+ scoped_ptr<base::SharedMemory> shared_memory,
+ scoped_ptr<media::AudioOutputController::SyncReader> reader);
+ virtual ~AudioEntry();
- // The AudioOutputController that manages the audio stream.
- scoped_refptr<media::AudioOutputController> controller;
+ int stream_id() const {
+ return stream_id_;
+ }
- // The audio stream ID.
- int stream_id;
+ int render_view_id() const {
+ return render_view_id_;
+ }
+
+ media::AudioOutputController* controller() const {
+ return controller_;
+ }
+
+ base::SharedMemory* shared_memory() {
+ return shared_memory_.get();
+ }
+
+ media::AudioOutputController::SyncReader* reader() const {
+ return reader_.get();
+ }
+
+ private:
+ // media::AudioOutputController::EventHandler implementation.
+ virtual void OnCreated() OVERRIDE;
+ virtual void OnPlaying() OVERRIDE;
+ virtual void OnAudible(bool is_audible) OVERRIDE;
+ virtual void OnPaused() OVERRIDE;
+ virtual void OnError() OVERRIDE;
+ virtual void OnDeviceChange(int new_buffer_size, int new_sample_rate)
+ OVERRIDE;
+
+ AudioRendererHost* const host_;
+ const int stream_id_;
// The routing ID of the source render view.
- int render_view_id;
+ const int render_view_id_;
+
+ // The AudioOutputController that manages the audio stream.
+ const scoped_refptr<media::AudioOutputController> controller_;
// Shared memory for transmission of the audio data.
- base::SharedMemory shared_memory;
+ const scoped_ptr<base::SharedMemory> shared_memory_;
- // The synchronous reader to be used by the controller. We have the
- // ownership of the reader.
- scoped_ptr<media::AudioOutputController::SyncReader> reader;
-
- // Set to true after we called Close() for the controller.
- bool pending_close;
+ // The synchronous reader to be used by the controller.
+ const scoped_ptr<media::AudioOutputController::SyncReader> reader_;
};
-AudioRendererHost::AudioEntry::AudioEntry()
- : stream_id(0),
- render_view_id(MSG_ROUTING_NONE),
- pending_close(false) {
+AudioRendererHost::AudioEntry::AudioEntry(
+ AudioRendererHost* host, int stream_id, int render_view_id,
+ const media::AudioParameters& params,
+ scoped_ptr<base::SharedMemory> shared_memory,
+ scoped_ptr<media::AudioOutputController::SyncReader> reader)
+ : host_(host),
+ stream_id_(stream_id),
+ render_view_id_(render_view_id),
+ controller_(media::AudioOutputController::Create(
+ host->audio_manager_, this, params, reader.get())),
+ shared_memory_(shared_memory.Pass()),
+ reader_(reader.Pass()) {
+ DCHECK(controller_);
}
AudioRendererHost::AudioEntry::~AudioEntry() {}
@@ -78,96 +119,94 @@
}
void AudioRendererHost::OnChannelClosing() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
BrowserMessageFilter::OnChannelClosing();
// Since the IPC channel is gone, close all requested audio streams.
- DeleteEntries();
+ while (!audio_entries_.empty()) {
+ // Note: OnCloseStream() removes the entries from audio_entries_.
+ OnCloseStream(audio_entries_.begin()->first);
+ }
}
void AudioRendererHost::OnDestruct() const {
BrowserThread::DeleteOnIOThread::Destruct(this);
}
-///////////////////////////////////////////////////////////////////////////////
-// media::AudioOutputController::EventHandler implementations.
-void AudioRendererHost::OnCreated(media::AudioOutputController* controller) {
+void AudioRendererHost::AudioEntry::OnCreated() {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&AudioRendererHost::DoCompleteCreation, host_, this));
+}
+
+void AudioRendererHost::AudioEntry::OnPlaying() {
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
base::Bind(
- &AudioRendererHost::DoCompleteCreation,
- this,
- make_scoped_refptr(controller)));
+ base::IgnoreResult(&AudioRendererHost::Send), host_,
+ new AudioMsg_NotifyStreamStateChanged(
+ stream_id_, media::AudioOutputIPCDelegate::kPlaying)));
}
-void AudioRendererHost::OnPlaying(media::AudioOutputController* controller) {
+void AudioRendererHost::AudioEntry::OnAudible(bool is_audible) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&AudioRendererHost::DoNotifyAudibleState, host_,
+ this, is_audible));
+}
+
+void AudioRendererHost::AudioEntry::OnPaused() {
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
base::Bind(
- &AudioRendererHost::DoSendPlayingMessage,
- this,
- make_scoped_refptr(controller)));
+ base::IgnoreResult(&AudioRendererHost::Send), host_,
+ new AudioMsg_NotifyStreamStateChanged(
+ stream_id_, media::AudioOutputIPCDelegate::kPaused)));
}
-void AudioRendererHost::OnPaused(media::AudioOutputController* controller) {
+void AudioRendererHost::AudioEntry::OnError() {
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
- base::Bind(
- &AudioRendererHost::DoSendPausedMessage,
- this,
- make_scoped_refptr(controller)));
+ base::Bind(&AudioRendererHost::ReportErrorAndClose, host_, stream_id_));
}
-void AudioRendererHost::OnError(media::AudioOutputController* controller) {
+void AudioRendererHost::AudioEntry::OnDeviceChange(int new_buffer_size,
+ int new_sample_rate) {
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
- base::Bind(
- &AudioRendererHost::DoHandleError,
- this,
- make_scoped_refptr(controller)));
+ base::Bind(base::IgnoreResult(&AudioRendererHost::Send), host_,
+ new AudioMsg_NotifyDeviceChanged(
+ stream_id_, new_buffer_size, new_sample_rate)));
}
-void AudioRendererHost::OnDeviceChange(media::AudioOutputController* controller,
- int new_buffer_size,
- int new_sample_rate) {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&AudioRendererHost::DoSendDeviceChangeMessage,
- this, make_scoped_refptr(controller), new_buffer_size,
- new_sample_rate));
-}
-
-void AudioRendererHost::DoCompleteCreation(
- media::AudioOutputController* controller) {
+void AudioRendererHost::DoCompleteCreation(AudioEntry* entry) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- AudioEntry* entry = LookupByController(controller);
- if (!entry)
- return;
-
if (!peer_handle()) {
NOTREACHED() << "Renderer process handle is invalid.";
- DeleteEntryOnError(entry);
+ ReportErrorAndClose(entry->stream_id());
return;
}
// Once the audio stream is created then complete the creation process by
// mapping shared memory and sharing with the renderer process.
base::SharedMemoryHandle foreign_memory_handle;
- if (!entry->shared_memory.ShareToProcess(peer_handle(),
- &foreign_memory_handle)) {
+ if (!entry->shared_memory()->ShareToProcess(peer_handle(),
+ &foreign_memory_handle)) {
// If we failed to map and share the shared memory then close the audio
// stream and send an error message.
- DeleteEntryOnError(entry);
+ ReportErrorAndClose(entry->stream_id());
return;
}
- AudioSyncReader* reader =
- static_cast<AudioSyncReader*>(entry->reader.get());
+ AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader());
#if defined(OS_WIN)
base::SyncSocket::Handle foreign_socket_handle;
@@ -179,63 +218,35 @@
// the construction of audio stream.
if (!reader->PrepareForeignSocketHandle(peer_handle(),
&foreign_socket_handle)) {
- DeleteEntryOnError(entry);
+ ReportErrorAndClose(entry->stream_id());
return;
}
Send(new AudioMsg_NotifyStreamCreated(
- entry->stream_id,
+ entry->stream_id(),
foreign_memory_handle,
foreign_socket_handle,
- media::PacketSizeInBytes(entry->shared_memory.created_size())));
+ media::PacketSizeInBytes(entry->shared_memory()->requested_size())));
}
-void AudioRendererHost::DoSendPlayingMessage(
- media::AudioOutputController* controller) {
+void AudioRendererHost::DoNotifyAudibleState(AudioEntry* entry,
+ bool is_audible) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- AudioEntry* entry = LookupByController(controller);
- if (!entry)
- return;
+ MediaObserver* const media_observer =
+ GetContentClient()->browser()->GetMediaObserver();
+ if (media_observer) {
+ DVLOG(1) << "AudioRendererHost@" << this
+ << "::DoNotifyAudibleState(is_audible=" << is_audible
+ << ") for stream_id=" << entry->stream_id();
- Send(new AudioMsg_NotifyStreamStateChanged(
- entry->stream_id, media::AudioOutputIPCDelegate::kPlaying));
-}
-
-void AudioRendererHost::DoSendPausedMessage(
- media::AudioOutputController* controller) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntry* entry = LookupByController(controller);
- if (!entry)
- return;
-
- Send(new AudioMsg_NotifyStreamStateChanged(
- entry->stream_id, media::AudioOutputIPCDelegate::kPaused));
-}
-
-void AudioRendererHost::DoSendDeviceChangeMessage(
- media::AudioOutputController* controller, int new_buffer_size,
- int new_sample_rate) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntry* entry = LookupByController(controller);
- if (!entry)
- return;
-
- Send(new AudioMsg_NotifyDeviceChanged(
- entry->stream_id, new_buffer_size, new_sample_rate));
-}
-
-void AudioRendererHost::DoHandleError(
- media::AudioOutputController* controller) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntry* entry = LookupByController(controller);
- if (!entry)
- return;
-
- DeleteEntryOnError(entry);
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableAudibleNotifications)) {
+ media_observer->OnAudioStreamPlayingChanged(
+ render_process_id_, entry->render_view_id(), entry->stream_id(),
+ is_audible);
+ }
+ }
}
///////////////////////////////////////////////////////////////////////////////
@@ -245,11 +256,8 @@
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_EX(AudioRendererHost, message, *message_was_ok)
IPC_MESSAGE_HANDLER(AudioHostMsg_CreateStream, OnCreateStream)
- IPC_MESSAGE_HANDLER(AudioHostMsg_AssociateStreamWithProducer,
- OnAssociateStreamWithProducer)
IPC_MESSAGE_HANDLER(AudioHostMsg_PlayStream, OnPlayStream)
IPC_MESSAGE_HANDLER(AudioHostMsg_PauseStream, OnPauseStream)
- IPC_MESSAGE_HANDLER(AudioHostMsg_FlushStream, OnFlushStream)
IPC_MESSAGE_HANDLER(AudioHostMsg_CloseStream, OnCloseStream)
IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -259,8 +267,14 @@
}
void AudioRendererHost::OnCreateStream(
- int stream_id, const media::AudioParameters& params) {
+ int stream_id, int render_view_id, const media::AudioParameters& params) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ DVLOG(1) << "AudioRendererHost@" << this
+ << "::OnCreateStream(stream_id=" << stream_id
+ << ", render_view_id=" << render_view_id << ")";
+ DCHECK_GT(render_view_id, 0);
+
// media::AudioParameters is validated in the deserializer.
int input_channels = params.input_channels();
if (input_channels < 0 ||
@@ -270,89 +284,43 @@
return;
}
- media::AudioParameters audio_params(params);
-
// Calculate output and input memory size.
- int output_memory_size = AudioBus::CalculateMemorySize(audio_params);
-
- int frames = audio_params.frames_per_buffer();
+ int output_memory_size = AudioBus::CalculateMemorySize(params);
+ int frames = params.frames_per_buffer();
int input_memory_size =
AudioBus::CalculateMemorySize(input_channels, frames);
- scoped_ptr<AudioEntry> entry(new AudioEntry());
-
// Create the shared memory and share with the renderer process.
// For synchronized I/O (if input_channels > 0) then we allocate
// extra memory after the output data for the input data.
uint32 io_buffer_size = output_memory_size + input_memory_size;
-
uint32 shared_memory_size =
media::TotalSharedMemorySizeInBytes(io_buffer_size);
- if (!entry->shared_memory.CreateAndMapAnonymous(shared_memory_size)) {
- // If creation of shared memory failed then send an error message.
+ scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
+ if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) {
SendErrorMessage(stream_id);
return;
}
- // Create sync reader and try to initialize it.
scoped_ptr<AudioSyncReader> reader(
- new AudioSyncReader(&entry->shared_memory, params, input_channels));
-
+ new AudioSyncReader(shared_memory.get(), params, input_channels));
if (!reader->Init()) {
SendErrorMessage(stream_id);
return;
}
- // If we have successfully created the SyncReader then assign it to the
- // entry and construct an AudioOutputController.
- entry->reader.reset(reader.release());
- entry->controller = media::AudioOutputController::Create(
- audio_manager_, this, audio_params, entry->reader.get());
-
- if (!entry->controller) {
- SendErrorMessage(stream_id);
- return;
+ scoped_ptr<AudioEntry> entry(new AudioEntry(
+ this, stream_id, render_view_id, params, shared_memory.Pass(),
+ reader.PassAs<media::AudioOutputController::SyncReader>()));
+ if (mirroring_manager_) {
+ mirroring_manager_->AddDiverter(
+ render_process_id_, entry->render_view_id(), entry->controller());
}
-
- // If we have created the controller successfully, create an entry and add it
- // to the map.
- entry->stream_id = stream_id;
audio_entries_.insert(std::make_pair(stream_id, entry.release()));
if (media_internals_)
media_internals_->OnSetAudioStreamStatus(this, stream_id, "created");
}
-void AudioRendererHost::OnAssociateStreamWithProducer(int stream_id,
- int render_view_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- DVLOG(1) << "AudioRendererHost@" << this
- << "::OnAssociateStreamWithProducer(stream_id=" << stream_id
- << ", render_view_id=" << render_view_id << ")";
-
- AudioEntry* const entry = LookupById(stream_id);
- if (!entry) {
- SendErrorMessage(stream_id);
- return;
- }
-
- if (entry->render_view_id == render_view_id)
- return;
-
- // TODO(miu): Merge "AssociateWithProducer" message into "CreateStream"
- // message so AudioRendererHost can assume a simpler "render_view_id is set
- // once" scheme. http://crbug.com/166779
- if (mirroring_manager_) {
- mirroring_manager_->RemoveDiverter(
- render_process_id_, entry->render_view_id, entry->controller);
- }
- entry->render_view_id = render_view_id;
- if (mirroring_manager_) {
- mirroring_manager_->AddDiverter(
- render_process_id_, entry->render_view_id, entry->controller);
- }
-}
-
void AudioRendererHost::OnPlayStream(int stream_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -362,18 +330,9 @@
return;
}
- entry->controller->Play();
+ entry->controller()->Play();
if (media_internals_)
media_internals_->OnSetAudioStreamPlaying(this, stream_id, true);
-
-#ifndef DISABLED_AUDIO_INDICATOR_TRIGGERS_FOR_M27_ONLY
- MediaObserver* media_observer =
- GetContentClient()->browser()->GetMediaObserver();
- if (media_observer) {
- media_observer->OnAudioStreamPlayingChanged(
- render_process_id_, entry->render_view_id, stream_id, true);
- }
-#endif
}
void AudioRendererHost::OnPauseStream(int stream_id) {
@@ -385,46 +344,9 @@
return;
}
- entry->controller->Pause();
+ entry->controller()->Pause();
if (media_internals_)
media_internals_->OnSetAudioStreamPlaying(this, stream_id, false);
-
-#ifndef DISABLED_AUDIO_INDICATOR_TRIGGERS_FOR_M27_ONLY
- MediaObserver* media_observer =
- GetContentClient()->browser()->GetMediaObserver();
- if (media_observer) {
- media_observer->OnAudioStreamPlayingChanged(
- render_process_id_, entry->render_view_id, stream_id, false);
- }
-#endif
-}
-
-void AudioRendererHost::OnFlushStream(int stream_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- AudioEntry* entry = LookupById(stream_id);
- if (!entry) {
- SendErrorMessage(stream_id);
- return;
- }
-
- entry->controller->Flush();
- if (media_internals_)
- media_internals_->OnSetAudioStreamStatus(this, stream_id, "flushed");
-}
-
-void AudioRendererHost::OnCloseStream(int stream_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- if (media_internals_)
- media_internals_->OnSetAudioStreamStatus(this, stream_id, "closed");
-
- AudioEntry* entry = LookupById(stream_id);
-
- if (!entry)
- return;
-
- CloseAndDeleteStream(entry);
}
void AudioRendererHost::OnSetVolume(int stream_id, double volume) {
@@ -439,110 +361,79 @@
// Make sure the volume is valid.
if (volume < 0 || volume > 1.0)
return;
- entry->controller->SetVolume(volume);
+ entry->controller()->SetVolume(volume);
if (media_internals_)
media_internals_->OnSetAudioStreamVolume(this, stream_id, volume);
-
-#ifndef DISABLED_AUDIO_INDICATOR_TRIGGERS_FOR_M27_ONLY
- MediaObserver* media_observer =
- GetContentClient()->browser()->GetMediaObserver();
- if (media_observer) {
- bool playing = volume > 0;
- media_observer->OnAudioStreamPlayingChanged(
- render_process_id_, entry->render_view_id, stream_id, playing);
- }
-#endif
}
-void AudioRendererHost::SendErrorMessage(int32 stream_id) {
+void AudioRendererHost::SendErrorMessage(int stream_id) {
Send(new AudioMsg_NotifyStreamStateChanged(
stream_id, media::AudioOutputIPCDelegate::kError));
}
-void AudioRendererHost::DeleteEntries() {
+void AudioRendererHost::OnCloseStream(int stream_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- for (AudioEntryMap::iterator i = audio_entries_.begin();
- i != audio_entries_.end(); ++i) {
- CloseAndDeleteStream(i->second);
+ // Prevent oustanding callbacks from attempting to close/delete the same
+ // AudioEntry twice.
+ AudioEntryMap::iterator i = audio_entries_.find(stream_id);
+ if (i == audio_entries_.end())
+ return;
+ scoped_ptr<AudioEntry> entry(i->second);
+ audio_entries_.erase(i);
+
+ media::AudioOutputController* const controller = entry->controller();
+ if (mirroring_manager_) {
+ mirroring_manager_->RemoveDiverter(
+ render_process_id_, entry->render_view_id(), controller);
}
+ controller->Close(
+ base::Bind(&AudioRendererHost::DeleteEntry, this, base::Passed(&entry)));
+
+ if (media_internals_)
+ media_internals_->OnSetAudioStreamStatus(this, stream_id, "closed");
}
-void AudioRendererHost::CloseAndDeleteStream(AudioEntry* entry) {
+void AudioRendererHost::DeleteEntry(scoped_ptr<AudioEntry> entry) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-#ifndef DISABLED_AUDIO_INDICATOR_TRIGGERS_FOR_M27_ONLY
- MediaObserver* media_observer =
+ // At this point, make the final "say" in audio playback state.
+ MediaObserver* const media_observer =
GetContentClient()->browser()->GetMediaObserver();
if (media_observer) {
media_observer->OnAudioStreamPlayingChanged(
- render_process_id_, entry->render_view_id, entry->stream_id, false);
+ render_process_id_, entry->render_view_id(), entry->stream_id(), false);
}
-#endif
- if (!entry->pending_close) {
- if (mirroring_manager_) {
- mirroring_manager_->RemoveDiverter(
- render_process_id_, entry->render_view_id, entry->controller);
- }
- entry->controller->Close(
- base::Bind(&AudioRendererHost::DeleteEntry, this, entry));
- entry->pending_close = true;
- }
-}
-
-void AudioRendererHost::DeleteEntry(AudioEntry* entry) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- // Delete the entry when this method goes out of scope.
- scoped_ptr<AudioEntry> entry_deleter(entry);
-
- // Erase the entry identified by |stream_id| from the map.
- audio_entries_.erase(entry->stream_id);
// Notify the media observer.
if (media_internals_)
- media_internals_->OnDeleteAudioStream(this, entry->stream_id);
+ media_internals_->OnDeleteAudioStream(this, entry->stream_id());
+
+ // Note: |entry| will be deleted upon leaving this scope.
}
-void AudioRendererHost::DeleteEntryOnError(AudioEntry* entry) {
+void AudioRendererHost::ReportErrorAndClose(int stream_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- // Sends the error message first before we close the stream because
- // |entry| is destroyed in DeleteEntry().
- SendErrorMessage(entry->stream_id);
+ // Make sure this isn't a stray callback executing after the stream has been
+ // closed, so error notifications aren't sent after clients believe the stream
+ // is closed.
+ if (!LookupById(stream_id))
+ return;
+
+ SendErrorMessage(stream_id);
if (media_internals_)
- media_internals_->OnSetAudioStreamStatus(this, entry->stream_id, "error");
- CloseAndDeleteStream(entry);
+ media_internals_->OnSetAudioStreamStatus(this, stream_id, "error");
+
+ OnCloseStream(stream_id);
}
AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- AudioEntryMap::iterator i = audio_entries_.find(stream_id);
- if (i != audio_entries_.end() && !i->second->pending_close)
- return i->second;
- return NULL;
-}
-
-AudioRendererHost::AudioEntry* AudioRendererHost::LookupByController(
- media::AudioOutputController* controller) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- // Iterate the map of entries.
- // TODO(hclam): Implement a faster look up method.
- for (AudioEntryMap::iterator i = audio_entries_.begin();
- i != audio_entries_.end(); ++i) {
- if (!i->second->pending_close && controller == i->second->controller.get())
- return i->second;
- }
- return NULL;
-}
-
-media::AudioOutputController* AudioRendererHost::LookupControllerByIdForTesting(
- int stream_id) {
- AudioEntry* const entry = LookupById(stream_id);
- return entry ? entry->controller : NULL;
+ AudioEntryMap::const_iterator i = audio_entries_.find(stream_id);
+ return i != audio_entries_.end() ? i->second : NULL;
}
} // namespace content
diff --git a/content/browser/renderer_host/media/audio_renderer_host.h b/content/browser/renderer_host/media/audio_renderer_host.h
index de5944e..803539c 100644
--- a/content/browser/renderer_host/media/audio_renderer_host.h
+++ b/content/browser/renderer_host/media/audio_renderer_host.h
@@ -63,9 +63,7 @@
class MediaInternals;
class ResourceContext;
-class CONTENT_EXPORT AudioRendererHost
- : public BrowserMessageFilter,
- public media::AudioOutputController::EventHandler {
+class CONTENT_EXPORT AudioRendererHost : public BrowserMessageFilter {
public:
// Called from UI thread from the owner of this object.
AudioRendererHost(int render_process_id,
@@ -79,15 +77,6 @@
virtual bool OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) OVERRIDE;
- // AudioOutputController::EventHandler implementations.
- virtual void OnCreated(media::AudioOutputController* controller) OVERRIDE;
- virtual void OnPlaying(media::AudioOutputController* controller) OVERRIDE;
- virtual void OnPaused(media::AudioOutputController* controller) OVERRIDE;
- virtual void OnError(media::AudioOutputController* controller) OVERRIDE;
- virtual void OnDeviceChange(media::AudioOutputController* controller,
- int new_buffer_size,
- int new_sample_rate) OVERRIDE;
-
private:
friend class AudioRendererHostTest;
friend class BrowserThread;
@@ -96,7 +85,7 @@
FRIEND_TEST_ALL_PREFIXES(AudioRendererHostTest, CreateMockStream);
FRIEND_TEST_ALL_PREFIXES(AudioRendererHostTest, MockStreamDataConversation);
- struct AudioEntry;
+ class AudioEntry;
typedef std::map<int, AudioEntry*> AudioEntryMap;
virtual ~AudioRendererHost();
@@ -104,15 +93,14 @@
// Methods called on IO thread ----------------------------------------------
// Audio related IPC message handlers.
- // Creates an audio output stream with the specified format. If this call is
- // successful this object would keep an internal entry of the stream for the
- // required properties.
- void OnCreateStream(int stream_id,
- const media::AudioParameters& params);
- // Track that the data for the audio stream referenced by |stream_id| is
+ // Creates an audio output stream with the specified format whose data is
// produced by an entity in the render view referenced by |render_view_id|.
- void OnAssociateStreamWithProducer(int stream_id, int render_view_id);
+ // Upon success/failure, the peer is notified via the NotifyStreamCreated
+ // message.
+ void OnCreateStream(int stream_id,
+ int render_view_id,
+ const media::AudioParameters& params);
// Play the audio stream referenced by |stream_id|.
void OnPlayStream(int stream_id);
@@ -120,9 +108,6 @@
// Pause the audio stream referenced by |stream_id|.
void OnPauseStream(int stream_id);
- // Discard all audio data in stream referenced by |stream_id|.
- void OnFlushStream(int stream_id);
-
// Close the audio stream referenced by |stream_id|.
void OnCloseStream(int stream_id);
@@ -130,46 +115,27 @@
void OnSetVolume(int stream_id, double volume);
// Complete the process of creating an audio stream. This will set up the
- // shared memory or shared socket in low latency mode.
- void DoCompleteCreation(media::AudioOutputController* controller);
+ // shared memory or shared socket in low latency mode and send the
+ // NotifyStreamCreated message to the peer.
+ void DoCompleteCreation(AudioEntry* entry);
- // Send a state change message to the renderer.
- void DoSendPlayingMessage(media::AudioOutputController* controller);
- void DoSendPausedMessage(media::AudioOutputController* controller);
- void DoSendDeviceChangeMessage(media::AudioOutputController* controller,
- int new_buffer_size, int new_sample_rate);
-
- // Handle error coming from audio stream.
- void DoHandleError(media::AudioOutputController* controller);
+ // Propagate audible signal to MediaObserver.
+ void DoNotifyAudibleState(AudioEntry* entry, bool is_audible);
// Send an error message to the renderer.
void SendErrorMessage(int stream_id);
- // Delete all audio entry and all audio streams
- void DeleteEntries();
+ // Delete an audio entry, notifying observers first. This is called by
+ // AudioOutputController after it has closed.
+ void DeleteEntry(scoped_ptr<AudioEntry> entry);
- // Closes the stream. The stream is then deleted in DeleteEntry() after it
- // is closed.
- void CloseAndDeleteStream(AudioEntry* entry);
-
- // Delete an audio entry and close the related audio stream.
- void DeleteEntry(AudioEntry* entry);
-
- // Delete audio entry and close the related audio stream due to an error,
- // and error message is send to the renderer.
- void DeleteEntryOnError(AudioEntry* entry);
+ // Send an error message to the renderer, then close the stream.
+ void ReportErrorAndClose(int stream_id);
// A helper method to look up a AudioEntry identified by |stream_id|.
// Returns NULL if not found.
AudioEntry* LookupById(int stream_id);
- // Search for a AudioEntry having the reference to |controller|.
- // This method is used to look up an AudioEntry after a controller
- // event is received.
- AudioEntry* LookupByController(media::AudioOutputController* controller);
-
- media::AudioOutputController* LookupControllerByIdForTesting(int stream_id);
-
// ID of the RenderProcessHost that owns this instance.
const int render_process_id_;
diff --git a/content/browser/renderer_host/media/audio_renderer_host_unittest.cc b/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
index 4e9aaaa..6a674a4 100644
--- a/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
+++ b/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
@@ -70,7 +70,6 @@
MOCK_METHOD1(OnStreamPlaying, void(int stream_id));
MOCK_METHOD1(OnStreamPaused, void(int stream_id));
MOCK_METHOD1(OnStreamError, void(int stream_id));
- MOCK_METHOD2(OnStreamVolume, void(int stream_id, double volume));
private:
virtual ~MockAudioRendererHost() {
@@ -101,13 +100,13 @@
}
void OnStreamCreated(const IPC::Message& msg, int stream_id,
- base::SharedMemoryHandle handle,
+ base::SharedMemoryHandle handle,
#if defined(OS_WIN)
- base::SyncSocket::Handle socket_handle,
+ base::SyncSocket::Handle socket_handle,
#else
- base::FileDescriptor socket_descriptor,
+ base::FileDescriptor socket_descriptor,
#endif
- uint32 length) {
+ uint32 length) {
// Maps the shared memory.
shared_memory_.reset(new base::SharedMemory(handle, false));
CHECK(shared_memory_->Map(length));
@@ -153,7 +152,7 @@
};
ACTION_P(QuitMessageLoop, message_loop) {
- message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
}
class AudioRendererHostTest : public testing::Test {
@@ -163,7 +162,7 @@
protected:
virtual void SetUp() {
// Create a message loop so AudioRendererHost can use it.
- message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO));
+ message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO));
// Claim to be on both the UI and IO threads to pass all the DCHECKS.
io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
@@ -199,15 +198,16 @@
void Create() {
EXPECT_CALL(*observer_,
OnSetAudioStreamStatus(_, kStreamId, "created"));
-
- InSequence s;
- // We will first receive an OnStreamCreated() signal.
EXPECT_CALL(*host_, OnStreamCreated(kStreamId, _))
.WillOnce(QuitMessageLoop(message_loop_.get()));
+ EXPECT_CALL(mirroring_manager_,
+ AddDiverter(kRenderProcessId, kRenderViewId, NotNull()))
+ .RetiresOnSaturation();
// Send a create stream message to the audio output stream and wait until
// we receive the created message.
host_->OnCreateStream(kStreamId,
+ kRenderViewId,
media::AudioParameters(
media::AudioParameters::AUDIO_FAKE,
media::CHANNEL_LAYOUT_STEREO,
@@ -215,29 +215,21 @@
media::AudioParameters::kAudioCDSampleRate / 10));
message_loop_->Run();
- // Simulate the renderer process associating a stream with a render view.
- EXPECT_CALL(mirroring_manager_,
- RemoveDiverter(kRenderProcessId, MSG_ROUTING_NONE, _))
- .RetiresOnSaturation();
- EXPECT_CALL(mirroring_manager_,
- AddDiverter(kRenderProcessId, kRenderViewId, NotNull()))
- .RetiresOnSaturation();
- host_->OnAssociateStreamWithProducer(kStreamId, kRenderViewId);
- message_loop_->RunUntilIdle();
// At some point in the future, a corresponding RemoveDiverter() call must
// be made.
EXPECT_CALL(mirroring_manager_,
RemoveDiverter(kRenderProcessId, kRenderViewId, NotNull()))
.RetiresOnSaturation();
+ // All created streams should ultimately be closed.
+ EXPECT_CALL(*observer_,
+ OnSetAudioStreamStatus(_, kStreamId, "closed"));
+
// Expect the audio stream will be deleted at some later point.
EXPECT_CALL(*observer_, OnDeleteAudioStream(_, kStreamId));
}
void Close() {
- EXPECT_CALL(*observer_,
- OnSetAudioStreamStatus(_, kStreamId, "closed"));
-
// Send a message to AudioRendererHost to tell it we want to close the
// stream.
host_->OnCloseStream(kStreamId);
@@ -275,18 +267,14 @@
void SimulateError() {
EXPECT_CALL(*observer_,
OnSetAudioStreamStatus(_, kStreamId, "error"));
- // Find the first AudioOutputController in the AudioRendererHost.
- CHECK(host_->audio_entries_.size())
+ EXPECT_EQ(1u, host_->audio_entries_.size())
<< "Calls Create() before calling this method";
- media::AudioOutputController* controller =
- host_->LookupControllerByIdForTesting(kStreamId);
- CHECK(controller) << "AudioOutputController not found";
// Expect an error signal sent through IPC.
EXPECT_CALL(*host_, OnStreamError(kStreamId));
// Simulate an error sent from the audio device.
- host_->OnError(controller);
+ host_->ReportErrorAndClose(kStreamId);
SyncWithAudioThread();
// Expect the audio stream record is removed.
@@ -294,13 +282,13 @@
}
// Called on the audio thread.
- static void PostQuitMessageLoop(MessageLoop* message_loop) {
- message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ static void PostQuitMessageLoop(base::MessageLoop* message_loop) {
+ message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
}
// Called on the main thread.
static void PostQuitOnAudioThread(media::AudioManager* audio_manager,
- MessageLoop* message_loop) {
+ base::MessageLoop* message_loop) {
audio_manager->GetMessageLoop()->PostTask(FROM_HERE,
base::Bind(&PostQuitMessageLoop, message_loop));
}
@@ -323,7 +311,7 @@
scoped_ptr<MockMediaInternals> observer_;
MockAudioMirroringManager mirroring_manager_;
scoped_refptr<MockAudioRendererHost> host_;
- scoped_ptr<MessageLoop> message_loop_;
+ scoped_ptr<base::MessageLoop> message_loop_;
scoped_ptr<BrowserThreadImpl> io_thread_;
scoped_ptr<BrowserThreadImpl> ui_thread_;
scoped_ptr<media::AudioManager> audio_manager_;
diff --git a/content/browser/renderer_host/media/audio_sync_reader.cc b/content/browser/renderer_host/media/audio_sync_reader.cc
index 620ba54..9ebf5ed 100644
--- a/content/browser/renderer_host/media/audio_sync_reader.cc
+++ b/content/browser/renderer_host/media/audio_sync_reader.cc
@@ -24,7 +24,7 @@
input_channels_(input_channels),
renderer_callback_count_(0),
renderer_missed_callback_count_(0) {
- packet_size_ = media::PacketSizeInBytes(shared_memory_->created_size());
+ packet_size_ = media::PacketSizeInBytes(shared_memory_->requested_size());
int input_memory_size = 0;
int output_memory_size = AudioBus::CalculateMemorySize(params);
if (input_channels_ > 0) {
@@ -63,7 +63,7 @@
media::SetUnknownDataSize(shared_memory_, packet_size_);
}
- if (socket_.get()) {
+ if (socket_) {
socket_->Send(&bytes, sizeof(bytes));
}
}
@@ -75,10 +75,18 @@
// Copy optional synchronized live audio input for consumption by renderer
// process.
- if (source && input_bus_.get()) {
+ if (source && input_bus_) {
DCHECK_EQ(source->channels(), input_bus_->channels());
- DCHECK_LE(source->frames(), input_bus_->frames());
- source->CopyTo(input_bus_.get());
+ // TODO(crogers): In some cases with device and sample-rate changes
+ // it's possible for an AOR to insert a resampler in the path.
+ // Because this is used with the Web Audio API, it'd be better
+ // to bypass the device change handling in AOR and instead let
+ // the renderer-side Web Audio code deal with this.
+ if (source->frames() == input_bus_->frames() &&
+ source->channels() == input_bus_->channels())
+ source->CopyTo(input_bus_.get());
+ else
+ input_bus_->Zero();
}
// Retrieve the actual number of bytes available from the shared memory. If
@@ -119,7 +127,7 @@
}
void AudioSyncReader::Close() {
- if (socket_.get()) {
+ if (socket_) {
socket_->Close();
}
}
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
index 99fdc6b..abd600b 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -9,11 +9,11 @@
#include "content/browser/browser_thread_impl.h"
#include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
-#include "content/browser/renderer_host/media/mock_media_observer.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
#include "content/common/media/media_stream_messages.h"
#include "content/common/media/media_stream_options.h"
#include "content/public/test/mock_resource_context.h"
+#include "content/public/test/test_browser_thread.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_content_client.h"
#include "ipc/ipc_message_macros.h"
@@ -38,7 +38,7 @@
class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
public TestContentBrowserClient {
public:
- MockMediaStreamDispatcherHost(MessageLoop* message_loop,
+ MockMediaStreamDispatcherHost(base::MessageLoop* message_loop,
MediaStreamManager* manager)
: MediaStreamDispatcherHost(kProcessId),
message_loop_(message_loop),
@@ -49,7 +49,6 @@
void(int routing_id, int request_id, int audio_array_size,
int video_array_size));
MOCK_METHOD2(OnStreamGenerationFailed, void(int routing_id, int request_id));
- MOCK_METHOD0(GetMediaObserver, MediaObserver*());
// Accessor to private functions.
void OnGenerateStream(int page_request_id, const StreamOptions& components) {
@@ -110,7 +109,7 @@
OnStreamGenerated(msg.routing_id(), request_id, audio_device_list.size(),
video_device_list.size());
// Notify that the event have occured.
- message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ message_loop_->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
label_ = label;
audio_devices_ = audio_device_list;
video_devices_ = video_device_list;
@@ -118,18 +117,22 @@
void OnStreamGenerationFailed(const IPC::Message& msg, int request_id) {
OnStreamGenerationFailed(msg.routing_id(), request_id);
- message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ message_loop_->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
label_= "";
}
- MessageLoop* message_loop_;
+ base::MessageLoop* message_loop_;
MediaStreamManager* manager_;
};
+class MockMediaStreamUI : public MediaStreamUI {
+ public:
+ MOCK_METHOD1(OnStarted, void(const base::Closure& stop));
+};
+
class MediaStreamDispatcherHostTest : public testing::Test {
public:
- MediaStreamDispatcherHostTest() : old_client_(NULL),
- old_browser_client_(NULL) {}
+ MediaStreamDispatcherHostTest() : old_browser_client_(NULL) {}
virtual ~MediaStreamDispatcherHostTest() {}
void WaitForResult() {
@@ -139,12 +142,11 @@
protected:
virtual void SetUp() OVERRIDE {
// MediaStreamManager must be created and called on IO thread.
- message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO));
- io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
+ message_loop_.reset(new MessageLoop(base::MessageLoop::TYPE_IO));
+ ui_thread_.reset(new TestBrowserThread(BrowserThread::UI,
message_loop_.get()));
-
- // Create our own media observer.
- media_observer_.reset(new MockMediaObserver());
+ io_thread_.reset(new TestBrowserThread(BrowserThread::IO,
+ message_loop_.get()));
// Create our own MediaStreamManager.
audio_manager_.reset(media::AudioManager::Create());
@@ -156,19 +158,24 @@
media_stream_manager_.get());
// Use the fake content client and browser.
- old_client_ = GetContentClient();
- old_browser_client_ = GetContentClient()->browser();
content_client_.reset(new TestContentClient);
SetContentClient(content_client_.get());
- content_client_->set_browser_for_testing(host_);
+ old_browser_client_ = SetBrowserClientForTesting(host_);
+ }
+
+ virtual void SetupFakeUI(bool expect_started) {
+ scoped_ptr<MockMediaStreamUI> stream_ui(new MockMediaStreamUI());
+ if (expect_started) {
+ EXPECT_CALL(*stream_ui, OnStarted(_));
+ }
+ media_stream_manager_->UseFakeUI(stream_ui.PassAs<MediaStreamUI>());
}
virtual void TearDown() OVERRIDE {
message_loop_->RunUntilIdle();
// Recover the old browser client and content client.
- GetContentClient()->set_browser_for_testing(old_browser_client_);
- SetContentClient(old_client_);
+ SetBrowserClientForTesting(old_browser_client_);
content_client_.reset();
// Delete the IO message loop to delete the device thread,
@@ -177,27 +184,22 @@
}
scoped_refptr<MockMediaStreamDispatcherHost> host_;
- scoped_ptr<MessageLoop> message_loop_;
- scoped_ptr<BrowserThreadImpl> io_thread_;
+ scoped_ptr<base::MessageLoop> message_loop_;
+ scoped_ptr<TestBrowserThread> ui_thread_;
+ scoped_ptr<TestBrowserThread> io_thread_;
scoped_ptr<media::AudioManager> audio_manager_;
scoped_ptr<MediaStreamManager> media_stream_manager_;
- ContentClient* old_client_;
ContentBrowserClient* old_browser_client_;
scoped_ptr<ContentClient> content_client_;
- scoped_ptr<MockMediaObserver> media_observer_;
};
TEST_F(MediaStreamDispatcherHostTest, GenerateStream) {
StreamOptions options(MEDIA_NO_SERVICE, MEDIA_DEVICE_VIDEO_CAPTURE);
- EXPECT_CALL(*host_, GetMediaObserver())
- .WillRepeatedly(Return(media_observer_.get()));
+ SetupFakeUI(true);
EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
host_->OnGenerateStream(kPageRequestId, options);
- EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesOpened(_, _, _, _));
- EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesClosed(_, _, _));
-
WaitForResult();
std::string label = host_->label_;
@@ -217,13 +219,10 @@
StreamOptions options(MEDIA_NO_SERVICE, MEDIA_DEVICE_VIDEO_CAPTURE);
// Generate first stream.
- EXPECT_CALL(*host_, GetMediaObserver())
- .WillRepeatedly(Return(media_observer_.get()));
+ SetupFakeUI(true);
EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
host_->OnGenerateStream(kPageRequestId, options);
- EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesOpened(_, _, _, _));
-
WaitForResult();
// Check the latest generated stream.
@@ -236,10 +235,10 @@
EXPECT_EQ(host_->NumberOfStreams(), 1u);
// Generate second stream.
+ SetupFakeUI(true);
EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
host_->OnGenerateStream(kPageRequestId+1, options);
- EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesOpened(_, _, _, _));
WaitForResult();
@@ -252,16 +251,13 @@
EXPECT_NE(label1, label2);
// Check that we now have two opened streams.
- EXPECT_EQ(host_->NumberOfStreams(), 2u);
+ EXPECT_EQ(2u, host_->NumberOfStreams());
// Generate third stream.
+ SetupFakeUI(true);
EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId + 2, 0, 1));
host_->OnGenerateStream(kPageRequestId+2, options);
- EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesOpened(_, _, _, _));
- EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesClosed(_, _, _))
- .Times(3);
-
WaitForResult();
// Check the latest generated stream.
@@ -285,10 +281,8 @@
TEST_F(MediaStreamDispatcherHostTest, FailOpenVideoDevice) {
StreamOptions options(MEDIA_NO_SERVICE, MEDIA_DEVICE_VIDEO_CAPTURE);
- EXPECT_CALL(*host_, GetMediaObserver())
- .WillRepeatedly(Return(media_observer_.get()));
media::FakeVideoCaptureDevice::SetFailNextCreate();
- media_stream_manager_->UseFakeDevice();
+ SetupFakeUI(false);
host_->OnGenerateStream(kPageRequestId, options);
EXPECT_CALL(*host_, OnStreamGenerationFailed(kRenderId, kPageRequestId));
WaitForResult();
@@ -297,9 +291,6 @@
TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
StreamOptions options(MEDIA_NO_SERVICE, MEDIA_DEVICE_VIDEO_CAPTURE);
- EXPECT_CALL(*host_, GetMediaObserver())
- .WillRepeatedly(Return(media_observer_.get()));
-
// Create multiple GenerateStream requests.
size_t streams = 5;
for (size_t i = 1; i <= streams; ++i) {
@@ -317,14 +308,11 @@
TEST_F(MediaStreamDispatcherHostTest, StopGeneratedStreamsOnChannelClosing) {
StreamOptions options(MEDIA_NO_SERVICE, MEDIA_DEVICE_VIDEO_CAPTURE);
- EXPECT_CALL(*host_, GetMediaObserver())
- .WillRepeatedly(Return(media_observer_.get()));
-
// Create first group of streams.
size_t generated_streams = 3;
for (size_t i = 0; i < generated_streams; ++i) {
+ SetupFakeUI(true);
EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId + i, 0, 1));
- EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesOpened(_, _, _, _));
host_->OnGenerateStream(kPageRequestId + i, options);
// Wait until the stream is generated.
@@ -333,10 +321,10 @@
EXPECT_EQ(host_->NumberOfStreams(), generated_streams);
// Calling OnChannelClosing() to cancel all the pending/generated streams.
- EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesClosed(_, _, _))
- .Times(3);
host_->OnChannelClosing();
+ message_loop_->RunUntilIdle();
+
// Streams should have been cleaned up.
EXPECT_EQ(host_->NumberOfStreams(), 0u);
}
@@ -344,18 +332,16 @@
TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
StreamOptions options(MEDIA_NO_SERVICE, MEDIA_DEVICE_VIDEO_CAPTURE);
- EXPECT_CALL(*host_, GetMediaObserver())
- .WillRepeatedly(Return(media_observer_.get()));
+ base::Closure close_callback;
+ scoped_ptr<MockMediaStreamUI> stream_ui(new MockMediaStreamUI());
+ EXPECT_CALL(*stream_ui, OnStarted(_))
+ .WillOnce(SaveArg<0>(&close_callback));
+ media_stream_manager_->UseFakeUI(stream_ui.PassAs<MediaStreamUI>());
+
EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
EXPECT_CALL(*host_, OnStreamGenerationFailed(kRenderId, kPageRequestId));
host_->OnGenerateStream(kPageRequestId, options);
- base::Closure close_callback;
-
- EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesOpened(_, _, _, _))
- .WillOnce(SaveArg<3>(&close_callback));
- EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesClosed(_, _, _));
-
WaitForResult();
EXPECT_EQ(host_->audio_devices_.size(), 0u);
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
index a640dc5..1d63262 100644
--- a/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -147,8 +147,7 @@
}
MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager)
- : ALLOW_THIS_IN_INITIALIZER_LIST(
- ui_controller_(new MediaStreamUIController(this))),
+ : ui_controller_(new MediaStreamUIController(this)),
audio_manager_(audio_manager),
monitoring_started_(false),
io_loop_(NULL),
@@ -343,7 +342,7 @@
MEDIA_REQUEST_STATE_CLOSING);
}
}
- NotifyDevicesClosed(*request);
+ NotifyUIDevicesClosed(label);
}
// If request isn't complete, notify the UI on the cancellation. And it
@@ -458,23 +457,14 @@
return label;
}
-void MediaStreamManager::NotifyUIDevicesOpened(
- const std::string& label,
- int render_process_id,
- int render_view_id,
- const MediaStreamDevices& devices) {
+void MediaStreamManager::NotifyUIDevicesOpened(const std::string& label) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- ui_controller_->NotifyUIIndicatorDevicesOpened(
- label, render_process_id, render_view_id, devices);
+ ui_controller_->NotifyUIIndicatorDevicesOpened(label);
}
-void MediaStreamManager::NotifyUIDevicesClosed(
- int render_process_id,
- int render_view_id,
- const MediaStreamDevices& devices) {
+void MediaStreamManager::NotifyUIDevicesClosed(const std::string& label) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- ui_controller_->NotifyUIIndicatorDevicesClosed(
- render_process_id, render_view_id, devices);
+ ui_controller_->NotifyUIIndicatorDevicesClosed(label);
}
void MediaStreamManager::SendCachedDeviceList(
@@ -508,7 +498,7 @@
}
void MediaStreamManager::StopMonitoring() {
- DCHECK_EQ(MessageLoop::current(), io_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), io_loop_);
if (monitoring_started_) {
base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this);
monitoring_started_ = false;
@@ -518,7 +508,7 @@
}
void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) {
- DCHECK_EQ(MessageLoop::current(), io_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), io_loop_);
cache->valid = false;
}
@@ -564,6 +554,8 @@
screen_capture_active_ = false;
}
+ NotifyUIDevicesClosed(it->first);
+
requests_.erase(it);
}
@@ -615,7 +607,7 @@
void MediaStreamManager::InitializeDeviceManagersOnIOThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (device_thread_.get())
+ if (device_thread_)
return;
device_thread_.reset(new base::Thread("MediaStreamDeviceThread"));
@@ -633,7 +625,7 @@
// We want to be notified of IO message loop destruction to delete the thread
// and the device managers.
- io_loop_ = MessageLoop::current();
+ io_loop_ = base::MessageLoop::current();
io_loop_->AddDestructionObserver(this);
}
@@ -717,7 +709,7 @@
}
request->requester->StreamGenerated(label, audio_devices, video_devices);
- NotifyDevicesOpened(label, *request);
+ NotifyUIDevicesOpened(label);
break;
}
default:
@@ -995,13 +987,17 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
video_capture_manager()->UseFakeDevice();
audio_input_device_manager()->UseFakeDevice();
- ui_controller_->UseFakeUI();
+ UseFakeUI(scoped_ptr<MediaStreamUI>());
+}
+
+void MediaStreamManager::UseFakeUI(scoped_ptr<MediaStreamUI> fake_ui) {
+ ui_controller_->UseFakeUI(fake_ui.Pass());
}
void MediaStreamManager::WillDestroyCurrentMessageLoop() {
- DCHECK_EQ(MessageLoop::current(), io_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), io_loop_);
DCHECK(requests_.empty());
- if (device_thread_.get()) {
+ if (device_thread_) {
StopMonitoring();
video_capture_manager_->Unregister();
@@ -1015,37 +1011,6 @@
ui_controller_.reset();
}
-void MediaStreamManager::NotifyDevicesOpened(const std::string& label,
- const DeviceRequest& request) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- MediaStreamDevices opened_devices;
- DevicesFromRequest(request, &opened_devices);
- if (opened_devices.empty())
- return;
-
- NotifyUIDevicesOpened(
- label, request.render_process_id, request.render_view_id, opened_devices);
-}
-
-void MediaStreamManager::NotifyDevicesClosed(const DeviceRequest& request) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- MediaStreamDevices closed_devices;
- DevicesFromRequest(request, &closed_devices);
- if (closed_devices.empty())
- return;
-
- NotifyUIDevicesClosed(
- request.render_process_id, request.render_view_id, closed_devices);
-}
-
-void MediaStreamManager::DevicesFromRequest(
- const DeviceRequest& request, MediaStreamDevices* devices) {
- for (StreamDeviceInfoArray::const_iterator it = request.devices.begin();
- it != request.devices.end(); ++it) {
- devices->push_back(it->device);
- }
-}
-
void MediaStreamManager::NotifyDevicesChanged(
MediaStreamType stream_type,
const StreamDeviceInfoArray& devices) {
diff --git a/content/browser/renderer_host/media/media_stream_manager.h b/content/browser/renderer_host/media/media_stream_manager.h
index 205ddb2..acde644 100644
--- a/content/browser/renderer_host/media/media_stream_manager.h
+++ b/content/browser/renderer_host/media/media_stream_manager.h
@@ -58,7 +58,7 @@
// MediaStreamManager::Listener.
class CONTENT_EXPORT MediaStreamManager
: public MediaStreamProviderListener,
- public MessageLoop::DestructionObserver,
+ public base::MessageLoop::DestructionObserver,
public SettingsRequester,
public base::SystemMonitor::DevicesChangedObserver {
public:
@@ -125,15 +125,10 @@
// Signals the UI that the devices are opened.
// Users are responsible for calling NotifyUIDevicesClosed when the devices
// are not used anymore, otherwise UI will leak.
- void NotifyUIDevicesOpened(const std::string& label,
- int render_process_id,
- int render_view_id,
- const MediaStreamDevices& devices);
+ void NotifyUIDevicesOpened(const std::string& label);
// Signals the UI that the devices are being closed.
- void NotifyUIDevicesClosed(int render_process_id,
- int render_view_id,
- const MediaStreamDevices& devices);
+ void NotifyUIDevicesClosed(const std::string& label);
// Implements MediaStreamProviderListener.
virtual void Opened(MediaStreamType stream_type,
@@ -161,6 +156,10 @@
// devices, which is needed for server based testing.
void UseFakeDevice();
+ // Called by the unittests to specify fake UI that should be used for next
+ // generated stream.
+ void UseFakeUI(scoped_ptr<MediaStreamUI> fake_ui);
+
// This object gets deleted on the UI thread after the IO thread has been
// destroyed. So we need to know when IO thread is being destroyed so that
// we can delete VideoCaptureManager and AudioInputDeviceManager.
@@ -185,14 +184,6 @@
// thread and registers this as a listener with the device managers.
void InitializeDeviceManagersOnIOThread();
- // Helpers for signaling the media observer that new capture devices are
- // opened/closed.
- void NotifyDevicesOpened(const std::string& label,
- const DeviceRequest& request);
- void NotifyDevicesClosed(const DeviceRequest& request);
- void DevicesFromRequest(const DeviceRequest& request,
- MediaStreamDevices* devices);
-
// Helper for sending up-to-date device lists to media observer when a
// capture device is plugged in or unplugged.
void NotifyDevicesChanged(MediaStreamType stream_type,
@@ -249,7 +240,7 @@
// Hold a pointer to the IO loop to check we delete the device thread and
// managers on the right thread.
- MessageLoop* io_loop_;
+ base::MessageLoop* io_loop_;
bool screen_capture_active_;
diff --git a/content/browser/renderer_host/media/media_stream_manager_unittest.cc b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
index 27c1dea..a515a36 100644
--- a/content/browser/renderer_host/media/media_stream_manager_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
@@ -67,14 +67,14 @@
void ResponseCallback(const std::string& label,
const MediaStreamDevices& devices) {
Response(label);
- message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ message_loop_->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
}
void WaitForResult() { message_loop_->Run(); }
protected:
virtual void SetUp() {
- message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO));
+ message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO));
ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI,
message_loop_.get()));
io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
@@ -111,7 +111,7 @@
callback);
}
- scoped_ptr<MessageLoop> message_loop_;
+ scoped_ptr<base::MessageLoop> message_loop_;
scoped_ptr<BrowserThreadImpl> ui_thread_;
scoped_ptr<BrowserThreadImpl> io_thread_;
scoped_ptr<media::AudioManager> audio_manager_;
diff --git a/content/browser/renderer_host/media/media_stream_ui_controller.cc b/content/browser/renderer_host/media/media_stream_ui_controller.cc
index 63c0264..115bfd6 100644
--- a/content/browser/renderer_host/media/media_stream_ui_controller.cc
+++ b/content/browser/renderer_host/media/media_stream_ui_controller.cc
@@ -62,7 +62,7 @@
// Tab may have gone away.
if (!host || !host->GetDelegate()) {
- callback.Run(MediaStreamDevices());
+ callback.Run(MediaStreamDevices(), scoped_ptr<MediaStreamUI>());
return;
}
@@ -73,13 +73,13 @@
MediaStreamUIController::MediaStreamUIController(SettingsRequester* requester)
: requester_(requester),
- use_fake_ui_(false),
- weak_ptr_factory_(this) {
+ use_fake_ui_(false) {
DCHECK(requester_);
}
MediaStreamUIController::~MediaStreamUIController() {
DCHECK(requests_.empty());
+ DCHECK(stream_indicators_.empty());
}
void MediaStreamUIController::MakeUIRequest(
@@ -135,16 +135,25 @@
// page.
ProcessNextRequestForView(render_process_id, render_view_id);
}
+
+ NotifyUIIndicatorDevicesClosed(label);
}
-void MediaStreamUIController::PostResponse(
+void MediaStreamUIController::ProcessAccessRequestResponse(
const std::string& label,
- const MediaStreamDevices& devices) {
+ const MediaStreamDevices& devices,
+ scoped_ptr<MediaStreamUI> stream_ui) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
UIRequests::iterator request_iter = requests_.find(label);
// Return if the request has been removed.
- if (request_iter == requests_.end())
+ if (request_iter == requests_.end()) {
+ if (stream_ui) {
+ BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE,
+ stream_ui.release());
+ }
return;
+ }
DCHECK(requester_);
scoped_ptr<MediaStreamRequestForUI> request(request_iter->second);
@@ -155,7 +164,12 @@
ProcessNextRequestForView(request->render_process_id,
request->render_view_id);
- if (devices.size() > 0) {
+ if (!devices.empty()) {
+ if (stream_ui) {
+ DCHECK(stream_indicators_.find(label) == stream_indicators_.end());
+ stream_indicators_[label] = stream_ui.release();
+ }
+
// Build a list of "full" device objects for the accepted devices.
StreamDeviceInfoArray device_list;
// TODO(xians): figure out if it is all right to hard code in_use to false,
@@ -169,49 +183,47 @@
requester_->DevicesAccepted(label, device_list);
} else {
+ DCHECK(!stream_ui);
requester_->SettingsError(label);
}
}
void MediaStreamUIController::NotifyUIIndicatorDevicesOpened(
- const std::string& label,
- int render_process_id,
- int render_view_id,
- const MediaStreamDevices& devices) {
+ const std::string& label) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DCHECK(!devices.empty());
- MediaObserver* media_observer =
- GetContentClient()->browser()->GetMediaObserver();
- if (media_observer == NULL)
- return;
- media_observer->OnCaptureDevicesOpened(
- render_process_id, render_view_id, devices,
- media::BindToLoop(
- base::MessageLoopProxy::current(),
- base::Bind(&MediaStreamUIController::OnStopStreamFromUI,
- weak_ptr_factory_.GetWeakPtr(), label)));
+ IndicatorsMap::iterator it = stream_indicators_.find(label);
+ if (it != stream_indicators_.end()) {
+ base::Closure stop_callback = media::BindToLoop(
+ base::MessageLoopProxy::current(),
+ base::Bind(&MediaStreamUIController::OnStopStreamFromUI,
+ base::Unretained(this), label));
+
+ // base::Unretained is safe here because the target can be deleted only on
+ // UI thread when posted from IO thread (see
+ // NotifyUIIndicatorDevicesClosed()).
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&MediaStreamUI::OnStarted,
+ base::Unretained(it->second), stop_callback));
+ }
}
void MediaStreamUIController::NotifyUIIndicatorDevicesClosed(
- int render_process_id,
- int render_view_id,
- const MediaStreamDevices& devices) {
+ const std::string& label) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DCHECK(!devices.empty());
- MediaObserver* media_observer =
- GetContentClient()->browser()->GetMediaObserver();
- if (media_observer == NULL)
- return;
- media_observer->OnCaptureDevicesClosed(render_process_id,
- render_view_id,
- devices);
+ IndicatorsMap::iterator indicator = stream_indicators_.find(label);
+ if (indicator != stream_indicators_.end()) {
+ BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, indicator->second);
+ stream_indicators_.erase(indicator);
+ }
}
-void MediaStreamUIController::UseFakeUI() {
+void MediaStreamUIController::UseFakeUI(scoped_ptr<MediaStreamUI> fake_ui) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
use_fake_ui_ = true;
+ fake_ui_ = fake_ui.Pass();
}
bool MediaStreamUIController::IsUIBusy(int render_process_id,
@@ -246,7 +258,7 @@
if (next_request_label.empty())
return;
- if (use_fake_ui_) {
+ if (fake_ui_) {
PostRequestToFakeUI(next_request_label);
} else {
PostRequestToUI(next_request_label);
@@ -256,6 +268,7 @@
void MediaStreamUIController::PostRequestToUI(const std::string& label) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
UIRequests::iterator request_iter = requests_.find(label);
+
if (request_iter == requests_.end()) {
NOTREACHED();
return;
@@ -266,11 +279,11 @@
request->posted_task = true;
BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&ProceedMediaAccessPermission, *request, media::BindToLoop(
+ BrowserThread::UI, FROM_HERE, base::Bind(
+ &ProceedMediaAccessPermission, *request, media::BindToLoop(
base::MessageLoopProxy::current(), base::Bind(
- &MediaStreamUIController::PostResponse,
- weak_ptr_factory_.GetWeakPtr(), label))));
+ &MediaStreamUIController::ProcessAccessRequestResponse,
+ base::Unretained(this), label))));
}
void MediaStreamUIController::PostRequestToFakeUI(const std::string& label) {
@@ -304,13 +317,20 @@
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(&MediaStreamUIController::PostResponse,
- weak_ptr_factory_.GetWeakPtr(), label, devices_to_use));
+ base::Bind(&MediaStreamUIController::ProcessAccessRequestResponse,
+ base::Unretained(this), label, devices_to_use,
+ base::Passed(&fake_ui_)));
}
void MediaStreamUIController::OnStopStreamFromUI(const std::string& label) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- requester_->StopStreamFromUI(label);
+ // It's safe to base::Unretained() here because |requester_| references
+ // MediaStreamManager which always outlives IO thread.
+ //
+ // TODO(sergeyu): Refactor this code to not rely on what |requester_| is.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&SettingsRequester::StopStreamFromUI,
+ base::Unretained(requester_), label));
}
} // namespace content
diff --git a/content/browser/renderer_host/media/media_stream_ui_controller.h b/content/browser/renderer_host/media/media_stream_ui_controller.h
index 72bdc6d..6d14e83 100644
--- a/content/browser/renderer_host/media/media_stream_ui_controller.h
+++ b/content/browser/renderer_host/media/media_stream_ui_controller.h
@@ -21,7 +21,6 @@
#include <string>
#include "base/basictypes.h"
-#include "base/memory/weak_ptr.h"
#include "content/browser/renderer_host/media/media_stream_provider.h"
#include "content/public/browser/web_contents_delegate.h"
@@ -52,34 +51,20 @@
// user has no action for the media stream InfoBar.
void CancelUIRequest(const std::string& label);
- // Called by the InfoBar when the user grants/denies access to some devices
- // to the webpage. This is placed here, so the request can be cleared from the
- // list of pending requests, instead of letting the InfoBar itself respond to
- // the requester. An empty list of devices means that access has been denied.
- // This method must be called on the IO thread.
- void PostResponse(const std::string& label,
- const MediaStreamDevices& devices);
-
// Called to signal the UI indicator that the devices are opened.
- void NotifyUIIndicatorDevicesOpened(
- const std::string& label,
- int render_process_id,
- int render_view_id,
- const MediaStreamDevices& devices);
+ void NotifyUIIndicatorDevicesOpened(const std::string& label);
// Called to signal the UI indicator that the devices are closed.
- void NotifyUIIndicatorDevicesClosed(
- int render_process_id,
- int render_view_id,
- const MediaStreamDevices& devices);
+ void NotifyUIIndicatorDevicesClosed(const std::string& label);
// Used for testing only. This function is called to use faked UI, which is
// needed for server based tests. The first non-opened device(s) will be
// picked.
- void UseFakeUI();
+ void UseFakeUI(scoped_ptr<MediaStreamUI> fake_ui);
private:
typedef std::map<std::string, MediaStreamRequestForUI*> UIRequests;
+ typedef std::map<std::string, MediaStreamUI*> IndicatorsMap;
// Returns true if the UI is already processing a request for this render
// view.
@@ -95,6 +80,11 @@
// Posts a request to fake UI which is used for testing purpose.
void PostRequestToFakeUI(const std::string& label);
+ // Callback handler for WebContents::RequestMediaAccessPermission().
+ void ProcessAccessRequestResponse(const std::string& label,
+ const MediaStreamDevices& devices,
+ scoped_ptr<MediaStreamUI> stream_ui);
+
// Callback for UI called when user requests a stream to be stopped.
void OnStopStreamFromUI(const std::string& label);
@@ -103,8 +93,10 @@
// See comment above for method UseFakeUI. Used for automated testing.
bool use_fake_ui_;
+ scoped_ptr<MediaStreamUI> fake_ui_;
- base::WeakPtrFactory<MediaStreamUIController> weak_ptr_factory_;
+ // Container MediaStreamUI objects for currently active streams.
+ IndicatorsMap stream_indicators_;
DISALLOW_COPY_AND_ASSIGN(MediaStreamUIController);
};
diff --git a/content/browser/renderer_host/media/media_stream_ui_controller_unittest.cc b/content/browser/renderer_host/media/media_stream_ui_controller_unittest.cc
index 695bdac..708fe7a 100644
--- a/content/browser/renderer_host/media/media_stream_ui_controller_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_ui_controller_unittest.cc
@@ -43,7 +43,7 @@
protected:
virtual void SetUp() {
- message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO));
+ message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO));
ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI,
message_loop_.get()));
io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
@@ -71,7 +71,7 @@
std::string());
}
- scoped_ptr<MessageLoop> message_loop_;
+ scoped_ptr<base::MessageLoop> message_loop_;
scoped_ptr<BrowserThreadImpl> ui_thread_;
scoped_ptr<BrowserThreadImpl> io_thread_;
scoped_ptr<MediaStreamUIController> ui_controller_;
@@ -98,17 +98,21 @@
}
TEST_F(MediaStreamDeviceUIControllerTest, HandleRequestUsingFakeUI) {
- ui_controller_->UseFakeUI();
+ ui_controller_->UseFakeUI(scoped_ptr<MediaStreamUI>());
const std::string label = "label";
CreateDummyRequest(label, true, true);
// Remove the current request, it should not crash.
EXPECT_CALL(*this, DevicesAccepted(label, _));
+
+ message_loop_->RunUntilIdle();
+
+ ui_controller_->NotifyUIIndicatorDevicesClosed(label);
}
TEST_F(MediaStreamDeviceUIControllerTest, CreateRequestsAndCancelTheFirst) {
- ui_controller_->UseFakeUI();
+ ui_controller_->UseFakeUI(scoped_ptr<MediaStreamUI>());
// Create the first audio request.
const std::string label_1 = "label_1";
@@ -128,10 +132,15 @@
// We should get callbacks from the rest of the requests.
EXPECT_CALL(*this, DevicesAccepted(label_2, _));
EXPECT_CALL(*this, DevicesAccepted(label_3, _));
+
+ message_loop_->RunUntilIdle();
+
+ ui_controller_->NotifyUIIndicatorDevicesClosed(label_2);
+ ui_controller_->NotifyUIIndicatorDevicesClosed(label_3);
}
TEST_F(MediaStreamDeviceUIControllerTest, CreateRequestsAndCancelTheLast) {
- ui_controller_->UseFakeUI();
+ ui_controller_->UseFakeUI(scoped_ptr<MediaStreamUI>());
// Create the first audio request.
const std::string label_1 = "label_1";
@@ -151,6 +160,11 @@
// We should get callbacks from the rest of the requests.
EXPECT_CALL(*this, DevicesAccepted(label_1, _));
EXPECT_CALL(*this, DevicesAccepted(label_2, _));
+
+ message_loop_->RunUntilIdle();
+
+ ui_controller_->NotifyUIIndicatorDevicesClosed(label_1);
+ ui_controller_->NotifyUIIndicatorDevicesClosed(label_2);
}
} // namespace content
diff --git a/content/browser/renderer_host/media/mock_media_observer.h b/content/browser/renderer_host/media/mock_media_observer.h
index d4c297c..54f419e 100644
--- a/content/browser/renderer_host/media/mock_media_observer.h
+++ b/content/browser/renderer_host/media/mock_media_observer.h
@@ -20,13 +20,6 @@
MockMediaObserver();
virtual ~MockMediaObserver();
- MOCK_METHOD4(OnCaptureDevicesOpened,
- void(int render_process_id, int render_view_id,
- const MediaStreamDevices& devices,
- const base::Closure& close_callback));
- MOCK_METHOD3(OnCaptureDevicesClosed,
- void(int render_process_id, int render_view_id,
- const MediaStreamDevices& devices));
MOCK_METHOD1(OnAudioCaptureDevicesChanged,
void(const MediaStreamDevices& devices));
MOCK_METHOD1(OnVideoCaptureDevicesChanged,
diff --git a/content/browser/renderer_host/media/peer_connection_tracker_host.cc b/content/browser/renderer_host/media/peer_connection_tracker_host.cc
index 68314b4..4ba1a0a 100644
--- a/content/browser/renderer_host/media/peer_connection_tracker_host.cc
+++ b/content/browser/renderer_host/media/peer_connection_tracker_host.cc
@@ -40,7 +40,7 @@
void PeerConnectionTrackerHost::OnAddPeerConnection(
const PeerConnectionInfo& info) {
- WebRTCInternals::GetInstance()->AddPeerConnection(
+ WebRTCInternals::GetInstance()->OnAddPeerConnection(
render_process_id_,
base::GetProcId(peer_handle()),
info.lid,
@@ -50,13 +50,13 @@
}
void PeerConnectionTrackerHost::OnRemovePeerConnection(int lid) {
- WebRTCInternals::GetInstance()->RemovePeerConnection(
+ WebRTCInternals::GetInstance()->OnRemovePeerConnection(
base::GetProcId(peer_handle()), lid);
}
void PeerConnectionTrackerHost::OnUpdatePeerConnection(
int lid, const std::string& type, const std::string& value) {
- WebRTCInternals::GetInstance()->UpdatePeerConnection(
+ WebRTCInternals::GetInstance()->OnUpdatePeerConnection(
base::GetProcId(peer_handle()),
lid,
type,
@@ -65,7 +65,7 @@
void PeerConnectionTrackerHost::OnAddStats(int lid,
const base::ListValue& value) {
- WebRTCInternals::GetInstance()->AddStats(
+ WebRTCInternals::GetInstance()->OnAddStats(
base::GetProcId(peer_handle()), lid, value);
}
diff --git a/content/browser/renderer_host/media/video_capture_buffer_pool.cc b/content/browser/renderer_host/media/video_capture_buffer_pool.cc
index d702201..8a6a0f8 100644
--- a/content/browser/renderer_host/media/video_capture_buffer_pool.cc
+++ b/content/browser/renderer_host/media/video_capture_buffer_pool.cc
@@ -65,7 +65,7 @@
Buffer* buffer = buffers_[buffer_id];
- CHECK_GE(buffer->shared_memory.created_size(), GetMemorySize());
+ CHECK_GE(buffer->shared_memory.requested_size(), GetMemorySize());
// Complete the reservation.
buffer->held_by_producer = true;
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc
index 879317b..b82b796 100644
--- a/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -190,7 +190,9 @@
controller_clients_.remove(client);
// No more clients. Stop device.
- if (controller_clients_.empty() && state_ == VIDEO_CAPTURE_STATE_STARTED) {
+ if (controller_clients_.empty() &&
+ (state_ == VIDEO_CAPTURE_STATE_STARTED ||
+ state_ == VIDEO_CAPTURE_STATE_ERROR)) {
video_capture_manager_->Stop(session_id,
base::Bind(&VideoCaptureController::OnDeviceStopped, this));
frame_info_available_ = false;
@@ -209,7 +211,7 @@
if (client) {
client->session_closed = true;
- client->event_handler->OnPaused(client->controller_id);
+ client->event_handler->OnEnded(client->controller_id);
}
}
@@ -257,9 +259,9 @@
int rotation,
bool flip_vert,
bool flip_horiz) {
- DCHECK (frame_info_.color == media::VideoCaptureCapability::kI420 ||
- frame_info_.color == media::VideoCaptureCapability::kYV12 ||
- (rotation == 0 && !flip_vert && !flip_horiz));
+ DCHECK(frame_info_.color == media::VideoCaptureCapability::kI420 ||
+ frame_info_.color == media::VideoCaptureCapability::kYV12 ||
+ (rotation == 0 && !flip_vert && !flip_horiz));
scoped_refptr<media::VideoFrame> dst;
{
@@ -396,6 +398,7 @@
const int kYPlane = media::VideoFrame::kYPlane;
const int kUPlane = media::VideoFrame::kUPlane;
const int kVPlane = media::VideoFrame::kVPlane;
+ const int kAPlane = media::VideoFrame::kAPlane;
const int kRGBPlane = media::VideoFrame::kRGBPlane;
// Do color conversion from the camera format to I420.
@@ -428,6 +431,26 @@
target);
break;
}
+ case media::VideoFrame::YV12A: {
+ DCHECK(!chopped_width_ && !chopped_height_);
+ media::CopyYPlane(frame->data(kYPlane),
+ frame->stride(kYPlane),
+ frame->rows(kYPlane),
+ target);
+ media::CopyUPlane(frame->data(kUPlane),
+ frame->stride(kUPlane),
+ frame->rows(kUPlane),
+ target);
+ media::CopyVPlane(frame->data(kVPlane),
+ frame->stride(kVPlane),
+ frame->rows(kVPlane),
+ target);
+ media::CopyAPlane(frame->data(kAPlane),
+ frame->stride(kAPlane),
+ frame->rows(kAPlane),
+ target);
+ break;
+ }
case media::VideoFrame::RGB32: {
media::ConvertRGB32ToYUV(frame->data(kRGBPlane),
target->data(kYPlane),
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 58f963c..35ab3ef 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
@@ -45,8 +45,8 @@
int height,
int frame_rate) = 0;
- // The capture session has been paused. No more frame will be sent.
- virtual void OnPaused(const VideoCaptureControllerID& id) = 0;
+ // The capture session has ended and no more frames will be sent.
+ virtual void OnEnded(const VideoCaptureControllerID& id) = 0;
protected:
virtual ~VideoCaptureControllerEventHandler() {}
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 14c8da1..544001f 100644
--- a/content/browser/renderer_host/media/video_capture_controller_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
@@ -36,21 +36,21 @@
message_loop->PostTask(FROM_HERE,
base::Bind(&VideoCaptureController::StopCapture,
controller, controller_id, controller_handler));
- message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
}
ACTION_P3(StopSession, controller, session_id, message_loop) {
message_loop->PostTask(FROM_HERE,
base::Bind(&VideoCaptureController::StopSession,
controller, session_id));
- message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
}
class MockVideoCaptureControllerEventHandler
: public VideoCaptureControllerEventHandler {
public:
MockVideoCaptureControllerEventHandler(VideoCaptureController* controller,
- MessageLoop* message_loop)
+ base::MessageLoop* message_loop)
: controller_(controller),
message_loop_(message_loop),
controller_id_(kDeviceId),
@@ -61,7 +61,7 @@
MOCK_METHOD1(DoBufferCreated, void(const VideoCaptureControllerID&));
MOCK_METHOD1(DoBufferReady, void(const VideoCaptureControllerID&));
MOCK_METHOD1(DoFrameInfo, void(const VideoCaptureControllerID&));
- MOCK_METHOD1(DoPaused, void(const VideoCaptureControllerID&));
+ MOCK_METHOD1(DoEnded, void(const VideoCaptureControllerID&));
virtual void OnError(const VideoCaptureControllerID& id) OVERRIDE {}
virtual void OnBufferCreated(const VideoCaptureControllerID& id,
@@ -86,13 +86,13 @@
EXPECT_EQ(id, controller_id_);
DoFrameInfo(id);
}
- virtual void OnPaused(const VideoCaptureControllerID& id) OVERRIDE {
+ virtual void OnEnded(const VideoCaptureControllerID& id) OVERRIDE {
EXPECT_EQ(id, controller_id_);
- DoPaused(id);
+ DoEnded(id);
}
scoped_refptr<VideoCaptureController> controller_;
- MessageLoop* message_loop_;
+ base::MessageLoop* message_loop_;
VideoCaptureControllerID controller_id_;
base::ProcessHandle process_handle_;
};
@@ -148,7 +148,7 @@
protected:
virtual void SetUp() OVERRIDE {
- message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO));
+ message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO));
file_thread_.reset(new BrowserThreadImpl(BrowserThread::FILE,
message_loop_.get()));
io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
@@ -164,7 +164,7 @@
virtual void TearDown() OVERRIDE {}
- scoped_ptr<MessageLoop> message_loop_;
+ scoped_ptr<base::MessageLoop> message_loop_;
scoped_ptr<BrowserThreadImpl> file_thread_;
scoped_ptr<BrowserThreadImpl> io_thread_;
scoped_refptr<MockVideoCaptureManager> vcm_;
@@ -240,7 +240,7 @@
vcm_->video_session_id_,
message_loop_.get()));
EXPECT_CALL(*controller_handler_,
- DoPaused(controller_handler_->controller_id_))
+ DoEnded(controller_handler_->controller_id_))
.Times(1);
controller_->StartCapture(controller_handler_->controller_id_,
@@ -254,8 +254,8 @@
EXPECT_CALL(*controller_handler_,
DoBufferReady(controller_handler_->controller_id_))
.Times(0);
- message_loop_->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), base::TimeDelta::FromSeconds(1));
+ message_loop_->PostDelayedTask(FROM_HERE,
+ base::MessageLoop::QuitClosure(), base::TimeDelta::FromSeconds(1));
message_loop_->Run();
EXPECT_CALL(*vcm_,
diff --git a/content/browser/renderer_host/media/video_capture_host.cc b/content/browser/renderer_host/media/video_capture_host.cc
index 8e7231c..91d8f51 100644
--- a/content/browser/renderer_host/media/video_capture_host.cc
+++ b/content/browser/renderer_host/media/video_capture_host.cc
@@ -50,6 +50,7 @@
// Implements VideoCaptureControllerEventHandler.
void VideoCaptureHost::OnError(const VideoCaptureControllerID& controller_id) {
+ DVLOG(1) << "VideoCaptureHost::OnError";
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&VideoCaptureHost::DoHandleErrorOnIOThread,
@@ -88,10 +89,11 @@
this, controller_id, width, height, frame_per_second));
}
-void VideoCaptureHost::OnPaused(const VideoCaptureControllerID& controller_id) {
+void VideoCaptureHost::OnEnded(const VideoCaptureControllerID& controller_id) {
+ DVLOG(1) << "VideoCaptureHost::OnEnded";
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(&VideoCaptureHost::DoPausedOnIOThread, this, controller_id));
+ base::Bind(&VideoCaptureHost::DoEndedOnIOThread, this, controller_id));
}
void VideoCaptureHost::DoSendNewBufferOnIOThread(
@@ -132,15 +134,15 @@
DeleteVideoCaptureControllerOnIOThread(controller_id);
}
-void VideoCaptureHost::DoPausedOnIOThread(
+void VideoCaptureHost::DoEndedOnIOThread(
const VideoCaptureControllerID& controller_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
+ DVLOG(1) << "VideoCaptureHost::DoEndedOnIOThread";
if (entries_.find(controller_id) == entries_.end())
return;
Send(new VideoCaptureMsg_StateChanged(controller_id.device_id,
- VIDEO_CAPTURE_STATE_PAUSED));
+ VIDEO_CAPTURE_STATE_ENDED));
DeleteVideoCaptureControllerOnIOThread(controller_id);
}
@@ -241,6 +243,7 @@
void VideoCaptureHost::OnPauseCapture(int device_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DVLOG(1) << "VideoCaptureHost::OnPauseCapture, device_id " << device_id;
// Not used.
Send(new VideoCaptureMsg_StateChanged(device_id, VIDEO_CAPTURE_STATE_ERROR));
}
diff --git a/content/browser/renderer_host/media/video_capture_host.h b/content/browser/renderer_host/media/video_capture_host.h
index 4f2f8cd..581ae88 100644
--- a/content/browser/renderer_host/media/video_capture_host.h
+++ b/content/browser/renderer_host/media/video_capture_host.h
@@ -71,7 +71,7 @@
int width,
int height,
int frame_per_second) OVERRIDE;
- virtual void OnPaused(const VideoCaptureControllerID& id) OVERRIDE;
+ virtual void OnEnded(const VideoCaptureControllerID& id) OVERRIDE;
private:
friend class BrowserThread;
@@ -128,7 +128,7 @@
// Handle error coming from VideoCaptureDevice.
void DoHandleErrorOnIOThread(const VideoCaptureControllerID& controller_id);
- void DoPausedOnIOThread(const VideoCaptureControllerID& controller_id);
+ void DoEndedOnIOThread(const VideoCaptureControllerID& controller_id);
void DeleteVideoCaptureControllerOnIOThread(
const VideoCaptureControllerID& controller_id);
diff --git a/content/browser/renderer_host/media/video_capture_host_unittest.cc b/content/browser/renderer_host/media/video_capture_host_unittest.cc
index 4c6334f..6da2b9f 100644
--- a/content/browser/renderer_host/media/video_capture_host_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_host_unittest.cc
@@ -191,7 +191,7 @@
};
ACTION_P(ExitMessageLoop, message_loop) {
- message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
}
class VideoCaptureHostTest : public testing::Test {
@@ -201,7 +201,7 @@
protected:
virtual void SetUp() OVERRIDE {
// Create a message loop so VideoCaptureHostTest can use it.
- message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO));
+ message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO));
// MediaStreamManager must be created on the IO thread.
io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
@@ -338,7 +338,7 @@
scoped_refptr<MockVideoCaptureHost> host_;
private:
- scoped_ptr<MessageLoop> message_loop_;
+ scoped_ptr<base::MessageLoop> message_loop_;
scoped_ptr<BrowserThreadImpl> io_thread_;
scoped_ptr<media::AudioManager> audio_manager_;
scoped_ptr<MediaStreamManager> media_stream_manager_;
diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc
index 1eaeabb..5605abb 100644
--- a/content/browser/renderer_host/media/video_capture_manager.cc
+++ b/content/browser/renderer_host/media/video_capture_manager.cc
@@ -94,6 +94,7 @@
void VideoCaptureManager::Close(int capture_session_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK(listener_);
+ DVLOG(1) << "VideoCaptureManager::Close, id " << capture_session_id;
device_loop_->PostTask(
FROM_HERE,
base::Bind(&VideoCaptureManager::OnClose, this, capture_session_id));
@@ -112,6 +113,7 @@
void VideoCaptureManager::Stop(
const media::VideoCaptureSessionId& capture_session_id,
base::Closure stopped_cb) {
+ DVLOG(1) << "VideoCaptureManager::Stop, id " << capture_session_id;
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
device_loop_->PostTask(
FROM_HERE,
@@ -174,7 +176,7 @@
}
case MEDIA_TAB_VIDEO_CAPTURE: {
video_capture_device = WebContentsVideoCaptureDevice::Create(
- vc_device_name.unique_id, base::Closure());
+ vc_device_name.unique_id);
break;
}
case MEDIA_SCREEN_VIDEO_CAPTURE: {
diff --git a/content/browser/renderer_host/media/video_capture_manager_unittest.cc b/content/browser/renderer_host/media/video_capture_manager_unittest.cc
index 295697a..a5890b1 100644
--- a/content/browser/renderer_host/media/video_capture_manager_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_manager_unittest.cc
@@ -70,7 +70,7 @@
protected:
virtual void SetUp() OVERRIDE {
listener_.reset(new MockMediaStreamProviderListener());
- message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO));
+ message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO));
io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
message_loop_.get()));
vcm_ = new VideoCaptureManager();
@@ -83,7 +83,7 @@
scoped_refptr<VideoCaptureManager> vcm_;
scoped_ptr<MockMediaStreamProviderListener> listener_;
- scoped_ptr<MessageLoop> message_loop_;
+ scoped_ptr<base::MessageLoop> message_loop_;
scoped_ptr<BrowserThreadImpl> io_thread_;
scoped_ptr<MockFrameObserver> frame_observer_;
diff --git a/content/browser/renderer_host/media/web_contents_audio_input_stream.cc b/content/browser/renderer_host/media/web_contents_audio_input_stream.cc
index beddcb8..4e1928a 100644
--- a/content/browser/renderer_host/media/web_contents_audio_input_stream.cc
+++ b/content/browser/renderer_host/media/web_contents_audio_input_stream.cc
@@ -27,7 +27,7 @@
public:
// Takes ownership of |mixer_stream|. The rest outlive this instance.
Impl(int render_process_id, int render_view_id,
- base::MessageLoopProxy* message_loop,
+ const scoped_refptr<base::MessageLoopProxy>& message_loop,
AudioMirroringManager* mirroring_manager,
const scoped_refptr<WebContentsTracker>& tracker,
media::VirtualAudioInputStream* mixer_stream);
@@ -86,7 +86,7 @@
void OnTargetChanged(int render_process_id, int render_view_id);
// Injected dependencies.
- base::MessageLoopProxy* const message_loop_;
+ const scoped_refptr<base::MessageLoopProxy> message_loop_;
AudioMirroringManager* const mirroring_manager_;
const scoped_refptr<WebContentsTracker> tracker_;
// The AudioInputStream implementation that handles the audio conversion and
@@ -107,7 +107,7 @@
WebContentsAudioInputStream::Impl::Impl(
int render_process_id, int render_view_id,
- base::MessageLoopProxy* message_loop,
+ const scoped_refptr<base::MessageLoopProxy>& message_loop,
AudioMirroringManager* mirroring_manager,
const scoped_refptr<WebContentsTracker>& tracker,
media::VirtualAudioInputStream* mixer_stream)
@@ -279,7 +279,7 @@
WebContentsAudioInputStream* WebContentsAudioInputStream::Create(
const std::string& device_id,
const media::AudioParameters& params,
- base::MessageLoopProxy* message_loop) {
+ const scoped_refptr<base::MessageLoopProxy>& message_loop) {
int render_process_id;
int render_view_id;
if (!WebContentsCaptureUtil::ExtractTabCaptureTarget(
@@ -298,7 +298,7 @@
WebContentsAudioInputStream::WebContentsAudioInputStream(
int render_process_id, int render_view_id,
- base::MessageLoopProxy* message_loop,
+ const scoped_refptr<base::MessageLoopProxy>& message_loop,
AudioMirroringManager* mirroring_manager,
const scoped_refptr<WebContentsTracker>& tracker,
media::VirtualAudioInputStream* mixer_stream)
diff --git a/content/browser/renderer_host/media/web_contents_audio_input_stream.h b/content/browser/renderer_host/media/web_contents_audio_input_stream.h
index fa4801c..b424801 100644
--- a/content/browser/renderer_host/media/web_contents_audio_input_stream.h
+++ b/content/browser/renderer_host/media/web_contents_audio_input_stream.h
@@ -58,7 +58,7 @@
static WebContentsAudioInputStream* Create(
const std::string& device_id,
const media::AudioParameters& params,
- base::MessageLoopProxy* message_loop);
+ const scoped_refptr<base::MessageLoopProxy>& message_loop);
private:
friend class WebContentsAudioInputStreamTest;
@@ -72,7 +72,7 @@
WebContentsAudioInputStream(
int render_process_id, int render_view_id,
- base::MessageLoopProxy* message_loop,
+ const scoped_refptr<base::MessageLoopProxy>& message_loop,
AudioMirroringManager* mirroring_manager,
const scoped_refptr<WebContentsTracker>& tracker,
media::VirtualAudioInputStream* mixer_stream);
diff --git a/content/browser/renderer_host/media/web_contents_audio_input_stream_unittest.cc b/content/browser/renderer_host/media/web_contents_audio_input_stream_unittest.cc
index b786932..ffd9cbb 100644
--- a/content/browser/renderer_host/media/web_contents_audio_input_stream_unittest.cc
+++ b/content/browser/renderer_host/media/web_contents_audio_input_stream_unittest.cc
@@ -88,7 +88,8 @@
// tests to check how/when they are invoked.
class MockVirtualAudioInputStream : public VirtualAudioInputStream {
public:
- explicit MockVirtualAudioInputStream(base::MessageLoopProxy* message_loop)
+ explicit MockVirtualAudioInputStream(
+ const scoped_refptr<base::MessageLoopProxy>& message_loop)
: VirtualAudioInputStream(TestAudioParameters(), message_loop,
VirtualAudioInputStream::AfterCloseCallback()),
real_(TestAudioParameters(), message_loop,
diff --git a/content/browser/renderer_host/media/web_contents_capture_util.cc b/content/browser/renderer_host/media/web_contents_capture_util.cc
index 46b7376..843a8e5 100644
--- a/content/browser/renderer_host/media/web_contents_capture_util.cc
+++ b/content/browser/renderer_host/media/web_contents_capture_util.cc
@@ -6,8 +6,8 @@
#include "base/basictypes.h"
#include "base/string_number_conversions.h"
-#include "base/string_piece.h"
#include "base/string_util.h"
+#include "base/strings/string_piece.h"
namespace {
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 97eeda3..04327dd 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
@@ -61,8 +61,10 @@
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/message_loop_proxy.h"
#include "base/metrics/histogram.h"
+#include "base/sequenced_task_runner.h"
#include "base/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
@@ -101,9 +103,20 @@
const int kMaxFramesInFlight = 2;
const int kMaxSnapshotsInFlight = 1;
+// This value controls how many redundant, timer-base captures occur when the
+// content is static. Redundantly capturing the same frame allows iterative
+// quality enhancement, and also allows the buffer to fill in "buffered mode".
+//
+// TODO(nick): Controlling this here is a hack and a layering violation, since
+// it's a strategy specific to the WebRTC consumer, and probably just papers
+// over some frame dropping and quality bugs. It should either be controlled at
+// a higher level, or else redundant frame generation should be pushed down
+// further into the WebRTC encoding stack.
+const int kNumRedundantCapturesOfStaticContent = 200;
+
// TODO(nick): Remove this once frame subscription is supported on Aura and
// Linux.
-#if (defined(OS_WIN) || defined(OS_MACOSX)) && !defined(USE_AURA)
+#if (defined(OS_WIN) || defined(OS_MACOSX)) || defined(USE_AURA)
const bool kAcceleratedSubscriberIsSupported = true;
#else
const bool kAcceleratedSubscriberIsSupported = false;
@@ -155,6 +168,7 @@
// capture should be done, and a callback to invoke once the frame is ready.
bool ObserveEventAndDecideCapture(
Event event,
+ base::Time event_time,
scoped_refptr<media::VideoFrame>* storage,
DeliverFrameCallback* callback);
@@ -179,6 +193,7 @@
// Callback invoked upon completion of all captures.
void DidCaptureFrame(const scoped_refptr<media::VideoFrame>& frame,
+ int frame_number,
base::Time timestamp,
bool success);
@@ -194,6 +209,12 @@
// Incremented every time a paint or update event occurs.
int frame_number_;
+ // Stores the frame number from the last delivered frame.
+ int last_delivered_frame_number_;
+
+ // Stores the timestamp of the last delivered frame.
+ base::Time last_delivered_frame_timestamp_;
+
// Whether capturing is currently allowed. Can toggle back and forth.
bool is_started_;
@@ -211,6 +232,7 @@
oracle_(oracle) {}
virtual bool ShouldCaptureFrame(
+ base::Time present_time,
scoped_refptr<media::VideoFrame>* storage,
RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback*
deliver_frame_cb) OVERRIDE;
@@ -237,7 +259,8 @@
// autonomously on some other thread.
class ContentCaptureSubscription : public content::NotificationObserver {
public:
- typedef base::Callback<void(const scoped_refptr<media::VideoFrame>&,
+ typedef base::Callback<void(const base::Time&,
+ const scoped_refptr<media::VideoFrame>&,
const DeliverFrameCallback&)> CaptureCallback;
// Create a subscription. Whenever a manual capture is required, the
@@ -269,30 +292,18 @@
DISALLOW_COPY_AND_ASSIGN(ContentCaptureSubscription);
};
-// Renders captures (from the backing store) into video frame buffers on a
-// dedicated thread. Intended for use in the software rendering case, when GPU
-// acceleration of these activities is not possible.
-class VideoFrameRenderer {
- public:
- VideoFrameRenderer();
-
- // Render the SkBitmap |input| into the given VideoFrame buffer |output|, then
- // invoke |done_cb| to indicate success or failure. |input| is expected to be
- // ARGB. |output| must be YV12 or I420. Colorspace conversion is always done.
- // Scaling and letterboxing will be done as needed.
- void Render(const SkBitmap& input,
- const scoped_refptr<media::VideoFrame>& output,
- const base::Callback<void(bool)>& done_cb);
-
- private:
- void RenderOnRenderThread(const SkBitmap& input,
- const scoped_refptr<media::VideoFrame>& output,
- const base::Callback<void(bool)>& done_cb);
-
- base::Thread render_thread_;
-
- DISALLOW_COPY_AND_ASSIGN(VideoFrameRenderer);
-};
+// Render the SkBitmap |input| into the given VideoFrame buffer |output|, then
+// invoke |done_cb| to indicate success or failure. |input| is expected to be
+// ARGB. |output| must be YV12 or I420. Colorspace conversion is always done.
+// Scaling and letterboxing will be done as needed.
+//
+// This software implementation should be used only when GPU acceleration of
+// these activities is not possible. This operation may be expensive (tens to
+// hundreds of milliseconds), so the caller should ensure that it runs on a
+// thread where such a pause would cause UI jank.
+void RenderVideoFrame(const SkBitmap& input,
+ const scoped_refptr<media::VideoFrame>& output,
+ const base::Callback<void(bool)>& done_cb);
// Keeps track of the RenderView to be sourced, and executes copying of the
// backing store on the UI BrowserThread.
@@ -311,6 +322,7 @@
static scoped_ptr<CaptureMachine> Create(
int render_process_id,
int render_view_id,
+ const scoped_refptr<base::SequencedTaskRunner>& render_task_runner,
const scoped_refptr<CaptureOracle>& oracle);
// Starts a copy from the backing store or the composited surface. Must be run
@@ -319,6 +331,7 @@
//
// This may be used as a ContentCaptureSubscription::CaptureCallback.
void Capture(
+ const base::Time& start_time,
const scoped_refptr<media::VideoFrame>& target,
const DeliverFrameCallback& deliver_frame_cb);
@@ -338,19 +351,22 @@
RenewFrameSubscription();
}
- virtual void AboutToNavigateRenderView(RenderViewHost* rvh) {
+ virtual void AboutToNavigateRenderView(RenderViewHost* rvh) OVERRIDE {
RenewFrameSubscription();
}
virtual void DidNavigateMainFrame(
- const LoadCommittedDetails& details, const FrameNavigateParams& params) {
+ const LoadCommittedDetails& details,
+ const FrameNavigateParams& params) OVERRIDE {
RenewFrameSubscription();
}
virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
private:
- explicit CaptureMachine(const scoped_refptr<CaptureOracle>& oracle);
+ CaptureMachine(
+ const scoped_refptr<base::SequencedTaskRunner>& render_task_runner,
+ const scoped_refptr<CaptureOracle>& oracle);
// Starts observing the web contents, returning false if lookup fails.
bool StartObservingWebContents(int initial_render_process_id,
@@ -361,7 +377,7 @@
// Response callback for RenderWidgetHost::CopyFromBackingStore().
void DidCopyFromBackingStore(
- base::Time start_time,
+ const base::Time& start_time,
const scoped_refptr<media::VideoFrame>& target,
const DeliverFrameCallback& deliver_frame_cb,
bool success,
@@ -369,7 +385,7 @@
// Response callback for RWHVP::CopyFromCompositingSurfaceToVideoFrame().
void DidCopyFromCompositingSurfaceToVideoFrame(
- base::Time start_time,
+ const base::Time& start_time,
const DeliverFrameCallback& deliver_frame_cb,
bool success);
@@ -378,6 +394,11 @@
// attached views.
void RenewFrameSubscription();
+ // The task runner of the thread on which SkBitmap->VideoFrame conversion will
+ // occur. Only used when this activity cannot be done on the GPU.
+ const scoped_refptr<base::SequencedTaskRunner> render_task_runner_;
+
+ // Makes all the decisions about which frames to copy, and how.
const scoped_refptr<CaptureOracle> oracle_;
// Routing ID of any active fullscreen render widget or MSG_ROUTING_NONE
@@ -387,13 +408,10 @@
// Last known RenderView size.
gfx::Size last_view_size_;
+ // Responsible for forwarding events from the active RenderWidgetHost to the
+ // oracle, and initiating captures accordingly.
scoped_ptr<ContentCaptureSubscription> subscription_;
- // Handles SkBitmap->VideoFrame copying (including scaling, letterboxing, and
- // YV12 conversion) on another thread for us. Only used when this activity
- // cannot be done on the GPU.
- VideoFrameRenderer renderer_;
-
DISALLOW_COPY_AND_ASSIGN(CaptureMachine);
};
@@ -422,11 +440,14 @@
: capture_period_(capture_period),
consumer_(consumer),
frame_number_(0),
+ last_delivered_frame_number_(0),
is_started_(false),
- sampler_(capture_period_, kAcceleratedSubscriberIsSupported) {}
+ sampler_(capture_period_, kAcceleratedSubscriberIsSupported,
+ kNumRedundantCapturesOfStaticContent) {}
bool CaptureOracle::ObserveEventAndDecideCapture(
Event event,
+ base::Time event_time,
scoped_refptr<media::VideoFrame>* storage,
RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback* callback) {
base::AutoLock guard(lock_);
@@ -440,13 +461,12 @@
// Record |event| and decide whether it's a good time to capture.
const bool content_is_dirty = (event == COMPOSITOR_UPDATE ||
event == SOFTWARE_PAINT);
- base::Time now = base::Time::Now();
bool should_sample;
if (content_is_dirty) {
frame_number_++;
- should_sample = sampler_.AddEventAndConsiderSampling(now);
+ should_sample = sampler_.AddEventAndConsiderSampling(event_time);
} else {
- should_sample = sampler_.IsOverdueForSamplingAt(now);
+ should_sample = sampler_.IsOverdueForSamplingAt(event_time);
}
const char* event_name = (event == TIMER_POLL ? "poll" :
@@ -456,6 +476,7 @@
// Step 3: Consider the various reasons not to initiate a capture.
if (should_sample && !output_buffer) {
TRACE_EVENT_INSTANT1("mirroring", "EncodeLimited",
+ TRACE_EVENT_SCOPE_THREAD,
"trigger", event_name);
return false;
} else if (!should_sample && output_buffer) {
@@ -464,6 +485,7 @@
// capture rate limit: for example, the content is animating at 60fps but
// we're capturing at 30fps.
TRACE_EVENT_INSTANT1("mirroring", "FpsRateLimited",
+ TRACE_EVENT_SCOPE_THREAD,
"trigger", event_name);
}
return false;
@@ -471,6 +493,7 @@
// We decided not to capture, but we wouldn't have been able to if we wanted
// to because no output buffer was available.
TRACE_EVENT_INSTANT1("mirroring", "NearlyEncodeLimited",
+ TRACE_EVENT_SCOPE_THREAD,
"trigger", event_name);
return false;
}
@@ -482,7 +505,7 @@
"trigger", event_name);
*storage = output_buffer;
*callback = base::Bind(&CaptureOracle::DidCaptureFrame,
- this, output_buffer);
+ this, output_buffer, frame_number_);
return true;
}
@@ -505,7 +528,8 @@
void CaptureOracle::InvalidateConsumer() {
base::AutoLock guard(lock_);
- TRACE_EVENT_INSTANT0("mirroring", "InvalidateConsumer");
+ TRACE_EVENT_INSTANT0("mirroring", "InvalidateConsumer",
+ TRACE_EVENT_SCOPE_THREAD);
is_started_ = false;
consumer_ = NULL;
@@ -513,28 +537,50 @@
void CaptureOracle::DidCaptureFrame(
const scoped_refptr<media::VideoFrame>& frame,
+ int frame_number,
base::Time timestamp,
bool success) {
base::AutoLock guard(lock_);
- TRACE_EVENT_ASYNC_END1("mirroring", "Capture", frame.get(),
- "success", success);
+ TRACE_EVENT_ASYNC_END2("mirroring", "Capture", frame.get(),
+ "success", success,
+ "timestamp", timestamp.ToInternalValue());
if (!consumer_ || !is_started_)
return; // Capture is stopped.
- if (success)
+ if (success) {
+ // Drop frame if previous frame number is higher or we're trying to deliver
+ // a frame with the same timestamp.
+ if (last_delivered_frame_number_ > frame_number ||
+ last_delivered_frame_timestamp_ == timestamp) {
+ LOG(ERROR) << "Frame with same timestamp or out of order delivery. "
+ << "Dropping frame.";
+ return;
+ }
+
+ if (last_delivered_frame_timestamp_ > timestamp) {
+ // We should not get here unless time was adjusted backwards.
+ LOG(ERROR) << "Frame with past timestamp (" << timestamp.ToInternalValue()
+ << ") was delivered";
+ }
+
+ last_delivered_frame_number_ = frame_number;
+ last_delivered_frame_timestamp_ = timestamp;
+
consumer_->OnIncomingCapturedVideoFrame(frame, timestamp);
+ }
}
bool FrameSubscriber::ShouldCaptureFrame(
+ base::Time present_time,
scoped_refptr<media::VideoFrame>* storage,
DeliverFrameCallback* deliver_frame_cb) {
TRACE_EVENT1("mirroring", "FrameSubscriber::ShouldCaptureFrame",
"instance", this);
- return oracle_->ObserveEventAndDecideCapture(event_type_, storage,
- deliver_frame_cb);
+ return oracle_->ObserveEventAndDecideCapture(event_type_, present_time,
+ storage, deliver_frame_cb);
}
ContentCaptureSubscription::ContentCaptureSubscription(
@@ -607,12 +653,15 @@
base::Closure copy_done_callback;
scoped_refptr<media::VideoFrame> frame;
RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback deliver_frame_cb;
- if (paint_subscriber_.ShouldCaptureFrame(&frame, &deliver_frame_cb)) {
+ const base::Time start_time = base::Time::Now();
+ if (paint_subscriber_.ShouldCaptureFrame(start_time,
+ &frame,
+ &deliver_frame_cb)) {
// This message happens just before paint. If we post a task to do the copy,
// it should run soon after the paint.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(capture_callback_, frame, deliver_frame_cb));
+ base::Bind(capture_callback_, start_time, frame, deliver_frame_cb));
}
}
@@ -622,30 +671,18 @@
scoped_refptr<media::VideoFrame> frame;
RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback deliver_frame_cb;
- if (timer_subscriber_.ShouldCaptureFrame(&frame, &deliver_frame_cb)) {
- capture_callback_.Run(frame, deliver_frame_cb);
+
+ const base::Time start_time = base::Time::Now();
+ if (timer_subscriber_.ShouldCaptureFrame(start_time,
+ &frame,
+ &deliver_frame_cb)) {
+ capture_callback_.Run(start_time, frame, deliver_frame_cb);
}
}
-VideoFrameRenderer::VideoFrameRenderer()
- : render_thread_("WebContentsVideo_RenderThread") {
- render_thread_.Start();
-}
-
-void VideoFrameRenderer::Render(const SkBitmap& input,
- const scoped_refptr<media::VideoFrame>& output,
- const base::Callback<void(bool)>& done_cb) {
- render_thread_.message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&VideoFrameRenderer::RenderOnRenderThread,
- base::Unretained(this), input, output, done_cb));
-}
-
-void VideoFrameRenderer::RenderOnRenderThread(
- const SkBitmap& input,
- const scoped_refptr<media::VideoFrame>& output,
- const base::Callback<void(bool)>& done_cb) {
- DCHECK_EQ(render_thread_.message_loop(), MessageLoop::current());
+void RenderVideoFrame(const SkBitmap& input,
+ const scoped_refptr<media::VideoFrame>& output,
+ const base::Callback<void(bool)>& done_cb) {
base::ScopedClosureRunner failure_handler(base::Bind(done_cb, false));
SkAutoLockPixels locker(input);
@@ -744,9 +781,13 @@
scoped_ptr<CaptureMachine> CaptureMachine::Create(
int render_process_id,
int render_view_id,
+ const scoped_refptr<base::SequencedTaskRunner>& render_task_runner,
const scoped_refptr<CaptureOracle>& oracle) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- scoped_ptr<CaptureMachine> machine(new CaptureMachine(oracle));
+ DCHECK(render_task_runner);
+ DCHECK(oracle);
+ scoped_ptr<CaptureMachine> machine(
+ new CaptureMachine(render_task_runner, oracle));
if (!machine->StartObservingWebContents(render_process_id, render_view_id))
machine.reset();
@@ -754,12 +795,16 @@
return machine.Pass();
}
-CaptureMachine::CaptureMachine(const scoped_refptr<CaptureOracle>& oracle)
- : oracle_(oracle),
+CaptureMachine::CaptureMachine(
+ const scoped_refptr<base::SequencedTaskRunner>& render_task_runner,
+ const scoped_refptr<CaptureOracle>& oracle)
+ : render_task_runner_(render_task_runner),
+ oracle_(oracle),
fullscreen_widget_id_(MSG_ROUTING_NONE) {}
CaptureMachine::~CaptureMachine() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
+ !BrowserThread::IsMessageLoopValid(BrowserThread::UI));
// Stop observing the web contents.
subscription_.reset();
@@ -770,6 +815,7 @@
}
void CaptureMachine::Capture(
+ const base::Time& start_time,
const scoped_refptr<media::VideoFrame>& target,
const DeliverFrameCallback& deliver_frame_cb) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -797,7 +843,6 @@
view_size.width() * view_size.height() / 1024);
}
- base::Time start_time = base::Time::Now();
if (!view->IsSurfaceAvailableForCopy()) {
// Fallback to the more expensive renderer-side copy if the surface and
// backing store are not accessible.
@@ -879,7 +924,7 @@
}
void CaptureMachine::DidCopyFromBackingStore(
- base::Time start_time,
+ const base::Time& start_time,
const scoped_refptr<media::VideoFrame>& target,
const DeliverFrameCallback& deliver_frame_cb,
bool success,
@@ -890,18 +935,18 @@
if (success) {
UMA_HISTOGRAM_TIMES("TabCapture.CopyTimeBitmap", now - start_time);
TRACE_EVENT_ASYNC_STEP0("mirroring", "Capture", target.get(), "Render");
- renderer_.Render(bitmap,
- target,
- base::Bind(deliver_frame_cb, now));
+ render_task_runner_->PostTask(FROM_HERE, base::Bind(
+ &RenderVideoFrame, bitmap, target,
+ base::Bind(deliver_frame_cb, start_time)));
} else {
// Capture can fail due to transient issues, so just skip this frame.
DVLOG(1) << "CopyFromBackingStore failed; skipping frame.";
- deliver_frame_cb.Run(now, false);
+ deliver_frame_cb.Run(start_time, false);
}
}
void CaptureMachine::DidCopyFromCompositingSurfaceToVideoFrame(
- base::Time start_time,
+ const base::Time& start_time,
const DeliverFrameCallback& deliver_frame_cb,
bool success) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -913,7 +958,7 @@
// Capture can fail due to transient issues, so just skip this frame.
DVLOG(1) << "CopyFromCompositingSurface failed; skipping frame.";
}
- deliver_frame_cb.Run(now, success);
+ deliver_frame_cb.Run(start_time, success);
}
void CaptureMachine::RenewFrameSubscription() {
@@ -930,6 +975,12 @@
base::Bind(&CaptureMachine::Capture, this->AsWeakPtr())));
}
+void DeleteCaptureMachineOnUIThread(
+ scoped_ptr<CaptureMachine> capture_machine) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ capture_machine.reset();
+}
+
} // namespace
// The "meat" of the video capture implementation, which is a ref-counted class.
@@ -941,15 +992,11 @@
// pipeline (see notes at top of this file). It times the start of successive
// captures and facilitates the processing of each through the stages of the
// pipeline.
-class WebContentsVideoCaptureDevice::Impl
- : public base::RefCountedThreadSafe<Impl> {
+class WebContentsVideoCaptureDevice::Impl : public base::SupportsWeakPtr<Impl> {
public:
- // |destroy_cb| will be invoked after WebContentsVideoCaptureDevice::Impl is
- // fully destroyed, to synchronize tear-down.
- Impl(int render_process_id,
- int render_view_id,
- const base::Closure& destroy_cb);
+ Impl(int render_process_id, int render_view_id);
+ virtual ~Impl();
// Asynchronous requests to change WebContentsVideoCaptureDevice::Impl state.
void Allocate(int width,
@@ -961,7 +1008,6 @@
void DeAllocate();
private:
- friend class base::RefCountedThreadSafe<Impl>;
// Flag indicating current state.
enum State {
@@ -971,19 +1017,17 @@
kError
};
- virtual ~Impl();
-
void TransitionStateTo(State next_state);
// Stops capturing and notifies consumer_ of an error state.
void Error();
- bool CreateCaptureMachineOnUIThread(
- const scoped_refptr<CaptureOracle>& oracle);
- void DestroyCaptureMachineOnUIThread();
-
- // Response callback for CreateCaptureMachineOnUIThread.
- void DidCreateCaptureMachine(bool created);
+ // Called in response to CaptureMachine::Create that runs on the UI thread.
+ // It will assign the capture machine to the Impl class if it still exists
+ // otherwise it will post a task to delete CaptureMachine on the UI thread.
+ static void AssignCaptureMachine(
+ base::WeakPtr<WebContentsVideoCaptureDevice::Impl> impl,
+ scoped_ptr<CaptureMachine> capture_machine);
// Tracks that all activity occurs on the media stream manager's thread.
base::ThreadChecker thread_checker_;
@@ -1000,6 +1044,10 @@
// Current lifecycle state.
State state_;
+ // A dedicated worker thread for doing image operations. Started/joined here,
+ // but used by the CaptureMachine.
+ base::Thread render_thread_;
+
// Tracks the CaptureMachine that's doing work on our behalf on the UI thread.
// This value should never be dereferenced by this class, other than to
// create and destroy it on the UI thread.
@@ -1010,20 +1058,16 @@
// system with direct access to |consumer_|.
scoped_refptr<CaptureOracle> oracle_;
- // Invoked once WebContentsVideoCaptureDevice::Impl is destroyed.
- base::Closure destroy_cb_;
-
DISALLOW_COPY_AND_ASSIGN(Impl);
};
WebContentsVideoCaptureDevice::Impl::Impl(int render_process_id,
- int render_view_id,
- const base::Closure& destroy_cb)
+ int render_view_id)
: initial_render_process_id_(render_process_id),
initial_render_view_id_(render_view_id),
consumer_(NULL),
state_(kIdle),
- destroy_cb_(destroy_cb) {
+ render_thread_("WebContentsVideo_RenderThread") {
}
void WebContentsVideoCaptureDevice::Impl::Allocate(
@@ -1044,6 +1088,12 @@
return;
}
+ if (!render_thread_.Start()) {
+ DVLOG(1) << "Failed to spawn render thread.";
+ consumer->OnError();
+ return;
+ }
+
// Frame dimensions must each be a positive, even integer, since the consumer
// wants (or will convert to) YUV420.
width = MakeEven(width);
@@ -1075,6 +1125,19 @@
consumer_->OnFrameInfo(settings);
oracle_ = new CaptureOracle(consumer_, capture_period);
+ // Allocates the CaptureMachine. The CaptureMachine will be tracking render
+ // view swapping over its lifetime, and we don't want to lose our reference to
+ // the current render view by starting over with the stale
+ // |initial_render_view_id_|.
+ DCHECK(!capture_machine_.get());
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&CaptureMachine::Create,
+ initial_render_process_id_,
+ initial_render_view_id_,
+ render_thread_.message_loop_proxy(), oracle_),
+ base::Bind(&Impl::AssignCaptureMachine, AsWeakPtr()));
+
TransitionStateTo(kAllocated);
}
@@ -1088,39 +1151,29 @@
TransitionStateTo(kCapturing);
oracle_->Start();
-
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&Impl::CreateCaptureMachineOnUIThread, this, oracle_),
- base::Bind(&Impl::DidCreateCaptureMachine, this));
}
-bool WebContentsVideoCaptureDevice::Impl::CreateCaptureMachineOnUIThread(
- const scoped_refptr<CaptureOracle>& oracle) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+// static
+void WebContentsVideoCaptureDevice::Impl::AssignCaptureMachine(
+ base::WeakPtr<WebContentsVideoCaptureDevice::Impl> impl,
+ scoped_ptr<CaptureMachine> capture_machine) {
+ DCHECK(!impl || impl->thread_checker_.CalledOnValidThread());
- // Only create the CaptureMachine if we haven't already. The CaptureMachine
- // will be tracking render view swapping over its lifetime, and we don't want
- // to lose our reference to the current render view by starting over with the
- // stale |initial_render_view_id_|.
- if (!capture_machine_) {
- capture_machine_ = CaptureMachine::Create(
- initial_render_process_id_, initial_render_view_id_, oracle).Pass();
+ if (!impl) {
+ // If WCVD::Impl was destroyed before we got back on it's thread and
+ // capture_machine is not NULL, then we need to return to the UI thread to
+ // safely cleanup the CaptureMachine.
+ if (capture_machine) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE, base::Bind(
+ &DeleteCaptureMachineOnUIThread, base::Passed(&capture_machine)));
+ return;
+ }
+ } else if (!capture_machine) {
+ impl->Error();
+ } else {
+ impl->capture_machine_ = capture_machine.Pass();
}
-
- return capture_machine_ != NULL;
-}
-
-void WebContentsVideoCaptureDevice::Impl::DestroyCaptureMachineOnUIThread() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- capture_machine_.reset();
-}
-
-void WebContentsVideoCaptureDevice::Impl::DidCreateCaptureMachine(
- bool created) {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (!created)
- Error();
}
void WebContentsVideoCaptureDevice::Impl::Stop() {
@@ -1144,26 +1197,28 @@
oracle_->InvalidateConsumer();
consumer_ = NULL;
oracle_ = NULL;
-
- // The above call to InvalidateConsumer() has shut-off capture at the
- // |consumer_| interface. But there is still a capture pipeline running that
- // is checking in with the oracle, and processing captures that are already
- // started in flight. That pipeline must be shut down asynchronously, on the
- // UI thread.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&Impl::DestroyCaptureMachineOnUIThread, this));
+ render_thread_.Stop();
TransitionStateTo(kIdle);
}
}
WebContentsVideoCaptureDevice::Impl::~Impl() {
+ // There is still a capture pipeline running that is checking in with the
+ // oracle, and processing captures that are already started in flight. That
+ // pipeline must be shut down asynchronously, on the UI thread.
+ if (capture_machine_) {
+ // The task that is posted to the UI thread might not run if we are shutting
+ // down, so we transfer ownership of CaptureMachine to the closure so that
+ // it is still cleaned up when the closure is deleted.
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE, base::Bind(
+ &DeleteCaptureMachineOnUIThread, base::Passed(&capture_machine_)));
+ }
+
DCHECK(!capture_machine_) << "Cleanup on UI thread did not happen.";
DCHECK(!consumer_) << "Device not DeAllocated -- possible data race.";
DVLOG(1) << "WebContentsVideoCaptureDevice::Impl@" << this << " destroying.";
- if (!destroy_cb_.is_null())
- destroy_cb_.Run();
}
void WebContentsVideoCaptureDevice::Impl::TransitionStateTo(State next_state) {
@@ -1196,12 +1251,10 @@
WebContentsVideoCaptureDevice::WebContentsVideoCaptureDevice(
const media::VideoCaptureDevice::Name& name,
int render_process_id,
- int render_view_id,
- const base::Closure& destroy_cb)
+ int render_view_id)
: device_name_(name),
- capturer_(new WebContentsVideoCaptureDevice::Impl(render_process_id,
- render_view_id,
- destroy_cb)) {}
+ impl_(new WebContentsVideoCaptureDevice::Impl(render_process_id,
+ render_view_id)) {}
WebContentsVideoCaptureDevice::~WebContentsVideoCaptureDevice() {
DVLOG(2) << "WebContentsVideoCaptureDevice@" << this << " destroying.";
@@ -1209,8 +1262,7 @@
// static
media::VideoCaptureDevice* WebContentsVideoCaptureDevice::Create(
- const std::string& device_id,
- const base::Closure& destroy_cb) {
+ const std::string& device_id) {
// Parse device_id into render_process_id and render_view_id.
int render_process_id = -1;
int render_view_id = -1;
@@ -1226,29 +1278,25 @@
name.unique_id = device_id;
return new WebContentsVideoCaptureDevice(
- name, render_process_id, render_view_id, destroy_cb);
+ name, render_process_id, render_view_id);
}
void WebContentsVideoCaptureDevice::Allocate(
int width, int height, int frame_rate,
VideoCaptureDevice::EventHandler* consumer) {
- DCHECK(capturer_);
- capturer_->Allocate(width, height, frame_rate, consumer);
+ impl_->Allocate(width, height, frame_rate, consumer);
}
void WebContentsVideoCaptureDevice::Start() {
- DCHECK(capturer_);
- capturer_->Start();
+ impl_->Start();
}
void WebContentsVideoCaptureDevice::Stop() {
- DCHECK(capturer_);
- capturer_->Stop();
+ impl_->Stop();
}
void WebContentsVideoCaptureDevice::DeAllocate() {
- DCHECK(capturer_);
- capturer_->DeAllocate();
+ impl_->DeAllocate();
}
const media::VideoCaptureDevice::Name&
@@ -1257,56 +1305,80 @@
}
SmoothEventSampler::SmoothEventSampler(base::TimeDelta capture_period,
- bool events_are_reliable)
+ bool events_are_reliable,
+ int redundant_capture_goal)
: events_are_reliable_(events_are_reliable),
- capture_period_(capture_period) {}
+ capture_period_(capture_period),
+ redundant_capture_goal_(redundant_capture_goal),
+ token_bucket_capacity_(capture_period + capture_period / 2),
+ overdue_sample_count_(0),
+ token_bucket_(token_bucket_capacity_) {
+ DCHECK_GT(capture_period_.InMicroseconds(), 0);
+}
-bool SmoothEventSampler::AddEventAndConsiderSampling(base::Time now) {
- current_event_ = now;
+bool SmoothEventSampler::AddEventAndConsiderSampling(base::Time event_time) {
+ DCHECK(!event_time.is_null());
- // If we've never sampled, then the choice is obvious.
- if (last_sample_.is_null())
- return true;
+ // Add tokens to the bucket based on advancement in time. Then, re-bound the
+ // number of tokens in the bucket. Overflow occurs when there is too much
+ // time between events (a common case), or when RecordSample() is not being
+ // called often enough (a bug). On the other hand, if RecordSample() is being
+ // called too often (e.g., as a reaction to IsOverdueForSamplingAt()), the
+ // bucket will underflow.
+ if (!current_event_.is_null()) {
+ if (current_event_ < event_time) {
+ token_bucket_ += event_time - current_event_;
+ if (token_bucket_ > token_bucket_capacity_)
+ token_bucket_ = token_bucket_capacity_;
+ }
+ // Side note: If the system clock is reset, causing |current_event_| to be
+ // greater than |event_time|, everything here will simply gracefully adjust.
+ if (token_bucket_ < base::TimeDelta())
+ token_bucket_ = base::TimeDelta();
+ TRACE_COUNTER1("mirroring",
+ "MirroringTokenBucketUsec", token_bucket_.InMicroseconds());
+ }
+ current_event_ = event_time;
- // TODO(nick): Actually track the effective frame rate here, and use an
- // uncertainty window based on that (half seems like a reasonable choice). E.g
- // if content is updating every 16.6ms, and we're hoping to sampling every
- // 100ms, then we might consider sampling events no sooner than (100ms -
- // 8.3ms) from the last sample.
- base::TimeDelta uncertainty_window = capture_period_ / 10;
-
- base::TimeDelta interval = current_event_ - last_sample_;
- return interval >= (capture_period_ - uncertainty_window);
+ // Return true if one capture period's worth of tokens are in the bucket.
+ return token_bucket_ >= capture_period_;
}
void SmoothEventSampler::RecordSample() {
- if (!current_event_.is_null())
+ token_bucket_ -= capture_period_;
+ TRACE_COUNTER1("mirroring",
+ "MirroringTokenBucketUsec", token_bucket_.InMicroseconds());
+ if (HasUnrecordedEvent()) {
last_sample_ = current_event_;
- current_event_ = base::Time();
+ overdue_sample_count_ = 0;
+ } else {
+ ++overdue_sample_count_;
+ }
}
-bool SmoothEventSampler::IsOverdueForSamplingAt(base::Time now) const {
- if (last_sample_.is_null())
- return true; // Definitely old and dirty.
+bool SmoothEventSampler::IsOverdueForSamplingAt(base::Time event_time) const {
+ DCHECK(!event_time.is_null());
// If we don't get events on compositor updates on this platform, then we
// don't reliably know whether we're dirty.
if (events_are_reliable_) {
- if (current_event_.is_null())
+ if (!HasUnrecordedEvent() &&
+ overdue_sample_count_ >= redundant_capture_goal_) {
return false; // Not dirty.
+ }
}
// If we're dirty but not yet old, then we've recently gotten updates, so we
// won't request a sample just yet.
- base::TimeDelta dirty_interval = now - last_sample_;
- if (dirty_interval < capture_period_ * 2)
+ base::TimeDelta dirty_interval = event_time - last_sample_;
+ if (dirty_interval < capture_period_ * 4)
return false;
else
return true;
}
-base::Time SmoothEventSampler::GetLastSampledEvent() {
- return last_sample_;
+bool SmoothEventSampler::HasUnrecordedEvent() const {
+ return !current_event_.is_null() && current_event_ != last_sample_;
}
} // namespace content
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 fe9820b..ec23511 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
@@ -38,8 +38,7 @@
// WebContentsVideoCaptureDevice is itself deleted.
// TODO(miu): Passing a destroy callback suggests needing to revisit the
// design philosophy of an asynchronous DeAllocate(). http://crbug.com/158641
- static media::VideoCaptureDevice* Create(const std::string& device_id,
- const base::Closure& destroy_cb);
+ static media::VideoCaptureDevice* Create(const std::string& device_id);
virtual ~WebContentsVideoCaptureDevice();
@@ -60,13 +59,13 @@
private:
class Impl;
+
WebContentsVideoCaptureDevice(const Name& name,
int render_process_id,
- int render_view_id,
- const base::Closure& destroy_cb);
+ int render_view_id);
Name device_name_;
- scoped_refptr<Impl> capturer_;
+ const scoped_ptr<Impl> impl_;
DISALLOW_COPY_AND_ASSIGN(WebContentsVideoCaptureDevice);
};
@@ -75,29 +74,38 @@
class CONTENT_EXPORT SmoothEventSampler {
public:
explicit SmoothEventSampler(base::TimeDelta capture_period,
- bool events_are_reliable);
+ bool events_are_reliable,
+ int redundant_capture_goal);
// Add a new event to the event history, and return whether it ought to be
- // sampled per to the sampling frequency limit. Even if this method returns
- // true, the event is not recorded as a sample until RecordSample() is called.
- bool AddEventAndConsiderSampling(base::Time now);
+ // sampled based on the desired |capture_period|. The event is not recorded as
+ // a sample until RecordSample() is called.
+ bool AddEventAndConsiderSampling(base::Time event_time);
// Operates on the last event added by AddEventAndConsiderSampling(), marking
// it as sampled. After this point we are current in the stream of events, as
// we have sampled the most recent event.
void RecordSample();
- // Returns true if, at time |now|, sampling should occur because too much time
- // will have passed relative to the last event and/or sample.
- bool IsOverdueForSamplingAt(base::Time now) const;
+ // Returns true if, at time |event_time|, sampling should occur because too
+ // much time will have passed relative to the last event and/or sample.
+ bool IsOverdueForSamplingAt(base::Time event_time) const;
- base::Time GetLastSampledEvent();
+ // Returns true if AddEventAndConsiderSampling() has been called since the
+ // last call to RecordSample().
+ bool HasUnrecordedEvent() const;
private:
const bool events_are_reliable_;
const base::TimeDelta capture_period_;
+ const int redundant_capture_goal_;
+ const base::TimeDelta token_bucket_capacity_;
+
base::Time current_event_;
base::Time last_sample_;
+ int overdue_sample_count_;
+ base::TimeDelta token_bucket_;
+
DISALLOW_COPY_AND_ASSIGN(SmoothEventSampler);
};
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 b160452..a09ac16 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
@@ -7,6 +7,7 @@
#include "base/bind_helpers.h"
#include "base/debug/debugger.h"
#include "base/run_loop.h"
+#include "base/test/test_timeouts.h"
#include "base/time.h"
#include "base/timer.h"
#include "content/browser/browser_thread_impl.h"
@@ -32,10 +33,10 @@
namespace content {
namespace {
+
const int kTestWidth = 320;
const int kTestHeight = 240;
const int kTestFramesPerSecond = 20;
-const base::TimeDelta kWaitTimeout = base::TimeDelta::FromMilliseconds(10000);
const SkColor kNothingYet = 0xdeadbeef;
const SkColor kNotInterested = ~kNothingYet;
@@ -51,9 +52,9 @@
void RunCurrentLoopWithDeadline() {
base::Timer deadline(false, false);
- deadline.Start(FROM_HERE, kWaitTimeout, base::Bind(
- &DeadlineExceeded, MessageLoop::current()->QuitClosure()));
- MessageLoop::current()->Run();
+ deadline.Start(FROM_HERE, TestTimeouts::action_max_timeout(), base::Bind(
+ &DeadlineExceeded, base::MessageLoop::current()->QuitClosure()));
+ base::MessageLoop::current()->Run();
deadline.Stop();
}
@@ -129,22 +130,12 @@
void WaitForNextCopy() {
{
base::AutoLock guard(lock_);
- copy_done_ = MessageLoop::current()->QuitClosure();
+ copy_done_ = base::MessageLoop::current()->QuitClosure();
}
RunCurrentLoopWithDeadline();
}
- void OnShutdown() {
- base::AutoLock guard(lock_);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, shutdown_hook_);
- }
-
- void SetShutdownHook(base::Closure shutdown_hook) {
- base::AutoLock guard(lock_);
- shutdown_hook_ = shutdown_hook;
- }
-
private:
base::Lock lock_; // Guards changes to all members.
SkColor color_;
@@ -152,7 +143,6 @@
bool can_copy_to_video_frame_;
bool use_frame_subscriber_;
base::Closure copy_done_;
- base::Closure shutdown_hook_;
DISALLOW_COPY_AND_ASSIGN(CaptureTestSourceController);
};
@@ -167,6 +157,7 @@
CaptureTestSourceController* controller)
: TestRenderWidgetHostView(rwh),
controller_(controller) {}
+
virtual ~CaptureTestView() {}
// TestRenderWidgetHostView overrides.
@@ -199,13 +190,15 @@
// Simulate a compositor paint event for our subscriber.
void SimulateUpdate() {
+ const base::Time present_time = base::Time::Now();
RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback;
scoped_refptr<media::VideoFrame> target;
- if (subscriber_ && subscriber_->ShouldCaptureFrame(&target, &callback)) {
+ if (subscriber_ && subscriber_->ShouldCaptureFrame(present_time,
+ &target, &callback)) {
SkColor c = ConvertRgbToYuv(controller_->GetSolidColor());
media::FillYUV(target, SkColorGetR(c), SkColorGetG(c), SkColorGetB(c));
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(callback, base::Time::Now(), true));
+ base::Bind(callback, present_time, true));
controller_->SignalCopy();
}
}
@@ -321,7 +314,7 @@
base::AutoLock guard(lock_);
if (wait_color_yuv_ == color || error_encountered_)
- MessageLoop::current()->Quit();
+ base::MessageLoop::current()->Quit();
}
void WaitForNextColor(SkColor expected_color) {
@@ -350,6 +343,11 @@
}
}
+ bool HasError() {
+ base::AutoLock guard(lock_);
+ return error_encountered_;
+ }
+
virtual scoped_refptr<media::VideoFrame> ReserveOutputBuffer() OVERRIDE {
return buffer_pool_->ReserveForProducer(0);
}
@@ -409,8 +407,6 @@
DISALLOW_COPY_AND_ASSIGN(StubConsumer);
};
-} // namespace
-
// Test harness that sets up a minimal environment with necessary stubs.
class WebContentsVideoCaptureDeviceTest : public testing::Test {
public:
@@ -458,11 +454,7 @@
base::StringPrintf("%d:%d", rwh->GetProcess()->GetID(),
rwh->GetRoutingID()));
- base::Closure destroy_cb = base::Bind(
- &CaptureTestSourceController::OnShutdown,
- base::Unretained(&controller_));
-
- device_.reset(WebContentsVideoCaptureDevice::Create(device_id, destroy_cb));
+ device_.reset(WebContentsVideoCaptureDevice::Create(device_id));
content::RunAllPendingInMessageLoop();
}
@@ -473,11 +465,10 @@
// The device is destroyed asynchronously, and will notify the
// CaptureTestSourceController when it finishes destruction.
// Trigger this, and wait.
- base::RunLoop shutdown_loop;
- controller_.SetShutdownHook(shutdown_loop.QuitClosure());
- device_->DeAllocate();
- device_.reset();
- shutdown_loop.Run();
+ if (device_) {
+ device_->DeAllocate();
+ device_.reset();
+ }
content::RunAllPendingInMessageLoop();
@@ -511,6 +502,8 @@
}
}
+ void DestroyVideoCaptureDevice() { device_.reset(); }
+
private:
// The consumer is the ultimate recipient of captured pixel data.
StubConsumer consumer_;
@@ -520,7 +513,7 @@
// We run the UI message loop on the main thread. The capture device
// will also spin up its own threads.
- MessageLoopForUI message_loop_;
+ base::MessageLoopForUI message_loop_;
scoped_ptr<TestBrowserThread> ui_thread_;
// Self-registering RenderProcessHostFactory.
@@ -574,6 +567,76 @@
device()->DeAllocate();
}
+TEST_F(WebContentsVideoCaptureDeviceTest,
+ StopDeviceBeforeCaptureMachineCreation) {
+ device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer());
+ device()->Start();
+ // Make a point of not running the UI messageloop here.
+ device()->Stop();
+ device()->DeAllocate();
+ DestroyVideoCaptureDevice();
+
+ // Currently, there should be CreateCaptureMachineOnUIThread() and
+ // DestroyCaptureMachineOnUIThread() tasks pending on the current (UI) message
+ // loop. These should both succeed without crashing, and the machine should
+ // wind up in the idle state.
+ content::RunAllPendingInMessageLoop();
+}
+
+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());
+ device()->Start();
+ // Make a point of not running the UI messageloop here.
+ content::RunAllPendingInMessageLoop();
+
+ for (int i = 0; i < 10; ++i)
+ SimulateDrawEvent();
+
+ device()->Stop();
+ device()->DeAllocate();
+ // Currently, there should be CreateCaptureMachineOnUIThread() and
+ // DestroyCaptureMachineOnUIThread() tasks pending on the current message
+ // loop. These should both succeed without crashing, and the machine should
+ // wind up in the idle state.
+ ASSERT_FALSE(consumer()->HasError());
+ content::RunAllPendingInMessageLoop();
+ ASSERT_FALSE(consumer()->HasError());
+}
+
+TEST_F(WebContentsVideoCaptureDeviceTest, DeviceRestart) {
+ device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer());
+ device()->Start();
+ content::RunAllPendingInMessageLoop();
+ source()->SetSolidColor(SK_ColorRED);
+ SimulateDrawEvent();
+ SimulateDrawEvent();
+ ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorRED));
+ SimulateDrawEvent();
+ SimulateDrawEvent();
+ source()->SetSolidColor(SK_ColorGREEN);
+ SimulateDrawEvent();
+ ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorGREEN));
+ device()->Stop();
+
+ // Device is stopped, but content can still be animating.
+ SimulateDrawEvent();
+ SimulateDrawEvent();
+ content::RunAllPendingInMessageLoop();
+
+ device()->Start();
+ source()->SetSolidColor(SK_ColorBLUE);
+ SimulateDrawEvent();
+ ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorBLUE));
+ source()->SetSolidColor(SK_ColorYELLOW);
+ SimulateDrawEvent();
+ ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorYELLOW));
+ device()->DeAllocate();
+}
+
// The "happy case" test. No scaling is needed, so we should be able to change
// the picture emitted from the source and expect to see each delivered to the
// consumer. The test will alternate between the three capture paths, simulating
@@ -660,30 +723,211 @@
device()->DeAllocate();
}
-// 60Hz sampled at 30Hz should produce 30Hz.
+void SteadyStateSampleAndAdvance(base::TimeDelta vsync,
+ SmoothEventSampler* sampler, base::Time* t) {
+ ASSERT_TRUE(sampler->AddEventAndConsiderSampling(*t));
+ ASSERT_TRUE(sampler->HasUnrecordedEvent());
+ sampler->RecordSample();
+ ASSERT_FALSE(sampler->HasUnrecordedEvent());
+ ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t));
+ *t += vsync;
+ ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t));
+}
+
+void SteadyStateNoSampleAndAdvance(base::TimeDelta vsync,
+ SmoothEventSampler* sampler, base::Time* t) {
+ ASSERT_FALSE(sampler->AddEventAndConsiderSampling(*t));
+ ASSERT_TRUE(sampler->HasUnrecordedEvent());
+ ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t));
+ *t += vsync;
+ ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t));
+}
+
+void TestRedundantCaptureStrategy(base::TimeDelta capture_period,
+ int redundant_capture_goal,
+ SmoothEventSampler* sampler, base::Time* t) {
+ // Before any events have been considered, we're overdue for sampling.
+ ASSERT_TRUE(sampler->IsOverdueForSamplingAt(*t));
+
+ // Consider the first event. We want to sample that.
+ ASSERT_FALSE(sampler->HasUnrecordedEvent());
+ ASSERT_TRUE(sampler->AddEventAndConsiderSampling(*t));
+ ASSERT_TRUE(sampler->HasUnrecordedEvent());
+ sampler->RecordSample();
+ ASSERT_FALSE(sampler->HasUnrecordedEvent());
+
+ // After more than one capture period has passed without considering an event,
+ // we should repeatedly be overdue for sampling. However, once the redundant
+ // capture goal is achieved, we should no longer be overdue for sampling.
+ *t += capture_period * 4;
+ for (int i = 0; i < redundant_capture_goal; i++) {
+ SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
+ ASSERT_FALSE(sampler->HasUnrecordedEvent());
+ ASSERT_TRUE(sampler->IsOverdueForSamplingAt(*t))
+ << "Should sample until redundant capture goal is hit";
+ sampler->RecordSample();
+ *t += capture_period; // Timer fires once every capture period.
+ }
+ ASSERT_FALSE(sampler->IsOverdueForSamplingAt(*t))
+ << "Should not be overdue once redundant capture goal achieved.";
+}
+
+// 60Hz sampled at 30Hz should produce 30Hz. In addition, this test contains
+// much more comprehensive before/after/edge-case scenarios than the others.
TEST(SmoothEventSamplerTest, Sample60HertzAt30Hertz) {
- SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, true);
+ const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
+ const int redundant_capture_goal = 200;
const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 60;
+ SmoothEventSampler sampler(capture_period, true, redundant_capture_goal);
base::Time t;
ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t));
- ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t))
- << "First timer event should sample.";
- sampler.RecordSample();
- ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t))
- << "Should always be overdue until first paint.";
+
+ TestRedundantCaptureStrategy(capture_period, redundant_capture_goal,
+ &sampler, &t);
// Steady state, we should capture every other vsync, indefinitely.
for (int i = 0; i < 100; i++) {
SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
- ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
- sampler.RecordSample();
- t += vsync;
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
+ }
- ASSERT_FALSE(sampler.AddEventAndConsiderSampling(t));
+ // Now pretend we're limited by backpressure in the pipeline. In this scenario
+ // case we are adding events but not sampling them.
+ for (int i = 0; i < 20; i++) {
+ SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
+ ASSERT_EQ(i >= 7, sampler.IsOverdueForSamplingAt(t));
+ ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
+ ASSERT_TRUE(sampler.HasUnrecordedEvent());
t += vsync;
}
+ // Now suppose we can sample again. We should be back in the steady state,
+ // but at a different phase.
+ ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t));
+ for (int i = 0; i < 100; i++) {
+ SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
+ }
+}
+
+// 50Hz sampled at 30Hz should produce a sequence where some frames are skipped.
+TEST(SmoothEventSamplerTest, Sample50HertzAt30Hertz) {
+ const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
+ const int redundant_capture_goal = 2;
+ const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 50;
+
+ SmoothEventSampler sampler(capture_period, true, redundant_capture_goal);
+ base::Time t;
+ ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t));
+
+ TestRedundantCaptureStrategy(capture_period, redundant_capture_goal,
+ &sampler, &t);
+
+ // Steady state, we should capture 1st, 2nd and 4th frames out of every five
+ // frames, indefinitely.
+ for (int i = 0; i < 100; i++) {
+ SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
+ }
+
+ // Now pretend we're limited by backpressure in the pipeline. In this scenario
+ // case we are adding events but not sampling them.
+ for (int i = 0; i < 12; i++) {
+ SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
+ ASSERT_EQ(i >= 5, sampler.IsOverdueForSamplingAt(t));
+ ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
+ t += vsync;
+ }
+
+ // Now suppose we can sample again. We should be back in the steady state
+ // again.
+ ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t));
+ for (int i = 0; i < 100; i++) {
+ SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
+ }
+}
+
+// 75Hz sampled at 30Hz should produce a sequence where some frames are skipped.
+TEST(SmoothEventSamplerTest, Sample75HertzAt30Hertz) {
+ const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
+ const int redundant_capture_goal = 32;
+ const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 75;
+
+ SmoothEventSampler sampler(capture_period, true, redundant_capture_goal);
+ base::Time t;
+ ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t));
+
+ TestRedundantCaptureStrategy(capture_period, redundant_capture_goal,
+ &sampler, &t);
+
+ // Steady state, we should capture 1st and 3rd frames out of every five
+ // frames, indefinitely.
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
+ for (int i = 0; i < 100; i++) {
+ SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
+ }
+
+ // Now pretend we're limited by backpressure in the pipeline. In this scenario
+ // case we are adding events but not sampling them.
+ for (int i = 0; i < 20; i++) {
+ SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
+ ASSERT_EQ(i >= 8, sampler.IsOverdueForSamplingAt(t));
+ ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
+ t += vsync;
+ }
+
+ // Now suppose we can sample again. We capture the next frame, and not the one
+ // after that, and then we're back in the steady state again.
+ ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t));
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
+ for (int i = 0; i < 100; i++) {
+ SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
+ SteadyStateNoSampleAndAdvance(vsync, &sampler, &t);
+ }
+}
+
+// 30Hz sampled at 30Hz should produce 30Hz.
+TEST(SmoothEventSamplerTest, Sample30HertzAt30Hertz) {
+ const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
+ const int redundant_capture_goal = 1;
+ const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 30;
+
+ SmoothEventSampler sampler(capture_period, true, redundant_capture_goal);
+ base::Time t;
+ ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t));
+
+ TestRedundantCaptureStrategy(capture_period, redundant_capture_goal,
+ &sampler, &t);
+
+ // Steady state, we should capture every vsync, indefinitely.
+ for (int i = 0; i < 200; i++) {
+ SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
+ }
+
// Now pretend we're limited by backpressure in the pipeline. In this scenario
// case we are adding events but not sampling them.
for (int i = 0; i < 7; i++) {
@@ -693,139 +937,38 @@
t += vsync;
}
- // Now suppose we can sample again. We should be back in the steady state,
- // but at a different phase.
- ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t));
- for (int i = 0; i < 100; i++) {
- SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
- ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
- sampler.RecordSample();
- t += vsync;
- ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t));
-
- ASSERT_FALSE(sampler.AddEventAndConsiderSampling(t));
- t += vsync;
- ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t));
- }
-}
-
-// 50Hz sampled at 30Hz should produce 25Hz.
-TEST(SmoothEventSamplerTest, Sample50HertzAt30Hertz) {
- SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, true);
- const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 50;
-
- base::Time t;
- ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t));
- ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t))
- << "First timer event should sample.";
- sampler.RecordSample();
- ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t))
- << "Should always be overdue until first paint.";
-
- // Steady state, we should capture every other vsync, indefinitely.
- for (int i = 0; i < 100; i++) {
- SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
- ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
- sampler.RecordSample();
- t += vsync;
-
- ASSERT_FALSE(sampler.AddEventAndConsiderSampling(t));
- t += vsync;
- }
-
- // Now pretend we're limited by backpressure in the pipeline. In this scenario
- // case we are adding events but not sampling them.
- for (int i = 0; i < 7; i++) {
- SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
- ASSERT_EQ(i >= 2, sampler.IsOverdueForSamplingAt(t));
- ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
- t += vsync;
- }
-
- // Now suppose we can sample again. We should be back in the steady state,
- // but at a different phase.
- ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t));
- for (int i = 0; i < 100; i++) {
- SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
- ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
- sampler.RecordSample();
- t += vsync;
- ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t));
-
- ASSERT_FALSE(sampler.AddEventAndConsiderSampling(t));
- t += vsync;
- ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t));
- }
-}
-
-// 30Hz sampled at 30Hz should produce 30Hz.
-TEST(SmoothEventSamplerTest, Sample30HertzAt30Hertz) {
- SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, true);
- const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 30;
-
- base::Time t;
- ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t));
- ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t))
- << "First timer event should sample.";
- sampler.RecordSample();
- ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t))
- << "Should always be overdue until first paint.";
-
- // Steady state, we should capture every vsync, indefinitely.
- for (int i = 0; i < 200; i++) {
- SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
- ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
- sampler.RecordSample();
- t += vsync;
- }
-
- // Now pretend we're limited by backpressure in the pipeline. In this scenario
- // case we are adding events but not sampling them.
- for (int i = 0; i < 7; i++) {
- SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
- ASSERT_EQ(i >= 1, sampler.IsOverdueForSamplingAt(t));
- ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
- t += vsync;
- }
-
// Now suppose we can sample again. We should be back in the steady state.
ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t));
for (int i = 0; i < 100; i++) {
SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
- ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
- sampler.RecordSample();
- t += vsync;
- ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t));
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
}
}
-
// 24Hz sampled at 30Hz should produce 24Hz.
TEST(SmoothEventSamplerTest, Sample24HertzAt30Hertz) {
- SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, true);
+ const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
+ const int redundant_capture_goal = 333;
const base::TimeDelta vsync = base::TimeDelta::FromSeconds(1) / 24;
+ SmoothEventSampler sampler(capture_period, true, redundant_capture_goal);
base::Time t;
ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t));
- ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t))
- << "First timer event should sample.";
- sampler.RecordSample();
- ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t))
- << "Should always be overdue until first paint.";
+
+ TestRedundantCaptureStrategy(capture_period, redundant_capture_goal,
+ &sampler, &t);
// Steady state, we should capture every vsync, indefinitely.
for (int i = 0; i < 200; i++) {
SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
- ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
- sampler.RecordSample();
- t += vsync;
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
}
// Now pretend we're limited by backpressure in the pipeline. In this scenario
// case we are adding events but not sampling them.
for (int i = 0; i < 7; i++) {
SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
- ASSERT_EQ(i >= 1, sampler.IsOverdueForSamplingAt(t));
+ ASSERT_EQ(i >= 3, sampler.IsOverdueForSamplingAt(t));
ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
t += vsync;
}
@@ -834,24 +977,23 @@
ASSERT_TRUE(sampler.IsOverdueForSamplingAt(t));
for (int i = 0; i < 100; i++) {
SCOPED_TRACE(base::StringPrintf("Iteration %d", i));
- ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
- sampler.RecordSample();
- t += vsync;
- ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t));
+ SteadyStateSampleAndAdvance(vsync, &sampler, &t);
}
}
TEST(SmoothEventSamplerTest, DoubleDrawAtOneTimeStillDirties) {
- SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, true);
+ const base::TimeDelta capture_period = base::TimeDelta::FromSeconds(1) / 30;
const base::TimeDelta overdue_period = base::TimeDelta::FromSeconds(1);
+ SmoothEventSampler sampler(capture_period, true, 1);
base::Time t;
ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t));
+
ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
sampler.RecordSample();
- t += overdue_period;
ASSERT_FALSE(sampler.IsOverdueForSamplingAt(t))
<< "Sampled last event; should not be dirty.";
+ t += overdue_period;
// Now simulate 2 events with the same clock value.
ASSERT_TRUE(sampler.AddEventAndConsiderSampling(t));
@@ -866,32 +1008,49 @@
TEST(SmoothEventSamplerTest, FallbackToPollingIfUpdatesUnreliable) {
const base::TimeDelta timer_interval = base::TimeDelta::FromSeconds(1) / 30;
- SmoothEventSampler should_not_poll(timer_interval, true);
- SmoothEventSampler should_poll(timer_interval, false);
+ SmoothEventSampler should_not_poll(timer_interval, true, 1);
+ SmoothEventSampler should_poll(timer_interval, false, 1);
base::Time t;
ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t));
+
+ // Do one round of the "happy case" where an event was received and
+ // RecordSample() was called by the client.
ASSERT_TRUE(should_not_poll.AddEventAndConsiderSampling(t));
ASSERT_TRUE(should_poll.AddEventAndConsiderSampling(t));
should_not_poll.RecordSample();
should_poll.RecordSample();
+
+ // One time period ahead, neither sampler says we're overdue.
+ for (int i = 0; i < 3; i++) {
+ t += timer_interval;
+ ASSERT_FALSE(should_not_poll.IsOverdueForSamplingAt(t))
+ << "Sampled last event; should not be dirty.";
+ ASSERT_FALSE(should_poll.IsOverdueForSamplingAt(t))
+ << "Dirty interval has not elapsed yet.";
+ }
+
+ // Next time period ahead, both samplers say we're overdue. The non-polling
+ // sampler is returning true here because it has been configured to allow one
+ // redundant capture.
t += timer_interval;
- ASSERT_FALSE(should_not_poll.IsOverdueForSamplingAt(t))
- << "Sampled last event; should not be dirty.";
- ASSERT_FALSE(should_poll.IsOverdueForSamplingAt(t))
- << "Dirty interval has not elapsed yet.";
- t += timer_interval;
- ASSERT_FALSE(should_not_poll.IsOverdueForSamplingAt(t))
- << "Sampled last event; should not be dirty.";
+ ASSERT_TRUE(should_not_poll.IsOverdueForSamplingAt(t))
+ << "Sampled last event; is dirty one time only to meet redundancy goal.";
ASSERT_TRUE(should_poll.IsOverdueForSamplingAt(t))
<< "If updates are unreliable, must fall back to polling when idle.";
+ should_not_poll.RecordSample();
should_poll.RecordSample();
- t += timer_interval;
- ASSERT_FALSE(should_not_poll.IsOverdueForSamplingAt(t))
- << "Sampled last event; should not be dirty.";
- ASSERT_TRUE(should_poll.IsOverdueForSamplingAt(t))
- << "If updates are unreliable, must fall back to polling when idle.";
- should_poll.RecordSample();
+
+ // Forever more, the non-polling sampler returns false while the polling one
+ // returns true.
+ for (int i = 0; i < 100; ++i) {
+ t += timer_interval;
+ ASSERT_FALSE(should_not_poll.IsOverdueForSamplingAt(t))
+ << "Sampled last event; should not be dirty.";
+ ASSERT_TRUE(should_poll.IsOverdueForSamplingAt(t))
+ << "If updates are unreliable, must fall back to polling when idle.";
+ should_poll.RecordSample();
+ }
t += timer_interval / 3;
ASSERT_FALSE(should_not_poll.IsOverdueForSamplingAt(t))
<< "Sampled last event; should not be dirty.";
@@ -900,5 +1059,132 @@
should_poll.RecordSample();
}
-} // namespace content
+struct DataPoint {
+ bool should_capture;
+ double increment_ms;
+};
+void ReplayCheckingSamplerDecisions(const DataPoint* data_points,
+ size_t num_data_points,
+ SmoothEventSampler* sampler) {
+ base::Time t;
+ ASSERT_TRUE(base::Time::FromString("Sat, 23 Mar 2013 1:21:08 GMT", &t));
+ for (size_t i = 0; i < num_data_points; ++i) {
+ t += base::TimeDelta::FromMicroseconds(
+ static_cast<int64>(data_points[i].increment_ms * 1000));
+ ASSERT_EQ(data_points[i].should_capture,
+ sampler->AddEventAndConsiderSampling(t))
+ << "at data_points[" << i << ']';
+ if (data_points[i].should_capture)
+ sampler->RecordSample();
+ }
+}
+
+TEST(SmoothEventSamplerTest, DrawingAt24FpsWith60HzVsyncSampledAt30Hertz) {
+ // Actual capturing of timing data: Initial instability as a 24 FPS video was
+ // started from a still screen, then clearly followed by steady-state.
+ static const DataPoint data_points[] = {
+ { true, 1437.93 }, { true, 150.484 }, { true, 217.362 }, { true, 50.161 },
+ { true, 33.44 }, { false, 0 }, { true, 16.721 }, { true, 66.88 },
+ { true, 50.161 }, { false, 0 }, { false, 0 }, { true, 50.16 },
+ { true, 33.441 }, { true, 16.72 }, { false, 16.72 }, { true, 117.041 },
+ { true, 16.72 }, { false, 16.72 }, { true, 50.161 }, { true, 50.16 },
+ { true, 33.441 }, { true, 33.44 }, { true, 33.44 }, { true, 16.72 },
+ { false, 0 }, { true, 50.161 }, { false, 0 }, { true, 33.44 },
+ { true, 16.72 }, { false, 16.721 }, { true, 66.881 }, { false, 0 },
+ { true, 33.441 }, { true, 16.72 }, { true, 50.16 }, { true, 16.72 },
+ { false, 16.721 }, { true, 50.161 }, { true, 50.16 }, { false, 0 },
+ { true, 33.441 }, { true, 50.337 }, { true, 50.183 }, { true, 16.722 },
+ { true, 50.161 }, { true, 33.441 }, { true, 50.16 }, { true, 33.441 },
+ { true, 50.16 }, { true, 33.441 }, { true, 50.16 }, { true, 33.44 },
+ { true, 50.161 }, { true, 50.16 }, { true, 33.44 }, { true, 33.441 },
+ { true, 50.16 }, { true, 50.161 }, { true, 33.44 }, { true, 33.441 },
+ { true, 50.16 }, { true, 33.44 }, { true, 50.161 }, { true, 33.44 },
+ { true, 50.161 }, { true, 33.44 }, { true, 50.161 }, { true, 33.44 },
+ { true, 83.601 }, { true, 16.72 }, { true, 33.44 }, { false, 0 }
+ };
+
+ SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, true, 3);
+ ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler);
+}
+
+TEST(SmoothEventSamplerTest, DrawingAt30FpsWith60HzVsyncSampledAt30Hertz) {
+ // Actual capturing of timing data: Initial instability as a 30 FPS video was
+ // started from a still screen, then followed by steady-state. Drawing
+ // framerate from the video rendering was a bit volatile, but averaged 30 FPS.
+ static const DataPoint data_points[] = {
+ { true, 2407.69 }, { true, 16.733 }, { true, 217.362 }, { true, 33.441 },
+ { true, 33.44 }, { true, 33.44 }, { true, 33.441 }, { true, 33.44 },
+ { true, 33.44 }, { true, 33.441 }, { true, 33.44 }, { true, 33.44 },
+ { true, 16.721 }, { true, 33.44 }, { false, 0 }, { true, 50.161 },
+ { true, 50.16 }, { false, 0 }, { true, 50.161 }, { true, 33.44 },
+ { true, 16.72 }, { false, 0 }, { false, 16.72 }, { true, 66.881 },
+ { false, 0 }, { true, 33.44 }, { true, 16.72 }, { true, 50.161 },
+ { false, 0 }, { true, 33.538 }, { true, 33.526 }, { true, 33.447 },
+ { true, 33.445 }, { true, 33.441 }, { true, 16.721 }, { true, 33.44 },
+ { true, 33.44 }, { true, 50.161 }, { true, 16.72 }, { true, 33.44 },
+ { true, 33.441 }, { true, 33.44 }, { false, 0 }, { false, 16.72 },
+ { true, 66.881 }, { true, 16.72 }, { false, 16.72 }, { true, 50.16 },
+ { true, 33.441 }, { true, 33.44 }, { true, 33.44 }, { true, 33.44 },
+ { true, 33.441 }, { true, 33.44 }, { true, 50.161 }, { false, 0 },
+ { true, 33.44 }, { true, 33.44 }, { true, 50.161 }, { true, 16.72 },
+ { true, 33.44 }, { true, 33.441 }, { false, 0 }, { true, 66.88 },
+ { true, 33.441 }, { true, 33.44 }, { true, 33.44 }, { false, 0 },
+ { true, 33.441 }, { true, 33.44 }, { true, 33.44 }, { false, 0 },
+ { true, 16.72 }, { true, 50.161 }, { false, 0 }, { true, 50.16 },
+ { false, 0.001 }, { true, 16.721 }, { true, 66.88 }, { true, 33.44 },
+ { true, 33.441 }, { true, 33.44 }, { true, 50.161 }, { true, 16.72 },
+ { false, 0 }, { true, 33.44 }, { false, 16.72 }, { true, 66.881 },
+ { true, 33.44 }, { true, 16.72 }, { true, 33.441 }, { false, 16.72 },
+ { true, 66.88 }, { true, 16.721 }, { true, 50.16 }, { true, 33.44 },
+ { true, 16.72 }, { true, 33.441 }, { true, 33.44 }, { true, 33.44 }
+ };
+
+ SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, true, 3);
+ ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler);
+}
+
+TEST(SmoothEventSamplerTest, DrawingAt60FpsWith60HzVsyncSampledAt30Hertz) {
+ // Actual capturing of timing data: WebGL Acquarium demo
+ // (http://webglsamples.googlecode.com/hg/aquarium/aquarium.html) which ran
+ // between 55-60 FPS in the steady-state.
+ static const DataPoint data_points[] = {
+ { true, 16.72 }, { true, 16.72 }, { true, 4163.29 }, { true, 50.193 },
+ { true, 117.041 }, { true, 50.161 }, { true, 50.16 }, { true, 33.441 },
+ { true, 50.16 }, { true, 33.44 }, { false, 0 }, { false, 0 },
+ { true, 50.161 }, { true, 83.601 }, { true, 50.16 }, { true, 16.72 },
+ { true, 33.441 }, { false, 16.72 }, { true, 50.16 }, { true, 16.72 },
+ { false, 0.001 }, { true, 33.441 }, { false, 16.72 }, { true, 16.72 },
+ { true, 50.16 }, { false, 0 }, { true, 16.72 }, { true, 33.441 },
+ { false, 0 }, { true, 33.44 }, { false, 16.72 }, { true, 16.72 },
+ { true, 50.161 }, { false, 0 }, { true, 16.72 }, { true, 33.44 },
+ { false, 0 }, { true, 33.44 }, { false, 16.721 }, { true, 16.721 },
+ { true, 50.161 }, { false, 0 }, { true, 16.72 }, { true, 33.441 },
+ { false, 0 }, { true, 33.44 }, { false, 16.72 }, { true, 33.44 },
+ { false, 0 }, { true, 16.721 }, { true, 50.161 }, { false, 0 },
+ { true, 33.44 }, { false, 0 }, { true, 16.72 }, { true, 33.441 },
+ { false, 0 }, { true, 33.44 }, { false, 16.72 }, { true, 16.72 },
+ { true, 50.16 }, { false, 0 }, { true, 16.721 }, { true, 33.44 },
+ { false, 0 }, { true, 33.44 }, { false, 16.721 }, { true, 16.721 },
+ { true, 50.161 }, { false, 0 }, { true, 16.72 }, { true, 33.44 },
+ { false, 0 }, { true, 33.441 }, { false, 16.72 }, { true, 16.72 },
+ { true, 50.16 }, { false, 0 }, { true, 16.72 }, { true, 33.441 },
+ { true, 33.44 }, { false, 0 }, { true, 33.44 }, { true, 33.441 },
+ { false, 0 }, { true, 33.44 }, { true, 33.441 }, { false, 0 },
+ { true, 33.44 }, { false, 0 }, { true, 33.44 }, { false, 16.72 },
+ { true, 16.721 }, { true, 50.161 }, { false, 0 }, { true, 16.72 },
+ { true, 33.44 }, { true, 33.441 }, { false, 0 }, { true, 33.44 },
+ { true, 33.44 }, { false, 0 }, { true, 33.441 }, { false, 16.72 },
+ { true, 16.72 }, { true, 50.16 }, { false, 0 }, { true, 16.72 },
+ { true, 33.441 }, { false, 0 }, { true, 33.44 }, { false, 16.72 },
+ { true, 33.44 }, { false, 0 }, { true, 16.721 }, { true, 50.161 },
+ { false, 0 }, { true, 16.72 }, { true, 33.44 }, { false, 0 },
+ { true, 33.441 }, { false, 16.72 }, { true, 16.72 }, { true, 50.16 }
+ };
+
+ SmoothEventSampler sampler(base::TimeDelta::FromSeconds(1) / 30, true, 3);
+ ReplayCheckingSamplerDecisions(data_points, arraysize(data_points), &sampler);
+}
+
+} // namespace
+} // namespace content
diff --git a/content/browser/renderer_host/media/webrtc_logging_handler_host.cc b/content/browser/renderer_host/media/webrtc_logging_handler_host.cc
new file mode 100644
index 0000000..00d90fd
--- /dev/null
+++ b/content/browser/renderer_host/media/webrtc_logging_handler_host.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/media/webrtc_logging_handler_host.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "content/common/media/webrtc_logging_messages.h"
+
+namespace content {
+
+const size_t kWebRtcLogSize = 6 * 1024 * 1024; // 6 MB
+
+WebRtcLoggingHandlerHost::WebRtcLoggingHandlerHost() {
+}
+
+WebRtcLoggingHandlerHost::~WebRtcLoggingHandlerHost() {
+}
+
+void WebRtcLoggingHandlerHost::OnChannelClosing() {
+ BrowserMessageFilter::OnChannelClosing();
+}
+
+void WebRtcLoggingHandlerHost::OnDestruct() const {
+ BrowserThread::DeleteOnIOThread::Destruct(this);
+}
+
+bool WebRtcLoggingHandlerHost::OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(WebRtcLoggingHandlerHost, message, *message_was_ok)
+ IPC_MESSAGE_HANDLER(WebRtcLoggingMsg_OpenLog, OnOpenLog)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP_EX()
+
+ return handled;
+}
+
+void WebRtcLoggingHandlerHost::OnOpenLog() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(!base::SharedMemory::IsHandleValid(shared_memory_.handle()));
+
+ if (!shared_memory_.CreateAndMapAnonymous(kWebRtcLogSize)) {
+ DLOG(ERROR) << "Failed to create shared memory.";
+ Send(new WebRtcLoggingMsg_OpenLogFailed());
+ return;
+ }
+
+ base::SharedMemoryHandle foreign_memory_handle;
+ if (!shared_memory_.ShareToProcess(peer_handle(),
+ &foreign_memory_handle)) {
+ Send(new WebRtcLoggingMsg_OpenLogFailed());
+ return;
+ }
+
+ Send(new WebRtcLoggingMsg_LogOpened(foreign_memory_handle, kWebRtcLogSize));
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/media/webrtc_logging_handler_host.h b/content/browser/renderer_host/media/webrtc_logging_handler_host.h
new file mode 100644
index 0000000..f3ab4a4
--- /dev/null
+++ b/content/browser/renderer_host/media/webrtc_logging_handler_host.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_WEBRTC_LOGGING_HANDLER_HOST_H_
+#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_WEBRTC_LOGGING_HANDLER_HOST_H_
+
+#include "base/basictypes.h"
+#include "base/shared_memory.h"
+#include "content/public/browser/browser_message_filter.h"
+
+namespace content {
+
+// WebRtcLoggingHandlerHost handles operations regarding the WebRTC logging:
+// opening and closing shared memory buffer that the handler in the renderer
+// process writes to.
+class WebRtcLoggingHandlerHost : public BrowserMessageFilter {
+ public:
+ WebRtcLoggingHandlerHost();
+
+ private:
+ // BrowserMessageFilter implementation.
+ virtual void OnChannelClosing() OVERRIDE;
+ virtual void OnDestruct() const OVERRIDE;
+ virtual bool OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok) OVERRIDE;
+
+ friend class BrowserThread;
+ friend class base::DeleteHelper<WebRtcLoggingHandlerHost>;
+
+ virtual ~WebRtcLoggingHandlerHost();
+
+ void OnOpenLog();
+
+ base::SharedMemory shared_memory_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcLoggingHandlerHost);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_WEBRTC_LOGGING_HANDLER_HOST_H_
diff --git a/content/browser/renderer_host/overscroll_controller.cc b/content/browser/renderer_host/overscroll_controller.cc
index 0b5925a..0a4086a 100644
--- a/content/browser/renderer_host/overscroll_controller.cc
+++ b/content/browser/renderer_host/overscroll_controller.cc
@@ -65,6 +65,10 @@
// Consume the event and update overscroll state when in the middle of the
// overscroll gesture.
ProcessEventForOverscroll(event);
+
+ if (event.type == WebKit::WebInputEvent::TouchEnd ||
+ event.type == WebKit::WebInputEvent::TouchCancel)
+ return true;
return false;
}
diff --git a/content/browser/renderer_host/p2p/socket_dispatcher_host.cc b/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
index 7c79711..36b9210 100644
--- a/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
+++ b/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
@@ -197,7 +197,7 @@
scoped_ptr<P2PSocketHost> socket(
P2PSocketHost::Create(this, socket_id, type));
- if (!socket.get()) {
+ if (!socket) {
Send(new P2PMsg_OnError(socket_id));
return;
}
diff --git a/content/browser/renderer_host/p2p/socket_host.h b/content/browser/renderer_host/p2p/socket_host.h
index 0abb74e..9fe985d 100644
--- a/content/browser/renderer_host/p2p/socket_host.h
+++ b/content/browser/renderer_host/p2p/socket_host.h
@@ -62,15 +62,6 @@
STATE_ERROR,
};
- // Maximum size of send buffers. Must be big enough to fit data for
- // one data burst. Send buffers size needs to be limited to prevent
- // from consuming too much memory with misbehaving renderer process.
- //
- // TODO(sergeyu): Consider implementing congestion notifications to
- // minimize buffering. This will require some fixes in libjingle,
- // see crbug.com/91495 .
- static const int kMaxSendBufferSize = 256 * 1024;
-
P2PSocketHost(IPC::Sender* message_sender, int id);
// Verifies that the packet |data| has a valid STUN header. In case
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp.cc b/content/browser/renderer_host/p2p/socket_host_tcp.cc
index 2409280..de62ffb 100644
--- a/content/browser/renderer_host/p2p/socket_host_tcp.cc
+++ b/content/browser/renderer_host/p2p/socket_host_tcp.cc
@@ -21,6 +21,7 @@
P2PSocketHostTcp::P2PSocketHostTcp(IPC::Sender* message_sender, int id)
: P2PSocketHost(message_sender, id),
+ write_pending_(false),
connected_(false) {
}
@@ -87,10 +88,6 @@
return;
}
- if (!socket_->SetSendBufferSize(kMaxSendBufferSize)) {
- LOG(WARNING) << "Failed to set send buffer size for TCP socket.";
- }
-
net::IPEndPoint address;
result = socket_->GetLocalAddress(&address);
if (result < 0) {
@@ -190,22 +187,14 @@
void P2PSocketHostTcp::Send(const net::IPEndPoint& to,
const std::vector<char>& data) {
- if (!socket_.get()) {
+ if (!socket_) {
// The Send message may be sent after the an OnError message was
// sent by hasn't been processed the renderer.
return;
}
- if (write_buffer_) {
- // Silently drop packet if we haven't finished sending previous
- // packet.
- VLOG(1) << "Dropping TCP packet.";
- return;
- }
-
if (!(to == remote_address_)) {
- // Renderer should use this socket only to send data to
- // |remote_address_|.
+ // Renderer should use this socket only to send data to |remote_address_|.
NOTREACHED();
OnError();
return;
@@ -223,51 +212,56 @@
}
int size = kPacketHeaderSize + data.size();
- write_buffer_ = new net::DrainableIOBuffer(new net::IOBuffer(size), size);
- *reinterpret_cast<uint16*>(write_buffer_->data()) =
- base::HostToNet16(data.size());
- memcpy(write_buffer_->data() + kPacketHeaderSize, &data[0], data.size());
+ scoped_refptr<net::DrainableIOBuffer> buffer =
+ new net::DrainableIOBuffer(new net::IOBuffer(size), size);
+ *reinterpret_cast<uint16*>(buffer->data()) = base::HostToNet16(data.size());
+ memcpy(buffer->data() + kPacketHeaderSize, &data[0], data.size());
+ if (write_buffer_) {
+ write_queue_.push(buffer);
+ return;
+ }
+
+ write_buffer_ = buffer;
DoWrite();
}
void P2PSocketHostTcp::DoWrite() {
- while (true) {
+ while (write_buffer_ && state_ == STATE_OPEN && !write_pending_) {
int result = socket_->Write(write_buffer_, write_buffer_->BytesRemaining(),
base::Bind(&P2PSocketHostTcp::OnWritten,
base::Unretained(this)));
- if (result >= 0) {
- write_buffer_->DidConsume(result);
- if (write_buffer_->BytesRemaining() == 0) {
- write_buffer_ = NULL;
- break;
- }
- } else {
- if (result != net::ERR_IO_PENDING) {
- LOG(ERROR) << "Error when sending data in TCP socket: " << result;
- OnError();
- }
- break;
- }
+ HandleWriteResult(result);
}
}
void P2PSocketHostTcp::OnWritten(int result) {
- DCHECK(write_buffer_);
+ DCHECK(write_pending_);
DCHECK_NE(result, net::ERR_IO_PENDING);
- if (result < 0) {
- DCHECK(result != net::ERR_IO_PENDING);
+ write_pending_ = false;
+ HandleWriteResult(result);
+ DoWrite();
+}
+
+void P2PSocketHostTcp::HandleWriteResult(int result) {
+ DCHECK(write_buffer_);
+ if (result >= 0) {
+ write_buffer_->DidConsume(result);
+ if (write_buffer_->BytesRemaining() == 0) {
+ message_sender_->Send(new P2PMsg_OnSendComplete(id_));
+ if (write_queue_.empty()) {
+ write_buffer_ = NULL;
+ } else {
+ write_buffer_ = write_queue_.front();
+ write_queue_.pop();
+ }
+ }
+ } else if (result == net::ERR_IO_PENDING) {
+ write_pending_ = true;
+ } else {
LOG(ERROR) << "Error when sending data in TCP socket: " << result;
OnError();
- return;
- }
-
- write_buffer_->DidConsume(result);
- if (write_buffer_->BytesRemaining() == 0) {
- write_buffer_ = NULL;
- } else {
- DoWrite();
}
}
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp.h b/content/browser/renderer_host/p2p/socket_host_tcp.h
index 48cc7f9..4fa3fae 100644
--- a/content/browser/renderer_host/p2p/socket_host_tcp.h
+++ b/content/browser/renderer_host/p2p/socket_host_tcp.h
@@ -51,6 +51,7 @@
void OnPacket(std::vector<char>& data);
void DoWrite();
+ void HandleWriteResult(int result);
// Callbacks for Connect(), Read() and Write().
void OnConnected(int result);
@@ -61,7 +62,10 @@
scoped_ptr<net::StreamSocket> socket_;
scoped_refptr<net::GrowableIOBuffer> read_buffer_;
+
+ std::queue<scoped_refptr<net::DrainableIOBuffer> > write_queue_;
scoped_refptr<net::DrainableIOBuffer> write_buffer_;
+ bool write_pending_;
bool connected_;
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp_server.cc b/content/browser/renderer_host/p2p/socket_host_tcp_server.cc
index 206a0e4..113eb4d 100644
--- a/content/browser/renderer_host/p2p/socket_host_tcp_server.cc
+++ b/content/browser/renderer_host/p2p/socket_host_tcp_server.cc
@@ -24,9 +24,9 @@
IPC::Sender* message_sender, int id)
: P2PSocketHost(message_sender, id),
socket_(new net::TCPServerSocket(NULL, net::NetLog::Source())),
- ALLOW_THIS_IN_INITIALIZER_LIST(accept_callback_(
+ accept_callback_(
base::Bind(&P2PSocketHostTcpServer::OnAccepted,
- base::Unretained(this)))) {
+ base::Unretained(this))) {
}
P2PSocketHostTcpServer::~P2PSocketHostTcpServer() {
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc b/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc
index 86e1d97..cc46b2b 100644
--- a/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc
+++ b/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc
@@ -62,6 +62,11 @@
// Verify that we can send STUN message and that they are formatted
// properly.
TEST_F(P2PSocketHostTcpTest, SendStunNoAuth) {
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ .Times(3)
+ .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
+
std::vector<char> packet1;
CreateStunRequest(&packet1);
socket_host_->Send(dest_, packet1);
@@ -88,6 +93,11 @@
// Verify that we can receive STUN messages from the socket, and that
// the messages are parsed properly.
TEST_F(P2PSocketHostTcpTest, ReceiveStun) {
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ .Times(3)
+ .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
+
std::vector<char> packet1;
CreateStunRequest(&packet1);
socket_host_->Send(dest_, packet1);
@@ -152,6 +162,9 @@
received_data.append(IntToSize(request_packet.size()));
received_data.append(request_packet.begin(), request_packet.end());
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
socket_->AppendInputData(&received_data[0], received_data.size());
@@ -168,4 +181,34 @@
EXPECT_EQ(expected_data, sent_data_);
}
+// Verify that asynchronous writes are handled correctly.
+TEST_F(P2PSocketHostTcpTest, AsyncWrites) {
+ base::MessageLoop message_loop;
+
+ socket_->set_async_write(true);
+
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ .Times(2)
+ .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
+
+ std::vector<char> packet1;
+ CreateStunRequest(&packet1);
+ socket_host_->Send(dest_, packet1);
+
+ std::vector<char> packet2;
+ CreateStunResponse(&packet2);
+ socket_host_->Send(dest_, packet2);
+
+ message_loop.RunUntilIdle();
+
+ std::string expected_data;
+ expected_data.append(IntToSize(packet1.size()));
+ expected_data.append(packet1.begin(), packet1.end());
+ expected_data.append(IntToSize(packet2.size()));
+ expected_data.append(packet2.begin(), packet2.end());
+
+ EXPECT_EQ(expected_data, sent_data_);
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/p2p/socket_host_test_utils.h b/content/browser/renderer_host/p2p/socket_host_test_utils.h
index c3deea8..77da0cd 100644
--- a/content/browser/renderer_host/p2p/socket_host_test_utils.h
+++ b/content/browser/renderer_host/p2p/socket_host_test_utils.h
@@ -7,10 +7,13 @@
#include <vector>
+#include "base/location.h"
+#include "base/single_thread_task_runner.h"
#include "base/sys_byteorder.h"
+#include "base/thread_task_runner_handle.h"
#include "content/common/p2p_messages.h"
-#include "ipc/ipc_sender.h"
#include "ipc/ipc_message_utils.h"
+#include "ipc/ipc_sender.h"
#include "net/base/address_list.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
@@ -49,6 +52,7 @@
FakeSocket(std::string* written_data);
virtual ~FakeSocket();
+ void set_async_write(bool async_write) { async_write_ = async_write; }
void AppendInputData(const char* data, int data_size);
int input_pos() const { return input_pos_; }
bool read_pending() const { return read_pending_; }
@@ -73,22 +77,26 @@
virtual void SetOmniboxSpeculation() OVERRIDE;
virtual bool WasEverUsed() const OVERRIDE;
virtual bool UsingTCPFastOpen() const OVERRIDE;
- virtual int64 NumBytesRead() const OVERRIDE;
- virtual base::TimeDelta GetConnectTimeMicros() const OVERRIDE;
virtual bool WasNpnNegotiated() const OVERRIDE;
virtual net::NextProto GetNegotiatedProtocol() const OVERRIDE;
virtual bool GetSSLInfo(net::SSLInfo* ssl_info) OVERRIDE;
private:
+ void DoAsyncWrite(scoped_refptr<net::IOBuffer> buf, int buf_len,
+ const net::CompletionCallback& callback);
+
bool read_pending_;
scoped_refptr<net::IOBuffer> read_buffer_;
int read_buffer_size_;
net::CompletionCallback read_callback_;
- std::string* written_data_;
std::string input_data_;
int input_pos_;
+ std::string* written_data_;
+ bool async_write_;
+ bool write_pending_;
+
net::IPEndPoint peer_address_;
net::IPEndPoint local_address_;
@@ -97,8 +105,10 @@
FakeSocket::FakeSocket(std::string* written_data)
: read_pending_(false),
+ input_pos_(0),
written_data_(written_data),
- input_pos_(0) {
+ async_write_(false),
+ write_pending_(false) {
}
FakeSocket::~FakeSocket() { }
@@ -149,6 +159,17 @@
int FakeSocket::Write(net::IOBuffer* buf, int buf_len,
const net::CompletionCallback& callback) {
DCHECK(buf);
+ DCHECK(!write_pending_);
+
+ if (async_write_) {
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(
+ &FakeSocket::DoAsyncWrite, base::Unretained(this),
+ scoped_refptr<net::IOBuffer>(buf), buf_len, callback));
+ write_pending_ = true;
+ return net::ERR_IO_PENDING;
+ }
+
if (written_data_) {
written_data_->insert(written_data_->end(),
buf->data(), buf->data() + buf_len);
@@ -156,6 +177,16 @@
return buf_len;
}
+void FakeSocket::DoAsyncWrite(scoped_refptr<net::IOBuffer> buf, int buf_len,
+ const net::CompletionCallback& callback) {
+ write_pending_ = false;
+
+ if (written_data_) {
+ written_data_->insert(written_data_->end(),
+ buf->data(), buf->data() + buf_len);
+ }
+ callback.Run(buf_len);
+}
bool FakeSocket::SetReceiveBufferSize(int32 size) {
NOTIMPLEMENTED();
@@ -213,14 +244,6 @@
return false;
}
-int64 FakeSocket::NumBytesRead() const {
- return -1;
-}
-
-base::TimeDelta FakeSocket::GetConnectTimeMicros() const {
- return base::TimeDelta::FromMicroseconds(-1);
-}
-
bool FakeSocket::WasNpnNegotiated() const {
return false;
}
diff --git a/content/browser/renderer_host/p2p/socket_host_udp.cc b/content/browser/renderer_host/p2p/socket_host_udp.cc
index b84ee68..402898c 100644
--- a/content/browser/renderer_host/p2p/socket_host_udp.cc
+++ b/content/browser/renderer_host/p2p/socket_host_udp.cc
@@ -5,6 +5,7 @@
#include "content/browser/renderer_host/p2p/socket_host_udp.h"
#include "base/bind.h"
+#include "base/debug/trace_event.h"
#include "content/common/p2p_messages.h"
#include "ipc/ipc_sender.h"
#include "net/base/io_buffer.h"
@@ -17,11 +18,23 @@
const int kReadBufferSize = 65536;
// Defines set of transient errors. These errors are ignored when we get them
-// from sendto() calls.
+// from sendto() or recvfrom() calls.
+//
+// net::ERR_OUT_OF_MEMORY
+//
+// This is caused by ENOBUFS which means the buffer of the network interface
+// is full.
+//
+// net::ERR_CONNECTION_RESET
+//
+// This is caused by WSAENETRESET or WSAECONNRESET which means the
+// last send resulted in an "ICMP Port Unreachable" message.
bool IsTransientError(int error) {
return error == net::ERR_ADDRESS_UNREACHABLE ||
error == net::ERR_ADDRESS_INVALID ||
- error == net::ERR_ACCESS_DENIED;
+ error == net::ERR_ACCESS_DENIED ||
+ error == net::ERR_CONNECTION_RESET ||
+ error == net::ERR_OUT_OF_MEMORY;
}
} // namespace
@@ -42,7 +55,6 @@
P2PSocketHostUdp::P2PSocketHostUdp(IPC::Sender* message_sender, int id)
: P2PSocketHost(message_sender, id),
socket_(new net::UDPServerSocket(NULL, net::NetLog::Source())),
- send_queue_bytes_(0),
send_pending_(false) {
}
@@ -102,18 +114,18 @@
base::Unretained(this)));
if (result == net::ERR_IO_PENDING)
return;
- DidCompleteRead(result);
+ HandleReadResult(result);
} while (state_ == STATE_OPEN);
}
void P2PSocketHostUdp::OnRecv(int result) {
- DidCompleteRead(result);
+ HandleReadResult(result);
if (state_ == STATE_OPEN) {
DoRead();
}
}
-void P2PSocketHostUdp::DidCompleteRead(int result) {
+void P2PSocketHostUdp::HandleReadResult(int result) {
DCHECK_EQ(state_, STATE_OPEN);
if (result > 0) {
@@ -141,7 +153,7 @@
void P2PSocketHostUdp::Send(const net::IPEndPoint& to,
const std::vector<char>& data) {
- if (!socket_.get()) {
+ if (!socket_) {
// The Send message may be sent after the an OnError message was
// sent by hasn't been processed the renderer.
return;
@@ -159,13 +171,7 @@
}
if (send_pending_) {
- if (send_queue_bytes_ + static_cast<int>(data.size()) >
- kMaxSendBufferSize) {
- LOG(WARNING) << "Send buffer is full. Dropping a packet.";
- return;
- }
send_queue_.push_back(PendingPacket(to, data));
- send_queue_bytes_ += data.size();
} else {
PendingPacket packet(to, data);
DoSend(packet);
@@ -173,6 +179,8 @@
}
void P2PSocketHostUdp::DoSend(const PendingPacket& packet) {
+ TRACE_EVENT_ASYNC_BEGIN2("p2p", "Udp::DoSend", this,
+ "id", id_, "size", packet.size);
int result = socket_->SendTo(packet.data, packet.size, packet.to,
base::Bind(&P2PSocketHostUdp::OnSend,
base::Unretained(this)));
@@ -188,12 +196,8 @@
if (result == net::ERR_IO_PENDING) {
send_pending_ = true;
- } else if (IsTransientError(result)) {
- LOG(INFO) << "sendto() has failed twice returning a "
- " transient error. Dropping the packet.";
- } else if (result < 0) {
- LOG(ERROR) << "Error when sending data in UDP socket: " << result;
- OnError();
+ } else {
+ HandleSendResult(result);
}
}
@@ -203,19 +207,28 @@
send_pending_ = false;
- if (result < 0 && !IsTransientError(result)) {
- OnError();
- return;
- }
+ HandleSendResult(result);
// Send next packets if we have them waiting in the buffer.
- while (!send_queue_.empty() && !send_pending_) {
+ while (state_ == STATE_OPEN && !send_queue_.empty() && !send_pending_) {
DoSend(send_queue_.front());
- send_queue_bytes_ -= send_queue_.front().size;
send_queue_.pop_front();
}
}
+void P2PSocketHostUdp::HandleSendResult(int result) {
+ TRACE_EVENT_ASYNC_END1("p2p", "Udp::DoSend", this, "result", result);
+ if (result > 0) {
+ message_sender_->Send(new P2PMsg_OnSendComplete(id_));
+ } else if (IsTransientError(result)) {
+ LOG(INFO) << "sendto() has failed twice returning a "
+ " transient error. Dropping the packet.";
+ } else if (result < 0) {
+ LOG(ERROR) << "Error when sending data in UDP socket: " << result;
+ OnError();
+ }
+}
+
P2PSocketHost* P2PSocketHostUdp::AcceptIncomingTcpConnection(
const net::IPEndPoint& remote_address, int id) {
NOTREACHED();
diff --git a/content/browser/renderer_host/p2p/socket_host_udp.h b/content/browser/renderer_host/p2p/socket_host_udp.h
index 710f743..2b83c97 100644
--- a/content/browser/renderer_host/p2p/socket_host_udp.h
+++ b/content/browser/renderer_host/p2p/socket_host_udp.h
@@ -48,20 +48,20 @@
};
void OnError();
- void DoRead();
- void DoSend(const PendingPacket& packet);
- void DidCompleteRead(int result);
- // Callbacks for RecvFrom() and SendTo().
+ void DoRead();
void OnRecv(int result);
+ void HandleReadResult(int result);
+
+ void DoSend(const PendingPacket& packet);
void OnSend(int result);
+ void HandleSendResult(int result);
scoped_ptr<net::DatagramServerSocket> socket_;
scoped_refptr<net::IOBuffer> recv_buffer_;
net::IPEndPoint recv_address_;
std::deque<PendingPacket> send_queue_;
- int send_queue_bytes_;
bool send_pending_;
// Set of peer for which we have received STUN binding request or
diff --git a/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc b/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
index 5a5f15a..d7a3bec 100644
--- a/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
+++ b/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
@@ -164,6 +164,11 @@
// Verify that we can send STUN messages before we receive anything
// from the other side.
TEST_F(P2PSocketHostUdpTest, SendStunNoAuth) {
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ .Times(3)
+ .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
+
std::vector<char> packet1;
CreateStunRequest(&packet1);
socket_host_->Send(dest1_, packet1);
@@ -208,6 +213,9 @@
socket_->ReceivePacket(dest1_, request_packet);
// Now we should be able to send any data to |dest1_|.
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
std::vector<char> packet;
CreateRandomPacket(&packet);
socket_host_->Send(dest1_, packet);
@@ -228,6 +236,9 @@
socket_->ReceivePacket(dest1_, request_packet);
// Now we should be able to send any data to |dest1_|.
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
std::vector<char> packet;
CreateRandomPacket(&packet);
socket_host_->Send(dest1_, packet);
diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc
index ff4284a..4fcbcf2 100644
--- a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc
+++ b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc
@@ -21,15 +21,14 @@
IPC::ChannelProxy* channel,
net::HostResolver* host_resolver,
int render_process_id,
- int render_view_id) {
- // TODO(raymes): Figure out how to plumb plugin_name and
- // profile_data_directory through for NaCl. They are currently only needed for
- // PPB_Flash_File interfaces so it doesn't matter.
+ int render_view_id,
+ const base::FilePath& profile_directory) {
+ // TODO(raymes): Figure out how to plumb plugin_name through for NaCl. It is
+ // currently only needed for PPB_Flash_File interfaces so it doesn't matter.
std::string plugin_name;
- base::FilePath profile_data_directory;
BrowserPpapiHostImpl* browser_ppapi_host =
new BrowserPpapiHostImpl(sender, permissions, plugin_name,
- profile_data_directory,
+ profile_directory,
true);
browser_ppapi_host->set_plugin_process_handle(plugin_child_process);
diff --git a/content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.cc b/content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.cc
index 02ae2a8..99a8e04 100644
--- a/content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.cc
+++ b/content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.cc
@@ -46,9 +46,12 @@
scoped_refptr<base::TaskRunner> FontMessageFilter::OverrideTaskRunnerForMessage(
const IPC::Message& msg) {
- // Use the blocking pool to get the font list (currently the only message
- // so we can always just return it).
- return scoped_refptr<base::TaskRunner>(BrowserThread::GetBlockingPool());
+ // Use the blocking pool to get the font list (currently the only message)
+ // Since getting the font list is non-threadsafe on Linux (for versions of
+ // Pango predating 2013), use a sequenced task runner.
+ base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
+ return pool->GetSequencedTaskRunner(
+ pool->GetNamedSequenceToken(kFontListSequenceToken));
}
int32_t FontMessageFilter::OnResourceMessageReceived(
diff --git a/content/browser/renderer_host/pepper/pepper_gamepad_host.cc b/content/browser/renderer_host/pepper/pepper_gamepad_host.cc
index 1edb1ba..818bf24 100644
--- a/content/browser/renderer_host/pepper/pepper_gamepad_host.cc
+++ b/content/browser/renderer_host/pepper/pepper_gamepad_host.cc
@@ -23,7 +23,7 @@
browser_ppapi_host_(host),
gamepad_service_(GamepadService::GetInstance()),
is_started_(false),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ weak_factory_(this) {
}
PepperGamepadHost::PepperGamepadHost(GamepadService* gamepad_service,
@@ -34,7 +34,7 @@
browser_ppapi_host_(host),
gamepad_service_(gamepad_service),
is_started_(false),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ weak_factory_(this) {
}
PepperGamepadHost::~PepperGamepadHost() {
diff --git a/content/browser/renderer_host/pepper/pepper_host_resolver_private_message_filter.cc b/content/browser/renderer_host/pepper/pepper_host_resolver_private_message_filter.cc
index d42cb56..ba27bf4 100644
--- a/content/browser/renderer_host/pepper/pepper_host_resolver_private_message_filter.cc
+++ b/content/browser/renderer_host/pepper/pepper_host_resolver_private_message_filter.cc
@@ -122,9 +122,9 @@
// Check plugin permissions.
SocketPermissionRequest request(
- content::SocketPermissionRequest::NONE, "", 0);
- RenderViewHost* render_view_host = RenderViewHost::FromID(render_process_id_,
- render_view_id_);
+ content::SocketPermissionRequest::TCP_CONNECT, std::string(), 0);
+ RenderViewHost* render_view_host =
+ RenderViewHost::FromID(render_process_id_, render_view_id_);
if (!render_view_host ||
!pepper_socket_utils::CanUseSocketAPIs(external_plugin_,
request,
diff --git a/content/browser/renderer_host/pepper/pepper_message_filter.cc b/content/browser/renderer_host/pepper/pepper_message_filter.cc
index 069678c..95fe84d 100644
--- a/content/browser/renderer_host/pepper/pepper_message_filter.cc
+++ b/content/browser/renderer_host/pepper/pepper_message_filter.cc
@@ -30,9 +30,9 @@
#include "content/public/common/content_client.h"
#include "net/base/address_family.h"
#include "net/base/address_list.h"
-#include "net/base/cert_verifier.h"
#include "net/base/host_port_pair.h"
#include "net/base/sys_addrinfo.h"
+#include "net/cert/cert_verifier.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/ppb_net_address_private.h"
#include "ppapi/proxy/ppapi_messages.h"
@@ -154,7 +154,7 @@
}
net::CertVerifier* PepperMessageFilter::GetCertVerifier() {
- if (!cert_verifier_.get())
+ if (!cert_verifier_)
cert_verifier_.reset(net::CertVerifier::CreateDefault());
return cert_verifier_.get();
diff --git a/content/browser/renderer_host/pepper/pepper_printing_host.cc b/content/browser/renderer_host/pepper/pepper_printing_host.cc
index 959d589..c11939c 100644
--- a/content/browser/renderer_host/pepper/pepper_printing_host.cc
+++ b/content/browser/renderer_host/pepper/pepper_printing_host.cc
@@ -20,7 +20,7 @@
scoped_ptr<PepperPrintSettingsManager> print_settings_manager)
: ResourceHost(host, instance, resource),
print_settings_manager_(print_settings_manager.Pass()),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ weak_factory_(this) {
}
PepperPrintingHost::~PepperPrintingHost() {
diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket.cc b/content/browser/renderer_host/pepper/pepper_tcp_socket.cc
index e6732e5..3638898 100644
--- a/content/browser/renderer_host/pepper/pepper_tcp_socket.cc
+++ b/content/browser/renderer_host/pepper/pepper_tcp_socket.cc
@@ -13,12 +13,12 @@
#include "base/string_util.h"
#include "content/browser/renderer_host/pepper/pepper_message_filter.h"
#include "content/public/browser/browser_thread.h"
-#include "net/base/cert_verifier.h"
#include "net/base/host_port_pair.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
-#include "net/base/x509_certificate.h"
+#include "net/cert/cert_verifier.h"
+#include "net/cert/x509_certificate.h"
#include "net/dns/host_resolver.h"
#include "net/dns/single_request_host_resolver.h"
#include "net/socket/client_socket_factory.h"
@@ -66,7 +66,7 @@
PepperTCPSocket::~PepperTCPSocket() {
// Make sure no further callbacks from socket_.
- if (socket_.get())
+ if (socket_)
socket_->Disconnect();
}
@@ -140,7 +140,7 @@
ssl_context.cert_verifier = manager_->GetCertVerifier();
socket_.reset(factory->CreateSSLClientSocket(
handle, host_port_pair, manager_->ssl_config(), ssl_context));
- if (!socket_.get()) {
+ if (!socket_) {
LOG(WARNING) << "Failed to create an SSL client socket.";
OnSSLHandshakeCompleted(net::ERR_UNEXPECTED);
return;
@@ -291,7 +291,7 @@
ppapi::PPB_X509Certificate_Fields* fields) {
scoped_refptr<net::X509Certificate> cert =
net::X509Certificate::CreateFromBytes(der, length);
- if (!cert.get())
+ if (!cert)
return false;
return GetCertificateFields(*cert, fields);
}
@@ -314,7 +314,7 @@
static_cast<net::SSLClientSocket*>(socket_.get());
net::SSLInfo ssl_info;
ssl_socket->GetSSLInfo(&ssl_info);
- if (ssl_info.cert.get())
+ if (ssl_info.cert)
GetCertificateFields(*ssl_info.cert, &certificate_fields);
}
manager_->Send(new PpapiMsg_PPBTCPSocket_SSLHandshakeACK(
diff --git a/content/browser/renderer_host/pepper/pepper_truetype_font_list.h b/content/browser/renderer_host/pepper/pepper_truetype_font_list.h
index c0ce782..da944c5 100644
--- a/content/browser/renderer_host/pepper/pepper_truetype_font_list.h
+++ b/content/browser/renderer_host/pepper/pepper_truetype_font_list.h
@@ -8,6 +8,12 @@
#include <string>
#include <vector>
+namespace ppapi {
+namespace proxy {
+struct SerializedTrueTypeFontDesc;
+}
+}
+
namespace content {
// Adds font family names on the host platform to the vector of strings.
@@ -16,6 +22,15 @@
// sure not to call this on a time-critical thread like the UI or I/O threads.
void GetFontFamilies_SlowBlocking(std::vector<std::string>* font_families);
+// Adds font descriptors for fonts on the host platform in the given family to
+// the vector of descriptors.
+//
+// This function is potentially slow (the system may do a bunch of I/O) so be
+// sure not to call this on a time-critical thread like the UI or I/O threads.
+void GetFontsInFamily_SlowBlocking(
+ const std::string& family,
+ std::vector<ppapi::proxy::SerializedTrueTypeFontDesc>* fonts_in_family);
+
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TRUETYPE_FONT_LIST_H_
diff --git a/content/browser/renderer_host/pepper/pepper_truetype_font_list_android.cc b/content/browser/renderer_host/pepper/pepper_truetype_font_list_android.cc
index 7a8880a..28db24f 100644
--- a/content/browser/renderer_host/pepper/pepper_truetype_font_list_android.cc
+++ b/content/browser/renderer_host/pepper/pepper_truetype_font_list_android.cc
@@ -11,4 +11,10 @@
NOTIMPLEMENTED(); // Font API isn't implemented on Android.
}
+void GetFontsInFamily_SlowBlocking(
+ const std::string& family,
+ std::vector<ppapi::proxy::SerializedTrueTypeFontDesc>* fonts_in_family) {
+ NOTIMPLEMENTED(); // Font API isn't implemented on Android.
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.cc b/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.cc
index 74e8653..1b2aa66 100644
--- a/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.cc
+++ b/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.cc
@@ -9,6 +9,7 @@
#include "base/safe_numerics.h"
#include "base/threading/sequenced_worker_pool.h"
#include "content/browser/renderer_host/pepper/pepper_truetype_font_list.h"
+#include "content/common/font_list.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/browser_thread.h"
#include "ppapi/host/dispatch_host_message.h"
@@ -35,8 +36,10 @@
private:
virtual ~FontMessageFilter();
- // Message handler.
+ // Message handlers.
int32_t OnHostMsgGetFontFamilies(ppapi::host::HostMessageContext* context);
+ int32_t OnHostMsgGetFontsInFamily(ppapi::host::HostMessageContext* context,
+ const std::string& family);
DISALLOW_COPY_AND_ASSIGN(FontMessageFilter);
};
@@ -49,9 +52,12 @@
scoped_refptr<base::TaskRunner> FontMessageFilter::OverrideTaskRunnerForMessage(
const IPC::Message& msg) {
- // Use the blocking pool to get the font list (currently the only message
- // so we can always just return it).
- return scoped_refptr<base::TaskRunner>(BrowserThread::GetBlockingPool());
+ // Use the blocking pool to get the font list (currently the only message)
+ // Since getting the font list is non-threadsafe on Linux (for versions of
+ // Pango predating 2013), use a sequenced task runner.
+ base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
+ return pool->GetSequencedTaskRunner(
+ pool->GetNamedSequenceToken(kFontListSequenceToken));
}
int32_t FontMessageFilter::OnResourceMessageReceived(
@@ -61,6 +67,9 @@
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
PpapiHostMsg_TrueTypeFontSingleton_GetFontFamilies,
OnHostMsgGetFontFamilies)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(
+ PpapiHostMsg_TrueTypeFontSingleton_GetFontsInFamily,
+ OnHostMsgGetFontsInFamily)
IPC_END_MESSAGE_MAP()
return PP_ERROR_FAILED;
}
@@ -82,6 +91,23 @@
return result;
}
+int32_t FontMessageFilter::OnHostMsgGetFontsInFamily(
+ ppapi::host::HostMessageContext* context,
+ const std::string& family) {
+ // OK to use "slow blocking" version since we're on the blocking pool.
+ std::vector<ppapi::proxy::SerializedTrueTypeFontDesc> fonts_in_family;
+ GetFontsInFamily_SlowBlocking(family, &fonts_in_family);
+
+ int32_t result = base::checked_numeric_cast<int32_t>(fonts_in_family.size());
+ ppapi::host::ReplyMessageContext reply_context =
+ context->MakeReplyMessageContext();
+ reply_context.params.set_result(result);
+ context->reply_msg =
+ PpapiPluginMsg_TrueTypeFontSingleton_GetFontsInFamilyReply(
+ fonts_in_family);
+ return result;
+}
+
} // namespace
PepperTrueTypeFontListHost::PepperTrueTypeFontListHost(
diff --git a/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.h b/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.h
index c67553b..69a471b 100644
--- a/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.h
+++ b/content/browser/renderer_host/pepper/pepper_truetype_font_list_host.h
@@ -15,8 +15,8 @@
class PepperTrueTypeFontListHost : public ppapi::host::ResourceHost {
public:
PepperTrueTypeFontListHost(BrowserPpapiHost* host,
- PP_Instance instance,
- PP_Resource resource);
+ PP_Instance instance,
+ PP_Resource resource);
virtual ~PepperTrueTypeFontListHost();
private:
diff --git a/content/browser/renderer_host/pepper/pepper_truetype_font_list_linux.cc b/content/browser/renderer_host/pepper/pepper_truetype_font_list_linux.cc
index 661266d..24c3f5d 100644
--- a/content/browser/renderer_host/pepper/pepper_truetype_font_list_linux.cc
+++ b/content/browser/renderer_host/pepper/pepper_truetype_font_list_linux.cc
@@ -9,6 +9,8 @@
#include <string>
+#include "ppapi/proxy/serialized_structs.h"
+
namespace content {
void GetFontFamilies_SlowBlocking(std::vector<std::string>* font_families) {
@@ -17,9 +19,46 @@
int num_families = 0;
::pango_font_map_list_families(font_map, &families, &num_families);
- for (int i = 0; i < num_families; i++)
+ for (int i = 0; i < num_families; ++i)
font_families->push_back(::pango_font_family_get_name(families[i]));
g_free(families);
}
+void GetFontsInFamily_SlowBlocking(
+ const std::string& family,
+ std::vector<ppapi::proxy::SerializedTrueTypeFontDesc>* fonts_in_family) {
+ PangoFontMap* font_map = ::pango_cairo_font_map_get_default();
+ PangoFontFamily** font_families = NULL;
+ int num_families = 0;
+ ::pango_font_map_list_families(font_map, &font_families, &num_families);
+
+ for (int i = 0; i < num_families; ++i) {
+ PangoFontFamily* font_family = font_families[i];
+ if (family.compare(::pango_font_family_get_name(font_family)) == 0) {
+ PangoFontFace** font_faces = NULL;
+ int num_faces = 0;
+ ::pango_font_family_list_faces(font_family, &font_faces, &num_faces);
+
+ for (int j = 0; j < num_faces; ++j) {
+ PangoFontFace* font_face = font_faces[j];
+ PangoFontDescription* font_desc = ::pango_font_face_describe(font_face);
+ ppapi::proxy::SerializedTrueTypeFontDesc desc;
+ desc.family = family;
+ if (::pango_font_description_get_style(font_desc) == PANGO_STYLE_ITALIC)
+ desc.style = PP_TRUETYPEFONTSTYLE_ITALIC;
+ desc.weight = static_cast<PP_TrueTypeFontWeight_Dev>(
+ ::pango_font_description_get_weight(font_desc));
+ desc.width = static_cast<PP_TrueTypeFontWidth_Dev>(
+ ::pango_font_description_get_stretch(font_desc));
+ // Character set is not part of Pango font description.
+ desc.charset = PP_TRUETYPEFONTCHARSET_DEFAULT;
+
+ fonts_in_family->push_back(desc);
+ }
+ g_free(font_faces);
+ }
+ }
+ g_free(font_families);
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/pepper/pepper_truetype_font_list_mac.mm b/content/browser/renderer_host/pepper/pepper_truetype_font_list_mac.mm
index 9b79e66..7615723 100644
--- a/content/browser/renderer_host/pepper/pepper_truetype_font_list_mac.mm
+++ b/content/browser/renderer_host/pepper/pepper_truetype_font_list_mac.mm
@@ -7,10 +7,33 @@
#import <Cocoa/Cocoa.h>
#include "base/mac/scoped_nsautorelease_pool.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
+#include "ppapi/c/dev/ppb_truetype_font_dev.h"
+#include "ppapi/proxy/serialized_structs.h"
namespace content {
+namespace {
+
+// Table to map AppKit weights to Pepper ones.
+const PP_TrueTypeFontWeight_Dev kPepperFontWeights[] = {
+ PP_TRUETYPEFONTWEIGHT_THIN, // 0 is the minimum AppKit weight.
+ PP_TRUETYPEFONTWEIGHT_ULTRALIGHT,
+ PP_TRUETYPEFONTWEIGHT_ULTRALIGHT,
+ PP_TRUETYPEFONTWEIGHT_LIGHT,
+ PP_TRUETYPEFONTWEIGHT_LIGHT,
+ PP_TRUETYPEFONTWEIGHT_NORMAL, // 5 is a 'normal' AppKit weight.
+ PP_TRUETYPEFONTWEIGHT_MEDIUM,
+ PP_TRUETYPEFONTWEIGHT_MEDIUM,
+ PP_TRUETYPEFONTWEIGHT_SEMIBOLD,
+ PP_TRUETYPEFONTWEIGHT_BOLD, // 9 is a 'bold' AppKit weight.
+ PP_TRUETYPEFONTWEIGHT_ULTRABOLD,
+ PP_TRUETYPEFONTWEIGHT_HEAVY,
+};
+const NSInteger kPepperFontWeightsLength = arraysize(kPepperFontWeights);
+
+} // namespace
+
void GetFontFamilies_SlowBlocking(std::vector<std::string>* font_families) {
base::mac::ScopedNSAutoreleasePool autorelease_pool;
NSFontManager* fontManager = [[[NSFontManager alloc] init] autorelease];
@@ -20,4 +43,40 @@
font_families->push_back(base::SysNSStringToUTF8(family_name));
}
+void GetFontsInFamily_SlowBlocking(
+ const std::string& family,
+ std::vector<ppapi::proxy::SerializedTrueTypeFontDesc>* fonts_in_family) {
+ base::mac::ScopedNSAutoreleasePool autorelease_pool;
+ NSFontManager* fontManager = [[[NSFontManager alloc] init] autorelease];
+ NSString* ns_family = base::SysUTF8ToNSString(family);
+ NSArray* ns_fonts_in_family =
+ [fontManager availableMembersOfFontFamily:ns_family];
+
+ for (NSArray* font_info in ns_fonts_in_family) {
+ ppapi::proxy::SerializedTrueTypeFontDesc desc;
+ desc.family = family;
+ NSInteger font_weight = [[font_info objectAtIndex:2] intValue];
+ font_weight = std::max(static_cast<NSInteger>(0), font_weight);
+ font_weight = std::min(kPepperFontWeightsLength - 1, font_weight);
+ desc.weight = kPepperFontWeights[font_weight];
+
+ NSFontTraitMask font_traits =
+ [[font_info objectAtIndex:3] unsignedIntValue];
+ desc.style = PP_TRUETYPEFONTSTYLE_NORMAL;
+ if (font_traits & NSItalicFontMask)
+ desc.style = PP_TRUETYPEFONTSTYLE_ITALIC;
+
+ desc.width = PP_TRUETYPEFONTWIDTH_NORMAL;
+ if (font_traits & NSCondensedFontMask)
+ desc.width = PP_TRUETYPEFONTWIDTH_CONDENSED;
+ else if (font_traits & NSExpandedFontMask)
+ desc.width = PP_TRUETYPEFONTWIDTH_EXPANDED;
+
+ // Mac doesn't support requesting non-default character sets.
+ desc.charset = PP_TRUETYPEFONTCHARSET_DEFAULT;
+
+ fonts_in_family->push_back(desc);
+ }
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/pepper/pepper_truetype_font_list_win.cc b/content/browser/renderer_host/pepper/pepper_truetype_font_list_win.cc
index 6a3ee0f..37dff9b 100644
--- a/content/browser/renderer_host/pepper/pepper_truetype_font_list_win.cc
+++ b/content/browser/renderer_host/pepper/pepper_truetype_font_list_win.cc
@@ -8,17 +8,21 @@
#include "base/utf_string_conversions.h"
#include "base/win/scoped_hdc.h"
+#include "ppapi/c/dev/ppb_truetype_font_dev.h"
+#include "ppapi/proxy/serialized_structs.h"
namespace content {
namespace {
-static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW* logical_font,
- NEWTEXTMETRICEXW* physical_font,
- DWORD font_type,
- LPARAM lparam) {
- std::vector<std::string>* font_families =
- reinterpret_cast<std::vector<std::string>*>(lparam);
+typedef std::vector<std::string> FontFamilyList;
+typedef std::vector<ppapi::proxy::SerializedTrueTypeFontDesc> FontDescList;
+
+static int CALLBACK EnumFontFamiliesProc(ENUMLOGFONTEXW* logical_font,
+ NEWTEXTMETRICEXW* physical_font,
+ DWORD font_type,
+ LPARAM lparam) {
+ FontFamilyList* font_families = reinterpret_cast<FontFamilyList*>(lparam);
if (font_families) {
const LOGFONTW& lf = logical_font->elfLogFont;
if (lf.lfFaceName[0] && lf.lfFaceName[0] != '@' &&
@@ -30,15 +34,50 @@
return 1;
}
+static int CALLBACK EnumFontsInFamilyProc(ENUMLOGFONTEXW* logical_font,
+ NEWTEXTMETRICEXW* physical_font,
+ DWORD font_type,
+ LPARAM lparam) {
+ FontDescList* fonts_in_family = reinterpret_cast<FontDescList*>(lparam);
+ if (fonts_in_family) {
+ const LOGFONTW& lf = logical_font->elfLogFont;
+ if (lf.lfFaceName[0] && lf.lfFaceName[0] != '@' &&
+ lf.lfOutPrecision == OUT_STROKE_PRECIS) { // Outline fonts only.
+ ppapi::proxy::SerializedTrueTypeFontDesc desc;
+ desc.family = UTF16ToUTF8(lf.lfFaceName);
+ if (lf.lfItalic)
+ desc.style = PP_TRUETYPEFONTSTYLE_ITALIC;
+ desc.weight = static_cast<PP_TrueTypeFontWeight_Dev>(lf.lfWeight);
+ desc.width = PP_TRUETYPEFONTWIDTH_NORMAL; // TODO(bbudge) support widths.
+ desc.charset =
+ static_cast<PP_TrueTypeFontCharset_Dev>(lf.lfCharSet);
+ fonts_in_family->push_back(desc);
+ }
+ }
+ return 1;
+}
+
} // namespace
-void GetFontFamilies_SlowBlocking(std::vector<std::string>* font_families) {
+void GetFontFamilies_SlowBlocking(FontFamilyList* font_families) {
LOGFONTW logfont;
memset(&logfont, 0, sizeof(logfont));
logfont.lfCharSet = DEFAULT_CHARSET;
- base::win::ScopedCreateDC hdc(::GetDC(NULL));
- ::EnumFontFamiliesExW(hdc, &logfont, (FONTENUMPROCW)&EnumFontFamExProc,
+ base::win::ScopedCreateDC hdc(::CreateCompatibleDC(NULL));
+ ::EnumFontFamiliesExW(hdc, &logfont, (FONTENUMPROCW)&EnumFontFamiliesProc,
(LPARAM)font_families, 0);
}
+void GetFontsInFamily_SlowBlocking(const std::string& family,
+ FontDescList* fonts_in_family) {
+ LOGFONTW logfont;
+ memset(&logfont, 0, sizeof(logfont));
+ logfont.lfCharSet = DEFAULT_CHARSET;
+ string16 family16 = UTF8ToUTF16(family);
+ memcpy(&logfont.lfFaceName, &family16[0], sizeof(logfont.lfFaceName));
+ base::win::ScopedCreateDC hdc(::CreateCompatibleDC(NULL));
+ ::EnumFontFamiliesExW(hdc, &logfont, (FONTENUMPROCW)&EnumFontsInFamilyProc,
+ (LPARAM)fonts_in_family, 0);
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc b/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc
index 08384e7..e6563cf 100644
--- a/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc
+++ b/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc
@@ -165,7 +165,7 @@
if (closed_)
return PP_ERROR_FAILED;
- if (recvfrom_buffer_.get())
+ if (recvfrom_buffer_)
return PP_ERROR_INPROGRESS;
if (num_bytes > ppapi::proxy::UDPSocketPrivateResource::kMaxReadSize) {
// |num_bytes| value is checked on the plugin side.
@@ -263,7 +263,7 @@
return;
}
- if (sendto_buffer_.get()) {
+ if (sendto_buffer_) {
SendSendToError(context, PP_ERROR_INPROGRESS);
return;
}
@@ -380,7 +380,9 @@
void PepperUDPSocketPrivateMessageFilter::SendRecvFromError(
const ppapi::host::ReplyMessageContext& context,
int32_t result) {
- SendRecvFromReply(context, result, "",
+ SendRecvFromReply(context,
+ result,
+ std::string(),
NetAddressPrivateImpl::kInvalidNetAddress);
}
diff --git a/content/browser/renderer_host/popup_menu_helper_mac.mm b/content/browser/renderer_host/popup_menu_helper_mac.mm
index c46d568..4e6d1a1 100644
--- a/content/browser/renderer_host/popup_menu_helper_mac.mm
+++ b/content/browser/renderer_host/popup_menu_helper_mac.mm
@@ -53,7 +53,8 @@
{
// Make sure events can be pumped while the menu is up.
- MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
+ base::MessageLoop::ScopedNestableTaskAllower allow(
+ base::MessageLoop::current());
// One of the events that could be pumped is |window.close()|.
// User-initiated event-tracking loops protect against this by
diff --git a/content/browser/renderer_host/quota_dispatcher_host.cc b/content/browser/renderer_host/quota_dispatcher_host.cc
index 9ba96d2..fd297e7 100644
--- a/content/browser/renderer_host/quota_dispatcher_host.cc
+++ b/content/browser/renderer_host/quota_dispatcher_host.cc
@@ -60,11 +60,11 @@
QuotaDispatcherHost* dispatcher_host,
int request_id)
: RequestDispatcher(dispatcher_host, request_id),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {}
+ weak_factory_(this) {}
virtual ~QueryUsageAndQuotaDispatcher() {}
void QueryStorageUsageAndQuota(const GURL& origin, StorageType type) {
- quota_manager()->GetUsageAndQuota(
+ quota_manager()->GetUsageAndQuotaForWebApps(
origin, type,
base::Bind(&QueryUsageAndQuotaDispatcher::DidQueryStorageUsageAndQuota,
weak_factory_.GetWeakPtr()));
@@ -104,19 +104,20 @@
current_quota_(0),
requested_quota_(requested_quota),
render_view_id_(render_view_id),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {}
+ weak_factory_(this) {}
virtual ~RequestQuotaDispatcher() {}
void Start() {
DCHECK(type_ == quota::kStorageTypeTemporary ||
- type_ == quota::kStorageTypePersistent);
+ type_ == quota::kStorageTypePersistent ||
+ type_ == quota::kStorageTypeSyncable);
if (type_ == quota::kStorageTypePersistent) {
quota_manager()->GetPersistentHostQuota(
host_,
base::Bind(&self_type::DidGetHostQuota,
weak_factory_.GetWeakPtr(), host_, type_));
} else {
- quota_manager()->GetUsageAndQuota(
+ quota_manager()->GetUsageAndQuotaForWebApps(
origin_, type_,
base::Bind(&self_type::DidGetTemporaryUsageAndQuota,
weak_factory_.GetWeakPtr()));
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc
index 8e2f45a..9bea24c 100644
--- a/content/browser/renderer_host/render_message_filter.cc
+++ b/content/browser/renderer_host/render_message_filter.cc
@@ -12,7 +12,7 @@
#include "base/debug/alias.h"
#include "base/file_util.h"
#include "base/process_util.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread.h"
#include "base/threading/worker_pool.h"
#include "base/utf_string_conversions.h"
@@ -83,6 +83,9 @@
#include "content/browser/renderer_host/backing_store_win.h"
#include "content/common/font_cache_dispatcher_win.h"
#endif
+#if defined(OS_ANDROID)
+#include "media/base/android/webaudio_media_codec_bridge.h"
+#endif
using net::CookieStore;
@@ -411,9 +414,12 @@
OnGetAudioHardwareConfig)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetMonitorColorProfile,
OnGetMonitorColorProfile)
- IPC_MESSAGE_HANDLER(ViewHostMsg_MediaLogEvent, OnMediaLogEvent)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_MediaLogEvents, OnMediaLogEvents)
IPC_MESSAGE_HANDLER(ViewHostMsg_Are3DAPIsBlocked, OnAre3DAPIsBlocked)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidLose3DContext, OnDidLose3DContext)
+#if defined(OS_ANDROID)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_RunWebAudioMediaCodec, OnWebAudioMediaCodec)
+#endif
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP_EX()
@@ -815,7 +821,7 @@
save_info->suggested_name = suggested_name;
scoped_ptr<net::URLRequest> request(
resource_context_->GetRequestContext()->CreateRequest(url, NULL));
- request->set_referrer(referrer.url.spec());
+ request->SetReferrer(referrer.url.spec());
webkit_glue::ConfigureURLRequestForReferrerPolicy(
request.get(), referrer.policy);
RecordDownloadSource(INITIATED_BY_RENDERER);
@@ -1007,9 +1013,10 @@
base::Bind(base::IgnoreResult(&RenderMessageFilter::Send), this, reply));
}
-void RenderMessageFilter::OnMediaLogEvent(const media::MediaLogEvent& event) {
+void RenderMessageFilter::OnMediaLogEvents(
+ const std::vector<media::MediaLogEvent>& events) {
if (media_internals_)
- media_internals_->OnMediaEvent(render_process_id_, event);
+ media_internals_->OnMediaEvents(render_process_id_, events);
}
void RenderMessageFilter::CheckPolicyForCookies(
@@ -1144,4 +1151,19 @@
}
#endif
+#if defined(OS_ANDROID)
+void RenderMessageFilter::OnWebAudioMediaCodec(
+ base::SharedMemoryHandle encoded_data_handle,
+ base::FileDescriptor pcm_output,
+ size_t data_size) {
+ // Let a WorkerPool handle this request since the WebAudio
+ // MediaCodec bridge is slow and can block while sending the data to
+ // the renderer.
+ base::WorkerPool::PostTask(
+ FROM_HERE,
+ base::Bind(&media::WebAudioMediaCodecBridge::RunWebAudioMediaCodec,
+ encoded_data_handle, pcm_output, data_size),
+ true);
+}
+#endif
} // namespace content
diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h
index 689b3f6..fb45016 100644
--- a/content/browser/renderer_host/render_message_filter.h
+++ b/content/browser/renderer_host/render_message_filter.h
@@ -33,6 +33,10 @@
#include "content/common/mac/font_loader.h"
#endif
+#if defined(OS_ANDROID)
+#include "base/threading/worker_pool.h"
+#endif
+
struct FontDescriptor;
struct ViewHostMsg_CreateWindow_Params;
@@ -227,7 +231,7 @@
int flags,
int message_id,
int routing_id);
- void OnMediaLogEvent(const media::MediaLogEvent&);
+ void OnMediaLogEvents(const std::vector<media::MediaLogEvent>&);
// Check the policy for getting cookies. Gets the cookies if allowed.
void CheckPolicyForCookies(const GURL& url,
@@ -256,6 +260,12 @@
ThreeDAPIType context_type,
int arb_robustness_status_code);
+#if defined(OS_ANDROID)
+ void OnWebAudioMediaCodec(base::SharedMemoryHandle encoded_data_handle,
+ base::FileDescriptor pcm_output,
+ size_t data_size);
+#endif
+
// Cached resource request dispatcher host and plugin service, guaranteed to
// be non-null if Init succeeds. We do not own the objects, they are managed
// by the BrowserProcess, which has a wider scope than we do.
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 9e71c1d..51d9298 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -56,8 +56,8 @@
#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/in_process_webkit/indexed_db_context_impl.h"
#include "content/browser/in_process_webkit/indexed_db_dispatcher_host.h"
+#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/loader/resource_message_filter.h"
#include "content/browser/loader/resource_scheduler_filter.h"
#include "content/browser/media/media_internals.h"
@@ -112,6 +112,7 @@
#include "content/public/common/url_constants.h"
#include "content/renderer/render_process_impl.h"
#include "content/renderer/render_thread_impl.h"
+#include "gpu/command_buffer/service/gpu_switches.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_logging.h"
#include "ipc/ipc_platform_file.h"
@@ -143,6 +144,8 @@
namespace content {
namespace {
+base::MessageLoop* g_in_process_thread;
+
void CacheShaderInfo(int32 id, base::FilePath path) {
ShaderCacheFactory::GetInstance()->SetCacheInfo(id, path);
}
@@ -170,9 +173,11 @@
virtual void Init() OVERRIDE {
render_process_.reset(new RenderProcessImpl());
new RenderThreadImpl(channel_id_);
+ g_in_process_thread = message_loop();
}
virtual void CleanUp() OVERRIDE {
+ g_in_process_thread = NULL;
render_process_.reset();
// It's a little lame to manually set this flag. But the single process
@@ -232,6 +237,9 @@
base::LazyInstance<IDMap<RenderProcessHost> >::Leaky
g_all_hosts = LAZY_INSTANCE_INITIALIZER;
+base::LazyInstance<scoped_refptr<BrowserPluginGeolocationPermissionContext> >
+ g_browser_plugin_geolocation_context = LAZY_INSTANCE_INITIALIZER;
+
// Map of site to process, to ensure we only have one RenderProcessHost per
// site in process-per-site mode. Each map is specific to a BrowserContext.
class SiteProcessMap : public base::SupportsUserData::Data {
@@ -375,9 +383,9 @@
pending_views_(0),
visible_widgets_(0),
backgrounded_(true),
- ALLOW_THIS_IN_INITIALIZER_LIST(cached_dibs_cleaner_(
- FROM_HERE, base::TimeDelta::FromSeconds(5),
- this, &RenderProcessHostImpl::ClearTransportDIBCache)),
+ cached_dibs_cleaner_(
+ FROM_HERE, base::TimeDelta::FromSeconds(5),
+ this, &RenderProcessHostImpl::ClearTransportDIBCache),
is_initialized_(false),
id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
browser_context_(browser_context),
@@ -399,10 +407,12 @@
// Initialize |child_process_activity_time_| to a reasonable value.
mark_child_process_activity_time();
- if (!GetBrowserContext()->IsOffTheRecord()) {
+ if (!GetBrowserContext()->IsOffTheRecord() &&
+ !CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableGpuShaderDiskCache)) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&CacheShaderInfo, GetID(),
- GetBrowserContext()->GetPath()));
+ storage_partition_impl_->GetPath()));
}
// Note: When we create the RenderProcessHostImpl, it's technically
@@ -425,8 +435,11 @@
ClearTransportDIBCache();
UnregisterHost(GetID());
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::Bind(&RemoveShaderInfo, GetID()));
+ if (!CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableGpuShaderDiskCache)) {
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&RemoveShaderInfo, GetID()));
+ }
}
void RenderProcessHostImpl::EnableSendQueue() {
@@ -436,7 +449,7 @@
bool RenderProcessHostImpl::Init() {
// calling Init() more than once does nothing, this makes it more convenient
// for the view host which may not be sure in some cases
- if (channel_.get())
+ if (channel_)
return true;
CommandLine::StringType renderer_prefix;
@@ -493,13 +506,13 @@
in_process_renderer_.reset(new RendererMainThread(channel_id));
base::Thread::Options options;
-#if !defined(TOOLKIT_GTK) && !defined(OS_ANDROID)
+#if defined(OS_WIN) && !defined(OS_MACOSX)
// In-process plugins require this to be a UI message loop.
- options.message_loop_type = MessageLoop::TYPE_UI;
+ options.message_loop_type = base::MessageLoop::TYPE_UI;
#else
- // We can't have multiple UI loops on GTK and Android, so we don't support
+ // We can't have multiple UI loops on Linux and Android, so we don't support
// in-process plugins.
- options.message_loop_type = MessageLoop::TYPE_DEFAULT;
+ options.message_loop_type = base::MessageLoop::TYPE_DEFAULT;
#endif
in_process_renderer_->StartWithOptions(options);
@@ -594,8 +607,12 @@
GetID(),
storage_partition_impl_->GetIndexedDBContext()));
if (IsGuest()) {
+ if (!g_browser_plugin_geolocation_context.Get()) {
+ g_browser_plugin_geolocation_context.Get() =
+ new BrowserPluginGeolocationPermissionContext();
+ }
channel_->AddFilter(GeolocationDispatcherHost::New(
- GetID(), new BrowserPluginGeolocationPermissionContext()));
+ GetID(), g_browser_plugin_geolocation_context.Get()));
} else {
channel_->AddFilter(GeolocationDispatcherHost::New(
GetID(), browser_context->GetGeolocationPermissionContext()));
@@ -786,9 +803,7 @@
switches::kDisableAcceleratedVideoDecode,
switches::kDisableApplicationCache,
switches::kDisableAudio,
- switches::kDisableAudioOutputResampler,
switches::kDisableBreakpad,
- switches::kDisableDataTransferItems,
switches::kDisableDatabases,
switches::kDisableDesktopNotifications,
switches::kDisableDeviceOrientation,
@@ -796,22 +811,26 @@
switches::kDisableGeolocation,
switches::kDisableGLMultisampling,
switches::kDisableGpuVsync,
+ switches::kDisableGpu,
switches::kDisableHistogramCustomizer,
switches::kDisableJavaScriptI18NAPI,
switches::kDisableLocalStorage,
switches::kDisableLogging,
switches::kDisableSeccompFilterSandbox,
- switches::kDisableSeccompSandbox,
switches::kDisableSessionStorage,
switches::kDisableSharedWorkers,
switches::kDisableSpeechInput,
+ switches::kDisableTouchDragDrop,
+ switches::kDisableTouchEditing,
#if defined(OS_ANDROID)
switches::kEnableWebAudio,
switches::kDisableWebRTC,
#else
switches::kDisableWebAudio,
#endif
- switches::kDisableWebSockets,
+ switches::kEnableWebMIDI,
+ switches::kEnableExperimentalCanvasFeatures,
+ switches::kEnableExperimentalWebSocket,
switches::kDomAutomationController,
switches::kEnableAccessibilityLogging,
switches::kEnableBrowserPluginForAllViewTypes,
@@ -827,22 +846,27 @@
switches::kEnableGpuBenchmarking,
switches::kEnableMemoryBenchmarking,
switches::kEnableLogging,
+ switches::kEnableSpeechSynthesis,
+ switches::kEnableTouchDragDrop,
+ switches::kEnableTouchEditing,
+ switches::kEnableVsyncNotification,
+ switches::kEnableWebPInAcceptHeader,
switches::kDisableMediaSource,
- switches::kDisableRendererSideMixing,
switches::kEnableStrictSiteIsolation,
switches::kDisableFullScreen,
switches::kEnableNewDialogStyle,
#if defined(ENABLE_PLUGINS)
switches::kEnablePepperTesting,
+ switches::kDisablePepper3d,
#endif
switches::kEnablePreparsedJsCaching,
switches::kEnablePruneGpuCommandBuffers,
switches::kEnablePinch,
+ switches::kDisablePinch,
#if defined(OS_MACOSX)
// Allow this to be set when invoking the browser and relayed along.
switches::kEnableSandboxLogging,
#endif
- switches::kEnableSeccompSandbox,
switches::kEnableSoftwareCompositingGLAdapter,
switches::kEnableStatsTable,
switches::kEnableThreadedCompositing,
@@ -850,7 +874,6 @@
switches::kEnableHighDpiCompositingForFixedPosition,
switches::kDisableCompositingForFixedPosition,
switches::kEnableAcceleratedPainting,
- switches::kEnableTouchDragDrop,
switches::kDisableThreadedCompositing,
switches::kDisableTouchAdjustment,
switches::kDefaultTileWidth,
@@ -860,6 +883,8 @@
switches::kEnableViewport,
switches::kEnableOpusPlayback,
switches::kEnableVp9Playback,
+ switches::kEnableVp8AlphaPlayback,
+ switches::kEnableEac3Playback,
switches::kForceDeviceScaleFactor,
switches::kFullMemoryCrashReport,
#if !defined (GOOGLE_CHROME_BUILD)
@@ -873,7 +898,7 @@
#if defined(OS_ANDROID)
switches::kNetworkCountryIso,
switches::kDisableGestureRequirementForMediaPlayback,
- switches::kUseExternalVideoSurface,
+ switches::kUseExternalVideoSurfaceThresholdInPixels,
#endif
switches::kNoReferrers,
switches::kNoSandbox,
@@ -902,18 +927,22 @@
// also be added to chrome/browser/chromeos/login/chrome_restart_request.cc.
cc::switches::kBackgroundColorInsteadOfCheckerboard,
cc::switches::kCompositeToMailbox,
- cc::switches::kDisableCheapnessEstimator,
+ cc::switches::kDisableColorEstimator,
cc::switches::kDisableImplSidePainting,
cc::switches::kDisableThreadedAnimation,
cc::switches::kEnableCompositorFrameMessage,
cc::switches::kEnableImplSidePainting,
cc::switches::kEnablePartialSwap,
cc::switches::kEnablePerTilePainting,
+ cc::switches::kEnablePinchZoomScrollbars,
+ cc::switches::kDisablePinchZoomScrollbars,
cc::switches::kEnablePredictionBenchmarking,
cc::switches::kEnableRightAlignedScheduling,
cc::switches::kEnableTopControlsPositionCalculation,
cc::switches::kLowResolutionContentsScaleFactor,
+ cc::switches::kMaxUnusedResourceMemoryUsagePercentage,
cc::switches::kNumRasterThreads,
+ cc::switches::kMaxTilesForInterestArea,
cc::switches::kShowCompositedLayerBorders,
cc::switches::kShowCompositedLayerTree,
cc::switches::kShowFPSCounter,
@@ -924,12 +953,12 @@
cc::switches::kShowScreenSpaceRects,
cc::switches::kShowSurfaceDamageRects,
cc::switches::kSlowDownRasterScaleFactor,
+ cc::switches::kStrictLayerPropertyChangeChecking,
cc::switches::kTopControlsHeight,
cc::switches::kTopControlsHideThreshold,
cc::switches::kTopControlsShowThreshold,
cc::switches::kTraceAllRenderedFrames,
cc::switches::kTraceOverdraw,
- cc::switches::kUseColorEstimator,
};
renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames,
arraysize(kSwitchNames));
@@ -1003,15 +1032,15 @@
STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE,
FALSE, 0);
return TransportDIB::Map(section);
-#elif defined(OS_MACOSX)
- // On OSX, the browser allocates all DIBs and keeps a file descriptor around
- // for each.
- return widget_helper_->MapTransportDIB(dib_id);
+#elif defined(TOOLKIT_GTK) || (defined(OS_LINUX) && defined(USE_AURA))
+ return TransportDIB::Map(dib_id.shmkey);
#elif defined(OS_ANDROID)
return TransportDIB::Map(dib_id);
-#elif defined(OS_POSIX)
- return TransportDIB::Map(dib_id.shmkey);
-#endif // defined(OS_POSIX)
+#else
+ // On POSIX, the browser allocates all DIBs and keeps a file descriptor around
+ // for each.
+ return widget_helper_->MapTransportDIB(dib_id);
+#endif
}
TransportDIB* RenderProcessHostImpl::GetTransportDIB(
@@ -1043,7 +1072,7 @@
}
}
-#if defined(USE_X11)
+#if defined(TOOLKIT_GTK) || (defined(OS_LINUX) && defined(USE_AURA))
smallest_iterator->second->Detach();
#else
delete smallest_iterator->second;
@@ -1057,7 +1086,7 @@
}
void RenderProcessHostImpl::ClearTransportDIBCache() {
-#if defined(USE_X11)
+#if defined(TOOLKIT_GTK) || (defined(OS_LINUX) && defined(USE_AURA))
std::map<TransportDIB::Id, TransportDIB*>::const_iterator dib =
cached_dibs_.begin();
for (; dib != cached_dibs_.end(); ++dib)
@@ -1070,7 +1099,7 @@
}
bool RenderProcessHostImpl::Send(IPC::Message* msg) {
- if (!channel_.get()) {
+ if (!channel_) {
if (!is_initialized_) {
queued_messages_.push(msg);
return true;
@@ -1229,7 +1258,7 @@
Source<RenderProcessHost>(this),
NotificationService::NoDetails());
- MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
deleting_soon_ = true;
// It's important not to wait for the DeleteTask to delete the channel
// proxy. Kill it off now. That way, in case the profile is going away, the
@@ -1519,6 +1548,11 @@
map->RegisterProcess(site, process);
}
+base::MessageLoop*
+ RenderProcessHostImpl::GetInProcessRendererThreadForTesting() {
+ return g_in_process_thread;
+}
+
void RenderProcessHostImpl::ProcessDied(bool already_dead) {
// Our child process has died. If we didn't expect it, it's a crash.
// In any case, we need to let everyone know it's gone.
@@ -1663,7 +1697,7 @@
if (deleting_soon_)
return;
- if (child_process_launcher_.get()) {
+ if (child_process_launcher_) {
if (!child_process_launcher_->GetHandle()) {
OnChannelError();
return;
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h
index 62abd7b..d1f71e0 100644
--- a/content/browser/renderer_host/render_process_host_impl.h
+++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -21,6 +21,10 @@
class CommandLine;
+namespace base {
+class MessageLoop;
+}
+
namespace gfx {
class Size;
}
@@ -174,6 +178,8 @@
RenderProcessHost* process,
const GURL& url);
+ static base::MessageLoop* GetInProcessRendererThreadForTesting();
+
protected:
// A proxy for our IPC::Channel that lives on the IO thread (see
// browser_process.h)
diff --git a/content/browser/renderer_host/render_sandbox_host_linux.cc b/content/browser/renderer_host/render_sandbox_host_linux.cc
index 07f0b20..97c9304 100644
--- a/content/browser/renderer_host/render_sandbox_host_linux.cc
+++ b/content/browser/renderer_host/render_sandbox_host_linux.cc
@@ -253,7 +253,7 @@
}
EnsureWebKitInitialized();
- scoped_array<WebUChar> chars(new WebUChar[num_chars]);
+ scoped_ptr<WebUChar[]> chars(new WebUChar[num_chars]);
for (int i = 0; i < num_chars; ++i) {
uint32_t c;
@@ -278,7 +278,7 @@
if (family.name.data()) {
reply.WriteString(family.name.data());
} else {
- reply.WriteString("");
+ reply.WriteString(std::string());
}
reply.WriteBool(family.isBold);
reply.WriteBool(family.isItalic);
@@ -664,12 +664,12 @@
SandboxIPCProcess::~SandboxIPCProcess() {
paths_.deleteAll();
- if (webkit_platform_support_.get())
+ if (webkit_platform_support_)
WebKit::shutdown();
}
void SandboxIPCProcess::EnsureWebKitInitialized() {
- if (webkit_platform_support_.get())
+ if (webkit_platform_support_)
return;
webkit_platform_support_.reset(new WebKitPlatformSupportImpl);
WebKit::initializeWithoutV8(webkit_platform_support_.get());
diff --git a/content/browser/renderer_host/render_view_host_browsertest.cc b/content/browser/renderer_host/render_view_host_browsertest.cc
index 335c966..d75dd7a 100644
--- a/content/browser/renderer_host/render_view_host_browsertest.cc
+++ b/content/browser/renderer_host/render_view_host_browsertest.cc
@@ -16,7 +16,7 @@
#include "content/test/content_browser_test_utils.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_util.h"
-#include "net/test/test_server.h"
+#include "net/test/spawned_test_server.h"
namespace content {
diff --git a/content/browser/renderer_host/render_view_host_delegate.cc b/content/browser/renderer_host/render_view_host_delegate.cc
index 0d7c523..ddd381f 100644
--- a/content/browser/renderer_host/render_view_host_delegate.cc
+++ b/content/browser/renderer_host/render_view_host_delegate.cc
@@ -37,8 +37,8 @@
return NULL;
}
-webkit_glue::WebPreferences RenderViewHostDelegate::GetWebkitPrefs() {
- return webkit_glue::WebPreferences();
+WebPreferences RenderViewHostDelegate::GetWebkitPrefs() {
+ return WebPreferences();
}
bool RenderViewHostDelegate::IsFullscreenForCurrentTab() const {
diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h
index 5ee7314..f2be7e1 100644
--- a/content/browser/renderer_host/render_view_host_delegate.h
+++ b/content/browser/renderer_host/render_view_host_delegate.h
@@ -27,10 +27,7 @@
struct ViewHostMsg_DidFailProvisionalLoadWithError_Params;
struct ViewHostMsg_FrameNavigate_Params;
struct ViewMsg_PostMessage_Params;
-
-namespace webkit_glue {
struct WebPreferences;
-}
namespace base {
class ListValue;
@@ -62,8 +59,6 @@
struct Referrer;
struct RendererPreferences;
-typedef base::Callback< void(const MediaStreamDevices&) > MediaResponseCallback;
-
//
// RenderViewHostDelegate
//
@@ -136,9 +131,9 @@
virtual void RenderViewReady(RenderViewHost* render_view_host) {}
// The RenderView died somehow (crashed or was killed by the user).
- virtual void RenderViewGone(RenderViewHost* render_view_host,
- base::TerminationStatus status,
- int error_code) {}
+ virtual void RenderViewTerminated(RenderViewHost* render_view_host,
+ base::TerminationStatus status,
+ int error_code) {}
// The RenderView is going to be deleted. This is called when each
// RenderView is going to be destroyed
@@ -219,10 +214,6 @@
// the window.
virtual void DidDisownOpener(RenderViewHost* rvh) {}
- // The RenderView has changed its frame hierarchy, so we need to update all
- // other renderers interested in this event.
- virtual void DidUpdateFrameTree(RenderViewHost* rvh) {}
-
// The RenderView's main frame document element is ready. This happens when
// the document has finished parsing.
virtual void DocumentAvailableInMainFrame(RenderViewHost* render_view_host) {}
@@ -284,7 +275,7 @@
// Returns a WebPreferences object that will be used by the renderer
// associated with the owning render view host.
- virtual webkit_glue::WebPreferences GetWebkitPrefs();
+ virtual WebPreferences GetWebkitPrefs();
// Notification the user has made a gesture while focus was on the
// page. This is used to avoid uninitiated user downloads (aka carpet
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index d48a82b..8424da9 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -13,7 +13,7 @@
#include "base/command_line.h"
#include "base/i18n/rtl.h"
#include "base/json/json_reader.h"
-#include "base/json/json_writer.h"
+#include "base/lazy_instance.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/stl_util.h"
@@ -31,9 +31,9 @@
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/common/accessibility_messages.h"
#include "content/common/browser_plugin/browser_plugin_messages.h"
-#include "content/common/content_constants_internal.h"
#include "content/common/desktop_notification_messages.h"
#include "content/common/drag_messages.h"
+#include "content/common/input_messages.h"
#include "content/common/inter_process_time_ticks_converter.h"
#include "content/common/speech_recognition_messages.h"
#include "content/common/swapped_out_messages.h"
@@ -76,7 +76,7 @@
#elif defined(OS_MACOSX)
#include "content/browser/renderer_host/popup_menu_helper_mac.h"
#elif defined(OS_ANDROID)
-#include "content/browser/android/media_player_manager_android.h"
+#include "content/browser/android/media_player_manager_impl.h"
#endif
using base::TimeDelta;
@@ -109,6 +109,9 @@
}
}
+base::LazyInstance<std::vector<RenderViewHost::CreatedCallback> >
+g_created_callbacks = LAZY_INSTANCE_INITIALIZER;
+
} // namespace
///////////////////////////////////////////////////////////////////////////////
@@ -164,7 +167,7 @@
enabled_bindings_(0),
pending_request_id_(-1),
navigations_suspended_(false),
- suspended_nav_message_(NULL),
+ suspended_nav_params_(NULL),
is_swapped_out_(swapped_out),
is_subframe_(false),
run_modal_reply_msg_(NULL),
@@ -188,15 +191,11 @@
GetProcess()->EnableSendQueue();
- GetContentClient()->browser()->RenderViewHostCreated(this);
-
- NotificationService::current()->Notify(
- NOTIFICATION_RENDER_VIEW_HOST_CREATED,
- Source<RenderViewHost>(this),
- NotificationService::NoDetails());
+ for (size_t i = 0; i < g_created_callbacks.Get().size(); i++)
+ g_created_callbacks.Get().at(i).Run(this);
#if defined(OS_ANDROID)
- media_player_manager_ = new MediaPlayerManagerAndroid(this);
+ media_player_manager_ = new MediaPlayerManagerImpl(this);
#endif
}
@@ -308,8 +307,6 @@
}
}
- ViewMsg_Navigate* nav_message = new ViewMsg_Navigate(GetRoutingID(), params);
-
// Only send the message if we aren't suspended at the start of a cross-site
// request.
if (navigations_suspended_) {
@@ -317,14 +314,14 @@
// navigations will only be suspended during a cross-site request. If a
// second navigation occurs, WebContentsImpl will cancel this pending RVH
// create a new pending RVH.
- DCHECK(!suspended_nav_message_.get());
- suspended_nav_message_.reset(nav_message);
+ DCHECK(!suspended_nav_params_.get());
+ suspended_nav_params_.reset(new ViewMsg_Navigate_Params(params));
} else {
// Get back to a clean state, in case we start a new navigation without
// completing a RVH swap or unload handler.
SetSwappedOut(false);
- Send(nav_message);
+ Send(new ViewMsg_Navigate(GetRoutingID(), params));
}
// Force the throbber to start. We do this because WebKit's "started
@@ -356,33 +353,33 @@
Navigate(params);
}
-void RenderViewHostImpl::SetNavigationsSuspended(bool suspend) {
+void RenderViewHostImpl::SetNavigationsSuspended(
+ bool suspend,
+ const base::TimeTicks& proceed_time) {
// This should only be called to toggle the state.
DCHECK(navigations_suspended_ != suspend);
navigations_suspended_ = suspend;
- if (!suspend && suspended_nav_message_.get()) {
- // There's a navigation message waiting to be sent. Now that we're not
- // suspended anymore, resume navigation by sending it. If we were swapped
+ if (!suspend && suspended_nav_params_) {
+ // There's navigation message params waiting to be sent. Now that we're not
+ // suspended anymore, resume navigation by sending them. If we were swapped
// out, we should also stop filtering out the IPC messages now.
SetSwappedOut(false);
- Send(suspended_nav_message_.release());
+ DCHECK(!proceed_time.is_null());
+ suspended_nav_params_->browser_navigation_start = proceed_time;
+ Send(new ViewMsg_Navigate(GetRoutingID(), *suspended_nav_params_.get()));
+ suspended_nav_params_.reset();
}
}
void RenderViewHostImpl::CancelSuspendedNavigations() {
// Clear any state if a pending navigation is canceled or pre-empted.
- if (suspended_nav_message_.get())
- suspended_nav_message_.reset();
+ if (suspended_nav_params_)
+ suspended_nav_params_.reset();
navigations_suspended_ = false;
}
-void RenderViewHostImpl::SetNavigationStartTime(
- const base::TimeTicks& navigation_start) {
- Send(new ViewMsg_SetNavigationStartTime(GetRoutingID(), navigation_start));
-}
-
void RenderViewHostImpl::FirePageBeforeUnload(bool for_cross_site_transition) {
if (!IsRenderViewLive()) {
// This RenderViewHostImpl doesn't have a live renderer, so just
@@ -565,7 +562,8 @@
void RenderViewHostImpl::ActivateNearestFindResult(int request_id,
float x,
float y) {
- Send(new ViewMsg_ActivateNearestFindResult(GetRoutingID(), request_id, x, y));
+ Send(new InputMsg_ActivateNearestFindResult(GetRoutingID(),
+ request_id, x, y));
}
void RenderViewHostImpl::RequestFindMatchRects(int current_version) {
@@ -995,7 +993,6 @@
OnDomOperationResponse)
IPC_MESSAGE_HANDLER(AccessibilityHostMsg_Notifications,
OnAccessibilityNotifications)
- IPC_MESSAGE_HANDLER(ViewHostMsg_FrameTreeUpdated, OnFrameTreeUpdated)
// Have the super handle all other messages.
IPC_MESSAGE_UNHANDLED(
handled = RenderWidgetHostImpl::OnMessageReceived(msg))
@@ -1122,9 +1119,9 @@
// Our base class RenderWidgetHost needs to reset some stuff.
RendererExited(render_view_termination_status_, exit_code);
- delegate_->RenderViewGone(this,
- static_cast<base::TerminationStatus>(status),
- exit_code);
+ delegate_->RenderViewTerminated(this,
+ static_cast<base::TerminationStatus>(status),
+ exit_code);
}
void RenderViewHostImpl::OnDidStartProvisionalLoadForFrame(
@@ -1228,9 +1225,6 @@
FilterURL(policy, process, true, &validated_params.password_form.action);
delegate_->DidNavigate(this, validated_params);
-
- // TODO(nasko): Send frame tree update for the top level frame, once
- // http://crbug.com/153701 is fixed.
}
void RenderViewHostImpl::OnUpdateState(int32 page_id,
@@ -1727,6 +1721,19 @@
}
}
+void RenderViewHost::AddCreatedCallback(const CreatedCallback& callback) {
+ g_created_callbacks.Get().push_back(callback);
+}
+
+void RenderViewHost::RemoveCreatedCallback(const CreatedCallback& callback) {
+ for (size_t i = 0; i < g_created_callbacks.Get().size(); ++i) {
+ if (g_created_callbacks.Get().at(i).Equals(callback)) {
+ g_created_callbacks.Get().erase(g_created_callbacks.Get().begin() + i);
+ return;
+ }
+ }
+}
+
void RenderViewHostImpl::SetAltErrorPageURL(const GURL& url) {
Send(new ViewMsg_SetAltErrorPageURL(GetRoutingID(), url));
}
@@ -1738,7 +1745,7 @@
WasResized();
}
-webkit_glue::WebPreferences RenderViewHostImpl::GetWebkitPreferences() {
+WebPreferences RenderViewHostImpl::GetWebkitPreferences() {
return delegate_->GetWebkitPrefs();
}
@@ -1749,20 +1756,6 @@
Send(new ViewMsg_DisownOpener(GetRoutingID()));
}
-void RenderViewHostImpl::UpdateFrameTree(
- int process_id,
- int route_id,
- const std::string& frame_tree) {
- // This should only be called when swapped out.
- DCHECK(is_swapped_out_);
-
- frame_tree_ = frame_tree;
- Send(new ViewMsg_UpdateFrameTree(GetRoutingID(),
- process_id,
- route_id,
- frame_tree_));
-}
-
void RenderViewHostImpl::SetAccessibilityLayoutCompleteCallbackForTesting(
const base::Closure& callback) {
accessibility_layout_callback_ = callback;
@@ -1778,8 +1771,7 @@
accessibility_other_callback_ = callback;
}
-void RenderViewHostImpl::UpdateWebkitPreferences(
- const webkit_glue::WebPreferences& prefs) {
+void RenderViewHostImpl::UpdateWebkitPreferences(const WebPreferences& prefs) {
Send(new ViewMsg_UpdateWebPreferences(GetRoutingID(), prefs));
}
@@ -1983,22 +1975,6 @@
GetProcess()->GetID(), GetRoutingID(), notification_id);
}
-#if defined(OS_MACOSX) || defined(OS_ANDROID)
-void RenderViewHostImpl::OnShowPopup(
- const ViewHostMsg_ShowPopup_Params& params) {
- RenderViewHostDelegateView* view = delegate_->GetDelegateView();
- if (view) {
- view->ShowPopupMenu(params.bounds,
- params.item_height,
- params.item_font_size,
- params.selected_item,
- params.popup_items,
- params.right_aligned,
- params.allow_multiple_selection);
- }
-}
-#endif
-
void RenderViewHostImpl::OnRunFileChooser(const FileChooserParams& params) {
delegate_->RunFileChooser(this, params);
}
@@ -2012,28 +1988,6 @@
Details<DomOperationNotificationDetails>(&details));
}
-void RenderViewHostImpl::OnFrameTreeUpdated(const std::string& frame_tree) {
- // TODO(nasko): Remove once http://crbug.com/153701 is fixed.
- DCHECK(false);
- frame_tree_ = frame_tree;
- delegate_->DidUpdateFrameTree(this);
-}
-
-void RenderViewHostImpl::SetSwappedOut(bool is_swapped_out) {
- is_swapped_out_ = is_swapped_out;
-
- // Whenever we change swap out state, we should not be waiting for
- // beforeunload or unload acks. We clear them here to be safe, since they
- // can cause navigations to be ignored in OnNavigate.
- is_waiting_for_beforeunload_ack_ = false;
- is_waiting_for_unload_ack_ = false;
- has_timed_out_on_unload_ = false;
-}
-
-void RenderViewHostImpl::ClearPowerSaveBlockers() {
- STLDeleteValues(&power_save_blockers_);
-}
-
void RenderViewHostImpl::OnGetWindowSnapshot(const int snapshot_id) {
std::vector<unsigned char> png;
@@ -2057,4 +2011,35 @@
GetRoutingID(), snapshot_id, gfx::Size(), png));
}
+#if defined(OS_MACOSX) || defined(OS_ANDROID)
+void RenderViewHostImpl::OnShowPopup(
+ const ViewHostMsg_ShowPopup_Params& params) {
+ RenderViewHostDelegateView* view = delegate_->GetDelegateView();
+ if (view) {
+ view->ShowPopupMenu(params.bounds,
+ params.item_height,
+ params.item_font_size,
+ params.selected_item,
+ params.popup_items,
+ params.right_aligned,
+ params.allow_multiple_selection);
+ }
+}
+#endif
+
+void RenderViewHostImpl::SetSwappedOut(bool is_swapped_out) {
+ is_swapped_out_ = is_swapped_out;
+
+ // Whenever we change swap out state, we should not be waiting for
+ // beforeunload or unload acks. We clear them here to be safe, since they
+ // can cause navigations to be ignored in OnNavigate.
+ is_waiting_for_beforeunload_ack_ = false;
+ is_waiting_for_unload_ack_ = false;
+ has_timed_out_on_unload_ = false;
+}
+
+void RenderViewHostImpl::ClearPowerSaveBlockers() {
+ STLDeleteValues(&power_save_blockers_);
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h
index 4b33cc0..baa4b2e 100644
--- a/content/browser/renderer_host/render_view_host_impl.h
+++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -66,7 +66,7 @@
struct ShowDesktopNotificationHostMsgParams;
#if defined(OS_ANDROID)
-class MediaPlayerManagerAndroid;
+class MediaPlayerManagerImpl;
#endif
#if defined(COMPILER_MSVC)
@@ -204,9 +204,9 @@
virtual void Zoom(PageZoom zoom) OVERRIDE;
virtual void SyncRendererPrefs() OVERRIDE;
virtual void ToggleSpeechInput() OVERRIDE;
- virtual webkit_glue::WebPreferences GetWebkitPreferences() OVERRIDE;
+ virtual WebPreferences GetWebkitPreferences() OVERRIDE;
virtual void UpdateWebkitPreferences(
- const webkit_glue::WebPreferences& prefs) OVERRIDE;
+ const WebPreferences& prefs) OVERRIDE;
virtual void NotifyTimezoneChange() OVERRIDE;
#if defined(OS_ANDROID)
@@ -260,17 +260,17 @@
// method with |suspend| equal to true. If |suspend| is false and there is
// a suspended_nav_message_, this will send the message. This function
// should only be called to toggle the state; callers should check
- // are_navigations_suspended() first.
- void SetNavigationsSuspended(bool suspend);
+ // are_navigations_suspended() first. If |suspend| is false, the time that the
+ // user decided the navigation should proceed should be passed as
+ // |proceed_time|.
+ void SetNavigationsSuspended(bool suspend,
+ const base::TimeTicks& proceed_time);
// Clears any suspended navigation state after a cross-site navigation is
// canceled or suspended. This is important if we later return to this
// RenderViewHost.
void CancelSuspendedNavigations();
- // Informs the renderer of when the current navigation was allowed to proceed.
- void SetNavigationStartTime(const base::TimeTicks& navigation_start);
-
// Whether this RenderViewHost has been swapped out to be displayed by a
// different process.
bool is_swapped_out() const { return is_swapped_out_; }
@@ -378,7 +378,7 @@
#endif
#if defined(OS_ANDROID)
- MediaPlayerManagerAndroid* media_player_manager() {
+ MediaPlayerManagerImpl* media_player_manager() {
return media_player_manager_;
}
@@ -395,20 +395,9 @@
is_subframe_ = is_subframe;
}
- const std::string& frame_tree() const {
- return frame_tree_;
- }
-
// Set the opener to null in the renderer process.
void DisownOpener();
- // Updates the frame tree for this RVH and sends an IPC down to the renderer
- // process to keep them in sync. For more details, see the comments on
- // ViewHostMsg_FrameTreeUpdated.
- void UpdateFrameTree(int process_id,
- int route_id,
- const std::string& frame_tree);
-
void set_save_accessibility_tree_for_testing(bool save) {
save_accessibility_tree_for_testing_ = save;
}
@@ -558,7 +547,6 @@
void OnRunFileChooser(const FileChooserParams& params);
void OnDomOperationResponse(const std::string& json_string,
int automation_id);
- void OnFrameTreeUpdated(const std::string& frame_tree);
void OnGetWindowSnapshot(const int snapshot_id);
#if defined(OS_MACOSX) || defined(OS_ANDROID)
@@ -603,11 +591,11 @@
// RenderViewHost.
bool navigations_suspended_;
- // We only buffer a suspended navigation message while we a pending RVH for a
- // WebContentsImpl. There will only ever be one suspended navigation, because
- // WebContentsImpl will destroy the pending RVH and create a new one if a
- // second navigation occurs.
- scoped_ptr<ViewMsg_Navigate> suspended_nav_message_;
+ // We only buffer the params for a suspended navigation while we have a
+ // pending RVH for a WebContentsImpl. There will only ever be one suspended
+ // navigation, because WebContentsImpl will destroy the pending RVH and create
+ // a new one if a second navigation occurs.
+ scoped_ptr<ViewMsg_Navigate_Params> suspended_nav_params_;
// Whether this RenderViewHost is currently swapped out, such that the view is
// being rendered by another process.
@@ -664,11 +652,6 @@
// Whether the accessibility tree should be saved, for unit testing.
bool save_accessibility_tree_for_testing_;
- // A JSON serialized representation of the frame tree for the current document
- // in the render view. For more details, see the comments on
- // ViewHostMsg_FrameTreeUpdated.
- std::string frame_tree_;
-
// The most recently received accessibility tree - for unit testing only.
AccessibilityNodeDataTreeNode accessibility_tree_;
@@ -689,7 +672,7 @@
#if defined(OS_ANDROID)
// Manages all the android mediaplayer objects and handling IPCs for video.
// This class inherits from RenderViewHostObserver.
- MediaPlayerManagerAndroid* media_player_manager_;
+ MediaPlayerManagerImpl* media_player_manager_;
#endif
DISALLOW_COPY_AND_ASSIGN(RenderViewHostImpl);
diff --git a/content/browser/renderer_host/render_view_host_manager_browsertest.cc b/content/browser/renderer_host/render_view_host_manager_browsertest.cc
index a2ce269..00a2f67 100644
--- a/content/browser/renderer_host/render_view_host_manager_browsertest.cc
+++ b/content/browser/renderer_host/render_view_host_manager_browsertest.cc
@@ -8,10 +8,10 @@
#include "base/path_service.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
-#include "content/common/content_constants_internal.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/content_constants_internal.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_details.h"
@@ -28,66 +28,9 @@
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"
#include "net/base/net_util.h"
-#include "net/test/test_server.h"
+#include "net/test/spawned_test_server.h"
namespace content {
-namespace {
-
-bool CompareTrees(base::DictionaryValue* first, base::DictionaryValue* second) {
- string16 name1;
- string16 name2;
- if (!first->GetString(kFrameTreeNodeNameKey, &name1) ||
- !second->GetString(kFrameTreeNodeNameKey, &name2))
- return false;
- if (name1 != name2)
- return false;
-
- int id1 = 0;
- int id2 = 0;
- if (!first->GetInteger(kFrameTreeNodeIdKey, &id1) ||
- !second->GetInteger(kFrameTreeNodeIdKey, &id2)) {
- return false;
- }
- if (id1 != id2)
- return false;
-
- ListValue* subtree1 = NULL;
- ListValue* subtree2 = NULL;
- bool result1 = first->GetList(kFrameTreeNodeSubtreeKey, &subtree1);
- bool result2 = second->GetList(kFrameTreeNodeSubtreeKey, &subtree2);
- if (!result1 && !result2)
- return true;
- if (!result1 || !result2)
- return false;
-
- if (subtree1->GetSize() != subtree2->GetSize())
- return false;
-
- base::DictionaryValue* child1 = NULL;
- base::DictionaryValue* child2 = NULL;
- for (size_t i = 0; i < subtree1->GetSize(); ++i) {
- if (!subtree1->GetDictionary(i, &child1) ||
- !subtree2->GetDictionary(i, &child2)) {
- return false;
- }
- if (!CompareTrees(child1, child2))
- return false;
- }
-
- return true;
-}
-
-base::DictionaryValue* GetTree(RenderViewHostImpl* rvh) {
- std::string frame_tree = rvh->frame_tree();
- EXPECT_FALSE(frame_tree.empty());
- base::Value* v = base::JSONReader::Read(frame_tree);
- base::DictionaryValue* tree = NULL;
- EXPECT_TRUE(v->IsType(base::Value::TYPE_DICTIONARY));
- EXPECT_TRUE(v->GetAsDictionary(&tree));
- return tree;
-}
-
-} // namespace
class RenderViewHostManagerTest : public ContentBrowserTest {
public:
@@ -97,10 +40,10 @@
const std::string& original_file_path,
const net::HostPortPair& host_port_pair,
std::string* replacement_path) {
- std::vector<net::TestServer::StringPair> replacement_text;
+ std::vector<net::SpawnedTestServer::StringPair> replacement_text;
replacement_text.push_back(
make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString()));
- return net::TestServer::GetFilePathWithReplacements(
+ return net::SpawnedTestServer::GetFilePathWithReplacements(
original_file_path, replacement_text, replacement_path);
}
};
@@ -109,9 +52,9 @@
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, NoScriptAccessAfterSwapOut) {
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -177,9 +120,9 @@
SwapProcessWithRelNoreferrerAndTargetBlank) {
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -230,9 +173,9 @@
SwapProcessWithSameSiteRelNoreferrer) {
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -283,9 +226,9 @@
DontSwapProcessWithOnlyTargetBlank) {
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -331,9 +274,9 @@
DontSwapProcessWithOnlyRelNoreferrer) {
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -377,9 +320,9 @@
AllowTargetedNavigationsAfterSwap) {
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -460,9 +403,9 @@
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, DisownOpener) {
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -535,6 +478,20 @@
EXPECT_TRUE(success);
}
+// Test that subframes can disown their openers. http://crbug.com/225528.
+IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, DisownSubframeOpener) {
+ const GURL frame_url("data:text/html,<iframe name=\"foo\"></iframe>");
+ NavigateToURL(shell(), frame_url);
+
+ // Give the frame an opener using window.open.
+ EXPECT_TRUE(ExecuteScript(shell()->web_contents(),
+ "window.open('about:blank','foo');"));
+
+ // Now disown the frame's opener. Shouldn't crash.
+ EXPECT_TRUE(ExecuteScript(shell()->web_contents(),
+ "window.frames[0].opener = null;"));
+}
+
// Test for crbug.com/99202. PostMessage calls should still work after
// navigating the source and target windows to different sites.
// Specifically:
@@ -548,9 +505,9 @@
SupportCrossProcessPostMessage) {
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -686,9 +643,9 @@
AllowTargetedNavigationsInOpenerAfterSwap) {
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -757,9 +714,9 @@
ProcessExitWithSwappedOutViews) {
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -824,9 +781,9 @@
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, ClickLinkAfter204Error) {
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -887,9 +844,9 @@
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -1002,9 +959,9 @@
SwappedOutViewHasCorrectVisibilityState) {
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -1128,9 +1085,9 @@
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, LeakingRenderViewHosts) {
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -1186,173 +1143,6 @@
EXPECT_EQ(0U, rvh_observers.GetNumObservers());
}
-// Test for correct propagation of the frame hierarchy across processes in the
-// same BrowsingInstance. The test starts by navigating to a page that has
-// multiple nested frames. It then opens two windows and navigates each one
-// to a separate site, so at the end we have 3 SiteInstances. The opened
-// windows have swapped out RenderViews corresponding to the opener, so those
-// swapped out views must have a matching frame hierarchy. The test checks
-// that frame hierarchies are kept in sync through navigations, reloading, and
-// JavaScript manipulation of the frame tree.
-//
-// Disable the test until http://crbug.com/153701 is fixed.
-IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, DISABLED_FrameTreeUpdates) {
- // Start two servers to allow using different sites.
- EXPECT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
- base::FilePath(FILE_PATH_LITERAL("content/test/data")));
- EXPECT_TRUE(https_server.Start());
-
- GURL frame_tree_url(test_server()->GetURL("files/frame_tree/top.html"));
-
- // Replace the 127.0.0.1 with localhost, which will give us a different
- // site instance.
- GURL::Replacements replacements;
- std::string new_host("localhost");
- replacements.SetHostStr(new_host);
- GURL remote_frame = test_server()->GetURL(
- "files/frame_tree/1-1.html").ReplaceComponents(replacements);
-
- bool success = false;
- base::DictionaryValue* frames = NULL;
- base::ListValue* subtree = NULL;
-
- // First navigate to a page with no frames and ensure the frame tree has no
- // subtrees.
- NavigateToURL(shell(), test_server()->GetURL("files/simple_page.html"));
- WebContents* opener_contents = shell()->web_contents();
- RenderViewHostManager* opener_rvhm = static_cast<WebContentsImpl*>(
- opener_contents)->GetRenderManagerForTesting();
- frames = GetTree(opener_rvhm->current_host());
- EXPECT_FALSE(frames->GetList(kFrameTreeNodeSubtreeKey, &subtree));
-
- NavigateToURL(shell(), frame_tree_url);
- frames = GetTree(opener_rvhm->current_host());
- EXPECT_TRUE(frames->GetList(kFrameTreeNodeSubtreeKey, &subtree));
- EXPECT_TRUE(subtree->GetSize() == 3);
-
- scoped_refptr<SiteInstance> orig_site_instance(
- opener_contents->GetSiteInstance());
- EXPECT_TRUE(orig_site_instance != NULL);
-
- ShellAddedObserver shell_observer1;
- EXPECT_TRUE(ExecuteScriptAndExtractBool(
- opener_contents,
- "window.domAutomationController.send(openWindow('1-3.html'));",
- &success));
- EXPECT_TRUE(success);
-
- Shell* shell1 = shell_observer1.GetShell();
- WebContents* contents1 = shell1->web_contents();
- WaitForLoadStop(contents1);
- RenderViewHostManager* rvhm1 = static_cast<WebContentsImpl*>(
- contents1)->GetRenderManagerForTesting();
- EXPECT_EQ("/files/frame_tree/1-3.html", contents1->GetURL().path());
-
- // Now navigate the new window to a different SiteInstance.
- NavigateToURL(shell1, https_server.GetURL("files/title1.html"));
- EXPECT_EQ("/files/title1.html", contents1->GetURL().path());
- scoped_refptr<SiteInstance> site_instance1(
- contents1->GetSiteInstance());
- EXPECT_NE(orig_site_instance, site_instance1);
-
- ShellAddedObserver shell_observer2;
- EXPECT_TRUE(ExecuteScriptAndExtractBool(
- opener_contents,
- "window.domAutomationController.send(openWindow('../title2.html'));",
- &success));
- EXPECT_TRUE(success);
-
- Shell* shell2 = shell_observer2.GetShell();
- WebContents* contents2 = shell2->web_contents();
- WaitForLoadStop(contents2);
- EXPECT_EQ("/files/title2.html", contents2->GetURL().path());
-
- // Navigate the second new window to a different SiteInstance as well.
- NavigateToURL(shell2, remote_frame);
- EXPECT_EQ("/files/frame_tree/1-1.html", contents2->GetURL().path());
- scoped_refptr<SiteInstance> site_instance2(
- contents2->GetSiteInstance());
- EXPECT_NE(orig_site_instance, site_instance2);
- EXPECT_NE(site_instance1, site_instance2);
-
- RenderViewHostManager* rvhm2 = static_cast<WebContentsImpl*>(
- contents2)->GetRenderManagerForTesting();
-
- EXPECT_TRUE(CompareTrees(
- GetTree(opener_rvhm->current_host()),
- GetTree(opener_rvhm->GetSwappedOutRenderViewHost(site_instance1))));
- EXPECT_TRUE(CompareTrees(
- GetTree(opener_rvhm->current_host()),
- GetTree(opener_rvhm->GetSwappedOutRenderViewHost(site_instance2))));
-
- EXPECT_TRUE(CompareTrees(
- GetTree(rvhm1->current_host()),
- GetTree(rvhm1->GetSwappedOutRenderViewHost(orig_site_instance))));
- EXPECT_TRUE(CompareTrees(
- GetTree(rvhm2->current_host()),
- GetTree(rvhm2->GetSwappedOutRenderViewHost(orig_site_instance))));
-
- // Verify that the frame trees from different windows aren't equal.
- EXPECT_FALSE(CompareTrees(
- GetTree(opener_rvhm->current_host()), GetTree(rvhm1->current_host())));
- EXPECT_FALSE(CompareTrees(
- GetTree(opener_rvhm->current_host()), GetTree(rvhm2->current_host())));
-
- // Reload the original page, which will cause subframe ids to change. This
- // will ensure that the ids are properly replicated across reload.
- NavigateToURL(shell(), frame_tree_url);
-
- EXPECT_TRUE(CompareTrees(
- GetTree(opener_rvhm->current_host()),
- GetTree(opener_rvhm->GetSwappedOutRenderViewHost(site_instance1))));
- EXPECT_TRUE(CompareTrees(
- GetTree(opener_rvhm->current_host()),
- GetTree(opener_rvhm->GetSwappedOutRenderViewHost(site_instance2))));
-
- EXPECT_FALSE(CompareTrees(
- GetTree(opener_rvhm->current_host()), GetTree(rvhm1->current_host())));
- EXPECT_FALSE(CompareTrees(
- GetTree(opener_rvhm->current_host()), GetTree(rvhm2->current_host())));
-
- // Now let's ensure that using JS to add/remove frames results in proper
- // updates.
- EXPECT_TRUE(ExecuteScriptAndExtractBool(
- opener_contents,
- "window.domAutomationController.send(removeFrame());",
- &success));
- EXPECT_TRUE(success);
- frames = GetTree(opener_rvhm->current_host());
- EXPECT_TRUE(frames->GetList(kFrameTreeNodeSubtreeKey, &subtree));
- EXPECT_EQ(subtree->GetSize(), 2U);
-
- // Create a load observer for the iframe that will be created by the
- // JavaScript code we will execute.
- WindowedNotificationObserver load_observer(
- NOTIFICATION_LOAD_STOP,
- Source<NavigationController>(
- &opener_contents->GetController()));
- EXPECT_TRUE(ExecuteScriptAndExtractBool(
- opener_contents,
- "window.domAutomationController.send(addFrame());",
- &success));
- EXPECT_TRUE(success);
- load_observer.Wait();
-
- frames = GetTree(opener_rvhm->current_host());
- EXPECT_TRUE(frames->GetList(kFrameTreeNodeSubtreeKey, &subtree));
- EXPECT_EQ(subtree->GetSize(), 3U);
-
- EXPECT_TRUE(CompareTrees(
- GetTree(opener_rvhm->current_host()),
- GetTree(opener_rvhm->GetSwappedOutRenderViewHost(site_instance1))));
- EXPECT_TRUE(CompareTrees(
- GetTree(opener_rvhm->current_host()),
- GetTree(opener_rvhm->GetSwappedOutRenderViewHost(site_instance2))));
-}
-
// Test for crbug.com/143155. Frame tree updates during unload should not
// interrupt the intended navigation and show swappedout:// instead.
// Specifically:
@@ -1368,9 +1158,9 @@
DontPreemptNavigationWithFrameTreeUpdate) {
// Start two servers with different sites.
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
diff --git a/content/browser/renderer_host/render_view_host_unittest.cc b/content/browser/renderer_host/render_view_host_unittest.cc
index 2645f62..f523c06 100644
--- a/content/browser/renderer_host/render_view_host_unittest.cc
+++ b/content/browser/renderer_host/render_view_host_unittest.cc
@@ -6,6 +6,7 @@
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/browser/web_contents/navigation_controller_impl.h"
+#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/port/browser/render_view_host_delegate_view.h"
#include "content/public/browser/navigation_entry.h"
@@ -214,11 +215,11 @@
// Test that OnInputEventAck() detects bad messages.
TEST_F(RenderViewHostTest, BadMessageHandlerInputEventAck) {
EXPECT_EQ(0, process()->bad_msg_count());
- // ViewHostMsg_HandleInputEvent_ACK is defined taking 0 params but
+ // InputHostMsg_HandleInputEvent_ACK is defined taking 0 params but
// the code actually expects it to have at least one int para, this this
// bogus message will not fail at de-serialization but should fail in
// OnInputEventAck() processing.
- IPC::Message message(0, ViewHostMsg_HandleInputEvent_ACK::ID,
+ IPC::Message message(0, InputHostMsg_HandleInputEvent_ACK::ID,
IPC::Message::PRIORITY_NORMAL);
test_rvh()->OnMessageReceived(message);
EXPECT_EQ(1, process()->bad_msg_count());
diff --git a/content/browser/renderer_host/render_widget_host_browsertest.cc b/content/browser/renderer_host/render_widget_host_browsertest.cc
new file mode 100644
index 0000000..9f11299
--- /dev/null
+++ b/content/browser/renderer_host/render_widget_host_browsertest.cc
@@ -0,0 +1,68 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/path_service.h"
+#include "base/run_loop.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_paths.h"
+#include "content/shell/shell.h"
+#include "content/test/content_browser_test.h"
+#include "content/test/content_browser_test_utils.h"
+#include "net/base/net_util.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+namespace content {
+
+class RenderWidgetHostBrowserTest : public ContentBrowserTest {
+ public:
+ RenderWidgetHostBrowserTest() {}
+
+ virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
+ ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &test_dir_));
+ }
+
+ void GetSnapshotFromRendererCallback(const base::Closure& quit_closure,
+ bool* snapshot_valid,
+ bool success,
+ const SkBitmap& bitmap) {
+ quit_closure.Run();
+ EXPECT_EQ(success, true);
+
+ const int row_bytes = bitmap.rowBytesAsPixels();
+ SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
+ for (int i = 0; i < bitmap.width(); ++i) {
+ for (int j = 0; j < bitmap.height(); ++j) {
+ if (pixels[j * row_bytes + i] != SK_ColorRED) {
+ return;
+ }
+ }
+ }
+ *snapshot_valid = true;
+ }
+
+ protected:
+ base::FilePath test_dir_;
+};
+
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostBrowserTest,
+ GetSnapshotFromRendererTest) {
+ base::RunLoop run_loop;
+
+ NavigateToURL(shell(), GURL(net::FilePathToFileURL(
+ test_dir_.AppendASCII("rwh_simple.html"))));
+
+ bool snapshot_valid = false;
+ RenderViewHost* const rwh = shell()->web_contents()->GetRenderViewHost();
+ rwh->GetSnapshotFromRenderer(gfx::Rect(), base::Bind(
+ &RenderWidgetHostBrowserTest::GetSnapshotFromRendererCallback,
+ base::Unretained(this),
+ run_loop.QuitClosure(),
+ &snapshot_valid));
+ run_loop.Run();
+
+ EXPECT_EQ(snapshot_valid, true);
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_delegate.cc b/content/browser/renderer_host/render_widget_host_delegate.cc
index 54465b9..73f5325 100644
--- a/content/browser/renderer_host/render_widget_host_delegate.cc
+++ b/content/browser/renderer_host/render_widget_host_delegate.cc
@@ -17,4 +17,11 @@
return false;
}
+#if defined(OS_WIN) && defined(USE_AURA)
+gfx::NativeViewAccessible
+RenderWidgetHostDelegate::GetParentNativeViewAccessible() {
+ return NULL;
+}
+#endif
+
} // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h
index e283756..fa41727 100644
--- a/content/browser/renderer_host/render_widget_host_delegate.h
+++ b/content/browser/renderer_host/render_widget_host_delegate.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_BROWSER_RENDER_WIDGET_HOST_DELEGATE_H_
#define CONTENT_BROWSER_RENDER_WIDGET_HOST_DELEGATE_H_
+#include "build/build_config.h"
#include "content/common/content_export.h"
+#include "ui/gfx/native_widget_types.h"
namespace WebKit {
class WebMouseWheelEvent;
@@ -44,6 +46,11 @@
// Returns true if the |event| was handled.
virtual bool PreHandleWheelEvent(const WebKit::WebMouseWheelEvent& event);
+#if defined(OS_WIN) && defined(USE_AURA)
+ // Returns the widget's parent's NativeViewAccessible.
+ virtual gfx::NativeViewAccessible GetParentNativeViewAccessible();
+#endif
+
protected:
virtual ~RenderWidgetHostDelegate() {}
};
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 4b02fda..d0a2d5c 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -37,9 +37,9 @@
#include "content/common/accessibility_messages.h"
#include "content/common/content_constants_internal.h"
#include "content/common/gpu/gpu_messages.h"
+#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/port/browser/render_widget_host_view_port.h"
-#include "content/port/browser/smooth_scroll_gesture.h"
#include "content/public/browser/compositor_util.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/notification_service.h"
@@ -90,9 +90,6 @@
// This timeout impacts the "choppiness" of our window resize perf.
const int kPaintMsgTimeoutMS = 50;
-// How many milliseconds apart synthetic scroll messages should be sent.
-static const int kSyntheticScrollMessageIntervalMs = 8;
-
// Returns |true| if the two wheel events should be coalesced.
bool ShouldCoalesceMouseWheelEvents(const WebMouseWheelEvent& last_event,
const WebMouseWheelEvent& new_event) {
@@ -168,8 +165,7 @@
pending_mouse_lock_request_(false),
allow_privileged_mouse_lock_(false),
has_touch_handler_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
- tick_active_smooth_scroll_gestures_task_posted_(false),
+ weak_factory_(this),
touch_event_queue_(new TouchEventQueue(this)),
gesture_event_filter_(new GestureEventFilter(this)) {
CHECK(delegate_);
@@ -200,11 +196,11 @@
process_->WidgetRestored();
accessibility_mode_ =
- BrowserAccessibilityStateImpl::GetInstance()->GetAccessibilityMode();
+ BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode();
#if defined(USE_AURA)
- bool overscroll_enabled = !CommandLine::ForCurrentProcess()->
- HasSwitch(switches::kDisableOverscrollHistoryNavigation);
+ bool overscroll_enabled = CommandLine::ForCurrentProcess()->
+ GetSwitchValueASCII(switches::kOverscrollHistoryNavigation) != "0";
SetOverscrollControllerEnabled(overscroll_enabled);
#endif
}
@@ -274,6 +270,10 @@
void RenderWidgetHostImpl::ResetSizeAndRepaintPendingFlags() {
resize_ack_pending_ = false;
+ if (repaint_ack_pending_) {
+ TRACE_EVENT_ASYNC_END0(
+ "renderer_host", "RenderWidgetHostImpl::repaint_ack_pending_", this);
+ }
repaint_ack_pending_ = false;
in_flight_size_.SetSize(0, 0);
}
@@ -298,14 +298,15 @@
waiting_for_screen_rects_ack_ = true;
}
-int RenderWidgetHostImpl::SyntheticScrollMessageInterval() const {
- return kSyntheticScrollMessageIntervalMs;
+base::TimeDelta
+ RenderWidgetHostImpl::GetSyntheticScrollMessageInterval() const {
+ return smooth_scroll_gesture_controller_.GetSyntheticScrollMessageInterval();
}
void RenderWidgetHostImpl::SetOverscrollControllerEnabled(bool enabled) {
if (!enabled)
overscroll_controller_.reset();
- else if (!overscroll_controller_.get())
+ else if (!overscroll_controller_)
overscroll_controller_.reset(new OverscrollController(this));
}
@@ -366,7 +367,7 @@
msg_is_ok = OnSwapCompositorFrame(msg))
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnUpdateRect)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateIsDelayed, OnUpdateIsDelayed)
- IPC_MESSAGE_HANDLER(ViewHostMsg_HandleInputEvent_ACK, OnInputEventAck)
+ IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck)
IPC_MESSAGE_HANDLER(ViewHostMsg_BeginSmoothScroll, OnBeginSmoothScroll)
IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck)
IPC_MESSAGE_HANDLER(ViewHostMsg_MoveCaret_ACK, OnMsgMoveCaretAck)
@@ -533,7 +534,7 @@
}
void RenderWidgetHostImpl::Focus() {
- Send(new ViewMsg_SetFocus(routing_id_, true));
+ Send(new InputMsg_SetFocus(routing_id_, true));
}
void RenderWidgetHostImpl::Blur() {
@@ -543,11 +544,11 @@
if (IsMouseLocked())
view_->UnlockMouse();
- Send(new ViewMsg_SetFocus(routing_id_, false));
+ Send(new InputMsg_SetFocus(routing_id_, false));
}
void RenderWidgetHostImpl::LostCapture() {
- Send(new ViewMsg_MouseCaptureLost(routing_id_));
+ Send(new InputMsg_MouseCaptureLost(routing_id_));
}
void RenderWidgetHostImpl::SetActive(bool active) {
@@ -699,6 +700,8 @@
if (!repaint_ack_pending_ && !resize_ack_pending_ && !view_being_painted_) {
repaint_start_time_ = TimeTicks::Now();
repaint_ack_pending_ = true;
+ TRACE_EVENT_ASYNC_BEGIN0(
+ "renderer_host", "RenderWidgetHostImpl::repaint_ack_pending_", this);
Send(new ViewMsg_Repaint(routing_id_, view_size));
}
@@ -760,7 +763,8 @@
}
void RenderWidgetHostImpl::ScheduleComposite() {
- if (is_hidden_ || !is_accelerated_compositing_active_) {
+ if (is_hidden_ || !is_accelerated_compositing_active_ ||
+ current_size_.IsEmpty()) {
return;
}
@@ -768,6 +772,8 @@
if (!repaint_ack_pending_ && !resize_ack_pending_ && !view_being_painted_) {
repaint_start_time_ = TimeTicks::Now();
repaint_ack_pending_ = true;
+ TRACE_EVENT_ASYNC_BEGIN0(
+ "renderer_host", "RenderWidgetHostImpl::repaint_ack_pending_", this);
Send(new ViewMsg_Repaint(routing_id_, current_size_));
}
}
@@ -1028,7 +1034,7 @@
// more WM_MOUSEMOVE events than we wish to send to the renderer.
if (mouse_event.type == WebInputEvent::MouseMove) {
if (mouse_move_pending_) {
- if (!next_mouse_move_.get()) {
+ if (!next_mouse_move_) {
next_mouse_move_.reset(new WebMouseEvent(mouse_event));
} else {
// Accumulate movement deltas.
@@ -1137,11 +1143,15 @@
}
}
+void RenderWidgetHostImpl::SendCursorVisibilityState(bool is_visible) {
+ Send(new InputMsg_CursorVisibilityChange(GetRoutingID(), is_visible));
+}
+
void RenderWidgetHostImpl::SendInputEvent(const WebInputEvent& input_event,
int event_size,
bool is_keyboard_shortcut) {
input_event_start_time_ = TimeTicks::Now();
- Send(new ViewMsg_HandleInputEvent(
+ Send(new InputMsg_HandleInputEvent(
routing_id_, &input_event, is_keyboard_shortcut));
increment_in_flight_event_count();
}
@@ -1232,15 +1242,14 @@
}
void RenderWidgetHostImpl::AddKeyboardListener(KeyboardListener* listener) {
- keyboard_listeners_.push_back(listener);
+ keyboard_listeners_.AddObserver(listener);
}
void RenderWidgetHostImpl::RemoveKeyboardListener(
KeyboardListener* listener) {
- // Ensure that the element is actually in the list.
- DCHECK(std::find(keyboard_listeners_.begin(), keyboard_listeners_.end(),
- listener) != keyboard_listeners_.end());
- keyboard_listeners_.remove(listener);
+ // Ensure that the element is actually an observer.
+ DCHECK(keyboard_listeners_.HasObserver(listener));
+ keyboard_listeners_.RemoveObserver(listener);
}
void RenderWidgetHostImpl::GetWebScreenInfo(WebKit::WebScreenInfo* result) {
@@ -1250,6 +1259,13 @@
RenderWidgetHostViewPort::GetDefaultScreenInfo(result);
}
+const NativeWebKeyboardEvent*
+ RenderWidgetHostImpl::GetLastKeyboardEvent() const {
+ if (key_queue_.empty())
+ return NULL;
+ return &key_queue_.front();
+}
+
void RenderWidgetHostImpl::NotifyScreenInfoChanged() {
WebKit::WebScreenInfo screen_info;
GetWebScreenInfo(&screen_info);
@@ -1322,7 +1338,7 @@
// Must reset these to ensure that gesture events work with a new renderer.
gesture_event_filter_->Reset();
- if (overscroll_controller_.get())
+ if (overscroll_controller_)
overscroll_controller_->Reset();
// Must reset these to ensure that keyboard events work with a new renderer.
@@ -1598,18 +1614,6 @@
param.a.AssignTo(frame.get());
if (view_) {
-#if defined(OS_ANDROID)
- view_->UpdateFrameInfo(
- frame->metadata.root_scroll_offset,
- frame->metadata.page_scale_factor,
- gfx::Vector2dF(
- frame->metadata.min_page_scale_factor,
- frame->metadata.max_page_scale_factor),
- frame->metadata.root_layer_size,
- frame->metadata.viewport_size,
- frame->metadata.location_bar_offset,
- frame->metadata.location_bar_content_translation);
-#endif
view_->OnSwapCompositorFrame(frame.Pass());
} else {
cc::CompositorFrameAck ack;
@@ -1618,6 +1622,8 @@
ack.gl_frame_data->sync_point = 0;
} else if (frame->delegated_frame_data) {
ack.resources.swap(frame->delegated_frame_data->resource_list);
+ } else if (frame->software_frame_data) {
+ ack.last_dib_id = frame->software_frame_data->dib_id;
}
SendSwapCompositorFrameAck(routing_id_, process_->GetID(), ack);
}
@@ -1648,6 +1654,9 @@
bool is_repaint_ack =
ViewHostMsg_UpdateRect_Flags::is_repaint_ack(params.flags);
if (is_repaint_ack) {
+ DCHECK(repaint_ack_pending_);
+ TRACE_EVENT_ASYNC_END0(
+ "renderer_host", "RenderWidgetHostImpl::repaint_ack_pending_", this);
repaint_ack_pending_ = false;
TimeDelta delta = TimeTicks::Now() - repaint_start_time_;
UMA_HISTOGRAM_TIMES("MPArch.RWH_RepaintDelta", delta);
@@ -1673,9 +1682,11 @@
GetProcess()->ReceivedBadMessage();
} else {
UNSHIPPED_TRACE_EVENT_INSTANT2("test_latency", "UpdateRect",
+ TRACE_EVENT_SCOPE_THREAD,
"x+y", params.bitmap_rect.x() + params.bitmap_rect.y(),
"color", 0xffffff & *static_cast<uint32*>(dib->memory()));
UNSHIPPED_TRACE_EVENT_INSTANT1("test_latency", "UpdateRectWidth",
+ TRACE_EVENT_SCOPE_THREAD,
"width", params.bitmap_rect.width());
// Scroll the backing store.
@@ -1707,7 +1718,7 @@
bool post_callback = new_auto_size_.IsEmpty();
new_auto_size_ = params.view_size;
if (post_callback) {
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&RenderWidgetHostImpl::DelayedAutoResized,
weak_factory_.GetWeakPtr()));
@@ -1788,6 +1799,7 @@
delta = now - paint_start;
UMA_HISTOGRAM_TIMES("MPArch.RWH_TotalPaintTime", delta);
UNSHIPPED_TRACE_EVENT_INSTANT1("test_latency", "UpdateRectComplete",
+ TRACE_EVENT_SCOPE_THREAD,
"x+y", params.bitmap_rect.x() + params.bitmap_rect.y());
}
@@ -1808,12 +1820,6 @@
if (decrement_in_flight_event_count() == 0)
StopHangMonitorTimeout();
- // If an input ack is pending, then hold off ticking the gesture
- // until we get an input ack.
- if (in_process_event_types_.empty() &&
- !active_smooth_scroll_gestures_.empty())
- TickActiveSmoothScrollGesture();
-
int type = static_cast<int>(event_type);
if (type < WebInputEvent::Undefined) {
RecordAction(UserMetricsAction("BadMessageTerminate_RWH2"));
@@ -1822,7 +1828,7 @@
mouse_move_pending_ = false;
// now, we can send the next mouse move event
- if (next_mouse_move_.get()) {
+ if (next_mouse_move_) {
DCHECK(next_mouse_move_->type == WebInputEvent::MouseMove);
ForwardMouseEvent(*next_mouse_move_);
}
@@ -1852,94 +1858,15 @@
}
void RenderWidgetHostImpl::OnBeginSmoothScroll(
- int gesture_id, const ViewHostMsg_BeginSmoothScroll_Params ¶ms) {
+ const ViewHostMsg_BeginSmoothScroll_Params& params) {
if (!view_)
return;
- active_smooth_scroll_gestures_.insert(
- std::make_pair(gesture_id,
- view_->CreateSmoothScrollGesture(
- params.scroll_down, params.pixels_to_scroll,
- params.mouse_event_x, params.mouse_event_y)));
-
- // If an input ack is pending, then hold off ticking the gesture
- // until we get an input ack.
- if (!in_process_event_types_.empty())
- return;
- if (tick_active_smooth_scroll_gestures_task_posted_)
- return;
- TickActiveSmoothScrollGesture();
-}
-
-void RenderWidgetHostImpl::TickActiveSmoothScrollGesture() {
- TRACE_EVENT0("input", "RenderWidgetHostImpl::TickActiveSmoothScrollGesture");
- tick_active_smooth_scroll_gestures_task_posted_ = false;
- if (active_smooth_scroll_gestures_.empty()) {
- TRACE_EVENT_INSTANT0("input", "EarlyOut_NoActiveScrollGesture");
- return;
- }
-
- base::TimeTicks now = TimeTicks::HighResNow();
- base::TimeDelta preferred_interval =
- base::TimeDelta::FromMilliseconds(kSyntheticScrollMessageIntervalMs);
- base::TimeDelta time_until_next_ideal_interval =
- (last_smooth_scroll_gestures_tick_time_ + preferred_interval) -
- now;
- if (time_until_next_ideal_interval.InMilliseconds() > 0) {
- TRACE_EVENT_INSTANT1(
- "input", "EarlyOut_TickedTooRecently",
- "delay", time_until_next_ideal_interval.InMilliseconds());
- // Post a task.
- tick_active_smooth_scroll_gestures_task_posted_ = true;
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&RenderWidgetHostImpl::TickActiveSmoothScrollGesture,
- weak_factory_.GetWeakPtr()),
- time_until_next_ideal_interval);
- return;
- }
-
- last_smooth_scroll_gestures_tick_time_ = now;
-
- // Separate ticking of gestures from sending their completion messages.
- std::vector<int> ids_that_are_done;
- for (SmoothScrollGestureMap::iterator it =
- active_smooth_scroll_gestures_.begin();
- it != active_smooth_scroll_gestures_.end();
- ++it) {
-
- bool active = it->second->ForwardInputEvents(now, this);
- if (!active)
- ids_that_are_done.push_back(it->first);
- }
-
- // Delete completed gestures and send their completion event.
- for(size_t i = 0; i < ids_that_are_done.size(); i++) {
- int id = ids_that_are_done[i];
- SmoothScrollGestureMap::iterator it =
- active_smooth_scroll_gestures_.find(id);
- DCHECK(it != active_smooth_scroll_gestures_.end());
- active_smooth_scroll_gestures_.erase(it);
-
- Send(new ViewMsg_SmoothScrollCompleted(routing_id_, id));
- }
-
- // No need to post the next tick if an input is in flight.
- if (!in_process_event_types_.empty())
- return;
-
- TRACE_EVENT_INSTANT1("input", "PostTickTask",
- "delay", preferred_interval.InMilliseconds());
- tick_active_smooth_scroll_gestures_task_posted_ = true;
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&RenderWidgetHostImpl::TickActiveSmoothScrollGesture,
- weak_factory_.GetWeakPtr()),
- preferred_interval);
+ smooth_scroll_gesture_controller_.BeginSmoothScroll(view_, params);
}
void RenderWidgetHostImpl::OnSelectRangeAck() {
select_range_pending_ = false;
- if (next_selection_range_.get()) {
+ if (next_selection_range_) {
scoped_ptr<SelectionRange> next(next_selection_range_.Pass());
SelectRange(next->start, next->end);
}
@@ -1947,7 +1874,7 @@
void RenderWidgetHostImpl::OnMsgMoveCaretAck() {
move_caret_pending_ = false;
- if (next_move_caret_.get()) {
+ if (next_move_caret_) {
scoped_ptr<gfx::Point> next(next_move_caret_.Pass());
MoveCaret(*next);
}
@@ -1956,7 +1883,7 @@
void RenderWidgetHostImpl::ProcessWheelAck(bool processed) {
mouse_wheel_pending_ = false;
- if (overscroll_controller_.get())
+ if (overscroll_controller_)
overscroll_controller_->ReceivedEventACK(current_wheel_event_, processed);
// Now send the next (coalesced) mouse wheel event.
@@ -1972,11 +1899,14 @@
}
void RenderWidgetHostImpl::ProcessGestureAck(bool processed, int type) {
- if (overscroll_controller_.get()) {
+ if (overscroll_controller_) {
overscroll_controller_->ReceivedEventACK(
gesture_event_filter_->GetGestureEventAwaitingAck(), processed);
}
gesture_event_filter_->ProcessGestureAck(processed, type);
+
+ if (view_)
+ view_->GestureEventAck(type);
}
void RenderWidgetHostImpl::ProcessTouchAck(InputEventAckState ack_result) {
@@ -2152,7 +2082,10 @@
&scheduled_completion_callback);
if (needs_full_paint) {
repaint_start_time_ = TimeTicks::Now();
+ DCHECK(!repaint_ack_pending_);
repaint_ack_pending_ = true;
+ TRACE_EVENT_ASYNC_BEGIN0(
+ "renderer_host", "RenderWidgetHostImpl::repaint_ack_pending_", this);
Send(new ViewMsg_Repaint(routing_id_, view_size));
}
@@ -2180,17 +2113,11 @@
}
void RenderWidgetHostImpl::Replace(const string16& word) {
- Send(new ViewMsg_Replace(routing_id_, word));
+ Send(new InputMsg_Replace(routing_id_, word));
}
void RenderWidgetHostImpl::ReplaceMisspelling(const string16& word) {
-#if defined(OS_MACOSX)
- // TODO(rouslan): Use ViewMsg_ReplaceMisspelling on Mac after Mac implements
- // asynchronous spell checking and enables unified text checking.
- Send(new ViewMsg_Replace(routing_id_, word));
-#else
- Send(new ViewMsg_ReplaceMisspelling(routing_id_, word));
-#endif
+ Send(new InputMsg_ReplaceMisspelling(routing_id_, word));
}
void RenderWidgetHostImpl::SetIgnoreInputEvents(bool ignore_input_events) {
@@ -2202,9 +2129,10 @@
if (event.skip_in_browser || event.type != WebKeyboardEvent::RawKeyDown)
return false;
- for (std::list<KeyboardListener*>::iterator it = keyboard_listeners_.begin();
- it != keyboard_listeners_.end(); ++it) {
- if ((*it)->HandleKeyPressEvent(event))
+ ObserverList<KeyboardListener>::Iterator it(keyboard_listeners_);
+ KeyboardListener* listener;
+ while ((listener = it.GetNext()) != NULL) {
+ if (listener->HandleKeyPressEvent(event))
return true;
}
@@ -2272,7 +2200,7 @@
void RenderWidgetHostImpl::SetEditCommandsForNextKeyEvent(
const std::vector<EditCommand>& commands) {
- Send(new ViewMsg_SetEditCommandsForNextKeyEvent(GetRoutingID(), commands));
+ Send(new InputMsg_SetEditCommandsForNextKeyEvent(GetRoutingID(), commands));
}
void RenderWidgetHostImpl::SetAccessibilityMode(AccessibilityMode mode) {
@@ -2310,20 +2238,27 @@
Send(new AccessibilityMsg_FatalError(GetRoutingID()));
}
+#if defined(OS_WIN) && defined(USE_AURA)
+gfx::NativeViewAccessible
+RenderWidgetHostImpl::GetParentNativeViewAccessible() const {
+ return delegate_->GetParentNativeViewAccessible();
+}
+#endif
+
void RenderWidgetHostImpl::ExecuteEditCommand(const std::string& command,
const std::string& value) {
- Send(new ViewMsg_ExecuteEditCommand(GetRoutingID(), command, value));
+ Send(new InputMsg_ExecuteEditCommand(GetRoutingID(), command, value));
}
void RenderWidgetHostImpl::ScrollFocusedEditableNodeIntoRect(
const gfx::Rect& rect) {
- Send(new ViewMsg_ScrollFocusedEditableNodeIntoRect(GetRoutingID(), rect));
+ Send(new InputMsg_ScrollFocusedEditableNodeIntoRect(GetRoutingID(), rect));
}
void RenderWidgetHostImpl::SelectRange(const gfx::Point& start,
const gfx::Point& end) {
if (select_range_pending_) {
- if (!next_selection_range_.get()) {
+ if (!next_selection_range_) {
next_selection_range_.reset(new SelectionRange());
}
next_selection_range_->start = start;
@@ -2332,7 +2267,7 @@
}
select_range_pending_ = true;
- Send(new ViewMsg_SelectRange(GetRoutingID(), start, end));
+ Send(new InputMsg_SelectRange(GetRoutingID(), start, end));
}
void RenderWidgetHostImpl::MoveCaret(const gfx::Point& point) {
@@ -2342,54 +2277,54 @@
}
move_caret_pending_ = true;
- Send(new ViewMsg_MoveCaret(GetRoutingID(), point));
+ Send(new InputMsg_MoveCaret(GetRoutingID(), point));
}
void RenderWidgetHostImpl::Undo() {
- Send(new ViewMsg_Undo(GetRoutingID()));
+ Send(new InputMsg_Undo(GetRoutingID()));
RecordAction(UserMetricsAction("Undo"));
}
void RenderWidgetHostImpl::Redo() {
- Send(new ViewMsg_Redo(GetRoutingID()));
+ Send(new InputMsg_Redo(GetRoutingID()));
RecordAction(UserMetricsAction("Redo"));
}
void RenderWidgetHostImpl::Cut() {
- Send(new ViewMsg_Cut(GetRoutingID()));
+ Send(new InputMsg_Cut(GetRoutingID()));
RecordAction(UserMetricsAction("Cut"));
}
void RenderWidgetHostImpl::Copy() {
- Send(new ViewMsg_Copy(GetRoutingID()));
+ Send(new InputMsg_Copy(GetRoutingID()));
RecordAction(UserMetricsAction("Copy"));
}
void RenderWidgetHostImpl::CopyToFindPboard() {
#if defined(OS_MACOSX)
// Windows/Linux don't have the concept of a find pasteboard.
- Send(new ViewMsg_CopyToFindPboard(GetRoutingID()));
+ Send(new InputMsg_CopyToFindPboard(GetRoutingID()));
RecordAction(UserMetricsAction("CopyToFindPboard"));
#endif
}
void RenderWidgetHostImpl::Paste() {
- Send(new ViewMsg_Paste(GetRoutingID()));
+ Send(new InputMsg_Paste(GetRoutingID()));
RecordAction(UserMetricsAction("Paste"));
}
void RenderWidgetHostImpl::PasteAndMatchStyle() {
- Send(new ViewMsg_PasteAndMatchStyle(GetRoutingID()));
+ Send(new InputMsg_PasteAndMatchStyle(GetRoutingID()));
RecordAction(UserMetricsAction("PasteAndMatchStyle"));
}
void RenderWidgetHostImpl::Delete() {
- Send(new ViewMsg_Delete(GetRoutingID()));
+ Send(new InputMsg_Delete(GetRoutingID()));
RecordAction(UserMetricsAction("DeleteSelection"));
}
void RenderWidgetHostImpl::SelectAll() {
- Send(new ViewMsg_SelectAll(GetRoutingID()));
+ Send(new InputMsg_SelectAll(GetRoutingID()));
RecordAction(UserMetricsAction("SelectAll"));
}
bool RenderWidgetHostImpl::GotResponseToLockMouseRequest(bool allowed) {
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index e81bc5d..487a9e9 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -17,11 +17,13 @@
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
#include "base/process_util.h"
#include "base/string16.h"
#include "base/time.h"
#include "base/timer.h"
#include "build/build_config.h"
+#include "content/browser/renderer_host/smooth_scroll_gesture_controller.h"
#include "content/common/view_message_enums.h"
#include "content/port/common/input_event_ack_state.h"
#include "content/public/browser/render_widget_host.h"
@@ -70,7 +72,7 @@
class OverscrollController;
class RenderWidgetHostDelegate;
class RenderWidgetHostViewPort;
-class SmoothScrollGesture;
+class SmoothScrollGestureController;
class TouchEventQueue;
struct EditCommand;
@@ -155,6 +157,8 @@
const gfx::Rect& src_subrect,
const base::Callback<void(bool, const SkBitmap&)>& callback) OVERRIDE;
+ const NativeWebKeyboardEvent* GetLastKeyboardEvent() const;
+
// Notification that the screen info has changed.
void NotifyScreenInfoChanged();
@@ -195,6 +199,9 @@
// Called to notify the RenderWidget that it has lost the mouse lock.
virtual void LostMouseLock();
+ // Noifies the RenderWidget of the current mouse cursor visibility state.
+ void SendCursorVisibilityState(bool is_visible);
+
// Tells us whether the page is rendered directly via the GPU process.
bool is_accelerated_compositing_active() {
return is_accelerated_compositing_active_;
@@ -371,6 +378,10 @@
// Kill the renderer because we got a fatal accessibility error.
void FatalAccessibilityTreeError();
+#if defined(OS_WIN) && defined(USE_AURA)
+ gfx::NativeViewAccessible GetParentNativeViewAccessible() const;
+#endif
+
// Executes the edit command on the RenderView.
void ExecuteEditCommand(const std::string& command,
const std::string& value);
@@ -449,7 +460,7 @@
return overscroll_controller_.get();
}
- int SyntheticScrollMessageInterval() const;
+ base::TimeDelta GetSyntheticScrollMessageInterval() const;
// Sets whether the overscroll controller should be enabled for this page.
void SetOverscrollControllerEnabled(bool enabled);
@@ -582,8 +593,7 @@
void OnInputEventAck(WebKit::WebInputEvent::Type event_type,
InputEventAckState ack_result);
void OnBeginSmoothScroll(
- int gesture_id,
- const ViewHostMsg_BeginSmoothScroll_Params ¶ms);
+ const ViewHostMsg_BeginSmoothScroll_Params& params);
void OnSelectRangeAck();
void OnMsgMoveCaretAck();
virtual void OnFocus();
@@ -664,9 +674,6 @@
// which may get in recursive loops).
void DelayedAutoResized();
- // Called periodically to advance the active scroll gesture after being
- // initiated by OnBeginSmoothScroll.
- void TickActiveSmoothScrollGesture();
// Our delegate, which wants to know mainly about keyboard events.
// It will remain non-NULL until DetachDelegate() is called.
@@ -733,7 +740,7 @@
gfx::Rect last_window_screen_rect_;
// True if a mouse move event was sent to the render view and we are waiting
- // for a corresponding ViewHostMsg_HandleInputEvent_ACK message.
+ // for a corresponding InputHostMsg_HandleInputEvent_ACK message.
bool mouse_move_pending_;
// The next mouse move event to send (only non-null while mouse_move_pending_
@@ -777,7 +784,7 @@
base::TimeTicks input_event_start_time_;
// Keyboard event listeners.
- std::list<KeyboardListener*> keyboard_listeners_;
+ ObserverList<KeyboardListener> keyboard_listeners_;
// If true, then we should repaint when restoring even if we have a
// backingstore. This flag is set to true if we receive a paint message
@@ -860,12 +867,7 @@
base::WeakPtrFactory<RenderWidgetHostImpl> weak_factory_;
- typedef std::map<int, scoped_refptr<SmoothScrollGesture> >
- SmoothScrollGestureMap;
- SmoothScrollGestureMap active_smooth_scroll_gestures_;
- base::TimeTicks last_smooth_scroll_gestures_tick_time_;
- bool tick_active_smooth_scroll_gestures_task_posted_;
-
+ SmoothScrollGestureController smooth_scroll_gesture_controller_;
scoped_ptr<TouchEventQueue> touch_event_queue_;
scoped_ptr<GestureEventFilter> gesture_event_filter_;
scoped_ptr<OverscrollController> overscroll_controller_;
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index 54e5472..84945b9 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -8,14 +8,15 @@
#include "base/timer.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/renderer_host/backing_store.h"
-#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/gesture_event_filter.h"
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/browser/renderer_host/overscroll_controller_delegate.h"
+#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/tap_suppression_controller.h"
#include "content/browser/renderer_host/tap_suppression_controller_client.h"
#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/browser/renderer_host/touch_event_queue.h"
+#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/port/browser/render_widget_host_view_port.h"
#include "content/public/browser/notification_details.h"
@@ -657,13 +658,13 @@
#endif
// Process all pending tasks to avoid leaks.
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
}
void SendInputEventACK(WebInputEvent::Type type,
InputEventAckState ack_result) {
scoped_ptr<IPC::Message> response(
- new ViewHostMsg_HandleInputEvent_ACK(0, type, ack_result));
+ new InputHostMsg_HandleInputEvent_ACK(0, type, ack_result));
host_->OnMessageReceived(*response);
}
@@ -821,7 +822,7 @@
return reinterpret_cast<const WebInputEvent*>(data);
}
- MessageLoopForUI message_loop_;
+ base::MessageLoopForUI message_loop_;
scoped_ptr<TestBrowserContext> browser_context_;
RenderWidgetHostProcess* process_; // Deleted automatically by the widget.
@@ -1096,7 +1097,7 @@
// Test that we don't paint when we're hidden, but we still send the ACK. Most
// of the rest of the painting is tested in the GetBackingStore* ones.
TEST_F(RenderWidgetHostTest, HiddenPaint) {
- BrowserThreadImpl ui_thread(BrowserThread::UI, MessageLoop::current());
+ BrowserThreadImpl ui_thread(BrowserThread::UI, base::MessageLoop::current());
// Hide the widget, it should have sent out a message to the renderer.
EXPECT_FALSE(host_->is_hidden_);
host_->WasHidden();
@@ -1160,7 +1161,7 @@
// Make sure we sent the input event to the renderer.
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
// Send the simulated response from the renderer back.
@@ -1186,7 +1187,7 @@
// Make sure we sent the input event to the renderer.
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
// Send the simulated response from the renderer back.
@@ -1225,7 +1226,7 @@
// Make sure only KeyUp was sent to the renderer.
EXPECT_EQ(1U, process_->sink().message_count());
- EXPECT_EQ(ViewMsg_HandleInputEvent::ID,
+ EXPECT_EQ(InputMsg_HandleInputEvent::ID,
process_->sink().GetMessageAt(0)->type());
process_->sink().ClearMessages();
@@ -1249,7 +1250,7 @@
// Check that only the first event was sent.
EXPECT_EQ(1U, process_->sink().message_count());
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
// Check that the ACK sends the second message.
@@ -1258,25 +1259,25 @@
// The coalesced events can queue up a delayed ack
// so that additional input events can be processed before
// we turn off coalescing.
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(1U, process_->sink().message_count());
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
// One more time.
SendInputEventACK(WebInputEvent::MouseWheel,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(1U, process_->sink().message_count());
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
// After the final ack, the queue should be empty.
SendInputEventACK(WebInputEvent::MouseWheel,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(0U, process_->sink().message_count());
SimulateGestureFlingStartEvent(0.f, 0.f, WebGestureEvent::Touchpad);
@@ -1292,7 +1293,7 @@
EXPECT_EQ(1U, process_->sink().message_count());
SendInputEventACK(WebInputEvent::GestureScrollBegin,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
// Send a wheel event, should get sent directly.
SimulateWheelEvent(0, -5, 0, false);
@@ -1365,40 +1366,40 @@
// Check that only the first event was sent.
EXPECT_EQ(1U, process_->sink().message_count());
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
// Check that the ACK sends the second message.
SendInputEventACK(WebInputEvent::GestureScrollBegin,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(1U, process_->sink().message_count());
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
// Ack for queued coalesced event.
SendInputEventACK(WebInputEvent::GestureScrollUpdate,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(1U, process_->sink().message_count());
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
// Ack for queued uncoalesced event.
SendInputEventACK(WebInputEvent::GestureScrollUpdate,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(1U, process_->sink().message_count());
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
// After the final ack, the queue should be empty.
SendInputEventACK(WebInputEvent::GestureScrollEnd,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(0U, process_->sink().message_count());
}
@@ -1487,16 +1488,16 @@
// Check that only the first event was sent.
EXPECT_EQ(1U, process_->sink().message_count());
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
// Check that the ACK sends the second message.
SendInputEventACK(WebInputEvent::GestureScrollBegin,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(1U, process_->sink().message_count());
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
// Enqueued.
@@ -1520,12 +1521,12 @@
// Check that the ACK sends both scroll and pinch updates.
SendInputEventACK(WebInputEvent::GesturePinchBegin,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(2U, process_->sink().message_count());
EXPECT_TRUE(process_->sink().GetFirstMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
// The next ACK should be getting ignored.
@@ -1579,7 +1580,7 @@
// Check that the ACK gets ignored.
SendInputEventACK(WebInputEvent::GestureScrollUpdate,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(0U, process_->sink().message_count());
// The flag should have been flipped back to false.
EXPECT_FALSE(host_->WillIgnoreNextACK());
@@ -1602,33 +1603,33 @@
// Check that the ACK sends the next scroll pinch pair.
SendInputEventACK(WebInputEvent::GesturePinchUpdate,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(2U, process_->sink().message_count());
EXPECT_TRUE(process_->sink().GetFirstMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
// Check that the ACK sends the second message.
SendInputEventACK(WebInputEvent::GestureScrollUpdate,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(0U, process_->sink().message_count());
// Check that the ACK sends the second message.
SendInputEventACK(WebInputEvent::GesturePinchUpdate,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(1U, process_->sink().message_count());
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_HandleInputEvent::ID));
+ InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
// Check that the queue is empty after ACK and no messages get sent.
SendInputEventACK(WebInputEvent::GestureScrollUpdate,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(0U, process_->sink().message_count());
EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
}
@@ -1651,13 +1652,13 @@
EXPECT_TRUE(host_->FlingInProgress());
SendInputEventACK(WebInputEvent::GestureFlingStart,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
SimulateGestureEvent(WebInputEvent::GestureFlingCancel, source_device);
EXPECT_FALSE(host_->FlingInProgress());
EXPECT_EQ(2U, process_->sink().message_count());
SendInputEventACK(WebInputEvent::GestureFlingCancel,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
// GFC before previous GFS is acked.
@@ -1672,10 +1673,10 @@
// Advance state realistically.
SendInputEventACK(WebInputEvent::GestureFlingStart,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
SendInputEventACK(WebInputEvent::GestureFlingCancel,
INPUT_EVENT_ACK_STATE_CONSUMED);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
// GFS is added to the queue if another event is pending
@@ -1742,9 +1743,11 @@
EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
// Wait long enough for first timeout and see if it fired.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(10));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(10));
+ base::MessageLoop::current()->Run();
EXPECT_EQ(1U, process_->sink().message_count());
EXPECT_EQ(1U, host_->GestureEventLastQueueEventSize());
@@ -1771,9 +1774,11 @@
EXPECT_EQ(WebInputEvent::GestureTap,
host_->GestureEventLastQueueEvent().type);
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(10));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(10));
+ base::MessageLoop::current()->Run();
// If the deferral timer incorrectly fired, it sent an extra message.
EXPECT_EQ(1U, process_->sink().message_count());
@@ -1793,9 +1798,11 @@
EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
// Wait long enough for the timeout and verify it fired.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(10));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(10));
+ base::MessageLoop::current()->Run();
EXPECT_EQ(1U, process_->sink().message_count());
EXPECT_EQ(1U, host_->GestureEventLastQueueEventSize());
@@ -1830,9 +1837,11 @@
EXPECT_EQ(WebInputEvent::GestureScrollBegin,
host_->GestureEventLastQueueEvent().type);
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(10));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(10));
+ base::MessageLoop::current()->Run();
// If the deferral timer incorrectly fired, it will send an extra message.
EXPECT_EQ(1U, process_->sink().message_count());
@@ -1856,9 +1865,11 @@
EXPECT_EQ(0U, process_->sink().message_count());
EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(10));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(10));
+ base::MessageLoop::current()->Run();
// If the deferral timer incorrectly fired, it will send an extra message.
EXPECT_EQ(0U, process_->sink().message_count());
@@ -1877,9 +1888,11 @@
EXPECT_EQ(0U, process_->sink().message_count());
EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(10));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(10));
+ base::MessageLoop::current()->Run();
EXPECT_EQ(1U, process_->sink().message_count());
EXPECT_EQ(1U, host_->GestureEventLastQueueEventSize());
@@ -1929,9 +1942,11 @@
EXPECT_EQ(2U, host_->GestureEventLastQueueEventSize());
EXPECT_EQ(3U, host_->GestureEventDebouncingQueueSize());
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(5));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(5));
+ base::MessageLoop::current()->Run();
// The deferred events are correctly queued in coalescing queue.
EXPECT_EQ(1U, process_->sink().message_count());
@@ -2976,9 +2991,11 @@
host_->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
// Wait long enough for first timeout and see if it fired.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(10));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(10));
+ base::MessageLoop::current()->Run();
EXPECT_TRUE(host_->unresponsive_timer_fired());
}
@@ -2994,9 +3011,11 @@
host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
// Wait long enough for first timeout and see if it fired.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(40));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(40));
+ base::MessageLoop::current()->Run();
EXPECT_TRUE(host_->unresponsive_timer_fired());
}
@@ -3011,9 +3030,11 @@
host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
// Wait long enough for the second timeout and see if it fired.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(25));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(25));
+ base::MessageLoop::current()->Run();
EXPECT_TRUE(host_->unresponsive_timer_fired());
}
@@ -3032,9 +3053,11 @@
INPUT_EVENT_ACK_STATE_CONSUMED);
// Wait long enough for first timeout and see if it fired.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(40));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(40));
+ base::MessageLoop::current()->Run();
EXPECT_TRUE(host_->unresponsive_timer_fired());
}
@@ -3492,9 +3515,11 @@
// enough overscroll to complete the gesture, the overscroll controller
// will reset the state. The scroll-end should therefore be dispatched to the
// renderer, and the gesture-event-filter should await an ACK for it.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(15));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(15));
+ base::MessageLoop::current()->Run();
EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode());
EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_delegate()->current_mode());
@@ -3596,15 +3621,26 @@
EXPECT_EQ(205.f, host_->overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, host_->overscroll_delegate()->delta_y());
+ // The touch-end/cancel event should always reach the renderer if the page has
+ // touch handlers.
ReleaseTouchPoint(0);
SendTouchEvent();
+ EXPECT_EQ(1U, process_->sink().message_count());
+ EXPECT_EQ(1U, host_->TouchEventQueueSize());
+ process_->sink().ClearMessages();
+
+ SendInputEventACK(WebInputEvent::TouchEnd,
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, process_->sink().message_count());
+ EXPECT_EQ(0U, host_->TouchEventQueueSize());
SimulateGestureEvent(WebKit::WebInputEvent::GestureScrollEnd,
WebGestureEvent::Touchscreen);
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(10));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(10));
+ base::MessageLoop::current()->Run();
EXPECT_EQ(1U, process_->sink().message_count());
EXPECT_EQ(0U, host_->TouchEventQueueSize());
EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode());
@@ -3664,9 +3700,11 @@
EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_delegate()->completed_mode());
EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
EXPECT_EQ(1U, host_->GestureEventDebouncingQueueSize());
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(10));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(10));
+ base::MessageLoop::current()->Run();
EXPECT_EQ(1U, process_->sink().message_count());
process_->sink().ClearMessages();
EXPECT_EQ(1U, host_->GestureEventLastQueueEventSize());
@@ -3721,9 +3759,11 @@
EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
EXPECT_EQ(1U, host_->GestureEventDebouncingQueueSize());
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(10));
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(10));
+ base::MessageLoop::current()->Run();
EXPECT_EQ(1U, process_->sink().message_count());
process_->sink().ClearMessages();
EXPECT_EQ(1U, host_->GestureEventLastQueueEventSize());
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 1ebece6..dce6a51 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -22,6 +22,7 @@
#include "content/browser/renderer_host/surface_texture_transport_client_android.h"
#include "content/common/gpu/client/gl_helper.h"
#include "content/common/gpu/gpu_messages.h"
+#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "third_party/WebKit/Source/Platform/chromium/public/Platform.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebExternalTextureLayer.h"
@@ -75,19 +76,19 @@
: host_(widget_host),
is_layer_attached_(true),
content_view_core_(NULL),
- ime_adapter_android_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ ime_adapter_android_(this),
cached_background_color_(SK_ColorWHITE),
texture_id_in_layer_(0) {
if (CompositorImpl::UsesDirectGL()) {
surface_texture_transport_.reset(new SurfaceTextureTransportClient());
layer_ = surface_texture_transport_->Initialize();
+ layer_->SetIsDrawable(true);
} else {
- texture_layer_ = cc::TextureLayer::Create(NULL);
+ texture_layer_ = cc::TextureLayer::Create(this);
layer_ = texture_layer_;
}
layer_->SetContentsOpaque(true);
- layer_->SetIsDrawable(true);
host_->SetView(this);
SetContentViewCore(content_view_core);
@@ -95,10 +96,23 @@
RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
SetContentViewCore(NULL);
- if (texture_id_in_layer_) {
- ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
- texture_id_in_layer_);
+ DCHECK(ack_callbacks_.empty());
+ if (texture_id_in_layer_ || !last_mailbox_.IsZero()) {
+ ImageTransportFactoryAndroid* factory =
+ ImageTransportFactoryAndroid::GetInstance();
+ // TODO: crbug.com/230137 - make workaround obsolete with refcounting.
+ // Don't let the last frame we sent leak in the mailbox.
+ if (!last_mailbox_.IsZero()) {
+ if (!texture_id_in_layer_)
+ texture_id_in_layer_ = factory->CreateTexture();
+ factory->AcquireTexture(texture_id_in_layer_, last_mailbox_.name);
+ factory->GetContext3D()->getError(); // Clear error if mailbox was empty.
+ }
+ factory->DeleteTexture(texture_id_in_layer_);
}
+
+ if (texture_layer_)
+ texture_layer_->ClearClient();
}
@@ -111,6 +125,8 @@
IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor,
OnDidChangeBodyBackgroundColor)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_SetVSyncNotificationEnabled,
+ OnSetVSyncNotificationEnabled)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -143,6 +159,8 @@
}
void RenderWidgetHostViewAndroid::WasHidden() {
+ RunAckCallbacks();
+
if (host_->is_hidden())
return;
@@ -233,7 +251,7 @@
}
gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
- return content_view_core_;
+ return content_view_core_->GetViewAndroid();
}
gfx::NativeViewId RenderWidgetHostViewAndroid::GetNativeViewId() const {
@@ -258,10 +276,11 @@
void RenderWidgetHostViewAndroid::Focus() {
host_->Focus();
host_->SetInputMethodActive(true);
+ ResetClipping();
}
void RenderWidgetHostViewAndroid::Blur() {
- host_->Send(new ViewMsg_ExecuteEditCommand(
+ host_->Send(new InputMsg_ExecuteEditCommand(
host_->GetRoutingID(), "Unselect", ""));
host_->SetInputMethodActive(false);
host_->Blur();
@@ -314,7 +333,11 @@
if (GetPhysicalBackingSize().IsEmpty())
return gfx::Rect();
- return gfx::Rect(content_view_core_->GetViewportSizeDip());
+ gfx::Size size = content_view_core_->GetViewportSizeDip();
+ gfx::Size offset = content_view_core_->GetViewportSizeOffsetDip();
+ size.Enlarge(-offset.width(), -offset.height());
+
+ return gfx::Rect(size);
}
gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
@@ -372,6 +395,15 @@
content_view_core_->OnBackgroundColorChanged(color);
}
+void RenderWidgetHostViewAndroid::SendVSync(base::TimeTicks frame_time) {
+ host_->Send(new ViewMsg_DidVSync(host_->GetRoutingID(), frame_time));
+}
+
+void RenderWidgetHostViewAndroid::OnSetVSyncNotificationEnabled(bool enabled) {
+ if (content_view_core_)
+ content_view_core_->SetVSyncNotificationEnabled(enabled);
+}
+
void RenderWidgetHostViewAndroid::OnStartContentIntent(
const GURL& content_url) {
if (content_view_core_)
@@ -491,6 +523,22 @@
void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
scoped_ptr<cc::CompositorFrame> frame) {
+ // Always let ContentViewCore know about the new frame first, so it can decide
+ // to schedule a Draw immediately when it sees the texture layer invalidation.
+ if (content_view_core_) {
+ // All offsets and sizes are in CSS pixels.
+ content_view_core_->UpdateFrameInfo(
+ frame->metadata.root_scroll_offset,
+ frame->metadata.page_scale_factor,
+ gfx::Vector2dF(frame->metadata.min_page_scale_factor,
+ frame->metadata.max_page_scale_factor),
+ frame->metadata.root_layer_size,
+ frame->metadata.viewport_size,
+ frame->metadata.location_bar_offset,
+ frame->metadata.location_bar_content_translation,
+ frame->metadata.overdraw_bottom_height);
+ }
+
if (!frame->gl_frame_data || frame->gl_frame_data->mailbox.IsZero())
return;
@@ -503,14 +551,16 @@
frame->gl_frame_data->sync_point);
const gfx::Size& texture_size = frame->gl_frame_data->size;
+ last_mailbox_ = current_mailbox_;
+
// Calculate the content size. This should be 0 if the texture_size is 0.
float dp2px = frame->metadata.device_scale_factor;
gfx::Vector2dF offset;
if (texture_size.GetArea() > 0)
offset = frame->metadata.location_bar_content_translation;
+ offset.set_y(offset.y() + frame->metadata.overdraw_bottom_height);
gfx::SizeF content_size(texture_size.width() - offset.x() * dp2px,
texture_size.height() - offset.y() * dp2px);
-
BuffersSwapped(frame->gl_frame_data->mailbox,
texture_size,
content_size,
@@ -564,33 +614,24 @@
texture_id_in_layer_, current_mailbox_.name);
} else {
texture_id_in_layer_ = factory->CreateTexture();
- texture_layer_->SetTextureId(texture_id_in_layer_);
+ texture_layer_->SetIsDrawable(true);
}
ImageTransportFactoryAndroid::GetInstance()->AcquireTexture(
texture_id_in_layer_, mailbox.name);
- // We need to tell ContentViewCore about the new frame before calling
- // setNeedsDisplay() below so that it has the needed information schedule the
- // next compositor frame.
- if (content_view_core_)
- content_view_core_->DidProduceRendererFrame();
-
- texture_layer_->SetNeedsDisplay();
- texture_layer_->SetBounds(gfx::Size(content_size.width(),
- content_size.height()));
-
- // Calculate the uv_max based on the content size relative to the texture
- // size.
- gfx::PointF uv_max;
- if (texture_size.GetArea() > 0) {
- uv_max.SetPoint(content_size.width() / texture_size.width(),
- content_size.height() / texture_size.height());
- }
- texture_layer_->SetUV(gfx::PointF(0, 0), uv_max);
texture_size_in_layer_ = texture_size;
+ content_size_in_layer_ = gfx::Size(content_size.width(),
+ content_size.height());
+
+ ResetClipping();
+
current_mailbox_ = mailbox;
- ack_callback.Run();
+
+ if (host_->is_hidden())
+ ack_callback.Run();
+ else
+ ack_callbacks_.push(ack_callback);
}
void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
@@ -607,6 +648,7 @@
// This tells us we should free the frontbuffer.
if (texture_id_in_layer_) {
texture_layer_->SetTextureId(0);
+ texture_layer_->SetIsDrawable(false);
ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
texture_id_in_layer_);
texture_id_in_layer_ = 0;
@@ -632,7 +674,7 @@
}
gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() {
- if (surface_texture_transport_.get()) {
+ if (surface_texture_transport_) {
return surface_texture_transport_->GetCompositingSurface(
host_->surface_id());
} else {
@@ -726,28 +768,58 @@
host_->MoveCaret(point);
}
+void RenderWidgetHostViewAndroid::RequestContentClipping(
+ const gfx::Rect& clipping,
+ const gfx::Size& content_size) {
+ // A focused view provides its own clipping.
+ if (HasFocus())
+ return;
+
+ ClipContents(clipping, content_size);
+}
+
+void RenderWidgetHostViewAndroid::ResetClipping() {
+ ClipContents(gfx::Rect(gfx::Point(), content_size_in_layer_),
+ content_size_in_layer_);
+}
+
+void RenderWidgetHostViewAndroid::ClipContents(const gfx::Rect& clipping,
+ const gfx::Size& content_size) {
+ if (!texture_id_in_layer_ || content_size_in_layer_.IsEmpty())
+ return;
+
+ gfx::Size clipped_content(content_size_in_layer_);
+ clipped_content.ClampToMax(clipping.size());
+ texture_layer_->SetBounds(clipped_content);
+ texture_layer_->SetNeedsDisplay();
+
+ if (texture_size_in_layer_.IsEmpty()) {
+ texture_layer_->SetUV(gfx::PointF(), gfx::PointF());
+ return;
+ }
+
+ gfx::PointF offset(
+ clipping.x() + content_size_in_layer_.width() - content_size.width(),
+ clipping.y() + content_size_in_layer_.height() - content_size.height());
+ offset.ClampToMin(gfx::PointF());
+
+ gfx::Vector2dF uv_scale(1.f / texture_size_in_layer_.width(),
+ 1.f / texture_size_in_layer_.height());
+ texture_layer_->SetUV(
+ gfx::PointF(offset.x() * uv_scale.x(),
+ offset.y() * uv_scale.y()),
+ gfx::PointF((offset.x() + clipped_content.width()) * uv_scale.x(),
+ (offset.y() + clipped_content.height()) * uv_scale.y()));
+}
+
SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
return cached_background_color_;
}
-void RenderWidgetHostViewAndroid::UpdateFrameInfo(
- const gfx::Vector2dF& scroll_offset,
- float page_scale_factor,
- const gfx::Vector2dF& page_scale_factor_limits,
- const gfx::SizeF& content_size,
- const gfx::SizeF& viewport_size,
- const gfx::Vector2dF& controls_offset,
- const gfx::Vector2dF& content_offset) {
- if (content_view_core_) {
- // All offsets and sizes are in CSS pixels.
- content_view_core_->UpdateFrameInfo(
- scroll_offset, page_scale_factor, page_scale_factor_limits,
- content_size, viewport_size, controls_offset, content_offset);
- }
-}
-
void RenderWidgetHostViewAndroid::SetContentViewCore(
ContentViewCoreImpl* content_view_core) {
+ RunAckCallbacks();
+
if (content_view_core_ && is_layer_attached_)
content_view_core_->RemoveLayer(layer_);
@@ -756,12 +828,34 @@
content_view_core_->AttachLayer(layer_);
}
+void RenderWidgetHostViewAndroid::RunAckCallbacks() {
+ while (!ack_callbacks_.empty()) {
+ ack_callbacks_.front().Run();
+ ack_callbacks_.pop();
+ }
+}
+
void RenderWidgetHostViewAndroid::HasTouchEventHandlers(
bool need_touch_events) {
if (content_view_core_)
content_view_core_->HasTouchEventHandlers(need_touch_events);
}
+unsigned RenderWidgetHostViewAndroid::PrepareTexture(
+ cc::ResourceUpdateQueue* queue) {
+ RunAckCallbacks();
+ return texture_id_in_layer_;
+}
+
+WebKit::WebGraphicsContext3D* RenderWidgetHostViewAndroid::Context3d() {
+ return ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
+}
+
+bool RenderWidgetHostViewAndroid::PrepareTextureMailbox(
+ cc::TextureMailbox* mailbox) {
+ return false;
+}
+
// static
void RenderWidgetHostViewPort::GetDefaultScreenInfo(
WebKit::WebScreenInfo* results) {
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 aec43cf..f0c65ada 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -6,12 +6,14 @@
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_ANDROID_H_
#include <map>
+#include <queue>
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/i18n/rtl.h"
#include "base/memory/scoped_ptr.h"
#include "base/process.h"
+#include "cc/layers/texture_layer_client.h"
#include "content/browser/renderer_host/ime_adapter_android.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "gpu/command_buffer/common/mailbox.h"
@@ -46,7 +48,8 @@
// -----------------------------------------------------------------------------
// See comments in render_widget_host_view.h about this class and its members.
// -----------------------------------------------------------------------------
-class RenderWidgetHostViewAndroid : public RenderWidgetHostViewBase {
+class RenderWidgetHostViewAndroid : public RenderWidgetHostViewBase,
+ public cc::TextureLayerClient {
public:
RenderWidgetHostViewAndroid(RenderWidgetHostImpl* widget,
ContentViewCoreImpl* content_view_core);
@@ -144,16 +147,14 @@
virtual void HasTouchEventHandlers(bool need_touch_events) OVERRIDE;
virtual void OnSwapCompositorFrame(
scoped_ptr<cc::CompositorFrame> frame) OVERRIDE;
- virtual void UpdateFrameInfo(const gfx::Vector2dF& scroll_offset,
- float page_scale_factor,
- const gfx::Vector2dF& page_scale_factor_limits,
- const gfx::SizeF& content_size,
- const gfx::SizeF& viewport_size,
- const gfx::Vector2dF& controls_offset,
- const gfx::Vector2dF& content_offset) OVERRIDE;
virtual void ShowDisambiguationPopup(const gfx::Rect& target_rect,
const SkBitmap& zoomed_bitmap) OVERRIDE;
+ // cc::TextureLayerClient implementation.
+ virtual unsigned PrepareTexture(cc::ResourceUpdateQueue* queue) OVERRIDE;
+ virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE;
+ virtual bool PrepareTextureMailbox(cc::TextureMailbox* mailbox) OVERRIDE;
+
// Non-virtual methods
void SetContentViewCore(ContentViewCoreImpl* content_view_core);
SkColor GetCachedBackgroundColor() const;
@@ -162,10 +163,12 @@
void SendMouseEvent(const WebKit::WebMouseEvent& event);
void SendMouseWheelEvent(const WebKit::WebMouseWheelEvent& event);
void SendGestureEvent(const WebKit::WebGestureEvent& event);
+ void SendVSync(base::TimeTicks frame_time);
void OnProcessImeBatchStateAck(bool is_begin);
void OnDidChangeBodyBackgroundColor(SkColor color);
void OnStartContentIntent(const GURL& content_url);
+ void OnSetVSyncNotificationEnabled(bool enabled);
int GetNativeImeAdapter();
@@ -181,12 +184,20 @@
void MoveCaret(const gfx::Point& point);
+ void RequestContentClipping(const gfx::Rect& clipping,
+ const gfx::Size& content_size);
+
private:
void BuffersSwapped(const gpu::Mailbox& mailbox,
const gfx::Size texture_size,
const gfx::SizeF content_size,
const base::Closure& ack_callback);
+ void RunAckCallbacks();
+
+ void ResetClipping();
+ void ClipContents(const gfx::Rect& clipping, const gfx::Size& content_size);
+
// The model object.
RenderWidgetHostImpl* host_;
@@ -218,12 +229,20 @@
// The most recent texture size that was pushed to the texture layer.
gfx::Size texture_size_in_layer_;
+ // The most recent content size that was pushed to the texture layer.
+ gfx::Size content_size_in_layer_;
+
// Used for image transport when needing to share resources across threads.
scoped_ptr<SurfaceTextureTransportClient> surface_texture_transport_;
// The mailbox of the previously received frame.
gpu::Mailbox current_mailbox_;
+ // The mailbox of the frame we last returned.
+ gpu::Mailbox last_mailbox_;
+
+ std::queue<base::Closure> ack_callbacks_;
+
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAndroid);
};
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index c7d3aff..c28c9ee 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -25,6 +25,7 @@
#include "content/common/gpu/client/gl_helper.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/common/view_messages.h"
+#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
#include "content/port/browser/render_widget_host_view_port.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@@ -40,6 +41,7 @@
#include "ui/aura/client/activation_client.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/cursor_client.h"
+#include "ui/aura/client/cursor_client_observer.h"
#include "ui/aura/client/focus_client.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/client/stacking_client.h"
@@ -67,6 +69,7 @@
#include "ui/gfx/skia_util.h"
#if defined(OS_WIN)
+#include "base/win/windows_version.h"
#include "content/browser/accessibility/browser_accessibility_manager_win.h"
#include "content/browser/accessibility/browser_accessibility_win.h"
#include "ui/base/win/hidden_window.h"
@@ -265,6 +268,10 @@
}
bool ShouldSendPinchGesture() {
+#if defined(OS_WIN)
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return true;
+#endif
static bool pinch_allowed =
CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableViewport) ||
CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePinch);
@@ -393,18 +400,15 @@
void RenderWidgetHostViewAura::ApplyEventFilterForPopupExit(
ui::MouseEvent* event) {
- if (in_shutdown_) {
- event_filter_for_popup_exit_.reset();
+ if (in_shutdown_ || is_fullscreen_)
return;
- }
- if (is_fullscreen_ || event->type() != ui::ET_MOUSE_PRESSED ||
- !event->target())
+
+ if (event->type() != ui::ET_MOUSE_PRESSED || !event->target())
return;
DCHECK(popup_parent_host_view_);
aura::Window* target = static_cast<aura::Window*>(event->target());
if (target != window_ && target != popup_parent_host_view_->window_) {
- event_filter_for_popup_exit_.reset();
in_shutdown_ = true;
host_->Shutdown();
}
@@ -558,6 +562,9 @@
root_window_->compositor()->GetCompositorLock()),
weak_ptr_factory_(this),
defer_compositor_lock_(defer_compositor_lock) {
+ TRACE_EVENT_ASYNC_BEGIN2("ui", "ResizeLock", this,
+ "width", new_size_.width(),
+ "height", new_size_.height());
root_window_->HoldMouseMoves();
BrowserThread::PostDelayedTask(
@@ -569,6 +576,9 @@
~ResizeLock() {
CancelLock();
+ TRACE_EVENT_ASYNC_END2("ui", "ResizeLock", this,
+ "width", new_size_.width(),
+ "height", new_size_.height());
}
void UnlockCompositor() {
@@ -612,7 +622,7 @@
RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host)
: host_(RenderWidgetHostImpl::From(host)),
- ALLOW_THIS_IN_INITIALIZER_LIST(window_(new aura::Window(this))),
+ window_(new aura::Window(this)),
in_shutdown_(false),
is_fullscreen_(false),
popup_parent_host_view_(NULL),
@@ -625,8 +635,9 @@
synthetic_move_sent_(false),
accelerated_compositing_state_changed_(false),
can_lock_compositor_(YES),
+ cursor_visibility_state_in_renderer_(UNKNOWN),
paint_observer_(NULL),
- accessible_parent_(NULL) {
+ touch_editing_client_(NULL) {
host_->SetView(this);
window_observer_.reset(new WindowObserver(this));
aura::client::SetTooltipText(window_, &tooltip_);
@@ -721,6 +732,11 @@
return;
host_->WasShown();
+ aura::client::CursorClient* cursor_client =
+ aura::client::GetCursorClient(window_->GetRootWindow());
+ if (cursor_client)
+ NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible());
+
if (!current_surface_ && host_->is_accelerated_compositing_active() &&
!released_front_lock_.get()) {
released_front_lock_ = GetCompositor()->GetCompositorLock();
@@ -756,7 +772,19 @@
}
void RenderWidgetHostViewAura::SetBounds(const gfx::Rect& rect) {
- if (window_->bounds().size() != rect.size() &&
+ window_->SetBounds(rect);
+ host_->WasResized();
+ MaybeCreateResizeLock();
+ if (touch_editing_client_) {
+ touch_editing_client_->OnSelectionOrCursorChanged(selection_anchor_rect_,
+ selection_focus_rect_);
+ }
+}
+
+void RenderWidgetHostViewAura::MaybeCreateResizeLock() {
+ gfx::Size desired_size = window_->bounds().size();
+ if (!resize_lock_.get() &&
+ desired_size != current_frame_size_ &&
host_->is_accelerated_compositing_active()) {
aura::RootWindow* root_window = window_->GetRootWindow();
ui::Compositor* compositor = root_window ?
@@ -766,6 +794,14 @@
if (!compositor->HasObserver(this))
compositor->AddObserver(this);
+// On Windows while resizing, the the resize locks makes us mis-paint a white
+// vertical strip (including the non-client area) if the content composition is
+// lagging the UI composition. So here we disable the throttling so that the UI
+// bits can draw ahead of the content thereby reducing the amount of whiteout.
+// Because this causes the content to be drawn at wrong sizes while resizing
+// we compensate by blocking the UI thread in Compositor::Draw() by issuing a
+// FinishAllRendering() if we are resizing.
+#if !defined (OS_WIN)
bool defer_compositor_lock =
can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
can_lock_compositor_ == NO_PENDING_COMMIT;
@@ -773,12 +809,11 @@
if (can_lock_compositor_ == YES)
can_lock_compositor_ = YES_DID_LOCK;
- resize_locks_.push_back(make_linked_ptr(
- new ResizeLock(root_window, rect.size(), defer_compositor_lock)));
+ resize_lock_.reset(new ResizeLock(root_window, desired_size,
+ defer_compositor_lock));
+#endif
}
}
- window_->SetBounds(rect);
- host_->WasResized();
}
gfx::NativeView RenderWidgetHostViewAura::GetNativeView() const {
@@ -825,8 +860,12 @@
return NULL;
HWND hwnd = root_window->GetAcceleratedWidget();
+ gfx::NativeViewAccessible accessible_parent =
+ host_->GetParentNativeViewAccessible();
+ DCHECK(accessible_parent);
+
manager = new BrowserAccessibilityManagerWin(
- hwnd, accessible_parent_,
+ hwnd, accessible_parent,
BrowserAccessibilityManagerWin::GetEmptyDocument(), this);
#else
manager = BrowserAccessibilityManager::Create(AccessibilityNodeData(), this);
@@ -913,7 +952,7 @@
}
bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const {
- return current_surface_ || !!host_->GetBackingStore(false);
+ return current_surface_ || current_dib_ || !!host_->GetBackingStore(false);
}
void RenderWidgetHostViewAura::Show() {
@@ -929,7 +968,14 @@
}
gfx::Rect RenderWidgetHostViewAura::GetViewBounds() const {
- return window_->GetBoundsInScreen();
+ // This is the size that we want the renderer to produce. While we're waiting
+ // for the correct frame (i.e. during a resize), don't change the size so that
+ // we don't pipeline more resizes than we can handle.
+ gfx::Rect bounds(window_->GetBoundsInScreen());
+ if (resize_lock_.get())
+ return gfx::Rect(bounds.origin(), resize_lock_->expected_size());
+ else
+ return bounds;
}
void RenderWidgetHostViewAura::SetBackground(const SkBitmap& background) {
@@ -939,17 +985,16 @@
}
#if defined(OS_WIN)
-void RenderWidgetHostViewAura::SetParentNativeViewAccessible(
- gfx::NativeViewAccessible accessible_parent) {
- accessible_parent_ = accessible_parent;
-
+gfx::NativeViewAccessible
+RenderWidgetHostViewAura::AccessibleObjectFromChildId(long child_id) {
BrowserAccessibilityManager* manager = GetBrowserAccessibilityManager();
- if (manager) {
- static_cast<BrowserAccessibilityManagerWin*>(manager)->
- set_parent_iaccessible(accessible_parent);
- }
+ if (!manager)
+ return NULL;
+
+ return manager->ToBrowserAccessibilityManagerWin()->GetFromUniqueIdWin(
+ child_id);
}
-#endif
+#endif // defined(OS_WIN)
void RenderWidgetHostViewAura::UpdateCursor(const WebCursor& cursor) {
current_cursor_ = cursor;
@@ -974,6 +1019,8 @@
can_compose_inline_ = params.can_compose_inline;
if (GetInputMethod())
GetInputMethod()->OnTextInputTypeChanged(this);
+ if (touch_editing_client_)
+ touch_editing_client_->OnTextInputTypeChanged(text_input_type_);
}
}
@@ -1089,6 +1136,11 @@
if (GetInputMethod())
GetInputMethod()->OnCaretBoundsChanged(this);
+
+ if (touch_editing_client_) {
+ touch_editing_client_->OnSelectionOrCursorChanged(selection_anchor_rect_,
+ selection_focus_rect_);
+ }
}
void RenderWidgetHostViewAura::ScrollOffsetChanged() {
@@ -1199,9 +1251,23 @@
}
bool RenderWidgetHostViewAura::CanCopyToVideoFrame() const {
- return current_surface_ != NULL;
+ return current_surface_ != NULL && host_->is_accelerated_compositing_active();
}
+bool RenderWidgetHostViewAura::CanSubscribeFrame() const {
+ return true;
+}
+
+void RenderWidgetHostViewAura::BeginFrameSubscription(
+ scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
+ frame_subscriber_ = subscriber.Pass();
+}
+
+void RenderWidgetHostViewAura::EndFrameSubscription() {
+ frame_subscriber_.reset();
+}
+
+
void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() {
// Delay processing the state change until we either get a software frame if
// switching to software mode or receive a buffers swapped notification
@@ -1214,50 +1280,27 @@
accelerated_compositing_state_changed_ = true;
}
-bool RenderWidgetHostViewAura::ShouldSkipFrame(gfx::Size size_in_dip) {
+bool RenderWidgetHostViewAura::ShouldSkipFrame(gfx::Size size_in_dip) const {
if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
can_lock_compositor_ == NO_PENDING_COMMIT ||
- resize_locks_.empty())
+ !resize_lock_.get())
return false;
- ResizeLockList::iterator it = resize_locks_.begin();
- while (it != resize_locks_.end()) {
- if ((*it)->expected_size() == size_in_dip)
- break;
- ++it;
- }
-
- // We could be getting an unexpected frame due to an animation
- // (i.e. we start resizing but we get an old size frame first).
- return it == resize_locks_.end() || ++it != resize_locks_.end();
+ return size_in_dip != resize_lock_->expected_size();
}
-void RenderWidgetHostViewAura::CheckResizeLocks(gfx::Size size_in_dip) {
- ResizeLockList::iterator it = resize_locks_.begin();
- while (it != resize_locks_.end()) {
- if ((*it)->expected_size() == size_in_dip)
- break;
- ++it;
- }
- if (it != resize_locks_.end()) {
- ++it;
- ui::Compositor* compositor = GetCompositor();
- if (compositor) {
- // Delay the release of the lock until we've kicked a frame with the
- // new texture, to avoid resizing the UI before we have a chance to
- // draw a "good" frame.
- locks_pending_commit_.insert(
- locks_pending_commit_.begin(), resize_locks_.begin(), it);
- // However since we got the size we were looking for, unlock the
- // compositor.
- for (ResizeLockList::iterator it2 = resize_locks_.begin();
- it2 !=it; ++it2) {
- it2->get()->UnlockCompositor();
- }
- if (!compositor->HasObserver(this))
- compositor->AddObserver(this);
- }
- resize_locks_.erase(resize_locks_.begin(), it);
+void RenderWidgetHostViewAura::CheckResizeLock() {
+ if (!resize_lock_ || resize_lock_->expected_size() != current_frame_size_)
+ return;
+
+ // Since we got the size we were looking for, unlock the compositor. But delay
+ // the release of the lock until we've kicked a frame with the new texture, to
+ // avoid resizing the UI before we have a chance to draw a "good" frame.
+ resize_lock_->UnlockCompositor();
+ ui::Compositor* compositor = GetCompositor();
+ if (compositor) {
+ if (!compositor->HasObserver(this))
+ compositor->AddObserver(this);
}
}
@@ -1268,13 +1311,19 @@
if (accelerated_compositing_state_changed_)
accelerated_compositing_state_changed_ = false;
- if (current_surface_ && host_->is_accelerated_compositing_active()) {
+ bool is_compositing_active = host_->is_accelerated_compositing_active();
+ if (is_compositing_active && current_surface_) {
window_->SetExternalTexture(current_surface_.get());
- gfx::Size container_size = ConvertSizeToDIP(this, current_surface_->size());
- CheckResizeLocks(container_size);
+ current_frame_size_ = ConvertSizeToDIP(this, current_surface_->size());
+ CheckResizeLock();
+ } else if (is_compositing_active && current_dib_) {
+ window_->SetExternalTexture(NULL);
+ current_frame_size_ = ConvertSizeToDIP(this, last_swapped_surface_size_);
+ CheckResizeLock();
} else {
window_->SetExternalTexture(NULL);
- resize_locks_.clear();
+ resize_lock_.reset();
+ host_->WasResized();
}
}
@@ -1318,15 +1367,25 @@
const BufferPresentedCallback& ack_callback,
const scoped_refptr<ui::Texture>& texture_to_return) {
ui::Compositor* compositor = GetCompositor();
+
+ if (frame_subscriber() && current_surface_ != NULL) {
+ const base::Time present_time = base::Time::Now();
+ scoped_refptr<media::VideoFrame> frame;
+ RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback;
+ if (frame_subscriber()->ShouldCaptureFrame(present_time,
+ &frame, &callback)) {
+ CopyFromCompositingSurfaceToVideoFrame(
+ gfx::Rect(ConvertSizeToDIP(this, current_surface_->size())),
+ frame,
+ base::Bind(callback, present_time));
+ }
+ }
+
if (!compositor) {
ack_callback.Run(false, texture_to_return);
} else {
- // Add sending an ACK to the list of things to do OnCompositingDidCommit
- can_lock_compositor_ = NO_PENDING_COMMIT;
- on_compositing_did_commit_callbacks_.push_back(
+ AddOnCommitCallbackAndDisableLocks(
base::Bind(ack_callback, false, texture_to_return));
- if (!compositor->HasObserver(this))
- compositor->AddObserver(this);
}
}
@@ -1381,12 +1440,16 @@
1.f/frame_device_scale_factor));
}
if (ShouldSkipFrame(frame_size_in_dip)) {
- SendDelegatedFrameAck();
+ cc::CompositorFrameAck ack;
+ ack.resources.swap(frame_data->resource_list);
+ RenderWidgetHostImpl::SendSwapCompositorFrameAck(
+ host_->GetRoutingID(), host_->GetProcess()->GetID(), ack);
return;
}
window_->layer()->SetDelegatedFrame(frame_data.Pass(), frame_size_in_dip);
released_front_lock_ = NULL;
- CheckResizeLocks(frame_size_in_dip);
+ current_frame_size_ = frame_size_in_dip;
+ CheckResizeLock();
if (paint_observer_)
paint_observer_->OnUpdateCompositorContent();
@@ -1395,12 +1458,9 @@
if (!compositor) {
SendDelegatedFrameAck();
} else {
- can_lock_compositor_ = NO_PENDING_COMMIT;
- on_compositing_did_commit_callbacks_.push_back(
+ AddOnCommitCallbackAndDisableLocks(
base::Bind(&RenderWidgetHostViewAura::SendDelegatedFrameAck,
- base::Unretained(this)));
- if (!compositor->HasObserver(this))
- compositor->AddObserver(this);
+ AsWeakPtr()));
}
}
@@ -1411,6 +1471,78 @@
host_->GetRoutingID(), host_->GetProcess()->GetID(), ack);
}
+void RenderWidgetHostViewAura::SwapSoftwareFrame(
+ scoped_ptr<cc::SoftwareFrameData> frame_data,
+ float frame_device_scale_factor) {
+ const gfx::Size& frame_size = frame_data->size;
+ const gfx::Rect& damage_rect = frame_data->damage_rect;
+ const TransportDIB::Id& dib_id = frame_data->dib_id;
+
+ scoped_ptr<TransportDIB> dib;
+#if defined(OS_WIN)
+ TransportDIB::Handle my_handle = TransportDIB::DefaultHandleValue();
+ ::DuplicateHandle(host_->GetProcess()->GetHandle(), dib_id.handle,
+ ::GetCurrentProcess(), &my_handle,
+ 0, FALSE, DUPLICATE_SAME_ACCESS);
+ dib.reset(TransportDIB::Map(my_handle));
+#elif defined(USE_X11)
+ dib.reset(TransportDIB::Map(dib_id.shmkey));
+#else
+ NOTIMPLEMENTED();
+#endif
+
+ // Validate the received DIB.
+ size_t expected_size = 4 * frame_size.GetArea();
+ if (!dib || dib->size() < expected_size) {
+ host_->GetProcess()->ReceivedBadMessage();
+ return;
+ }
+
+ if (last_swapped_surface_size_ != frame_size) {
+ DLOG_IF(ERROR, damage_rect != gfx::Rect(frame_size))
+ << "Expected full damage rect";
+ }
+
+ TransportDIB::Id last_dib_id = current_dib_id_;
+ current_dib_.reset(dib.release());
+ current_dib_id_ = dib_id;
+ last_swapped_surface_size_ = frame_size;
+
+ ui::Compositor* compositor = GetCompositor();
+ if (!compositor) {
+ SendSoftwareFrameAck(last_dib_id);
+ return;
+ }
+
+ gfx::Size frame_size_in_dip = gfx::ToFlooredSize(
+ gfx::ScaleSize(frame_size, 1.0f / frame_device_scale_factor));
+ if (ShouldSkipFrame(frame_size_in_dip)) {
+ can_lock_compositor_ = NO_PENDING_COMMIT;
+ SendSoftwareFrameAck(last_dib_id);
+ } else {
+ AddOnCommitCallbackAndDisableLocks(
+ base::Bind(&RenderWidgetHostViewAura::SendSoftwareFrameAck,
+ AsWeakPtr(), last_dib_id));
+ }
+
+ current_frame_size_ = frame_size_in_dip;
+ CheckResizeLock();
+ released_front_lock_ = NULL;
+ window_->SetExternalTexture(NULL);
+ window_->SchedulePaintInRect(ConvertRectToDIP(this, damage_rect));
+
+ if (paint_observer_)
+ paint_observer_->OnUpdateCompositorContent();
+}
+
+void RenderWidgetHostViewAura::SendSoftwareFrameAck(
+ const TransportDIB::Id& id) {
+ cc::CompositorFrameAck ack;
+ ack.last_dib_id = id;
+ RenderWidgetHostImpl::SendSwapCompositorFrameAck(
+ host_->GetRoutingID(), host_->GetProcess()->GetID(), ack);
+}
+
void RenderWidgetHostViewAura::OnSwapCompositorFrame(
scoped_ptr<cc::CompositorFrame> frame) {
if (frame->delegated_frame_data) {
@@ -1418,6 +1550,13 @@
frame->metadata.device_scale_factor);
return;
}
+
+ if (frame->software_frame_data) {
+ SwapSoftwareFrame(frame->software_frame_data.Pass(),
+ frame->metadata.device_scale_factor);
+ return;
+ }
+
if (!frame->gl_frame_data || frame->gl_frame_data->mailbox.IsZero())
return;
@@ -1447,7 +1586,7 @@
const std::string& mailbox_name,
const BufferPresentedCallback& ack_callback) {
scoped_refptr<ui::Texture> texture_to_return(current_surface_);
- const gfx::Rect surface_rect = gfx::Rect(gfx::Point(), size);
+ const gfx::Rect surface_rect = gfx::Rect(size);
if (!SwapBuffersPrepare(
surface_rect, surface_rect, mailbox_name, ack_callback)) {
return;
@@ -1473,7 +1612,7 @@
int gpu_host_id) {
scoped_refptr<ui::Texture> previous_texture(current_surface_);
const gfx::Rect surface_rect =
- gfx::Rect(gfx::Point(), params_in_pixel.surface_size);
+ gfx::Rect(params_in_pixel.surface_size);
gfx::Rect damage_rect(params_in_pixel.x,
params_in_pixel.y,
params_in_pixel.width,
@@ -1547,15 +1686,12 @@
if (compositor) {
// We need to wait for a commit to clear to guarantee that all we
// will not issue any more GL referencing the previous surface.
- can_lock_compositor_ = NO_PENDING_COMMIT;
- on_compositing_did_commit_callbacks_.push_back(
+ AddOnCommitCallbackAndDisableLocks(
base::Bind(&RenderWidgetHostViewAura::
SetSurfaceNotInUseByCompositor,
AsWeakPtr(),
current_surface_)); // Hold a ref so the texture will not
// get deleted until after commit.
- if (!compositor->HasObserver(this))
- compositor->AddObserver(this);
}
current_surface_ = NULL;
UpdateExternalTexture();
@@ -1581,7 +1717,7 @@
bool result) {
callback.Run(result, bitmap);
- if (!render_widget_host_view.get())
+ if (!render_widget_host_view)
return;
--render_widget_host_view->pending_thumbnail_tasks_;
}
@@ -1594,6 +1730,11 @@
return window_->GetToplevelWindow()->GetBoundsInScreen();
}
+void RenderWidgetHostViewAura::GestureEventAck(int gesture_event_type) {
+ if (touch_editing_client_)
+ touch_editing_client_->GestureEventAck(gesture_event_type);
+}
+
void RenderWidgetHostViewAura::ProcessAckedTouchEvent(
const WebKit::WebTouchEvent& touch_event, InputEventAckState ack_result) {
ScopedVector<ui::TouchEvent> events;
@@ -1653,8 +1794,11 @@
window_->SetCapture();
aura::client::CursorClient* cursor_client =
aura::client::GetCursorClient(root_window);
- if (cursor_client)
+ if (cursor_client) {
cursor_client->HideCursor();
+ cursor_client->LockCursor();
+ }
+
synthetic_move_sent_ = true;
window_->MoveCursorTo(gfx::Rect(window_->bounds().size()).CenterPoint());
if (aura::client::GetTooltipClient(root_window))
@@ -1673,8 +1817,11 @@
window_->MoveCursorTo(unlocked_mouse_position_);
aura::client::CursorClient* cursor_client =
aura::client::GetCursorClient(root_window);
- if (cursor_client)
+ if (cursor_client) {
+ cursor_client->UnlockCursor();
cursor_client->ShowCursor();
+ }
+
if (aura::client::GetTooltipClient(root_window))
aura::client::GetTooltipClient(root_window)->SetTooltipsEnabled(true);
@@ -1773,6 +1920,26 @@
return rect;
}
+gfx::Rect RenderWidgetHostViewAura::ConvertRectFromScreen(
+ const gfx::Rect& rect) {
+ gfx::Point origin = rect.origin();
+ gfx::Point end = gfx::Point(rect.right(), rect.bottom());
+
+ aura::RootWindow* root_window = window_->GetRootWindow();
+ if (root_window) {
+ aura::client::ScreenPositionClient* screen_position_client =
+ aura::client::GetScreenPositionClient(root_window);
+ screen_position_client->ConvertPointFromScreen(window_, &origin);
+ screen_position_client->ConvertPointFromScreen(window_, &end);
+ return gfx::Rect(origin.x(),
+ origin.y(),
+ end.x() - origin.x(),
+ end.y() - origin.y());
+ }
+
+ return rect;
+}
+
gfx::Rect RenderWidgetHostViewAura::GetCaretBounds() {
const gfx::Rect rect =
gfx::UnionRects(selection_anchor_rect_, selection_focus_rect_);
@@ -1868,9 +2035,19 @@
void RenderWidgetHostViewAura::ExtendSelectionAndDelete(
size_t before, size_t after) {
- // TODO(horo): implement this method if it is required.
- // http://crbug.com/149155
- NOTIMPLEMENTED();
+ if (host_)
+ host_->ExtendSelectionAndDelete(before, after);
+}
+
+void RenderWidgetHostViewAura::EnsureCaretInRect(const gfx::Rect& rect) {
+ gfx::Rect intersected_rect(
+ gfx::IntersectRects(rect, window_->GetBoundsInScreen()));
+
+ if (intersected_rect.IsEmpty())
+ return;
+
+ host_->ScrollFocusedEditableNodeIntoRect(
+ ConvertRectFromScreen(intersected_rect));
}
////////////////////////////////////////////////////////////////////////////////
@@ -1935,15 +2112,47 @@
void RenderWidgetHostViewAura::OnCaptureLost() {
host_->LostCapture();
+ if (touch_editing_client_)
+ touch_editing_client_->EndTouchEditing();
}
void RenderWidgetHostViewAura::OnPaint(gfx::Canvas* canvas) {
- paint_canvas_ = canvas;
- BackingStore* backing_store = host_->GetBackingStore(true);
- paint_canvas_ = NULL;
- if (backing_store) {
- static_cast<BackingStoreAura*>(backing_store)->SkiaShowRect(gfx::Point(),
- canvas);
+ bool is_compositing_active = host_->is_accelerated_compositing_active();
+ bool has_backing_store = !!host_->GetBackingStore(false);
+ if (is_compositing_active && current_dib_) {
+ const gfx::Size window_size = window_->bounds().size();
+ const gfx::Size& frame_size = last_swapped_surface_size_;
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config,
+ frame_size.width(),
+ frame_size.height());
+ bitmap.setPixels(current_dib_->memory());
+
+ SkCanvas* sk_canvas = canvas->sk_canvas();
+ sk_canvas->drawBitmap(bitmap, 0, 0);
+
+ if (frame_size != window_size) {
+ SkRegion region;
+ region.op(0, 0, window_size.width(), window_size.height(),
+ SkRegion::kUnion_Op);
+ region.op(0, 0, frame_size.width(), frame_size.height(),
+ SkRegion::kDifference_Op);
+ SkPaint paint;
+ paint.setColor(SK_ColorWHITE);
+ for (SkRegion::Iterator it(region); !it.done(); it.next())
+ sk_canvas->drawIRect(it.rect(), paint);
+ }
+
+ if (paint_observer_)
+ paint_observer_->OnPaintComplete();
+ } else if (!is_compositing_active && has_backing_store) {
+ paint_canvas_ = canvas;
+ BackingStoreAura* backing_store = static_cast<BackingStoreAura*>(
+ host_->GetBackingStore(true));
+ paint_canvas_ = NULL;
+ backing_store->SkiaShowRect(gfx::Point(), canvas);
+
if (paint_observer_)
paint_observer_->OnPaintComplete();
} else if (aura::Env::GetInstance()->render_white_bg()) {
@@ -2024,6 +2233,9 @@
void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent* event) {
TRACE_EVENT0("browser", "RenderWidgetHostViewAura::OnKeyEvent");
+ if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
+ return;
+
if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) {
popup_child_host_view_->OnKeyEvent(event);
if (event->handled())
@@ -2073,12 +2285,13 @@
void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) {
TRACE_EVENT0("browser", "RenderWidgetHostViewAura::OnMouseEvent");
+ if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
+ return;
+
if (mouse_locked_) {
- // Hide the cursor if someone else has shown it.
aura::client::CursorClient* cursor_client =
aura::client::GetCursorClient(window_->GetRootWindow());
- if (cursor_client && cursor_client->IsCursorVisible())
- cursor_client->DisableMouseEvents();
+ DCHECK(!cursor_client || !cursor_client->IsCursorVisible());
WebKit::WebMouseEvent mouse_event = MakeWebMouseEvent(event);
gfx::Point center(gfx::Rect(window_->bounds().size()).CenterPoint());
@@ -2164,7 +2377,11 @@
// Needed to propagate mouse event to native_tab_contents_view_aura.
// TODO(pkotwicz): Find a better way of doing this.
- if (window_->parent()->delegate() && !(event->flags() & ui::EF_FROM_TOUCH))
+ // In fullscreen mode which is typically used by flash, don't forward
+ // the mouse events to the parent. The renderer and the plugin process
+ // handle these events.
+ if (!is_fullscreen_ && window_->parent()->delegate() &&
+ !(event->flags() & ui::EF_FROM_TOUCH))
window_->parent()->delegate()->OnMouseEvent(event);
if (!IsXButtonUpEvent(event))
@@ -2173,6 +2390,9 @@
void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) {
TRACE_EVENT0("browser", "RenderWidgetHostViewAura::OnScrollEvent");
+ if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
+ return;
+
if (event->type() == ui::ET_SCROLL) {
if (event->finger_count() != 2)
return;
@@ -2197,6 +2417,9 @@
void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) {
TRACE_EVENT0("browser", "RenderWidgetHostViewAura::OnTouchEvent");
+ if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
+ return;
+
// Update the touch event first.
WebKit::WebTouchPoint* point = UpdateWebTouchEventFromUIEvent(*event,
&touch_event_);
@@ -2227,6 +2450,9 @@
return;
}
+ if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
+ return;
+
RenderViewHostDelegate* delegate = NULL;
if (popup_type_ == WebKit::WebPopupTypeNone && !is_fullscreen_)
delegate = RenderViewHost::From(host_)->GetDelegate();
@@ -2296,6 +2522,13 @@
}
////////////////////////////////////////////////////////////////////////////////
+// RenderWidgetHostViewAura, aura::client::CursorClientObserver implementation:
+
+void RenderWidgetHostViewAura::OnCursorVisibilityChanged(bool is_visible) {
+ NotifyRendererOfCursorVisibilityState(is_visible);
+}
+
+////////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewAura, aura::client::FocusChangeObserver implementation:
void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus,
@@ -2332,9 +2565,18 @@
DetachFromInputMethod();
host_->SetInputMethodActive(false);
+ if (touch_editing_client_)
+ touch_editing_client_->EndTouchEditing();
+
// If we lose the focus while fullscreen, close the window; Pepper Flash
- // won't do it for us (unlike NPAPI Flash).
- if (is_fullscreen_ && !in_shutdown_) {
+ // won't do it for us (unlike NPAPI Flash). However, we do not close the
+ // window if we lose the focus to a window on another display.
+ gfx::Screen* screen = gfx::Screen::GetScreenFor(window_);
+ bool focusing_other_display =
+ gained_focus && screen->GetNumDisplays() > 1 &&
+ (screen->GetDisplayNearestWindow(window_).id() !=
+ screen->GetDisplayNearestWindow(gained_focus).id());
+ if (is_fullscreen_ && !in_shutdown_ && !focusing_other_display) {
in_shutdown_ = true;
host_->Shutdown();
}
@@ -2356,13 +2598,18 @@
ui::Compositor* compositor) {
if (can_lock_compositor_ == NO_PENDING_COMMIT) {
can_lock_compositor_ = YES;
- for (ResizeLockList::iterator it = resize_locks_.begin();
- it != resize_locks_.end(); ++it)
- if ((*it)->GrabDeferredLock())
- can_lock_compositor_ = YES_DID_LOCK;
+ if (resize_lock_.get() && resize_lock_->GrabDeferredLock())
+ can_lock_compositor_ = YES_DID_LOCK;
}
- RunCompositingDidCommitCallbacks();
- locks_pending_commit_.clear();
+ RunOnCommitCallbacks();
+ if (resize_lock_ && resize_lock_->expected_size() == current_frame_size_) {
+ resize_lock_.reset();
+ host_->WasResized();
+ // We may have had a resize while we had the lock (e.g. if the lock expired,
+ // or if the UI still gave us some resizes), so make sure we grab a new lock
+ // if necessary.
+ MaybeCreateResizeLock();
+ }
}
void RenderWidgetHostViewAura::OnCompositingStarted(
@@ -2455,12 +2702,11 @@
void RenderWidgetHostViewAura::OnLostResources() {
current_surface_ = NULL;
UpdateExternalTexture();
- locks_pending_commit_.clear();
// Make sure all ImageTransportClients are deleted now that the context those
// are using is becoming invalid. This sends pending ACKs and needs to happen
// after calling UpdateExternalTexture() which syncs with the impl thread.
- RunCompositingDidCommitCallbacks();
+ RunOnCommitCallbacks();
DCHECK(!shared_surface_handle_.is_null());
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
@@ -2476,6 +2722,8 @@
RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
if (paint_observer_)
paint_observer_->OnViewDestroyed();
+ if (touch_editing_client_)
+ touch_editing_client_->OnViewDestroyed();
if (!shared_surface_handle_.is_null()) {
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
factory->DestroySharedSurfaceHandle(shared_surface_handle_);
@@ -2593,6 +2841,17 @@
}
}
+void RenderWidgetHostViewAura::NotifyRendererOfCursorVisibilityState(
+ bool is_visible) {
+ if (host_->is_hidden() ||
+ (cursor_visibility_state_in_renderer_ == VISIBLE && is_visible) ||
+ (cursor_visibility_state_in_renderer_ == NOT_VISIBLE && !is_visible))
+ return;
+
+ cursor_visibility_state_in_renderer_ = is_visible ? VISIBLE : NOT_VISIBLE;
+ host_->SendCursorVisibilityState(is_visible);
+}
+
void RenderWidgetHostViewAura::SchedulePaintIfNotInClip(
const gfx::Rect& rect,
const gfx::Rect& clip) {
@@ -2616,7 +2875,7 @@
global_mouse_position_.y() > rect.bottom() - border_y;
}
-void RenderWidgetHostViewAura::RunCompositingDidCommitCallbacks() {
+void RenderWidgetHostViewAura::RunOnCommitCallbacks() {
for (std::vector<base::Closure>::const_iterator
it = on_compositing_did_commit_callbacks_.begin();
it != on_compositing_did_commit_callbacks_.end(); ++it) {
@@ -2625,15 +2884,39 @@
on_compositing_did_commit_callbacks_.clear();
}
+void RenderWidgetHostViewAura::AddOnCommitCallbackAndDisableLocks(
+ const base::Closure& callback) {
+ ui::Compositor* compositor = GetCompositor();
+ DCHECK(compositor);
+
+ if (!compositor->HasObserver(this))
+ compositor->AddObserver(this);
+
+ can_lock_compositor_ = NO_PENDING_COMMIT;
+ on_compositing_did_commit_callbacks_.push_back(callback);
+}
+
void RenderWidgetHostViewAura::AddedToRootWindow() {
window_->GetRootWindow()->AddRootWindowObserver(this);
host_->ParentChanged(GetNativeViewId());
UpdateScreenInfo(window_);
if (popup_type_ != WebKit::WebPopupTypeNone)
event_filter_for_popup_exit_.reset(new EventFilterForPopupExit(this));
+
+ aura::client::CursorClient* cursor_client =
+ aura::client::GetCursorClient(window_->GetRootWindow());
+ if (cursor_client) {
+ cursor_client->AddObserver(this);
+ NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible());
+ }
}
void RenderWidgetHostViewAura::RemovingFromRootWindow() {
+ aura::client::CursorClient* cursor_client =
+ aura::client::GetCursorClient(window_->GetRootWindow());
+ if (cursor_client)
+ cursor_client->RemoveObserver(this);
+
event_filter_for_popup_exit_.reset();
window_->GetRootWindow()->RemoveRootWindowObserver(this);
host_->ParentChanged(0);
@@ -2644,11 +2927,11 @@
// frame though, because we will reissue a new frame right away without that
// composited data.
ui::Compositor* compositor = GetCompositor();
- RunCompositingDidCommitCallbacks();
- locks_pending_commit_.clear();
+ RunOnCommitCallbacks();
+ resize_lock_.reset();
+ host_->WasResized();
if (compositor && compositor->HasObserver(this))
compositor->RemoveObserver(this);
- DetachFromInputMethod();
}
ui::Compositor* RenderWidgetHostViewAura::GetCompositor() {
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 52c6376..b1e3a7e 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -22,6 +22,7 @@
#include "third_party/skia/include/core/SkRegion.h"
#include "ui/aura/client/activation_change_observer.h"
#include "ui/aura/client/activation_delegate.h"
+#include "ui/aura/client/cursor_client_observer.h"
#include "ui/aura/client/focus_change_observer.h"
#include "ui/aura/root_window_observer.h"
#include "ui/aura/window_delegate.h"
@@ -66,6 +67,7 @@
public aura::client::ActivationDelegate,
public aura::client::ActivationChangeObserver,
public aura::client::FocusChangeObserver,
+ public aura::client::CursorClientObserver,
public ImageTransportFactoryObserver,
public BrowserAccessibilityDelegate,
public base::SupportsWeakPtr<RenderWidgetHostViewAura> {
@@ -93,10 +95,47 @@
virtual void OnViewDestroyed() = 0;
};
+ // Displays and controls touch editing elements such as selection handles.
+ class TouchEditingClient {
+ public:
+ TouchEditingClient() {}
+
+ // Tells the client to start showing touch editing handles.
+ virtual void StartTouchEditing() = 0;
+
+ // Notifies the client that touch editing is no longer needed.
+ virtual void EndTouchEditing() = 0;
+
+ // Notifies the client that the selection bounds need to be updated.
+ virtual void OnSelectionOrCursorChanged(const gfx::Rect& anchor,
+ const gfx::Rect& focus) = 0;
+
+ // Notifies the client that the current text input type as changed.
+ virtual void OnTextInputTypeChanged(ui::TextInputType type) = 0;
+
+ // Notifies the client that an input event is about to be sent to the
+ // renderer. Returns true if the client wants to stop event propagation.
+ virtual bool HandleInputEvent(const ui::Event* event) = 0;
+
+ // Notifies the client that a gesture event ack was received.
+ virtual void GestureEventAck(int gesture_event_type) = 0;
+
+ // This is called when the view is destroyed, so that the client can
+ // perform any necessary clean-up.
+ virtual void OnViewDestroyed() = 0;
+
+ protected:
+ virtual ~TouchEditingClient() {}
+ };
+
void set_paint_observer(PaintObserver* observer) {
paint_observer_ = observer;
}
+ void set_touch_editing_client(TouchEditingClient* client) {
+ touch_editing_client_ = client;
+ }
+
// RenderWidgetHostView implementation.
virtual void InitAsChild(gfx::NativeView parent_view) OVERRIDE;
virtual RenderWidgetHost* GetRenderWidgetHost() const OVERRIDE;
@@ -113,8 +152,8 @@
virtual gfx::Rect GetViewBounds() const OVERRIDE;
virtual void SetBackground(const SkBitmap& background) OVERRIDE;
#if defined(OS_WIN)
- virtual void SetParentNativeViewAccessible(
- gfx::NativeViewAccessible accessible_parent) OVERRIDE;
+ virtual gfx::NativeViewAccessible AccessibleObjectFromChildId(long child_id)
+ OVERRIDE;
#endif
// Overridden from RenderWidgetHostViewPort:
@@ -161,6 +200,10 @@
const scoped_refptr<media::VideoFrame>& target,
const base::Callback<void(bool)>& callback) OVERRIDE;
virtual bool CanCopyToVideoFrame() const OVERRIDE;
+ virtual bool CanSubscribeFrame() const OVERRIDE;
+ virtual void BeginFrameSubscription(
+ scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) OVERRIDE;
+ virtual void EndFrameSubscription() OVERRIDE;
virtual void OnAcceleratedCompositingStateChange() OVERRIDE;
virtual void AcceleratedSurfaceBuffersSwapped(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel,
@@ -173,6 +216,7 @@
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 ProcessAckedTouchEvent(
const WebKit::WebTouchEvent& touch,
InputEventAckState ack_result) OVERRIDE;
@@ -213,6 +257,7 @@
virtual bool ChangeTextDirectionAndLayoutAlignment(
base::i18n::TextDirection direction) OVERRIDE;
virtual void ExtendSelectionAndDelete(size_t before, size_t after) OVERRIDE;
+ virtual void EnsureCaretInRect(const gfx::Rect& rect) OVERRIDE;
// Overridden from gfx::DisplayObserver:
virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE;
@@ -254,6 +299,9 @@
virtual void OnWindowActivated(aura::Window* gained_activation,
aura::Window* lost_activation) OVERRIDE;
+ // Overridden from aura::client::CursorClientObserver:
+ virtual void OnCursorVisibilityChanged(bool is_visible) OVERRIDE;
+
// Overridden from aura::client::FocusChangeObserver:
virtual void OnWindowFocused(aura::Window* gained_focus,
aura::Window* lost_focus) OVERRIDE;
@@ -275,6 +323,10 @@
// Should construct only via RenderWidgetHostView::CreateViewForWidget.
explicit RenderWidgetHostViewAura(RenderWidgetHost* host);
+ RenderWidgetHostViewFrameSubscriber* frame_subscriber() const {
+ return frame_subscriber_.get();
+ }
+
private:
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, TouchEventState);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, TouchEventSyncAsync);
@@ -316,8 +368,15 @@
virtual ~RenderWidgetHostViewAura();
void UpdateCursorIfOverSelf();
- bool ShouldSkipFrame(gfx::Size size_in_dip);
- void CheckResizeLocks(gfx::Size size_in_dip);
+ bool ShouldSkipFrame(gfx::Size size_in_dip) const;
+
+ // Lazily grab a resize lock if the aura window size doesn't match the current
+ // frame size, to give time to the renderer.
+ void MaybeCreateResizeLock();
+
+ // Checks if the resize lock can be released because we received an new frame.
+ void CheckResizeLock();
+
void UpdateExternalTexture();
ui::InputMethod* GetInputMethod() const;
@@ -332,6 +391,10 @@
// mouse lock on all mouse move events.
void ModifyEventMovementAndCoords(WebKit::WebMouseEvent* event);
+ // Sends an IPC to the renderer process to communicate whether or not
+ // the mouse cursor is visible anywhere on the screen.
+ void NotifyRendererOfCursorVisibilityState(bool is_visible);
+
// If |clip| is non-empty and and doesn't contain |rect| or |clip| is empty
// SchedulePaint() is invoked for |rect|.
void SchedulePaintIfNotInClip(const gfx::Rect& rect, const gfx::Rect& clip);
@@ -340,8 +403,11 @@
// moved to center.
bool ShouldMoveToCenter();
- // Run the compositing callbacks.
- void RunCompositingDidCommitCallbacks();
+ // Run all on compositing commit callbacks.
+ void RunOnCommitCallbacks();
+
+ // Add on compositing commit callback.
+ void AddOnCommitCallbackAndDisableLocks(const base::Closure& callback);
// Called after |window_| is parented to a RootWindow.
void AddedToRootWindow();
@@ -372,6 +438,9 @@
// Converts |rect| from window coordinate to screen coordinate.
gfx::Rect ConvertRectToScreen(const gfx::Rect& rect);
+ // Converts |rect| from screen coordinate to window coordinate.
+ gfx::Rect ConvertRectFromScreen(const gfx::Rect& rect);
+
typedef base::Callback<void(bool, const scoped_refptr<ui::Texture>&)>
BufferPresentedCallback;
@@ -391,10 +460,15 @@
const scoped_refptr<ui::Texture>& texture_to_return);
void SwapDelegatedFrame(
- scoped_ptr<cc::DelegatedFrameData> frame,
- float device_scale_factor);
+ scoped_ptr<cc::DelegatedFrameData> frame_data,
+ float frame_device_scale_factor);
void SendDelegatedFrameAck();
+ void SwapSoftwareFrame(
+ scoped_ptr<cc::SoftwareFrameData> frame_data,
+ float frame_device_scale_factor);
+ void SendSoftwareFrameAck(const TransportDIB::Id& id);
+
BrowserAccessibilityManager* GetOrCreateBrowserAccessibilityManager();
#if defined(OS_WIN)
@@ -471,6 +545,13 @@
// The current frontbuffer texture.
scoped_refptr<ui::Texture> current_surface_;
+ // The current frontbuffer DIB.
+ scoped_ptr<TransportDIB> current_dib_;
+
+ // The current DIB id as it was received from the renderer. Note that on
+ // some platforms (e.g. Windows) this is different from current_dib_->id().
+ TransportDIB::Id current_dib_id_;
+
// The damage in the previously presented buffer.
SkRegion previous_damage_;
@@ -511,13 +592,17 @@
// Used to prevent further resizes while a resize is pending.
class ResizeLock;
- typedef std::vector<linked_ptr<ResizeLock> > ResizeLockList;
- // These locks are the ones waiting for a texture of the right size to come
- // back from the renderer/GPU process.
- ResizeLockList resize_locks_;
- // These locks are the ones waiting for a frame to be committed.
- ResizeLockList locks_pending_commit_;
+ // This lock is the one waiting for a frame of the right size to come back
+ // from the renderer/GPU process. It is set from the moment the aura window
+ // got resized, to the moment we committed the renderer frame of the same
+ // size. It keeps track of the size we expect from the renderer, and locks the
+ // compositor, as well as the UI for a short time to give a chance to the
+ // renderer of producing a frame of the right size.
+ scoped_ptr<ResizeLock> resize_lock_;
+
+ // Keeps track of the current frame size.
+ gfx::Size current_frame_size_;
// This lock is for waiting for a front surface to become available to draw.
scoped_refptr<ui::CompositorLock> released_front_lock_;
@@ -537,6 +622,15 @@
};
CanLockCompositorState can_lock_compositor_;
+ // Used to track the last cursor visibility update that was sent to the
+ // renderer via NotifyRendererOfCursorVisibilityState().
+ enum CursorVisibilityState {
+ UNKNOWN,
+ VISIBLE,
+ NOT_VISIBLE,
+ };
+ CursorVisibilityState cursor_visibility_state_in_renderer_;
+
// An observer to notify that the paint content of the view has changed. The
// observer is not owned by the view, and must remove itself as an oberver
// when it is being destroyed.
@@ -560,7 +654,10 @@
base::TimeTicks last_draw_ended_;
- gfx::NativeViewAccessible accessible_parent_;
+ // Subscriber that listens to frame presentation events.
+ scoped_ptr<RenderWidgetHostViewFrameSubscriber> frame_subscriber_;
+
+ TouchEditingClient* touch_editing_client_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAura);
};
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index cfacd0c..9ad65fc 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -110,7 +110,7 @@
}
protected:
- MessageLoopForUI message_loop_;
+ base::MessageLoopForUI message_loop_;
scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_;
scoped_ptr<BrowserContext> browser_context_;
MockRenderWidgetHostDelegate delegate_;
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 0efb448..43d496b 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -84,7 +84,7 @@
// it's most likely the one for this plugin, try a few more times after a
// delay.
if (tries > 0) {
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&NotifyPluginProcessHostHelper, window, parent, tries - 1),
base::TimeDelta::FromMilliseconds(kTryDelayMs));
@@ -422,6 +422,9 @@
return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
}
+void RenderWidgetHostViewBase::GestureEventAck(int gesture_event_type) {
+}
+
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 ae58a59..662dbab 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -61,6 +61,7 @@
const WebKit::WebMouseWheelEvent& event) OVERRIDE;
virtual InputEventAckState FilterInputEvent(
const WebKit::WebInputEvent& input_event) OVERRIDE;
+ virtual void GestureEventAck(int gesture_event_type) 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 d158e6f..45cdd4b 100644
--- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -77,7 +77,7 @@
// not be available immediately so wait for it.
while (!CheckCompositingSurface()) {
base::RunLoop run_loop;
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
run_loop.QuitClosure(),
base::TimeDelta::FromMilliseconds(10));
@@ -126,10 +126,19 @@
}
virtual bool ShouldCaptureFrame(
+ base::Time present_time,
scoped_refptr<media::VideoFrame>* storage,
DeliverFrameCallback* callback) OVERRIDE {
+ // Only allow one frame capture to be made. Otherwise, the compositor could
+ // start multiple captures, unbounded, and eventually its own limiter logic
+ // will begin invoking |callback| with a |false| result. This flakes out
+ // the unit tests, since they receive a "failed" callback before the later
+ // "success" callbacks.
+ if (callback_.is_null())
+ return false;
*storage = media::VideoFrame::CreateBlackFrame(gfx::Size(100, 100));
*callback = callback_;
+ callback_.Reset();
return true;
}
@@ -247,8 +256,14 @@
}
// Test copying from backing store when page is non-accelerated-composited.
+// Flaky. http://crbug.com/224351
+#if defined(OS_MACOSX) || defined(OS_WIN)
+#define MAYBE_CopyFromBackingStore DISABLED_CopyFromBackingStore
+#else
+#define MAYBE_CopyFromBackingStore CopyFromBackingStore
+#endif
IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewBrowserTest,
- CopyFromBackingStore) {
+ MAYBE_CopyFromBackingStore) {
SetupNonCompositing();
base::RunLoop run_loop;
diff --git a/content/browser/renderer_host/render_widget_host_view_gtk.cc b/content/browser/renderer_host/render_widget_host_view_gtk.cc
index c137096..ece0421 100644
--- a/content/browser/renderer_host/render_widget_host_view_gtk.cc
+++ b/content/browser/renderer_host/render_widget_host_view_gtk.cc
@@ -4,11 +4,6 @@
#include "content/browser/renderer_host/render_widget_host_view_gtk.h"
-// If this gets included after the gtk headers, then a bunch of compiler
-// errors happen because of a "#define Status int" in Xlib.h, which interacts
-// badly with net::URLRequestStatus::Status.
-#include "content/common/view_messages.h"
-
#include <cairo/cairo.h>
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
@@ -37,6 +32,8 @@
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/common/gpu/gpu_messages.h"
+#include "content/common/input_messages.h"
+#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/common/content_switches.h"
@@ -712,6 +709,8 @@
// If we have a renderer, then inform it that we are being hidden so it can
// reduce its resource utilization.
host_->WasHidden();
+
+ web_contents_switch_paint_time_ = base::TimeTicks();
}
void RenderWidgetHostViewGtk::SetSize(const gfx::Size& size) {
@@ -929,7 +928,7 @@
// The RenderWidgetHost's destruction led here, so don't call it.
host_ = NULL;
- MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
void RenderWidgetHostViewGtk::SetTooltipText(const string16& tooltip_text) {
@@ -1369,7 +1368,7 @@
EditCommands edit_commands;
if (!event.skip_in_browser &&
key_bindings_handler_->Match(event, &edit_commands)) {
- Send(new ViewMsg_SetEditCommandsForNextKeyEvent(
+ Send(new InputMsg_SetEditCommandsForNextKeyEvent(
host_->GetRoutingID(), edit_commands));
NativeWebKeyboardEvent copy_event(event);
copy_event.match_edit_command = true;
@@ -1545,7 +1544,7 @@
void RenderWidgetHostViewGtk::OnAccessibilityNotifications(
const std::vector<AccessibilityHostMsg_NotificationParams>& params) {
- if (!browser_accessibility_manager_.get()) {
+ if (!browser_accessibility_manager_) {
GtkWidget* parent = gtk_widget_get_parent(view_.get());
browser_accessibility_manager_.reset(
new BrowserAccessibilityManagerGtk(
@@ -1557,7 +1556,7 @@
}
AtkObject* RenderWidgetHostViewGtk::GetAccessible() {
- if (!browser_accessibility_manager_.get()) {
+ if (!browser_accessibility_manager_) {
GtkWidget* parent = gtk_widget_get_parent(view_.get());
browser_accessibility_manager_.reset(
new BrowserAccessibilityManagerGtk(
diff --git a/content/browser/renderer_host/render_widget_host_view_guest.cc b/content/browser/renderer_host/render_widget_host_view_guest.cc
index 5e414cb..6f02367 100644
--- a/content/browser/renderer_host/render_widget_host_view_guest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_guest.cc
@@ -76,11 +76,12 @@
}
void RenderWidgetHostViewGuest::SetSize(const gfx::Size& size) {
- platform_view_->SetSize(size);
+ size_ = size;
+ host_->WasResized();
}
gfx::Rect RenderWidgetHostViewGuest::GetBoundsInRootWindow() {
- return platform_view_->GetBoundsInRootWindow();
+ return gfx::Rect(size_);
}
gfx::GLSurfaceHandle RenderWidgetHostViewGuest::GetCompositingSurface() {
@@ -124,7 +125,7 @@
}
gfx::Rect RenderWidgetHostViewGuest::GetViewBounds() const {
- return platform_view_->GetViewBounds();
+ return gfx::Rect(size_);
}
void RenderWidgetHostViewGuest::RenderViewGone(base::TerminationStatus status,
@@ -166,8 +167,19 @@
NOTREACHED();
}
+void RenderWidgetHostViewGuest::OnSwapCompositorFrame(
+ scoped_ptr<cc::CompositorFrame> frame) {
+ guest_->clear_damage_buffer();
+ guest_->SendMessageToEmbedder(
+ new BrowserPluginMsg_CompositorFrameSwapped(
+ guest_->instance_id(),
+ *frame,
+ host_->GetRoutingID(),
+ host_->GetProcess()->GetID()));
+}
+
void RenderWidgetHostViewGuest::SetBounds(const gfx::Rect& rect) {
- platform_view_->SetBounds(rect);
+ SetSize(rect.size());
}
bool RenderWidgetHostViewGuest::OnMessageReceived(const IPC::Message& msg) {
@@ -308,8 +320,10 @@
#endif
#if defined(OS_WIN) && defined(USE_AURA)
-void RenderWidgetHostViewGuest::SetParentNativeViewAccessible(
- gfx::NativeViewAccessible accessible_parent) {
+gfx::NativeViewAccessible
+RenderWidgetHostViewGuest::AccessibleObjectFromChildId(long child_id) {
+ NOTIMPLEMENTED();
+ return NULL;
}
#endif
@@ -336,7 +350,10 @@
}
void RenderWidgetHostViewGuest::GetScreenInfo(WebKit::WebScreenInfo* results) {
- platform_view_->GetScreenInfo(results);
+ RenderWidgetHostViewPort* embedder_view =
+ static_cast<RenderWidgetHostViewPort*>(
+ guest_->GetEmbedderRenderWidgetHostView());
+ embedder_view->GetScreenInfo(results);
}
void RenderWidgetHostViewGuest::OnAccessibilityNotifications(
@@ -397,16 +414,6 @@
const SkBitmap& zoomed_bitmap) {
}
-void RenderWidgetHostViewGuest::UpdateFrameInfo(
- const gfx::Vector2dF& scroll_offset,
- float page_scale_factor,
- const gfx::Vector2dF& page_scale_factor_limits,
- const gfx::SizeF& content_size,
- const gfx::SizeF& viewport_size,
- const gfx::Vector2dF& controls_offset,
- const gfx::Vector2dF& content_offset) {
-}
-
void RenderWidgetHostViewGuest::HasTouchEventHandlers(bool need_touch_events) {
}
#endif // defined(OS_ANDROID)
@@ -428,7 +435,7 @@
void RenderWidgetHostViewGuest::DestroyGuestView() {
host_ = NULL;
- MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
bool RenderWidgetHostViewGuest::DispatchLongPressGestureEvent(
diff --git a/content/browser/renderer_host/render_widget_host_view_guest.h b/content/browser/renderer_host/render_widget_host_view_guest.h
index a0949a7..b1c2816 100644
--- a/content/browser/renderer_host/render_widget_host_view_guest.h
+++ b/content/browser/renderer_host/render_widget_host_view_guest.h
@@ -66,8 +66,8 @@
virtual void SetClickthroughRegion(SkRegion* region) OVERRIDE;
#endif
#if defined(OS_WIN) && defined(USE_AURA)
- virtual void SetParentNativeViewAccessible(
- gfx::NativeViewAccessible accessible_parent) OVERRIDE;
+ virtual gfx::NativeViewAccessible AccessibleObjectFromChildId(long child_id)
+ OVERRIDE;
#endif
// RenderWidgetHostViewPort implementation.
@@ -119,6 +119,8 @@
virtual void AcceleratedSurfacePostSubBuffer(
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
int gpu_host_id) OVERRIDE;
+ virtual void OnSwapCompositorFrame(
+ scoped_ptr<cc::CompositorFrame> frame) OVERRIDE;
virtual void AcceleratedSurfaceSuspend() OVERRIDE;
virtual void AcceleratedSurfaceRelease() OVERRIDE;
virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) OVERRIDE;
@@ -161,13 +163,6 @@
// RenderWidgetHostViewPort implementation.
virtual void ShowDisambiguationPopup(const gfx::Rect& target_rect,
const SkBitmap& zoomed_bitmap) OVERRIDE;
- virtual void UpdateFrameInfo(const gfx::Vector2dF& scroll_offset,
- float page_scale_factor,
- const gfx::Vector2dF& page_scale_factor_limits,
- const gfx::SizeF& content_size,
- const gfx::SizeF& viewport_size,
- const gfx::Vector2dF& controls_offset,
- const gfx::Vector2dF& content_offset) OVERRIDE;
virtual void HasTouchEventHandlers(bool need_touch_events) OVERRIDE;
#endif // defined(OS_ANDROID)
@@ -202,6 +197,7 @@
BrowserPluginGuest *guest_;
bool is_hidden_;
+ gfx::Size size_;
// The platform view for this RenderWidgetHostView.
// RenderWidgetHostViewGuest mostly only cares about stuff related to
// compositing, the rest are directly forwared to this |platform_view_|.
diff --git a/content/browser/renderer_host/render_widget_host_view_guest_unittest.cc b/content/browser/renderer_host/render_widget_host_view_guest_unittest.cc
index fbe45b7..5cac690 100644
--- a/content/browser/renderer_host/render_widget_host_view_guest_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_guest_unittest.cc
@@ -51,7 +51,7 @@
}
protected:
- MessageLoopForUI message_loop_;
+ base::MessageLoopForUI message_loop_;
scoped_ptr<BrowserContext> browser_context_;
MockRenderWidgetHostDelegate delegate_;
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 a02f379..a38cd47 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.h
+++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -408,6 +408,8 @@
return frame_subscriber_.get();
}
+ int window_number() const;
+
private:
friend class RenderWidgetHostView;
friend class RenderWidgetHostViewMacTest;
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 e13bbdf..2a72354 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -16,10 +16,10 @@
#import "base/memory/scoped_nsobject.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
-#include "base/stringprintf.h"
#include "base/string_util.h"
+#include "base/stringprintf.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/sys_info.h"
-#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#import "content/browser/accessibility/browser_accessibility_cocoa.h"
#include "content/browser/accessibility/browser_accessibility_manager_mac.h"
@@ -32,6 +32,7 @@
#include "content/common/accessibility_messages.h"
#include "content/common/edit_command.h"
#include "content/common/gpu/gpu_messages.h"
+#include "content/common/input_messages.h"
#include "content/common/plugin_messages.h"
#include "content/common/view_messages.h"
#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
@@ -50,8 +51,8 @@
#include "ui/base/layout.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/size_conversions.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
+#include "ui/gfx/size_conversions.h"
#include "ui/surface/io_surface_support_mac.h"
#include "webkit/plugins/npapi/webplugin.h"
@@ -133,10 +134,11 @@
@interface RenderWidgetHostViewCocoa ()
@property(nonatomic, assign) NSRange selectedRange;
@property(nonatomic, assign) NSRange markedRange;
+@property(nonatomic, assign)
+ NSObject<RenderWidgetHostViewMacDelegate>* delegate;
+ (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event;
- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r;
-- (void)setRWHVDelegate:(NSObject<RenderWidgetHostViewMacDelegate>*)delegate;
- (void)gotUnhandledWheelEvent;
- (void)scrollOffsetPinnedToLeft:(BOOL)left toRight:(BOOL)right;
- (void)setHasHorizontalScrollbar:(BOOL)has_horizontal_scrollbar;
@@ -389,7 +391,7 @@
void RenderWidgetHostViewMac::SetDelegate(
NSObject<RenderWidgetHostViewMacDelegate>* delegate) {
- [cocoa_view_ setRWHVDelegate:delegate];
+ [cocoa_view_ setDelegate:delegate];
}
void RenderWidgetHostViewMac::SetAllowOverlappingViews(bool overlapping) {
@@ -471,6 +473,10 @@
[cocoa_view_ setCanBeKeyView:YES];
[cocoa_view_ setFrame:[[pepper_fullscreen_window_ contentView] bounds]];
[cocoa_view_ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ // If the pepper fullscreen window isn't opaque then there are performance
+ // issues when it's on the discrete GPU and the Chrome window is being drawn
+ // to. http://crbug.com/171911
+ [pepper_fullscreen_window_ setOpaque:YES];
// Note that this forms a reference cycle between the fullscreen window and
// the rwhvmac: The PepperFlashFullscreenWindow retains cocoa_view_,
@@ -500,6 +506,13 @@
pepper_fullscreen_window_.reset();
}
+int RenderWidgetHostViewMac::window_number() const {
+ NSWindow* window = [cocoa_view_ window];
+ if (!window)
+ return -1;
+ return [window windowNumber];
+}
+
RenderWidgetHost* RenderWidgetHostViewMac::GetRenderWidgetHost() const {
return render_widget_host_;
}
@@ -890,7 +903,7 @@
location:location
modifierFlags:0
timestamp:0
- windowNumber:[window windowNumber]
+ windowNumber:window_number()
context:nil
eventNumber:0
clickCount:0
@@ -1004,7 +1017,7 @@
void RenderWidgetHostViewMac::KillSelf() {
if (!weak_factory_.HasWeakPtrs()) {
[cocoa_view_ setHidden:YES];
- MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(&RenderWidgetHostViewMac::ShutdownHost,
weak_factory_.GetWeakPtr()));
}
@@ -1036,14 +1049,30 @@
if (is_hidden_)
return true;
- // TODO(shess) If the view does not have a window, or the window
- // does not have backing, the IOSurface will log "invalid drawable"
- // in -setView:. It is not clear how this code is reached with such
- // a case, so record some info into breakpad (some subset of
- // browsers are likely to crash later for unrelated reasons).
- // http://crbug.com/148882
NSWindow* window = [cocoa_view_ window];
- if ([window windowNumber] <= 0) {
+ if (window_number() <= 0) {
+ // There is no window to present so capturing during present won't work.
+ // We check if frame subscriber wants this frame and capture manually.
+ if (compositing_iosurface_.get() && frame_subscriber_) {
+ const base::Time present_time = base::Time::Now();
+ scoped_refptr<media::VideoFrame> frame;
+ RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback;
+ if (frame_subscriber_->ShouldCaptureFrame(present_time,
+ &frame, &callback)) {
+ compositing_iosurface_->SetIOSurface(surface_handle, size);
+ compositing_iosurface_->CopyToVideoFrame(
+ gfx::Rect(size), ScaleFactor(cocoa_view_), frame,
+ base::Bind(callback, present_time));
+ return true;
+ }
+ }
+
+ // TODO(shess) If the view does not have a window, or the window
+ // does not have backing, the IOSurface will log "invalid drawable"
+ // in -setView:. It is not clear how this code is reached with such
+ // a case, so record some info into breakpad (some subset of
+ // browsers are likely to crash later for unrelated reasons).
+ // http://crbug.com/148882
const char* const kCrashKey = "rwhvm_window";
if (!window) {
base::debug::SetCrashKeyValue(kCrashKey, "Missing window");
@@ -1059,14 +1088,17 @@
return true;
}
- if (!compositing_iosurface_.get()) {
+ bool should_post_notification = false;
+ if (!compositing_iosurface_) {
CompositingIOSurfaceMac::SurfaceOrder order = allow_overlapping_views_ ?
CompositingIOSurfaceMac::SURFACE_ORDER_BELOW_WINDOW :
CompositingIOSurfaceMac::SURFACE_ORDER_ABOVE_WINDOW;
- compositing_iosurface_.reset(CompositingIOSurfaceMac::Create(order));
+ compositing_iosurface_.reset(
+ CompositingIOSurfaceMac::Create(window_number(), order));
+ should_post_notification = true;
}
- if (!compositing_iosurface_.get())
+ if (!compositing_iosurface_)
return true;
compositing_iosurface_->SetIOSurface(surface_handle, size);
@@ -1085,8 +1117,15 @@
if (!about_to_validate_and_paint_) {
compositing_iosurface_->DrawIOSurface(cocoa_view_,
ScaleFactor(cocoa_view_),
+ window_number(),
frame_subscriber_.get());
}
+
+ if (should_post_notification && [[cocoa_view_ delegate]
+ respondsToSelector:@selector(compositingIOSurfaceCreated)]) {
+ [[cocoa_view_ delegate] compositingIOSurfaceCreated];
+ }
+
return true;
}
@@ -1096,7 +1135,7 @@
if (pending_swap_buffers_acks_.front().first != 0) {
AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
ack_params.sync_point = 0;
- if (compositing_iosurface_.get())
+ if (compositing_iosurface_)
ack_params.renderer_id = compositing_iosurface_->GetRendererID();
RenderWidgetHostImpl::AcknowledgeBufferPresent(
pending_swap_buffers_acks_.front().first,
@@ -1106,7 +1145,7 @@
render_widget_host_->AcknowledgeSwapBuffersToRenderer();
// Send VSync parameters to compositor thread.
- if (compositing_iosurface_.get()) {
+ if (compositing_iosurface_) {
base::TimeTicks timebase;
uint32 numerator = 0, denominator = 0;
compositing_iosurface_->GetVSyncParameters(&timebase,
@@ -1279,7 +1318,7 @@
}
void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() {
- if (compositing_iosurface_.get())
+ if (compositing_iosurface_)
compositing_iosurface_->UnrefIOSurface();
}
@@ -1406,7 +1445,7 @@
// Forget IOSurface since we are drawing a software frame now.
if (compositing_iosurface_.get() &&
compositing_iosurface_->HasIOSurface()) {
- compositing_iosurface_->UnrefIOSurface();
+ compositing_iosurface_->ClearDrawable();
}
}
}
@@ -1538,6 +1577,7 @@
@synthesize selectedRange = selectedRange_;
@synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_;
@synthesize markedRange = markedRange_;
+@synthesize delegate = delegate_;
- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r {
self = [super initWithFrame:NSZeroRect];
@@ -1580,10 +1620,6 @@
}
}
-- (void)setRWHVDelegate:(NSObject<RenderWidgetHostViewMacDelegate>*)delegate {
- delegate_ = delegate;
-}
-
- (void)gotUnhandledWheelEvent {
if (delegate_ &&
[delegate_ respondsToSelector:@selector(gotUnhandledWheelEvent)]) {
@@ -1916,7 +1952,7 @@
delayEventUntilAfterImeCompostion = YES;
} else {
if (!editCommands_.empty()) {
- widgetHost->Send(new ViewMsg_SetEditCommandsForNextKeyEvent(
+ widgetHost->Send(new InputMsg_SetEditCommandsForNextKeyEvent(
widgetHost->GetRoutingID(), editCommands_));
}
widgetHost->ForwardKeyboardEvent(event);
@@ -1982,7 +2018,7 @@
// thus it won't destroy the widget.
if (!editCommands_.empty()) {
- widgetHost->Send(new ViewMsg_SetEditCommandsForNextKeyEvent(
+ widgetHost->Send(new InputMsg_SetEditCommandsForNextKeyEvent(
widgetHost->GetRoutingID(), editCommands_));
}
widgetHost->ForwardKeyboardEvent(event);
@@ -2156,7 +2192,7 @@
return;
handlingGlobalFrameDidChange_ = YES;
- if (renderWidgetHostView_->compositing_iosurface_.get())
+ if (renderWidgetHostView_->compositing_iosurface_)
renderWidgetHostView_->compositing_iosurface_->GlobalFrameDidChange();
handlingGlobalFrameDidChange_ = NO;
}
@@ -2270,7 +2306,10 @@
}
renderWidgetHostView_->compositing_iosurface_->DrawIOSurface(
- self, ScaleFactor(self), renderWidgetHostView_->frame_subscriber());
+ self,
+ ScaleFactor(self),
+ renderWidgetHostView_->window_number(),
+ renderWidgetHostView_->frame_subscriber());
return;
}
@@ -3041,7 +3080,8 @@
editCommands_.push_back(EditCommand(command, ""));
} else {
RenderWidgetHostImpl* rwh = renderWidgetHostView_->render_widget_host_;
- rwh->Send(new ViewMsg_ExecuteEditCommand(rwh->GetRoutingID(), command, ""));
+ rwh->Send(new InputMsg_ExecuteEditCommand(rwh->GetRoutingID(),
+ command, ""));
}
}
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
index c81681a..460ec72 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
@@ -9,7 +9,7 @@
#include "base/message_loop.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
-#include "content/common/view_messages.h"
+#include "content/common/input_messages.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -83,7 +83,7 @@
}
virtual bool Send(IPC::Message* message) OVERRIDE {
- if (message->type() == ViewMsg_ExecuteEditCommand::ID)
+ if (message->type() == InputMsg_ExecuteEditCommand::ID)
edit_command_message_count_++;
return RenderWidgetHostImpl::Send(message);
}
@@ -105,7 +105,7 @@
NSArray* edit_command_strings = helper.GetEditSelectorNames();
// Set up a mock render widget and set expectations.
- MessageLoopForUI message_loop;
+ base::MessageLoopForUI message_loop;
TestBrowserContext browser_context;
MockRenderProcessHost mock_process(&browser_context);
MockRenderWidgetHostDelegate delegate;
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
index 6061ff5..9fa0d0e 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -11,6 +11,7 @@
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/common/gpu/gpu_messages.h"
+#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/notification_types.h"
#include "content/public/test/mock_render_process_host.h"
@@ -160,7 +161,7 @@
// Make sure the rwhv_mac_ is gone once the superclass's |TearDown()| runs.
rwhv_cocoa_.reset();
pool_.Recycle();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
pool_.Recycle();
// See comment in SetUp().
@@ -685,16 +686,15 @@
ASSERT_EQ(1U, process_host->sink().message_count());
// Send an ACK for the first wheel event, so that the queue will be flushed.
- scoped_ptr<IPC::Message> response(
- new ViewHostMsg_HandleInputEvent_ACK(0, WebKit::WebInputEvent::MouseWheel,
- INPUT_EVENT_ACK_STATE_CONSUMED));
+ scoped_ptr<IPC::Message> response(new InputHostMsg_HandleInputEvent_ACK(
+ 0, WebKit::WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED));
host->OnMessageReceived(*response);
// Post the NSEventPhaseEnded wheel event to NSApp and check whether the
// render view receives it.
NSEvent* event2 = MockScrollWheelEventWithPhase(@selector(phaseEnded));
[NSApp postEvent:event2 atStart:NO];
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
ASSERT_EQ(2U, process_host->sink().message_count());
// Clean up.
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 ec15a1a..000e532 100644
--- a/content/browser/renderer_host/render_widget_host_view_win.cc
+++ b/content/browser/renderer_host/render_widget_host_view_win.cc
@@ -4,6 +4,7 @@
#include "content/browser/renderer_host/render_widget_host_view_win.h"
+#include <dwmapi.h>
#include <InputScope.h>
#include <algorithm>
@@ -262,7 +263,6 @@
POINT client_point = gesture.location().ToPOINT();
POINT screen_point = gesture.location().ToPOINT();
- MapWindowPoints(::GetParent(hwnd), hwnd, &client_point, 1);
MapWindowPoints(hwnd, HWND_DESKTOP, &screen_point, 1);
gesture_event.x = client_point.x;
@@ -314,6 +314,22 @@
results->deviceScaleFactor = ui::win::GetDeviceScaleFactor();
}
+void SetDwmPresentParameters(HWND window) {
+ if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
+ BOOL is_composited;
+ HRESULT result = DwmIsCompositionEnabled(&is_composited);
+ if (SUCCEEDED(result) && is_composited) {
+ DWM_PRESENT_PARAMETERS present_parameters = {0};
+ present_parameters.cbSize = sizeof(present_parameters);
+ present_parameters.cBuffer = 2;
+
+ result = DwmSetPresentParameters(window, &present_parameters);
+ if (FAILED(result))
+ DLOG(ERROR) << "Unable to set present parameters: 0x%08X", result;
+ }
+ }
+}
+
} // namespace
const wchar_t kRenderWidgetHostHWNDClass[] = L"Chrome_RenderWidgetHostHWND";
@@ -390,13 +406,11 @@
is_fullscreen_(false),
ignore_mouse_movement_(true),
composition_range_(ui::Range::InvalidRange()),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- touch_state_(new WebTouchState(this))),
+ touch_state_(new WebTouchState(this)),
pointer_down_context_(false),
last_touch_location_(-1, -1),
touch_events_enabled_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- gesture_recognizer_(ui::GestureRecognizer::Create(this))) {
+ gesture_recognizer_(ui::GestureRecognizer::Create(this)) {
render_widget_host_->SetView(this);
registrar_.Add(this,
NOTIFICATION_RENDERER_PROCESS_TERMINATED,
@@ -470,7 +484,7 @@
if (render_widget_host_)
render_widget_host_->WasHidden();
- if (accelerated_surface_.get())
+ if (accelerated_surface_)
accelerated_surface_->WasHidden();
if (GetBrowserAccessibilityManager())
@@ -555,6 +569,8 @@
if (!compositor_host_window_)
return;
+ ui::SetWindowUserData(compositor_host_window_, NULL);
+
// Hide the compositor and parent it to the desktop rather than destroying
// it immediately. The GPU process has a grace period to stop accessing the
// window. TODO(apatrick): the GPU process should acknowledge that it has
@@ -845,7 +861,7 @@
const base::Callback<void(bool, const SkBitmap&)>& callback) {
base::ScopedClosureRunner scoped_callback_runner(
base::Bind(callback, false, SkBitmap()));
- if (!accelerated_surface_.get())
+ if (!accelerated_surface_)
return;
if (dst_size.IsEmpty() || src_subrect.IsEmpty())
@@ -860,7 +876,7 @@
const scoped_refptr<media::VideoFrame>& target,
const base::Callback<void(bool)>& callback) {
base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false));
- if (!accelerated_surface_.get())
+ if (!accelerated_surface_)
return;
if (!target || target->format() != media::VideoFrame::YV12)
@@ -1177,6 +1193,11 @@
render_widget_host_->ExtendSelectionAndDelete(before, after);
}
+void RenderWidgetHostViewWin::EnsureCaretInRect(const gfx::Rect& rect) {
+ // TODO(nona): Implement this function.
+ NOTIMPLEMENTED();
+}
+
///////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewWin, private:
@@ -1190,6 +1211,7 @@
props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(m_hWnd));
WTSRegisterSessionNotification(m_hWnd, NOTIFY_FOR_THIS_SESSION);
+ SetDwmPresentParameters(m_hWnd);
UpdateDesiredTouchMode();
UpdateIMEState();
@@ -1293,7 +1315,7 @@
// Blit only the damaged regions from the backing store.
DWORD data_size = GetRegionData(damage_region, 0, NULL);
- scoped_array<char> region_data_buf;
+ scoped_ptr<char[]> region_data_buf;
RGNDATA* region_data = NULL;
RECT* region_rects = NULL;
@@ -1479,7 +1501,8 @@
SetWindowPos(NULL, 0, 0, 0, 0,
SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOMOVE |
SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
- MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
base::Bind(&RenderWidgetHostViewWin::ShutdownHost,
weak_factory_.GetWeakPtr()));
}
@@ -2113,7 +2136,7 @@
touch_point->screenPosition.x = coordinates.x;
touch_point->screenPosition.y = coordinates.y;
- window_->GetParent().ScreenToClient(&coordinates);
+ window_->ScreenToClient(&coordinates);
touch_point->position.x = coordinates.x;
touch_point->position.y = coordinates.y;
touch_point->radiusX = radius_x;
@@ -2393,9 +2416,6 @@
switch (message) {
case WM_ERASEBKGND:
return 0;
- case WM_DESTROY:
- ui::SetWindowUserData(hWnd, NULL);
- return 0;
case WM_PAINT:
PaintCompositorHostWindow(hWnd);
return 0;
@@ -2407,7 +2427,7 @@
void RenderWidgetHostViewWin::AcceleratedPaint(HDC dc) {
if (render_widget_host_)
render_widget_host_->ScheduleComposite();
- if (accelerated_surface_.get())
+ if (accelerated_surface_)
accelerated_surface_->Present(dc);
}
@@ -2444,7 +2464,7 @@
// On Vista and later we present directly to the view window rather than a
// child window.
if (GpuDataManagerImpl::GetInstance()->IsUsingAcceleratedSurface()) {
- if (!accelerated_surface_.get())
+ if (!accelerated_surface_)
accelerated_surface_.reset(new AcceleratedSurface(m_hWnd));
return gfx::GLSurfaceHandle(m_hWnd, gfx::NATIVE_TRANSPORT);
}
@@ -2484,6 +2504,8 @@
ui::SetWindowUserData(compositor_host_window_, this);
+ SetDwmPresentParameters(compositor_host_window_);
+
gfx::GLSurfaceHandle surface_handle(compositor_host_window_,
gfx::NATIVE_TRANSPORT);
@@ -2532,7 +2554,7 @@
// Drop the backing store for the accelerated surface when the accelerated
// compositor is disabled. Otherwise, a flash of the last presented frame
// could appear when it is next enabled.
- if (accelerated_surface_.get())
+ if (accelerated_surface_)
accelerated_surface_->Suspend();
hide_compositor_window_at_next_paint_ = true;
}
@@ -2551,7 +2573,7 @@
}
void RenderWidgetHostViewWin::AcceleratedSurfaceSuspend() {
- if (!accelerated_surface_.get())
+ if (!accelerated_surface_)
return;
accelerated_surface_->Suspend();
@@ -2624,7 +2646,7 @@
// active windows screen reader.
BrowserAccessibilityState::GetInstance()->OnScreenReaderDetected();
render_widget_host_->SetAccessibilityMode(
- BrowserAccessibilityStateImpl::GetInstance()->GetAccessibilityMode());
+ BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode());
// Return with failure.
return static_cast<LRESULT>(0L);
@@ -2689,7 +2711,7 @@
handled = FALSE;
TRACE_EVENT0("browser", "RenderWidgetHostViewWin::OnSessionChange");
- if (!accelerated_surface_.get())
+ if (!accelerated_surface_)
return 0;
switch (wparam) {
diff --git a/content/browser/renderer_host/render_widget_host_view_win.h b/content/browser/renderer_host/render_widget_host_view_win.h
index 17f6a47..2990541 100644
--- a/content/browser/renderer_host/render_widget_host_view_win.h
+++ b/content/browser/renderer_host/render_widget_host_view_win.h
@@ -283,6 +283,7 @@
virtual bool ChangeTextDirectionAndLayoutAlignment(
base::i18n::TextDirection direction) OVERRIDE;
virtual void ExtendSelectionAndDelete(size_t before, size_t after) OVERRIDE;
+ virtual void EnsureCaretInRect(const gfx::Rect& rect) OVERRIDE;
protected:
friend class RenderWidgetHostView;
diff --git a/content/browser/renderer_host/smooth_scroll_gesture_controller.cc b/content/browser/renderer_host/smooth_scroll_gesture_controller.cc
new file mode 100644
index 0000000..3e8fcc1
--- /dev/null
+++ b/content/browser/renderer_host/smooth_scroll_gesture_controller.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/smooth_scroll_gesture_controller.h"
+
+#include "base/debug/trace_event.h"
+#include "base/message_loop.h"
+#include "content/common/view_messages.h"
+#include "content/port/browser/render_widget_host_view_port.h"
+#include "content/port/browser/smooth_scroll_gesture.h"
+#include "content/public/browser/render_widget_host.h"
+
+namespace content {
+
+namespace {
+
+// How many milliseconds apart synthetic scroll messages should be sent.
+const int kSyntheticScrollMessageIntervalMs = 8;
+
+} // namespace
+
+SmoothScrollGestureController::SmoothScrollGestureController()
+ : rwh_(NULL) {
+}
+
+SmoothScrollGestureController::~SmoothScrollGestureController() {
+}
+
+void SmoothScrollGestureController::BeginSmoothScroll(
+ RenderWidgetHostViewPort* view,
+ const ViewHostMsg_BeginSmoothScroll_Params& params) {
+ if (pending_smooth_scroll_gesture_)
+ return;
+
+ rwh_ = view->GetRenderWidgetHost();
+ pending_smooth_scroll_gesture_ = view->CreateSmoothScrollGesture(
+ params.scroll_down,
+ params.pixels_to_scroll,
+ params.mouse_event_x,
+ params.mouse_event_y);
+
+ timer_.Start(FROM_HERE, GetSyntheticScrollMessageInterval(), this,
+ &SmoothScrollGestureController::OnTimer);
+}
+
+base::TimeDelta
+ SmoothScrollGestureController::GetSyntheticScrollMessageInterval() const {
+ return base::TimeDelta::FromMilliseconds(kSyntheticScrollMessageIntervalMs);
+}
+
+void SmoothScrollGestureController::OnTimer() {
+ base::TimeTicks now = base::TimeTicks::Now();
+ if (!pending_smooth_scroll_gesture_->ForwardInputEvents(now, rwh_)) {
+ timer_.Stop();
+ pending_smooth_scroll_gesture_ = NULL;
+ rwh_->Send(new ViewMsg_SmoothScrollCompleted(rwh_->GetRoutingID()));
+ }
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/smooth_scroll_gesture_controller.h b/content/browser/renderer_host/smooth_scroll_gesture_controller.h
new file mode 100644
index 0000000..6e25cd7
--- /dev/null
+++ b/content/browser/renderer_host/smooth_scroll_gesture_controller.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_SMOOTH_SCROLL_GESTURE_CONTROLLER_H_
+#define CONTENT_BROWSER_RENDERER_HOST_SMOOTH_SCROLL_GESTURE_CONTROLLER_H_
+
+#include <map>
+
+#include "base/memory/weak_ptr.h"
+#include "base/time.h"
+#include "base/timer.h"
+#include "content/common/content_export.h"
+
+struct ViewHostMsg_BeginSmoothScroll_Params;
+
+namespace content {
+
+class RenderWidgetHost;
+class RenderWidgetHostViewPort;
+class SmoothScrollGesture;
+
+// Controls SmoothScrollGestures, used to inject synthetic events
+// for performance test harness.
+class CONTENT_EXPORT SmoothScrollGestureController {
+ public:
+ SmoothScrollGestureController();
+ ~SmoothScrollGestureController();
+
+ // Initiates a synthetic event stream.
+ void BeginSmoothScroll(RenderWidgetHostViewPort* view,
+ const ViewHostMsg_BeginSmoothScroll_Params& params);
+
+ base::TimeDelta GetSyntheticScrollMessageInterval() const;
+
+ private:
+ // Called periodically to advance the active scroll gesture after being
+ // initiated by OnBeginSmoothScroll.
+ void OnTimer();
+
+ base::RepeatingTimer<SmoothScrollGestureController> timer_;
+
+ RenderWidgetHost* rwh_;
+
+ scoped_refptr<SmoothScrollGesture> pending_smooth_scroll_gesture_;
+
+ DISALLOW_COPY_AND_ASSIGN(SmoothScrollGestureController);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_SMOOTH_SCROLL_GESTURE_CONTROLLER_H_
diff --git a/content/browser/renderer_host/smooth_scroll_gesture_controller_unittest.cc b/content/browser/renderer_host/smooth_scroll_gesture_controller_unittest.cc
new file mode 100644
index 0000000..96b70a2
--- /dev/null
+++ b/content/browser/renderer_host/smooth_scroll_gesture_controller_unittest.cc
@@ -0,0 +1,183 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/time.h"
+#include "content/browser/renderer_host/render_widget_host_delegate.h"
+#include "content/browser/renderer_host/smooth_scroll_gesture_controller.h"
+#include "content/browser/renderer_host/test_render_view_host.h"
+#include "content/common/view_messages.h"
+#include "content/port/browser/render_widget_host_view_port.h"
+#include "content/port/browser/smooth_scroll_gesture.h"
+#include "content/public/test/mock_render_process_host.h"
+#include "content/public/test/test_browser_context.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if defined(USE_AURA)
+#include "ui/aura/env.h"
+#include "ui/aura/test/test_screen.h"
+#endif
+
+using base::TimeDelta;
+
+namespace content {
+
+namespace {
+
+class MockSmoothScrollGesture : public SmoothScrollGesture {
+ public:
+ MockSmoothScrollGesture() :
+ called_(0) {
+ }
+
+ // SmoothScrollGesture implementation:
+ virtual bool ForwardInputEvents(base::TimeTicks now,
+ RenderWidgetHost* host) OVERRIDE {
+ ++called_;
+ return true;
+ }
+
+ int called_;
+
+ protected:
+ virtual ~MockSmoothScrollGesture() {
+ }
+};
+
+class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
+ public:
+ MockRenderWidgetHostDelegate() {
+ }
+ virtual ~MockRenderWidgetHostDelegate() {}
+};
+
+class MockRenderWidgetHost : public RenderWidgetHostImpl {
+ public:
+ MockRenderWidgetHost(
+ RenderWidgetHostDelegate* delegate,
+ RenderProcessHost* process,
+ int routing_id)
+ : RenderWidgetHostImpl(delegate, process, routing_id) {
+ }
+ virtual ~MockRenderWidgetHost() {}
+};
+
+class TestView : public TestRenderWidgetHostView {
+ public:
+ explicit TestView(RenderWidgetHostImpl* rwh)
+ : TestRenderWidgetHostView(rwh),
+ mock_gesture_(NULL) {
+ }
+ virtual ~TestView() {}
+
+ // TestRenderWidgetHostView implementation:
+ virtual SmoothScrollGesture* CreateSmoothScrollGesture(
+ bool scroll_down, int pixels_to_scroll, int mouse_event_x,
+ int mouse_event_y) OVERRIDE {
+ mock_gesture_ = new MockSmoothScrollGesture();
+ return mock_gesture_;
+ }
+
+ virtual RenderWidgetHost* GetRenderWidgetHost() const OVERRIDE {
+ return rwh_;
+ }
+
+ MockSmoothScrollGesture* mock_gesture_;
+};
+
+class SmoothScrollGestureControllerTest : public testing::Test {
+ public:
+ SmoothScrollGestureControllerTest() : process_(NULL) {
+ }
+ virtual ~SmoothScrollGestureControllerTest() {}
+
+ protected:
+ // testing::Test implementation:
+ virtual void SetUp() OVERRIDE {
+ browser_context_.reset(new TestBrowserContext());
+ delegate_.reset(new MockRenderWidgetHostDelegate());
+ process_ = new MockRenderProcessHost(browser_context_.get());
+#if defined(USE_AURA)
+ screen_.reset(aura::TestScreen::Create());
+ gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
+#endif
+ host_.reset(
+ new MockRenderWidgetHost(delegate_.get(), process_, MSG_ROUTING_NONE));
+ view_.reset(new TestView(host_.get()));
+ host_->SetView(view_.get());
+ host_->Init();
+ }
+
+ virtual void TearDown() OVERRIDE {
+ view_.reset();
+ host_.reset();
+ delegate_.reset();
+ process_ = NULL;
+ browser_context_.reset();
+
+#if defined(USE_AURA)
+ aura::Env::DeleteInstance();
+ screen_.reset();
+#endif
+
+ // Process all pending tasks to avoid leaks.
+ MessageLoop::current()->RunUntilIdle();
+ }
+
+ void PostQuitMessageAndRun() {
+ // Allow the message loop to process pending synthetic scrolls, then quit.
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE, MessageLoop::QuitClosure(),
+ TimeDelta::FromMilliseconds(
+ controller_.GetSyntheticScrollMessageInterval().InMilliseconds() *
+ 3));
+ MessageLoop::current()->Run();
+ }
+
+ MessageLoopForUI message_loop_;
+
+ scoped_ptr<TestBrowserContext> browser_context_;
+ MockRenderProcessHost* process_; // Deleted automatically by the widget.
+ scoped_ptr<MockRenderWidgetHostDelegate> delegate_;
+ scoped_ptr<MockRenderWidgetHost> host_;
+ scoped_ptr<TestView> view_;
+#if defined(USE_AURA)
+ scoped_ptr<gfx::Screen> screen_;
+#endif
+
+ SmoothScrollGestureController controller_;
+};
+
+TEST_F(SmoothScrollGestureControllerTest, Tick) {
+ ViewHostMsg_BeginSmoothScroll_Params params;
+ params.scroll_down = true;
+ params.pixels_to_scroll = 10;
+ params.mouse_event_x = 20;
+ params.mouse_event_y = 30;
+
+ // Begin a smooth scroll, |mock_gesture_| won't be |called| until we post
+ // message.
+ controller_.BeginSmoothScroll(view_.get(), params);
+ EXPECT_TRUE(view_->mock_gesture_ != NULL);
+ EXPECT_EQ(0, view_->mock_gesture_->called_);
+
+ PostQuitMessageAndRun();
+ const int current_ticks = view_->mock_gesture_->called_;
+ EXPECT_LT(0, current_ticks);
+
+ // Ensure it won't start another smooth scroll.
+ MockSmoothScrollGesture* original_gesture = view_->mock_gesture_;
+ controller_.BeginSmoothScroll(view_.get(), params);
+ PostQuitMessageAndRun();
+ EXPECT_EQ(original_gesture, view_->mock_gesture_);
+
+ // Ensure the smooth scroll is ticked.
+ PostQuitMessageAndRun();
+ EXPECT_LT(current_ticks, view_->mock_gesture_->called_);
+}
+
+} // namespace
+
+} // namespace content
diff --git a/content/browser/renderer_host/socket_stream_dispatcher_host.cc b/content/browser/renderer_host/socket_stream_dispatcher_host.cc
index 2eea8a8..3d0157b 100644
--- a/content/browser/renderer_host/socket_stream_dispatcher_host.cc
+++ b/content/browser/renderer_host/socket_stream_dispatcher_host.cc
@@ -101,6 +101,23 @@
DeleteSocketStreamHost(socket_id);
}
+void SocketStreamDispatcherHost::OnError(const net::SocketStream* socket,
+ int error) {
+ int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
+ DVLOG(1) << "SocketStreamDispatcherHost::OnError socket_id=" << socket_id;
+ if (socket_id == content::kNoSocketId) {
+ LOG(ERROR) << "NoSocketId in OnError";
+ return;
+ }
+ // SocketStream::Delegate::OnError() events are handled as WebSocket error
+ // event when user agent was required to fail WebSocket connection or the
+ // WebSocket connection is closed with prejudice.
+ if (!Send(new SocketStreamMsg_Failed(socket_id, error))) {
+ LOG(ERROR) << "SocketStreamMsg_Failed failed.";
+ DeleteSocketStreamHost(socket_id);
+ }
+}
+
void SocketStreamDispatcherHost::OnSSLCertificateError(
net::SocketStream* socket, const net::SSLInfo& ssl_info, bool fatal) {
int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
diff --git a/content/browser/renderer_host/socket_stream_dispatcher_host.h b/content/browser/renderer_host/socket_stream_dispatcher_host.h
index 7426acc..c9e1c86 100644
--- a/content/browser/renderer_host/socket_stream_dispatcher_host.h
+++ b/content/browser/renderer_host/socket_stream_dispatcher_host.h
@@ -51,6 +51,7 @@
virtual void OnReceivedData(net::SocketStream* socket,
const char* data, int len) OVERRIDE;
virtual void OnClose(net::SocketStream* socket) OVERRIDE;
+ virtual void OnError(const net::SocketStream* socket, int error) OVERRIDE;
virtual void OnSSLCertificateError(net::SocketStream* socket,
const net::SSLInfo& ssl_info,
bool fatal) OVERRIDE;
diff --git a/content/browser/renderer_host/socket_stream_host.cc b/content/browser/renderer_host/socket_stream_host.cc
index b3c9d4c..405a2b7 100644
--- a/content/browser/renderer_host/socket_stream_host.cc
+++ b/content/browser/renderer_host/socket_stream_host.cc
@@ -39,7 +39,8 @@
}
/* static */
-int SocketStreamHost::SocketIdFromSocketStream(net::SocketStream* socket) {
+int SocketStreamHost::SocketIdFromSocketStream(
+ const net::SocketStream* socket) {
net::SocketStream::UserData* d = socket->GetUserData(kSocketIdKey);
if (d) {
SocketStreamId* socket_stream_id = static_cast<SocketStreamId*>(d);
diff --git a/content/browser/renderer_host/socket_stream_host.h b/content/browser/renderer_host/socket_stream_host.h
index d0c65ab..b71e14f 100644
--- a/content/browser/renderer_host/socket_stream_host.h
+++ b/content/browser/renderer_host/socket_stream_host.h
@@ -34,7 +34,7 @@
~SocketStreamHost();
// Gets socket_id associated with |socket|.
- static int SocketIdFromSocketStream(net::SocketStream* socket);
+ static int SocketIdFromSocketStream(const net::SocketStream* socket);
int render_view_id() const { return render_view_id_; }
int socket_id() const { return socket_id_; }
diff --git a/content/browser/renderer_host/software_output_device_win.cc b/content/browser/renderer_host/software_output_device_win.cc
index 90bc032..29c4542 100644
--- a/content/browser/renderer_host/software_output_device_win.cc
+++ b/content/browser/renderer_host/software_output_device_win.cc
@@ -17,13 +17,11 @@
// TODO(skaslev) Remove this when crbug.com/180702 is fixed.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- hdc_ = ::GetWindowDC(compositor->widget());
+ hwnd_ = compositor->widget();
}
SoftwareOutputDeviceWin::~SoftwareOutputDeviceWin() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- ::ReleaseDC(compositor_->widget(), hdc_);
}
void SoftwareOutputDeviceWin::Resize(gfx::Size viewport_size) {
@@ -49,13 +47,15 @@
return;
const SkBitmap& bitmap = device_->accessBitmap(false);
- gfx::StretchDIBits(hdc_,
+ HDC hdc = ::GetDC(hwnd_);
+ gfx::StretchDIBits(hdc,
rect.x(), rect.y(),
rect.width(), rect.height(),
rect.x(), rect.y(),
rect.width(), rect.height(),
bitmap.getPixels(),
&bitmap_info_);
+ ::ReleaseDC(hwnd_, hdc);
}
} // namespace content
diff --git a/content/browser/renderer_host/software_output_device_win.h b/content/browser/renderer_host/software_output_device_win.h
index 930f523..057e48f 100644
--- a/content/browser/renderer_host/software_output_device_win.h
+++ b/content/browser/renderer_host/software_output_device_win.h
@@ -27,7 +27,7 @@
private:
ui::Compositor* compositor_;
- HDC hdc_;
+ HWND hwnd_;
BITMAPINFO bitmap_info_;
};
diff --git a/content/browser/renderer_host/surface_texture_transport_client_android.cc b/content/browser/renderer_host/surface_texture_transport_client_android.cc
index ca2a5be..23888af 100644
--- a/content/browser/renderer_host/surface_texture_transport_client_android.cc
+++ b/content/browser/renderer_host/surface_texture_transport_client_android.cc
@@ -11,42 +11,59 @@
#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/browser/renderer_host/compositor_impl_android.h"
#include "content/browser/renderer_host/image_transport_factory_android.h"
-#include "content/common/android/surface_texture_bridge.h"
+#include "content/public/browser/browser_thread.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
+#include "ui/gl/android/surface_texture_bridge.h"
#include "webkit/compositor_bindings/web_compositor_support_impl.h"
+namespace content {
+
namespace {
static const uint32 kGLTextureExternalOES = 0x8D65;
-} // anonymous namespace
+class SurfaceRefAndroid : public GpuSurfaceTracker::SurfaceRef {
+ public:
+ SurfaceRefAndroid(
+ const scoped_refptr<gfx::SurfaceTextureBridge>& surface,
+ ANativeWindow* window)
+ : surface_(surface),
+ window_(window) {
+ ANativeWindow_acquire(window_);
+ }
-namespace content {
+ private:
+ virtual ~SurfaceRefAndroid() {
+ DCHECK(window_);
+ ANativeWindow_release(window_);
+ }
+
+ scoped_refptr<gfx::SurfaceTextureBridge> surface_;
+ ANativeWindow* window_;
+};
+
+} // anonymous namespace
SurfaceTextureTransportClient::SurfaceTextureTransportClient()
: window_(NULL),
texture_id_(0),
- surface_id_(0) {
+ surface_id_(0),
+ weak_factory_(this) {
}
SurfaceTextureTransportClient::~SurfaceTextureTransportClient() {
- if (surface_id_) {
- GpuSurfaceTracker::Get()->SetNativeWidget(
- surface_id_, gfx::kNullAcceleratedWidget);
- }
- if (window_)
- ANativeWindow_release(window_);
}
scoped_refptr<cc::Layer> SurfaceTextureTransportClient::Initialize() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// Use a SurfaceTexture to stream frames to the UI thread.
video_layer_ = cc::VideoLayer::Create(this);
- surface_texture_ = new SurfaceTextureBridge(0);
+ surface_texture_ = new gfx::SurfaceTextureBridge(0);
surface_texture_->SetFrameAvailableCallback(
- base::Bind(
- &SurfaceTextureTransportClient::OnSurfaceTextureFrameAvailable,
- base::Unretained(this)));
+ base::Bind(
+ &SurfaceTextureTransportClient::OnSurfaceTextureFrameAvailable,
+ weak_factory_.GetWeakPtr()));
surface_texture_->DetachFromGLContext();
return video_layer_.get();
}
@@ -56,15 +73,22 @@
DCHECK(surface_id);
surface_id_ = surface_id;
- if (!window_)
+ if (!window_) {
window_ = surface_texture_->CreateSurface();
- GpuSurfaceTracker::Get()->SetNativeWidget(surface_id, window_);
+ GpuSurfaceTracker::Get()->SetNativeWidget(
+ surface_id, window_, new SurfaceRefAndroid(surface_texture_, window_));
+ // SurfaceRefAndroid took ownership (and an extra ref to) window_.
+ ANativeWindow_release(window_);
+ }
+
return gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::NATIVE_DIRECT);
}
void SurfaceTextureTransportClient::SetSize(const gfx::Size& size) {
- surface_texture_->SetDefaultBufferSize(size.width(), size.height());
+ if (size.width() > 0 && size.height() > 0) {
+ surface_texture_->SetDefaultBufferSize(size.width(), size.height());
+ }
video_layer_->SetBounds(size);
video_frame_ = NULL;
}
@@ -99,6 +123,7 @@
}
void SurfaceTextureTransportClient::OnSurfaceTextureFrameAvailable() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
video_layer_->SetNeedsDisplay();
}
diff --git a/content/browser/renderer_host/surface_texture_transport_client_android.h b/content/browser/renderer_host/surface_texture_transport_client_android.h
index d2540e1..8c5e63b 100644
--- a/content/browser/renderer_host/surface_texture_transport_client_android.h
+++ b/content/browser/renderer_host/surface_texture_transport_client_android.h
@@ -7,6 +7,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "cc/layers/video_frame_provider.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/size.h"
@@ -18,8 +19,11 @@
class VideoLayer;
}
-namespace content {
+namespace gfx {
class SurfaceTextureBridge;
+}
+
+namespace content {
class SurfaceTextureTransportClient : public cc::VideoFrameProvider {
public:
@@ -40,11 +44,12 @@
void OnSurfaceTextureFrameAvailable();
scoped_refptr<cc::VideoLayer> video_layer_;
- scoped_refptr<SurfaceTextureBridge> surface_texture_;
+ scoped_refptr<gfx::SurfaceTextureBridge> surface_texture_;
ANativeWindow* window_;
scoped_refptr<media::VideoFrame> video_frame_;
uint32 texture_id_;
int surface_id_;
+ base::WeakPtrFactory<SurfaceTextureTransportClient> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SurfaceTextureTransportClient);
};
diff --git a/content/browser/renderer_host/test_render_view_host.cc b/content/browser/renderer_host/test_render_view_host.cc
index 5bf77f1..0e1792a 100644
--- a/content/browser/renderer_host/test_render_view_host.cc
+++ b/content/browser/renderer_host/test_render_view_host.cc
@@ -212,9 +212,10 @@
#endif
#if defined(OS_WIN) && defined(USE_AURA)
-void TestRenderWidgetHostView::SetParentNativeViewAccessible(
- gfx::NativeViewAccessible accessible_parent) {
+gfx::NativeViewAccessible
+TestRenderWidgetHostView::AccessibleObjectFromChildId(long child_id) {
NOTIMPLEMENTED();
+ return NULL;
}
#endif
@@ -240,6 +241,7 @@
render_view_created_(false),
delete_counter_(NULL),
simulate_fetch_via_proxy_(false),
+ simulate_history_list_was_cleared_(false),
contents_mime_type_("text/html") {
// For normal RenderViewHosts, this is freed when |Shutdown()| is
// called. For TestRenderViewHost, the view is explicitly
@@ -273,22 +275,33 @@
SendNavigateWithTransition(page_id, url, PAGE_TRANSITION_LINK);
}
+void TestRenderViewHost::SendFailedNavigate(int page_id, const GURL& url) {
+ SendNavigateWithTransitionAndResponseCode(
+ page_id, url, PAGE_TRANSITION_LINK, 500);
+}
+
void TestRenderViewHost::SendNavigateWithTransition(
int page_id, const GURL& url, PageTransition transition) {
- OnDidStartProvisionalLoadForFrame(0, -1, true, url);
- SendNavigateWithParameters(page_id, url, transition, url);
+ SendNavigateWithTransitionAndResponseCode(page_id, url, transition, 200);
}
void TestRenderViewHost::SendNavigateWithOriginalRequestURL(
int page_id, const GURL& url, const GURL& original_request_url) {
OnDidStartProvisionalLoadForFrame(0, -1, true, url);
SendNavigateWithParameters(page_id, url, PAGE_TRANSITION_LINK,
- original_request_url);
+ original_request_url, 200);
+}
+
+void TestRenderViewHost::SendNavigateWithTransitionAndResponseCode(
+ int page_id, const GURL& url, PageTransition transition,
+ int response_code) {
+ OnDidStartProvisionalLoadForFrame(0, -1, true, url);
+ SendNavigateWithParameters(page_id, url, transition, url, response_code);
}
void TestRenderViewHost::SendNavigateWithParameters(
int page_id, const GURL& url, PageTransition transition,
- const GURL& original_request_url) {
+ const GURL& original_request_url, int response_code) {
ViewHostMsg_FrameNavigate_Params params;
params.page_id = page_id;
@@ -306,10 +319,11 @@
params.contents_mime_type = contents_mime_type_;
params.is_post = false;
params.was_within_same_page = false;
- params.http_status_code = 0;
+ params.http_status_code = response_code;
params.socket_address.set_host("2001:db8::1");
params.socket_address.set_port(80);
params.was_fetched_via_proxy = simulate_fetch_via_proxy_;
+ params.history_list_was_cleared = simulate_history_list_was_cleared_;
params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url));
params.original_request_url = original_request_url;
@@ -318,7 +332,8 @@
}
void TestRenderViewHost::SendShouldCloseACK(bool proceed) {
- OnShouldCloseACK(proceed, base::TimeTicks(), base::TimeTicks());
+ base::TimeTicks now = base::TimeTicks::Now();
+ OnShouldCloseACK(proceed, now, now);
}
void TestRenderViewHost::SetContentsMimeType(const std::string& mime_type) {
@@ -349,6 +364,10 @@
simulate_fetch_via_proxy_ = proxy;
}
+void TestRenderViewHost::set_simulate_history_list_was_cleared(bool cleared) {
+ simulate_history_list_was_cleared_ = cleared;
+}
+
RenderViewHostImplTestHarness::RenderViewHostImplTestHarness() {
}
diff --git a/content/browser/renderer_host/test_render_view_host.h b/content/browser/renderer_host/test_render_view_host.h
index 14ea4d8..a6ec555 100644
--- a/content/browser/renderer_host/test_render_view_host.h
+++ b/content/browser/renderer_host/test_render_view_host.h
@@ -141,13 +141,6 @@
virtual void ShowDisambiguationPopup(
const gfx::Rect& target_rect,
const SkBitmap& zoomed_bitmap) OVERRIDE {}
- virtual void UpdateFrameInfo(const gfx::Vector2dF& scroll_offset,
- float page_scale_factor,
- const gfx::Vector2dF& page_scale_factor_limits,
- const gfx::SizeF& content_size,
- const gfx::SizeF& viewport_size,
- const gfx::Vector2dF& controls_offset,
- const gfx::Vector2dF& content_offset) OVERRIDE {}
virtual void HasTouchEventHandlers(bool need_touch_events) OVERRIDE {}
#elif defined(OS_WIN) && !defined(USE_AURA)
virtual void WillWmDestroy() OVERRIDE;
@@ -166,8 +159,8 @@
virtual void SetClickthroughRegion(SkRegion* region) OVERRIDE;
#endif
#if defined(OS_WIN) && defined(USE_AURA)
- virtual void SetParentNativeViewAccessible(
- gfx::NativeViewAccessible accessible_parent) OVERRIDE;
+ virtual gfx::NativeViewAccessible AccessibleObjectFromChildId(long child_id)
+ OVERRIDE;
#endif
virtual bool LockMouse() OVERRIDE;
virtual void UnlockMouse() OVERRIDE;
@@ -237,6 +230,7 @@
// is not specified since it is synonymous with the one from
// RenderViewHostImpl, see below.
virtual void SendNavigate(int page_id, const GURL& url) OVERRIDE;
+ virtual void SendFailedNavigate(int page_id, const GURL& url) OVERRIDE;
virtual void SendNavigateWithTransition(int page_id, const GURL& url,
PageTransition transition) OVERRIDE;
virtual void SendShouldCloseACK(bool proceed) OVERRIDE;
@@ -252,12 +246,6 @@
void SendNavigateWithOriginalRequestURL(
int page_id, const GURL& url, const GURL& original_request_url);
- // Calls OnNavigate on the RenderViewHost with the given information.
- // Sets the rest of the parameters in the message to the "typical" values.
- // This is a helper function for simulating the most common types of loads.
- void SendNavigateWithParameters(
- int page_id, const GURL& url, PageTransition transition,
- const GURL& original_request_url);
void TestOnStartDragging(const WebDropData& drop_data);
@@ -296,6 +284,11 @@
// False by default.
void set_simulate_fetch_via_proxy(bool proxy);
+ // If set, navigations will appear to have cleared the history list in the
+ // RenderView (ViewHostMsg_FrameNavigate_Params::history_list_was_cleared).
+ // False by default.
+ void set_simulate_history_list_was_cleared(bool cleared);
+
// RenderViewHost overrides --------------------------------------------------
virtual bool CreateRenderView(const string16& frame_name,
@@ -306,6 +299,21 @@
private:
FRIEND_TEST_ALL_PREFIXES(RenderViewHostTest, FilterNavigate);
+ void SendNavigateWithTransitionAndResponseCode(int page_id,
+ const GURL& url,
+ PageTransition transition,
+ int response_code);
+
+ // Calls OnNavigate on the RenderViewHost with the given information.
+ // Sets the rest of the parameters in the message to the "typical" values.
+ // This is a helper function for simulating the most common types of loads.
+ void SendNavigateWithParameters(int page_id,
+ const GURL& url,
+ PageTransition transition,
+ const GURL& original_request_url,
+ int response_code);
+
+
// Tracks if the caller thinks if it created the RenderView. This is so we can
// respond to IsRenderViewLive appropriately.
bool render_view_created_;
@@ -316,6 +324,9 @@
// See set_simulate_fetch_via_proxy() above.
bool simulate_fetch_via_proxy_;
+ // See set_simulate_history_list_was_cleared() above.
+ bool simulate_history_list_was_cleared_;
+
// See SetContentsMimeType() above.
std::string contents_mime_type_;
diff --git a/content/browser/renderer_host/text_input_client_mac_unittest.mm b/content/browser/renderer_host/text_input_client_mac_unittest.mm
index 9930b3e..20976ef 100644
--- a/content/browser/renderer_host/text_input_client_mac_unittest.mm
+++ b/content/browser/renderer_host/text_input_client_mac_unittest.mm
@@ -35,7 +35,7 @@
class TextInputClientMacTest : public testing::Test {
public:
TextInputClientMacTest()
- : message_loop_(MessageLoop::TYPE_UI),
+ : message_loop_(base::MessageLoop::TYPE_UI),
browser_context_(),
process_factory_(),
delegate_(),
@@ -73,7 +73,7 @@
private:
friend class ScopedTestingThread;
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
TestBrowserContext browser_context_;
// Gets deleted when the last RWH in the "process" gets destroyed.
diff --git a/content/browser/renderer_host/web_input_event_aura.cc b/content/browser/renderer_host/web_input_event_aura.cc
index 81e1ebf..e293377 100644
--- a/content/browser/renderer_host/web_input_event_aura.cc
+++ b/content/browser/renderer_host/web_input_event_aura.cc
@@ -20,13 +20,32 @@
base::NativeEvent native_event);
WebKit::WebGestureEvent MakeWebGestureEventFromNativeEvent(
base::NativeEvent native_event);
-#else
+#elif defined(USE_X11)
WebKit::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent(
ui::ScrollEvent* event);
WebKit::WebKeyboardEvent MakeWebKeyboardEventFromAuraEvent(
ui::KeyEvent* event);
WebKit::WebGestureEvent MakeWebGestureEventFromAuraEvent(
ui::ScrollEvent* event);
+#else
+WebKit::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent(
+ ui::ScrollEvent* event) {
+ WebKit::WebMouseWheelEvent webkit_event;
+ return webkit_event;
+}
+
+WebKit::WebKeyboardEvent MakeWebKeyboardEventFromAuraEvent(
+ ui::KeyEvent* event) {
+ WebKit::WebKeyboardEvent webkit_event;
+ return webkit_event;
+}
+
+WebKit::WebGestureEvent MakeWebGestureEventFromAuraEvent(
+ ui::ScrollEvent* event) {
+ WebKit::WebGestureEvent webkit_event;
+ return webkit_event;
+}
+
#endif
WebKit::WebMouseEvent MakeWebMouseEventFromAuraEvent(
@@ -234,7 +253,8 @@
webkit_event.button = WebKit::WebMouseEvent::ButtonNone;
webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags());
webkit_event.timeStampSeconds = event->time_stamp().InSecondsF();
- webkit_event.deltaY = event->offset();
+ webkit_event.deltaX = event->x_offset();
+ webkit_event.deltaY = event->y_offset();
webkit_event.wheelTicksY = webkit_event.deltaY / kPixelsPerTick;
return webkit_event;
diff --git a/content/browser/resolve_proxy_msg_helper.cc b/content/browser/resolve_proxy_msg_helper.cc
index 52d0987..796b070 100644
--- a/content/browser/resolve_proxy_msg_helper.cc
+++ b/content/browser/resolve_proxy_msg_helper.cc
@@ -83,7 +83,7 @@
// Verify the request wasn't started yet.
DCHECK(NULL == req.pac_req);
- if (context_getter_.get()) {
+ if (context_getter_) {
proxy_service_ = context_getter_->GetURLRequestContext()->proxy_service();
context_getter_ = NULL;
}
diff --git a/content/browser/resolve_proxy_msg_helper_unittest.cc b/content/browser/resolve_proxy_msg_helper_unittest.cc
index f0d1c2d..628df86 100644
--- a/content/browser/resolve_proxy_msg_helper_unittest.cc
+++ b/content/browser/resolve_proxy_msg_helper_unittest.cc
@@ -41,10 +41,10 @@
ResolveProxyMsgHelperTest()
: resolver_(new net::MockAsyncProxyResolver),
- service_(new net::ProxyService(
- new MockProxyConfigService, resolver_, NULL)),
+ service_(
+ new net::ProxyService(new MockProxyConfigService, resolver_, NULL)),
helper_(new ResolveProxyMsgHelper(service_.get())),
- message_loop_(MessageLoop::TYPE_IO),
+ message_loop_(base::MessageLoop::TYPE_IO),
io_thread_(BrowserThread::IO, &message_loop_) {
test_sink_.AddFilter(this);
helper_->OnFilterAdded(&test_sink_);
@@ -79,7 +79,7 @@
return true;
}
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
BrowserThreadImpl io_thread_;
IPC::TestSink test_sink_;
};
diff --git a/content/browser/resources/indexed_db/OWNERS b/content/browser/resources/indexed_db/OWNERS
new file mode 100644
index 0000000..b106dad
--- /dev/null
+++ b/content/browser/resources/indexed_db/OWNERS
@@ -0,0 +1,4 @@
+dgrogan@chromium.org
+michaeln@chromium.org
+jsbell@chromium.org
+alecflett@chromium.org
diff --git a/content/browser/resources/indexed_db/indexeddb_internals.css b/content/browser/resources/indexed_db/indexeddb_internals.css
new file mode 100644
index 0000000..2bbea77
--- /dev/null
+++ b/content/browser/resources/indexed_db/indexeddb_internals.css
@@ -0,0 +1,35 @@
+/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+.indexeddb-summary {
+ background-color: rgb(235, 239, 249);
+ border-top: 1px solid rgb(156, 194, 239);
+ margin-bottom: 6px;
+ margin-top: 12px;
+ padding: 3px;
+ font-weight: bold;
+}
+
+.indexeddb-item {
+ margin-bottom: 15px;
+ margin-top: 6px;
+ position: relative;
+}
+
+.indexeddb-url {
+ color: rgb(85, 102, 221);
+ display: inline-block;
+ max-width: 500px;
+ overflow: hidden;
+ padding-bottom: 1px;
+ padding-top: 4px;
+ text-decoration: none;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.controls a {
+ -webkit-margin-end: 16px;
+ color: #777;
+}
diff --git a/content/browser/resources/indexed_db/indexeddb_internals.html b/content/browser/resources/indexed_db/indexeddb_internals.html
new file mode 100644
index 0000000..87337ec
--- /dev/null
+++ b/content/browser/resources/indexed_db/indexeddb_internals.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html i18n-values="dir:textdirection;">
+<head>
+ <meta charset="utf-8">
+ <title>IndexedDB</title>
+ <link rel="stylesheet" href="chrome://resources/css/tabs.css">
+ <link rel="stylesheet" href="chrome://resources/css/widgets.css">
+ <link rel="stylesheet" href="indexeddb_internals.css">
+</head>
+<body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize">
+ <!-- templates -->
+ <div style="display:none">
+ <div id="indexeddb-list-template"
+ jsvalues="$partition_path:$this.partition_path">
+ <div class="indexeddb-summary">
+ <span>Instances in: </span>
+ <span jscontent="$this.partition_path"></span>
+ <span jscontent="'(' + $this.idbs.length + ')'"></span>
+ </div>
+ <div class="indexeddb-item" jsselect="$this.idbs">
+ <a class="indexeddb-url" jscontent="url" jsvalues="href:url"
+ target="_blank"></a>
+ <div class="indexeddb-size">
+ <span>Size:</span>
+ <span jscontent="size + ' bytes'"></span>
+ </div>
+ <div class="indexeddb-last-modified">
+ <span>Last modified:</span>
+ <span jscontent="new Date(last_modified)"></span>
+ </div>
+ <div class="indexeddb-last-modified">
+ <span>Path:</span>
+ <span jscontent="path"></span>
+ </div>
+ <div class="controls">
+ <a href="#" class="download"
+ jsvalues=".idb_origin_url:url;.idb_partition_path:$partition_path">Download</a>
+ <span class="download-status" style="display: none">Loading...</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ <h1>IndexedDB</h1>
+ <div class="content">
+ <div id="indexeddb-list">
+ </div>
+ <script src="chrome://resources/js/util.js"></script>
+ <script src="chrome://resources/js/cr.js"></script>
+ <script src="indexeddb_internals.js"></script>
+ <script src="chrome://resources/js/load_time_data.js"></script>
+ <script src="chrome://resources/js/jstemplate_compiled.js"></script>
+ <script src="strings.js"></script>
+ <script src="chrome://resources/js/i18n_template2.js"></script>
+</body>
+</html>
+
diff --git a/content/browser/resources/indexed_db/indexeddb_internals.js b/content/browser/resources/indexed_db/indexeddb_internals.js
new file mode 100644
index 0000000..378b9ad
--- /dev/null
+++ b/content/browser/resources/indexed_db/indexeddb_internals.js
@@ -0,0 +1,59 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+cr.define('indexeddb', function() {
+ 'use strict';
+
+ function initialize() {
+ chrome.send('getAllOrigins');
+ }
+
+ function progressNodeFor(link) {
+ return link.parentNode.querySelector('.download-status');
+ }
+
+ function downloadOriginData(event) {
+ var link = event.target;
+ progressNodeFor(link).style.display = 'inline';
+ chrome.send('downloadOriginData', [link.idb_partition_path,
+ link.idb_origin_url]);
+ return false;
+ }
+
+ // Fired from the backend after the data has been zipped up, and the
+ // download manager has begun downloading the file.
+ function onOriginDownloadReady(partition_path, origin_url) {
+ var downloadLinks = document.querySelectorAll('a.download');
+ for (var i = 0; i < downloadLinks.length; ++i) {
+ var link = downloadLinks[i];
+ if (partition_path == link.idb_partition_path &&
+ origin_url == link.idb_origin_url) {
+ progressNodeFor(link).style.display = 'none';
+ }
+ }
+ }
+
+ // Fired from the backend with a single partition's worth of
+ // IndexedDB metadata.
+ function onOriginsReady(origins, partition_path) {
+ var template = jstGetTemplate('indexeddb-list-template');
+ var container = $('indexeddb-list');
+ container.appendChild(template);
+ jstProcess(new JsEvalContext({ idbs: origins,
+ partition_path: partition_path}), template);
+
+ var downloadLinks = container.querySelectorAll('a.download');
+ for (var i = 0; i < downloadLinks.length; ++i) {
+ downloadLinks[i].addEventListener('click', downloadOriginData, false);
+ }
+ }
+
+ return {
+ initialize: initialize,
+ onOriginDownloadReady: onOriginDownloadReady,
+ onOriginsReady: onOriginsReady,
+ };
+});
+
+document.addEventListener('DOMContentLoaded', indexeddb.initialize);
diff --git a/content/browser/resources/media/dump_creator.js b/content/browser/resources/media/dump_creator.js
new file mode 100644
index 0000000..3770e48
--- /dev/null
+++ b/content/browser/resources/media/dump_creator.js
@@ -0,0 +1,112 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/**
+ * Provides the UI to start and stop RTP recording, forwards the start/stop
+ * commands to Chrome, and updates the UI based on dump updates.
+ *
+ * @param {Element} containerElement The parent element of the dump creation UI.
+ */
+var DumpCreator = (function() {
+ /**
+ * @param {Element} containerElement The parent element of the dump creation
+ * UI.
+ * @constructor
+ */
+ function DumpCreator(containerElement) {
+ /**
+ * True if the RTP packets are being recorded.
+ * @type {bool}
+ * @private
+ */
+ this.recording_ = false;
+
+ /**
+ * @type {!Object.<string>}
+ * @private
+ * @const
+ */
+ this.StatusStrings_ = {
+ NOT_STARTED: 'not started.',
+ RECORDING: 'recording...',
+ },
+
+ /**
+ * The status of dump creation.
+ * @type {string}
+ * @private
+ */
+ this.status_ = this.StatusStrings_.NOT_STARTED;
+
+ /**
+ * The root element of the dump creation UI.
+ * @type {Element}
+ * @private
+ */
+ this.root_ = document.createElement('details');
+
+ this.root_.className = 'peer-connection-dump-root';
+ containerElement.appendChild(this.root_);
+ var summary = document.createElement('summary');
+ this.root_.appendChild(summary);
+ summary.textContent = 'Create Dump';
+ var content = document.createElement('pre');
+ this.root_.appendChild(content);
+ content.innerHTML = '<button></button> Status: <span></span>';
+ content.getElementsByTagName('button')[0].addEventListener(
+ 'click', this.onToggled_.bind(this));
+
+ this.updateDisplay_();
+ }
+
+ DumpCreator.prototype = {
+ /**
+ * Handles the event of toggling the dump recording state.
+ *
+ * @private
+ */
+ onToggled_: function() {
+ if (this.recording_) {
+ this.recording_ = false;
+ this.status_ = this.StatusStrings_.NOT_STARTED;
+ chrome.send('stopRtpRecording');
+ } else {
+ this.recording_ = true;
+ this.status_ = this.StatusStrings_.RECORDING;
+ chrome.send('startRtpRecording');
+ }
+ this.updateDisplay_();
+ },
+
+ /**
+ * Updates the UI based on the recording status.
+ *
+ * @private
+ */
+ updateDisplay_: function() {
+ if (this.recording_) {
+ this.root_.getElementsByTagName('button')[0].textContent =
+ 'Stop Recording RTP Packets';
+ } else {
+ this.root_.getElementsByTagName('button')[0].textContent =
+ 'Start Recording RTP Packets';
+ }
+
+ this.root_.getElementsByTagName('span')[0].textContent = this.status_;
+ },
+
+ /**
+ * Set the status to the content of the update.
+ * @param {!Object} update
+ */
+ onUpdate: function(update) {
+ if (this.recording_) {
+ this.status_ = JSON.stringify(update);
+ this.updateDisplay_();
+ }
+ },
+ };
+ return DumpCreator;
+})();
diff --git a/content/browser/resources/media/peer_connection_update_table.js b/content/browser/resources/media/peer_connection_update_table.js
new file mode 100644
index 0000000..facbefa
--- /dev/null
+++ b/content/browser/resources/media/peer_connection_update_table.js
@@ -0,0 +1,128 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/**
+ * The data of a peer connection update.
+ * @param {number} pid The id of the renderer.
+ * @param {number} lid The id of the peer conneciton inside a renderer.
+ * @param {string} type The type of the update.
+ * @param {string} value The details of the update.
+ * @constructor
+ */
+var PeerConnectionUpdateEntry = function(pid, lid, type, value) {
+ /**
+ * @type {number}
+ */
+ this.pid = pid;
+
+ /**
+ * @type {number}
+ */
+ this.lid = lid;
+
+ /**
+ * @type {string}
+ */
+ this.type = type;
+
+ /**
+ * @type {string}
+ */
+ this.value = value;
+};
+
+
+/**
+ * Maintains the peer connection update log table.
+ */
+var PeerConnectionUpdateTable = (function() {
+ 'use strict';
+
+ /**
+ * @constructor
+ */
+ function PeerConnectionUpdateTable() {
+ /**
+ * @type {string}
+ * @const
+ * @private
+ */
+ this.UPDATE_LOG_ID_SUFFIX_ = '-update-log';
+
+ /**
+ * @type {string}
+ * @const
+ * @private
+ */
+ this.UPDATE_LOG_CONTAINER_CLASS_ = 'update-log-container';
+
+ /**
+ * @type {string}
+ * @const
+ * @private
+ */
+ this.UPDATE_LOG_TABLE_CLASS_ = 'update-log-table';
+ }
+
+ PeerConnectionUpdateTable.prototype = {
+ /**
+ * Adds the update to the update table as a new row. The type of the update
+ * is set to the summary of the cell; clicking the cell will reveal or hide
+ * the details as the content of a TextArea element.
+ *
+ * @param {!Element} peerConnectionElement The root element.
+ * @param {!PeerConnectionUpdateEntry} update The update to add.
+ */
+ addPeerConnectionUpdate: function(peerConnectionElement, update) {
+ var tableElement = this.ensureUpdateContainer_(peerConnectionElement);
+
+ var row = document.createElement('tr');
+ tableElement.firstChild.appendChild(row);
+
+ row.innerHTML = '<td>' + (new Date()).toLocaleString() + '</td>';
+
+ if (update.value.length == 0) {
+ row.innerHTML += '<td>' + update.type + '</td>';
+ return;
+ }
+
+ row.innerHTML += '<td><details><summary>' + update.type +
+ '</summary></details></td>';
+
+ var valueContainer = document.createElement('pre');
+ var details = row.cells[1].childNodes[0];
+ details.appendChild(valueContainer);
+ valueContainer.textContent = update.value;
+ },
+
+ /**
+ * Makes sure the update log table of the peer connection is created.
+ *
+ * @param {!Element} peerConnectionElement The root element.
+ * @return {!Element} The log table element.
+ * @private
+ */
+ ensureUpdateContainer_: function(peerConnectionElement) {
+ var tableId = peerConnectionElement.id + this.UPDATE_LOG_ID_SUFFIX_;
+ var tableElement = $(tableId);
+ if (!tableElement) {
+ var tableContainer = document.createElement('div');
+ tableContainer.className = this.UPDATE_LOG_CONTAINER_CLASS_;
+ peerConnectionElement.appendChild(tableContainer);
+
+ tableElement = document.createElement('table');
+ tableElement.className = this.UPDATE_LOG_TABLE_CLASS_;
+ tableElement.id = tableId;
+ tableElement.border = 1;
+ tableContainer.appendChild(tableElement);
+ tableElement.innerHTML = '<tr><th>Time</th>' +
+ '<th class="update-log-header-event">Event</th></tr>';
+ }
+ return tableElement;
+ }
+ };
+
+ return PeerConnectionUpdateTable;
+})();
diff --git a/content/browser/resources/media/ssrc_info_manager.js b/content/browser/resources/media/ssrc_info_manager.js
new file mode 100644
index 0000000..8236e87
--- /dev/null
+++ b/content/browser/resources/media/ssrc_info_manager.js
@@ -0,0 +1,134 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/**
+ * SsrcInfoManager stores the ssrc stream info extracted from SDP.
+ */
+var SsrcInfoManager = (function() {
+ 'use strict';
+
+ /**
+ * @constructor
+ */
+ function SsrcInfoManager() {
+ /**
+ * Map from ssrc id to an object containing all the stream properties.
+ * @type {!Object.<string, !Object.<string>>}
+ * @private
+ */
+ this.streamInfoContainer_ = {};
+
+ /**
+ * The string separating attibutes in an SDP.
+ * @type {string}
+ * @const
+ * @private
+ */
+ this.ATTRIBUTE_SEPARATOR_ = /[\r,\n]/;
+
+ /**
+ * The regex separating fields within an ssrc description.
+ * @type {RegExp}
+ * @const
+ * @private
+ */
+ this.FIELD_SEPARATOR_REGEX_ = / .*:/;
+
+ /**
+ * The prefix string of an ssrc description.
+ * @type {string}
+ * @const
+ * @private
+ */
+ this.SSRC_ATTRIBUTE_PREFIX_ = 'a=ssrc:';
+
+ /**
+ * The className of the ssrc info parent element.
+ * @type {string}
+ * @const
+ * @private
+ */
+ this.SSRC_INFO_BLOCK_CLASS_ = 'ssrc-info-block';
+ }
+
+ SsrcInfoManager.prototype = {
+ /**
+ * Extracts the stream information from |sdp| and saves it.
+ * For example:
+ * a=ssrc:1234 msid:abcd
+ * a=ssrc:1234 label:hello
+ *
+ * @param {string} sdp The SDP string.
+ */
+ addSsrcStreamInfo: function(sdp) {
+ var attributes = sdp.split(this.ATTRIBUTE_SEPARATOR_);
+ for (var i = 0; i < attributes.length; ++i) {
+ // Check if this is a ssrc attribute.
+ if (attributes[i].indexOf(this.SSRC_ATTRIBUTE_PREFIX_) != 0)
+ continue;
+
+ var nextFieldIndex = attributes[i].search(this.FIELD_SEPARATOR_REGEX_);
+
+ if (nextFieldIndex == -1)
+ continue;
+
+ var ssrc = attributes[i].substring(this.SSRC_ATTRIBUTE_PREFIX_.length,
+ nextFieldIndex);
+ if (!this.streamInfoContainer_[ssrc])
+ this.streamInfoContainer_[ssrc] = {};
+
+ // Make |rest| starting at the next field.
+ var rest = attributes[i].substring(nextFieldIndex + 1);
+ var name, value;
+ while (rest.length > 0) {
+ nextFieldIndex = rest.search(this.FIELD_SEPARATOR_REGEX_);
+ if (nextFieldIndex == -1)
+ nextFieldIndex = rest.length;
+
+ // The field name is the string before the colon.
+ name = rest.substring(0, rest.indexOf(':'));
+ // The field value is from after the colon to the next field.
+ value = rest.substring(rest.indexOf(':') + 1, nextFieldIndex);
+ this.streamInfoContainer_[ssrc][name] = value;
+
+ // Move |rest| to the start of the next field.
+ rest = rest.substring(nextFieldIndex + 1);
+ }
+ }
+ },
+
+ /**
+ * @param {string} sdp The ssrc id.
+ * @return {!Object.<string>} The object containing the ssrc infomation.
+ */
+ getStreamInfo: function(ssrc) {
+ return this.streamInfoContainer_[ssrc];
+ },
+
+ /**
+ * Populate the ssrc information into |parentElement|, each field as a
+ * DIV element.
+ *
+ * @param {!Element} parentElement The parent element for the ssrc info.
+ * @param {string} ssrc The ssrc id.
+ */
+ populateSsrcInfo: function(parentElement, ssrc) {
+ if (!this.streamInfoContainer_[ssrc])
+ return;
+
+ parentElement.className = this.SSRC_INFO_BLOCK_CLASS_;
+
+ var fieldElement;
+ for (var property in this.streamInfoContainer_[ssrc]) {
+ fieldElement = document.createElement('div');
+ parentElement.appendChild(fieldElement);
+ fieldElement.textContent =
+ property + ':' + this.streamInfoContainer_[ssrc][property];
+ }
+ }
+ };
+
+ return SsrcInfoManager;
+})();
diff --git a/content/browser/resources/media/stats_graph_helper.js b/content/browser/resources/media/stats_graph_helper.js
index c56ab72..c252f0a 100644
--- a/content/browser/resources/media/stats_graph_helper.js
+++ b/content/browser/resources/media/stats_graph_helper.js
@@ -14,6 +14,8 @@
<include src="data_series.js"/>
<include src="timeline_graph_view.js"/>
+var STATS_GRAPH_CONTAINER_HEADING_CLASS = 'stats-graph-container-heading';
+
// Specifies which stats should be drawn on the 'bweCompound' graph and how.
var bweCompoundGraphConfig = {
googAvailableSendBandwidth: {color: 'red'},
@@ -82,12 +84,18 @@
// Adds the stats report |singleReport| to the timeline graph for the given
// |peerConnectionElement| and |reportName|.
-function drawSingleReport(peerConnectionElement, reportName, singleReport) {
+function drawSingleReport(
+ peerConnectionElement, reportType, reportId, singleReport) {
if (!singleReport || !singleReport.values)
return;
+
+ var reportName = reportType + '-' + reportId;
for (var i = 0; i < singleReport.values.length - 1; i = i + 2) {
var rawLabel = singleReport.values[i];
var rawValue = parseInt(singleReport.values[i + 1]);
+ if (isNaN(rawValue))
+ return;
+
var rawDataSeriesId =
peerConnectionElement.id + '-' + reportName + '-' + rawLabel;
@@ -121,7 +129,7 @@
if (!graphViews[graphViewId]) {
graphViews[graphViewId] = createStatsGraphView(peerConnectionElement,
- reportName,
+ reportType, reportId,
graphType);
var date = new Date(singleReport.timestamp);
graphViews[graphViewId].setDateRange(date, date);
@@ -147,41 +155,43 @@
dataSeries[dataSeriesId].addPoint(time, value);
}
-// Ensures a div container to hold all stats graphs for a report type
-// is created as a child of |peerConnectionElement|.
-function ensureStatsGraphTopContainer(peerConnectionElement, reportName) {
+// Ensures a div container to hold all stats graphs for one track is created as
+// a child of |peerConnectionElement|.
+function ensureStatsGraphTopContainer(
+ peerConnectionElement, reportType, reportId) {
var containerId = peerConnectionElement.id + '-' +
- reportName + '-graph-container';
+ reportType + '-' + reportId + '-graph-container';
var container = $(containerId);
if (!container) {
- container = document.createElement('div');
+ container = document.createElement('details');
container.id = containerId;
- container.className = 'stats-graph-container-collapsed';
+ container.className = 'stats-graph-container';
peerConnectionElement.appendChild(container);
- container.innerHTML =
- '<button>Expand/Collapse Graphs for ' + reportName + '</button>';
+ container.innerHTML ='<summary><span></span></summary>';
+ container.firstChild.firstChild.className =
+ STATS_GRAPH_CONTAINER_HEADING_CLASS;
+ container.firstChild.firstChild.textContent =
+ 'Stats graphs for ' + reportType + '-' + reportId;
- // Expands or collapses the graphs on click.
- container.childNodes[0].addEventListener('click', function(event) {
- var element = event.target.parentNode;
- if (element.className == 'stats-graph-container-collapsed')
- element.className = 'stats-graph-container';
- else
- element.className = 'stats-graph-container-collapsed';
- });
+ if (reportType == 'ssrc') {
+ var ssrcInfoElement = document.createElement('div');
+ container.firstChild.appendChild(ssrcInfoElement);
+ ssrcInfoManager.populateSsrcInfo(ssrcInfoElement, reportId);
+ }
}
return container;
}
// Creates the container elements holding a timeline graph
// and the TimelineGraphView object.
-function createStatsGraphView(peerConnectionElement, reportName, statsName) {
+function createStatsGraphView(
+ peerConnectionElement, reportType, reportId, statsName) {
var topContainer = ensureStatsGraphTopContainer(peerConnectionElement,
- reportName);
+ reportType, reportId);
- var graphViewId =
- peerConnectionElement.id + '-' + reportName + '-' + statsName;
+ var graphViewId = peerConnectionElement.id + '-' +
+ reportType + '-' + reportId + '-' + statsName;
var divId = graphViewId + '-div';
var canvasId = graphViewId + '-canvas';
var container = document.createElement("div");
@@ -191,9 +201,10 @@
container.innerHTML = '<div>' + statsName + '</div>' +
'<div id=' + divId + '><canvas id=' + canvasId + '></canvas></div>';
if (statsName == 'bweCompound') {
- container.insertBefore(createBweCompoundLegend(peerConnectionElement,
- reportName),
- $(divId));
+ container.insertBefore(
+ createBweCompoundLegend(
+ peerConnectionElement, reportType + '-' + reportId),
+ $(divId));
}
return new TimelineGraphView(divId, canvasId);
}
diff --git a/content/browser/resources/media/stats_table.js b/content/browser/resources/media/stats_table.js
new file mode 100644
index 0000000..d31c73a
--- /dev/null
+++ b/content/browser/resources/media/stats_table.js
@@ -0,0 +1,139 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/**
+ * Maintains the stats table.
+ * @param {SsrcInfoManager} ssrcInfoManager The source of the ssrc info.
+ */
+var StatsTable = (function(ssrcInfoManager) {
+ 'use strict';
+
+ /**
+ * @param {SsrcInfoManager} ssrcInfoManager The source of the ssrc info.
+ * @constructor
+ */
+ function StatsTable(ssrcInfoManager) {
+ /**
+ * @type {SsrcInfoManager}
+ * @private
+ */
+ this.ssrcInfoManager_ = ssrcInfoManager;
+ }
+
+ StatsTable.prototype = {
+ /**
+ * Adds |report| to the stats table of |peerConnectionElement|.
+ *
+ * @param {!Element} peerConnectionElement The root element.
+ * @param {!Object} report The object containing stats, which is the object
+ * containing timestamp and values, which is an array of strings, whose
+ * even index entry is the name of the stat, and the odd index entry is
+ * the value.
+ */
+ addStatsReport: function(peerConnectionElement, report) {
+ var statsTable = this.ensureStatsTable_(peerConnectionElement, report);
+
+ if (report.stats) {
+ this.addStatsToTable_(statsTable,
+ report.stats.timestamp, report.stats.values);
+ }
+ },
+
+ /**
+ * Ensure the DIV container for the stats tables is created as a child of
+ * |peerConnectionElement|.
+ *
+ * @param {!Element} peerConnectionElement The root element.
+ * @return {!Element} The stats table container.
+ * @private
+ */
+ ensureStatsTableContainer_: function(peerConnectionElement) {
+ var containerId = peerConnectionElement.id + '-table-container';
+ var container = $(containerId);
+ if (!container) {
+ container = document.createElement('div');
+ container.id = containerId;
+ container.className = 'stats-table-container';
+ peerConnectionElement.appendChild(container);
+ }
+ return container;
+ },
+
+ /**
+ * Ensure the stats table for track specified by |report| of PeerConnection
+ * |peerConnectionElement| is created.
+ *
+ * @param {!Element} peerConnectionElement The root element.
+ * @param {!Object} report The object containing stats, which is the object
+ * containing timestamp and values, which is an array of strings, whose
+ * even index entry is the name of the stat, and the odd index entry is
+ * the value.
+ * @return {!Element} The stats table element.
+ * @private
+ */
+ ensureStatsTable_: function(peerConnectionElement, report) {
+ var tableId = peerConnectionElement.id + '-table-' +
+ report.type + '-' + report.id;
+ var table = $(tableId);
+ if (!table) {
+ var container = this.ensureStatsTableContainer_(peerConnectionElement);
+ table = document.createElement('table');
+ container.appendChild(table);
+ table.id = tableId;
+ table.border = 1;
+
+ table.innerHTML = '<tr><th colspan=2></th></tr>';
+ table.rows[0].cells[0].textContent =
+ 'Statistics ' + report.type + '-' + report.id;
+ if (report.type == 'ssrc') {
+ table.insertRow(1);
+ table.rows[1].innerHTML = '<td colspan=2></td>';
+ this.ssrcInfoManager_.populateSsrcInfo(
+ table.rows[1].cells[0], report.id);
+ }
+ }
+ return table;
+ },
+
+ /**
+ * Update |statsTable| with |time| and |statsData|.
+ *
+ * @param {!Element} statsTable Which table to update.
+ * @param {number} time The number of miliseconds since epoch.
+ * @param {Array.<string>} statsData An array of stats name and value pairs.
+ * @private
+ */
+ addStatsToTable_: function(statsTable, time, statsData) {
+ var date = Date(time);
+ this.updateStatsTableRow_(statsTable, 'timestamp', date.toLocaleString());
+ for (var i = 0; i < statsData.length - 1; i = i + 2) {
+ this.updateStatsTableRow_(statsTable, statsData[i], statsData[i + 1]);
+ }
+ },
+
+ /**
+ * Update the value column of the stats row of |rowName| to |value|.
+ * A new row is created is this is the first report of this stats.
+ *
+ * @param {!Element} statsTable Which table to update.
+ * @param {string} rowName The name of the row to update.
+ * @param {string} value The new value to set.
+ * @private
+ */
+ updateStatsTableRow_: function(statsTable, rowName, value) {
+ var trId = statsTable.id + '-' + rowName;
+ var trElement = $(trId);
+ if (!trElement) {
+ trElement = document.createElement('tr');
+ trElement.id = trId;
+ statsTable.firstChild.appendChild(trElement);
+ trElement.innerHTML = '<td>' + rowName + '</td><td></td>';
+ }
+ trElement.cells[1].textContent = value;
+ }
+ };
+
+ return StatsTable;
+})();
diff --git a/content/browser/resources/media/webrtc_internals.css b/content/browser/resources/media/webrtc_internals.css
index 83d1f39..c0ac402 100644
--- a/content/browser/resources/media/webrtc_internals.css
+++ b/content/browser/resources/media/webrtc_internals.css
@@ -2,25 +2,33 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-.log-container {
+
+.peer-connection-dump-root {
+ font-size: 0.8em;
+ padding-bottom: 3px;
+}
+
+.peer-connection-hidden > *:not(h3) {
+ display:none;
+}
+
+.update-log-container {
float: left;
}
-.stats-graph-container,
-.stats-graph-container-collapsed {
+.ssrc-info-block {
+ color: #999;
+ font-size: 0.8em;
+}
+
+.stats-graph-container {
clear: both;
margin: 0.5em 0 0.5em 0;
}
-.stats-graph-container button,
-.stats-graph-container-collapsed button {
- display: block;
- margin: 0;
- padding: 0;
-}
-
-.stats-graph-container-collapsed .stats-graph-sub-container {
- display: none;
+.stats-graph-container-heading {
+ font-size: 0.8em;
+ font-weight: bold;
}
.stats-graph-sub-container {
@@ -47,7 +55,7 @@
}
details {
- width: 30em;
+ min-width: 30em;
}
h3 + div {
@@ -64,9 +72,11 @@
}
h3 {
- color: #666;
+ color: #555;
+ cursor: pointer;
font-size: 0.9em;
- margin: 1em 0 0.5em 0;
+ margin: 2em 0 0.5em 0;
+ text-decoration: underline;
}
li {
@@ -91,12 +101,6 @@
padding-top: 0.3em;
}
-textarea {
- border: none;
- outline: none;
- width: 100%;
-}
-
table > tr {
vertical-align: top;
}
diff --git a/content/browser/resources/media/webrtc_internals.js b/content/browser/resources/media/webrtc_internals.js
index 77faaf8..1fa0faf 100644
--- a/content/browser/resources/media/webrtc_internals.js
+++ b/content/browser/resources/media/webrtc_internals.js
@@ -2,212 +2,172 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-<include src="stats_graph_helper.js"/>
var peerConnectionsListElem = null;
+var ssrcInfoManager = null;
+var peerConnectionUpdateTable = null;
+var statsTable = null;
+var dumpCreator = null;
+
+<include src="ssrc_info_manager.js"/>
+<include src="stats_graph_helper.js"/>
+<include src="stats_table.js"/>
+<include src="peer_connection_update_table.js"/>
+<include src="dump_creator.js"/>
function initialize() {
peerConnectionsListElem = $('peer-connections-list');
+ dumpCreator = new DumpCreator(peerConnectionsListElem);
+ ssrcInfoManager = new SsrcInfoManager();
+ peerConnectionUpdateTable = new PeerConnectionUpdateTable();
+ statsTable = new StatsTable(ssrcInfoManager);
+
chrome.send('getAllUpdates');
- startGetStats();
-}
-// Polls stats from all PeerConnections every second.
-function startGetStats() {
- if (document.getElementsByTagName('li').length)
- chrome.send('getAllStats');
- window.setTimeout(startGetStats, 1000);
+ // Requests stats from all peer connections every second.
+ window.setInterval(function() {
+ if (peerConnectionsListElem.getElementsByTagName('li').length > 0)
+ chrome.send('getAllStats');
+ }, 1000);
}
+document.addEventListener('DOMContentLoaded', initialize);
+
+/**
+ * A helper function for getting a peer connection element id.
+ *
+ * @param {!Object.<string, number>} data The object containing the pid and lid
+ * of the peer connection.
+ * @return {string} The peer connection element id.
+ */
function getPeerConnectionId(data) {
return data.pid + '-' + data.lid;
}
-// Makes sure a LI element representing a PeerConnection is created
-// and appended to peerConnectionListElem.
-function ensurePeerConnectionElement(id) {
- var element = $(id);
- if (!element) {
- element = document.createElement('li');
- peerConnectionsListElem.appendChild(element);
- element.id = id;
- }
- return element;
-}
-// Makes sure the table representing the PeerConnection event log is created
-// and appended to peerConnectionElement.
-function ensurePeerConnectionLog(peerConnectionElement) {
- var logId = peerConnectionElement.id + '-log';
- var logElement = $(logId);
- if (!logElement) {
- var container = document.createElement('div');
- container.className = 'log-container';
- peerConnectionElement.appendChild(container);
-
- logElement = document.createElement('table');
- logElement.id = logId;
- logElement.className = 'log-table';
- logElement.border = 1;
- container.appendChild(logElement);
- logElement.innerHTML = '<tr><th>Time</th>' +
- '<th class="log-header-event">Event</th></tr>';
- }
- return logElement;
-}
-
-// Add the update to the log table as a new row. The type of the update is set
-// as the text of the cell; clicking the cell will reveal or hide the details
-// as the content of a TextArea element.
-function addToPeerConnectionLog(logElement, update) {
- var row = document.createElement('tr');
- logElement.appendChild(row);
-
- var expandable = (update.value.length > 0);
- // details.open is true initially so that we can get the real scrollHeight
- // of the textareas.
- row.innerHTML =
- '<td>' + (new Date()).toLocaleString() + '</td>' +
- (expandable ?
- '<td><details open><summary>' + update.type + '</summary>' +
- '</details></td>' :
- '<td>' + update.type + '</td>');
- if (!expandable)
- return;
-
- var valueContainer = document.createElement('textarea');
- var details = row.cells[1].childNodes[0];
- details.appendChild(valueContainer);
- valueContainer.value = update.value;
- valueContainer.style.height = valueContainer.scrollHeight + 'px';
- details.open = false;
-}
-
-// Ensure the DIV container for the stats tables is created as a child of
-// |peerConnectionElement|.
-function ensureStatsTableContainer(peerConnectionElement) {
- var containerId = peerConnectionElement.id + '-table-container';
- var container = $(containerId);
- if (!container) {
- container = document.createElement('div');
- container.id = containerId;
- container.className = 'stats-table-container';
- peerConnectionElement.appendChild(container);
- }
- return container;
-}
-
-// Ensure the stats table for track |statsId| of PeerConnection
-// |peerConnectionElement| is created as a child of the stats table container.
-function ensureStatsTable(peerConnectionElement, statsId) {
- var tableId = peerConnectionElement.id + '-table-' + statsId;
- var table = $(tableId);
- if (!table) {
- var container = ensureStatsTableContainer(peerConnectionElement);
- table = document.createElement('table');
- container.appendChild(table);
- table.id = tableId;
- table.border = 1;
- table.innerHTML = '<th>Statistics ' + statsId + '</th>';
- }
- return table;
-}
-
-// Update the value column of the stats row of |rowName| to |value|.
-// A new row is created is this is the first report of this stats.
-function updateStatsTableRow(statsTable, rowName, value) {
- var trId = statsTable.id + '-' + rowName;
- var trElement = $(trId);
- if (!trElement) {
- trElement = document.createElement('tr');
- trElement.id = trId;
- statsTable.appendChild(trElement);
- trElement.innerHTML = '<td>' + rowName + '</td><td></td>';
- }
- trElement.cells[1].textContent = value;
-}
-
-// Add |singleReport| to the stats table.
-function addSingleReportToTable(statsTable, singleReport) {
- if (!singleReport || !singleReport.values || singleReport.values.length == 0)
- return;
-
- var date = Date(singleReport.timestamp);
- updateStatsTableRow(statsTable, 'timestamp', date.toLocaleString());
- for (var i = 0; i < singleReport.values.length - 1; i = i + 2) {
- updateStatsTableRow(statsTable, singleReport.values[i],
- singleReport.values[i + 1]);
+/**
+ * Extracts ssrc info from a setLocal/setRemoteDescription update.
+ *
+ * @param {!PeerConnectionUpdateEntry} data The peer connection update data.
+ */
+function extractSsrcInfo(data) {
+ if (data.type == 'setLocalDescription' ||
+ data.type == 'setRemoteDescription') {
+ ssrcInfoManager.addSsrcStreamInfo(data.value);
}
}
-//
-// Browser message handlers.
-//
-// data = {pid:|integer|, lid:|integer|}.
+/**
+ * Browser message handlers.
+ */
+
+
+/**
+ * Removes all information about a peer connection.
+ *
+ * @param {!Object.<string, number>} data The object containing the pid and lid
+ * of a peer connection.
+ */
function removePeerConnection(data) {
var element = $(getPeerConnectionId(data));
if (element)
peerConnectionsListElem.removeChild(element);
}
-// data = {pid:|integer|, lid:|integer|,
-// url:|string|, servers:|string|, constraints:|string|}.
+
+/**
+ * Adds a peer connection.
+ *
+ * @param {!Object} data The object containing the pid, lid, url, servers, and
+ * constraints of a peer connection.
+ */
function addPeerConnection(data) {
- var peerConnectionElement = ensurePeerConnectionElement(
- getPeerConnectionId(data));
+ var peerConnectionElement = $(getPeerConnectionId(data));
+ if (!peerConnectionElement) {
+ peerConnectionElement = document.createElement('li');
+ peerConnectionsListElem.appendChild(peerConnectionElement);
+ peerConnectionElement.id = getPeerConnectionId(data);
+ }
peerConnectionElement.innerHTML =
'<h3>PeerConnection ' + peerConnectionElement.id + '</h3>' +
'<div>' + data.url + ' ' + data.servers + ' ' + data.constraints +
'</div>';
+
+ // Clicking the heading can expand or collapse the peer connection item.
+ peerConnectionElement.firstChild.title = 'Click to collapse or expand';
+ peerConnectionElement.firstChild.addEventListener('click', function(e) {
+ if (e.target.parentElement.className == '')
+ e.target.parentElement.className = 'peer-connection-hidden';
+ else
+ e.target.parentElement.className = '';
+ });
return peerConnectionElement;
}
-// data = {pid:|integer|, lid:|integer|, type:|string|, value:|string|}.
+
+/**
+ * Adds a peer connection update.
+ *
+ * @param {!PeerConnectionUpdateEntry} data The peer connection update data.
+ */
function updatePeerConnection(data) {
- var peerConnectionElement = ensurePeerConnectionElement(
- getPeerConnectionId(data));
- var logElement = ensurePeerConnectionLog(peerConnectionElement);
- addToPeerConnectionLog(logElement, data);
+ var peerConnectionElement = $(getPeerConnectionId(data));
+ peerConnectionUpdateTable.addPeerConnectionUpdate(
+ peerConnectionElement, data);
+ extractSsrcInfo(data);
}
-// data is an array and each entry is
-// {pid:|integer|, lid:|integer|,
-// url:|string|, servers:|string|, constraints:|string|, log:|array|},
-// each entry of log is {type:|string|, value:|string|}.
+
+/**
+ * Adds the information of all peer connections created so far.
+ *
+ * @param {Array.<!Object>} data An array of the information of all peer
+ * connections. Each array item contains pid, lid, url, servers,
+ * constraints, and an array of updates as the log.
+ */
function updateAllPeerConnections(data) {
for (var i = 0; i < data.length; ++i) {
var peerConnection = addPeerConnection(data[i]);
- var logElement = ensurePeerConnectionLog(peerConnection);
var log = data[i].log;
for (var j = 0; j < log.length; ++j) {
- addToPeerConnectionLog(logElement, log[j]);
+ peerConnectionUpdateTable.addPeerConnectionUpdate(
+ peerConnection, log[j]);
+ extractSsrcInfo(log[j]);
}
}
}
-// data = {pid:|integer|, lid:|integer|, reports:|array|}.
-// Each entry of reports =
-// {id:|string|, type:|string|, local:|object|, remote:|object|}.
-// reports.local or reports.remote =
-// {timestamp: |double|, values: |array|},
-// where values is an array of strings, whose even index entry represents
-// the name of the stat, and the odd index entry represents the value of
-// the stat.
+
+/**
+ * Handles the report of stats.
+ *
+ * @param {!Object} data The object containing pid, lid, and reports, where
+ * reports is an array of stats reports. Each report contains id, type,
+ * and stats, where stats is the object containing timestamp and values,
+ * which is an array of strings, whose even index entry is the name of the
+ * stat, and the odd index entry is the value.
+ */
function addStats(data) {
- var peerConnectionElement = ensurePeerConnectionElement(
- getPeerConnectionId(data));
+ var peerConnectionElement = $(getPeerConnectionId(data));
+ if (!peerConnectionElement)
+ return;
+
for (var i = 0; i < data.reports.length; ++i) {
var report = data.reports[i];
- var reportName = report.type + '-' + report.id;
- var statsTable = ensureStatsTable(peerConnectionElement, reportName);
-
- addSingleReportToTable(statsTable, report.local);
- drawSingleReport(peerConnectionElement, reportName, report.local);
- addSingleReportToTable(statsTable, report.remote);
- drawSingleReport(peerConnectionElement, reportName, report.remote);
+ statsTable.addStatsReport(peerConnectionElement, report);
+ drawSingleReport(peerConnectionElement,
+ report.type, report.id, report.stats);
}
}
-document.addEventListener('DOMContentLoaded', initialize);
+
+/**
+ * Delegates to dumpCreator to update the recording status.
+ * @param {!Object.<string>} update Key-value pairs describing the status of the
+ * RTP recording.
+ */
+function updateDumpStatus(update) {
+ dumpCreator.onUpdate(update);
+}
diff --git a/content/browser/session_history_browsertest.cc b/content/browser/session_history_browsertest.cc
index cd70207..cb5d100 100644
--- a/content/browser/session_history_browsertest.cc
+++ b/content/browser/session_history_browsertest.cc
@@ -14,7 +14,7 @@
#include "content/shell/shell.h"
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"
-#include "net/test/test_server.h"
+#include "net/test/spawned_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
diff --git a/content/browser/site_instance_impl_unittest.cc b/content/browser/site_instance_impl_unittest.cc
index a66e5c8..fb322b1 100644
--- a/content/browser/site_instance_impl_unittest.cc
+++ b/content/browser/site_instance_impl_unittest.cc
@@ -92,8 +92,7 @@
}
virtual void SetUp() {
- old_browser_client_ = GetContentClient()->browser();
- GetContentClient()->set_browser_for_testing(&browser_client_);
+ old_browser_client_ = SetBrowserClientForTesting(&browser_client_);
url_util::AddStandardScheme(kPrivilegedScheme);
url_util::AddStandardScheme(chrome::kChromeUIScheme);
}
@@ -102,7 +101,7 @@
// Ensure that no RenderProcessHosts are left over after the tests.
EXPECT_TRUE(RenderProcessHost::AllHostsIterator().IsAtEnd());
- GetContentClient()->set_browser_for_testing(old_browser_client_);
+ SetBrowserClientForTesting(old_browser_client_);
// http://crbug.com/143565 found SiteInstanceTest leaking an
// AppCacheDatabase. This happens because some part of the test indirectly
@@ -124,12 +123,12 @@
// We don't just do this in TearDown() because we create TestBrowserContext
// objects in each test, which will be destructed before
// TearDown() is called.
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
message_loop_.RunUntilIdle();
}
private:
- MessageLoopForUI message_loop_;
+ base::MessageLoopForUI message_loop_;
TestBrowserThread ui_thread_;
TestBrowserThread file_user_blocking_thread_;
TestBrowserThread io_thread_;
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index d4af058..0989c7a 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -166,9 +166,9 @@
// security checks are back in place.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, DISABLED_CrossSiteIframe) {
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
GURL main_url(test_server()->GetURL("files/site_per_process_main.html"));
@@ -198,9 +198,9 @@
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
DISABLED_CrossSiteIframeRedirectOnce) {
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
@@ -322,9 +322,9 @@
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
DISABLED_CrossSiteIframeRedirectTwice) {
ASSERT_TRUE(test_server()->Start());
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
diff --git a/content/browser/speech/audio_encoder.cc b/content/browser/speech/audio_encoder.cc
index 73bbd41..e1a407b 100644
--- a/content/browser/speech/audio_encoder.cc
+++ b/content/browser/speech/audio_encoder.cc
@@ -88,7 +88,7 @@
// FLAC encoder wants samples as int32s.
const int num_samples = raw_audio.NumSamples();
- scoped_array<FLAC__int32> flac_samples(new FLAC__int32[num_samples]);
+ scoped_ptr<FLAC__int32[]> flac_samples(new FLAC__int32[num_samples]);
FLAC__int32* flac_samples_ptr = flac_samples.get();
for (int i = 0; i < num_samples; ++i)
flac_samples_ptr[i] = static_cast<FLAC__int32>(raw_audio.GetSample16(i));
diff --git a/content/browser/speech/google_one_shot_remote_engine_unittest.cc b/content/browser/speech/google_one_shot_remote_engine_unittest.cc
index efcf84f..7f06f86 100644
--- a/content/browser/speech/google_one_shot_remote_engine_unittest.cc
+++ b/content/browser/speech/google_one_shot_remote_engine_unittest.cc
@@ -43,7 +43,7 @@
}
protected:
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
net::TestURLFetcherFactory url_fetcher_factory_;
SpeechRecognitionErrorCode error_;
SpeechRecognitionResults results_;
@@ -104,7 +104,7 @@
EXPECT_EQ(0U, result().hypotheses.size());
// Http failure case.
- CreateAndTestRequest(false, "");
+ CreateAndTestRequest(false, std::string());
EXPECT_EQ(error_, SPEECH_RECOGNITION_ERROR_NETWORK);
EXPECT_EQ(0U, result().hypotheses.size());
diff --git a/content/browser/speech/google_streaming_remote_engine_unittest.cc b/content/browser/speech/google_streaming_remote_engine_unittest.cc
index 8223fec..cd23d4b 100644
--- a/content/browser/speech/google_streaming_remote_engine_unittest.cc
+++ b/content/browser/speech/google_streaming_remote_engine_unittest.cc
@@ -79,7 +79,7 @@
scoped_ptr<GoogleStreamingRemoteEngine> engine_under_test_;
TestURLFetcherFactory url_fetcher_factory_;
size_t last_number_of_upstream_chunks_seen_;
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
std::string response_buffer_;
SpeechRecognitionErrorCode error_;
std::queue<SpeechRecognitionResults> results_;
diff --git a/content/browser/speech/proto/speech_proto.target.darwin-arm.mk b/content/browser/speech/proto/speech_proto.target.darwin-arm.mk
new file mode 100644
index 0000000..9e7cf38
--- /dev/null
+++ b/content/browser/speech/proto/speech_proto.target.darwin-arm.mk
@@ -0,0 +1,180 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_browser_speech_proto_speech_proto_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(gyp_shared_intermediate_dir)/protoc
+
+
+### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto":
+# "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'msvs_cygwin_shell': '0', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)', 'process_outputs_as_sources': '1'}":
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: $(LOCAL_PATH)/content/browser/speech/proto/google_streaming_api.proto $(LOCAL_PATH)/tools/protoc_wrapper/protoc_wrapper.py $(gyp_shared_intermediate_dir)/protoc $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto; cd $(gyp_local_path)/content/browser/speech/proto; python ../../../../tools/protoc_wrapper/protoc_wrapper.py --include "" --protobuf "$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h" --proto-in-dir . --proto-in-file "google_streaming_api$(suffix $<)" "--use-system-protobuf=0" -- "$(gyp_shared_intermediate_dir)/protoc" --cpp_out "$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto" --python_out "$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto"
+
+$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.cc: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py
+$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py
+.PHONY: content_browser_speech_proto_speech_proto_gyp_rule_trigger
+content_browser_speech_proto_speech_proto_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py \
+ $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.cc \
+ $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+$(gyp_intermediate_dir)/google_streaming_api.pb.cc: $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.cc
+ mkdir -p $(@D); cp $< $@
+LOCAL_GENERATED_SOURCES := \
+ $(gyp_intermediate_dir)/google_streaming_api.pb.cc \
+ $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py \
+ $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h \
+ content_browser_speech_proto_speech_proto_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS := \
+ $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-format \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-address \
+ -Wno-format-security \
+ -Wno-return-type \
+ -Wno-sequence-point \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DPROTOBUF_USE_DLLS' \
+ '-DGOOGLE_PROTOBUF_NO_RTTI' \
+ '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(gyp_shared_intermediate_dir)/protoc_out \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/protobuf \
+ $(LOCAL_PATH)/third_party/protobuf/src \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wno-deprecated \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo \
+ -Wno-non-virtual-dtor
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_browser_speech_proto_speech_proto_gyp
+
+# Alias gyp target name.
+.PHONY: speech_proto
+speech_proto: content_browser_speech_proto_speech_proto_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/browser/speech/proto/speech_proto.target.darwin-x86.mk b/content/browser/speech/proto/speech_proto.target.darwin-x86.mk
new file mode 100644
index 0000000..991fe36
--- /dev/null
+++ b/content/browser/speech/proto/speech_proto.target.darwin-x86.mk
@@ -0,0 +1,179 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_browser_speech_proto_speech_proto_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(gyp_shared_intermediate_dir)/protoc
+
+
+### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto":
+# "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'msvs_cygwin_shell': '0', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)', 'process_outputs_as_sources': '1'}":
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: $(LOCAL_PATH)/content/browser/speech/proto/google_streaming_api.proto $(LOCAL_PATH)/tools/protoc_wrapper/protoc_wrapper.py $(gyp_shared_intermediate_dir)/protoc $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto; cd $(gyp_local_path)/content/browser/speech/proto; python ../../../../tools/protoc_wrapper/protoc_wrapper.py --include "" --protobuf "$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h" --proto-in-dir . --proto-in-file "google_streaming_api$(suffix $<)" "--use-system-protobuf=0" -- "$(gyp_shared_intermediate_dir)/protoc" --cpp_out "$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto" --python_out "$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto"
+
+$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.cc: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py
+$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py
+.PHONY: content_browser_speech_proto_speech_proto_gyp_rule_trigger
+content_browser_speech_proto_speech_proto_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py \
+ $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.cc \
+ $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+$(gyp_intermediate_dir)/google_streaming_api.pb.cc: $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.cc
+ mkdir -p $(@D); cp $< $@
+LOCAL_GENERATED_SOURCES := \
+ $(gyp_intermediate_dir)/google_streaming_api.pb.cc \
+ $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py \
+ $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/google_streaming_api.pb.h \
+ content_browser_speech_proto_speech_proto_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS := \
+ $(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-format \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-address \
+ -Wno-format-security \
+ -Wno-return-type \
+ -Wno-sequence-point \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DPROTOBUF_USE_DLLS' \
+ '-DGOOGLE_PROTOBUF_NO_RTTI' \
+ '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(gyp_shared_intermediate_dir)/protoc_out \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/protobuf \
+ $(LOCAL_PATH)/third_party/protobuf/src \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wno-deprecated \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo \
+ -Wno-non-virtual-dtor
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_browser_speech_proto_speech_proto_gyp
+
+# Alias gyp target name.
+.PHONY: speech_proto
+speech_proto: content_browser_speech_proto_speech_proto_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/browser/speech/proto/speech_proto.target.linux-arm.mk b/content/browser/speech/proto/speech_proto.target.linux-arm.mk
index 951ff80..9e7cf38 100644
--- a/content/browser/speech/proto/speech_proto.target.linux-arm.mk
+++ b/content/browser/speech/proto/speech_proto.target.linux-arm.mk
@@ -92,7 +92,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -100,7 +99,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -157,9 +155,9 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/content/browser/speech/proto/speech_proto.target.linux-x86.mk b/content/browser/speech/proto/speech_proto.target.linux-x86.mk
index f3b9bd3..991fe36 100644
--- a/content/browser/speech/proto/speech_proto.target.linux-x86.mk
+++ b/content/browser/speech/proto/speech_proto.target.linux-x86.mk
@@ -69,6 +69,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -93,7 +94,6 @@
MY_CFLAGS_C :=
MY_DEFS := \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -101,7 +101,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -151,12 +150,13 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/content/browser/speech/speech_recognition_manager_impl.cc b/content/browser/speech/speech_recognition_manager_impl.cc
index 8f9c3e1..ea49579 100644
--- a/content/browser/speech/speech_recognition_manager_impl.cc
+++ b/content/browser/speech/speech_recognition_manager_impl.cc
@@ -60,7 +60,7 @@
is_dispatching_event_(false),
delegate_(GetContentClient()->browser()->
GetSpeechRecognitionManagerDelegate()),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ weak_factory_(this) {
DCHECK(!g_speech_recognition_manager_impl);
g_speech_recognition_manager_impl = this;
}
@@ -86,7 +86,7 @@
std::string hardware_info;
bool can_report_metrics = false;
- if (delegate_.get())
+ if (delegate_)
delegate_->GetDiagnosticInformation(&can_report_metrics, &hardware_info);
SpeechRecognitionEngineConfig remote_engine_config;
@@ -100,7 +100,8 @@
remote_engine_config.interim_results = config.interim_results;
remote_engine_config.max_hypotheses = config.max_hypotheses;
remote_engine_config.hardware_info = hardware_info;
- remote_engine_config.origin_url = can_report_metrics ? config.origin_url : "";
+ remote_engine_config.origin_url =
+ can_report_metrics ? config.origin_url : std::string();
SpeechRecognitionEngine* google_remote_engine;
if (config.is_legacy_api) {
@@ -137,7 +138,7 @@
primary_session_id_ = session_id;
- if (delegate_.get()) {
+ if (delegate_) {
delegate_->CheckRecognitionIsAllowed(
session_id,
base::Bind(&SpeechRecognitionManagerImpl::RecognitionAllowedCallback,
@@ -177,15 +178,21 @@
#endif // defined(OS_IOS)
if (is_allowed) {
- MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
base::Bind(&SpeechRecognitionManagerImpl::DispatchEvent,
- weak_factory_.GetWeakPtr(), session_id, EVENT_START));
+ weak_factory_.GetWeakPtr(),
+ session_id,
+ EVENT_START));
} else {
OnRecognitionError(session_id, SpeechRecognitionError(
SPEECH_RECOGNITION_ERROR_NOT_ALLOWED));
- MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
base::Bind(&SpeechRecognitionManagerImpl::DispatchEvent,
- weak_factory_.GetWeakPtr(), session_id, EVENT_ABORT));
+ weak_factory_.GetWeakPtr(),
+ session_id,
+ EVENT_ABORT));
}
}
@@ -224,9 +231,12 @@
BrowserMainLoop::GetMediaStreamManager()->CancelRequest(context.label);
#endif // !defined(OS_IOS)
- MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
base::Bind(&SpeechRecognitionManagerImpl::DispatchEvent,
- weak_factory_.GetWeakPtr(), session_id, EVENT_ABORT));
+ weak_factory_.GetWeakPtr(),
+ session_id,
+ EVENT_ABORT));
}
void SpeechRecognitionManagerImpl::StopAudioCaptureForSession(int session_id) {
@@ -241,9 +251,12 @@
BrowserMainLoop::GetMediaStreamManager()->CancelRequest(context.label);
#endif // !defined(OS_IOS)
- MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
base::Bind(&SpeechRecognitionManagerImpl::DispatchEvent,
- weak_factory_.GetWeakPtr(), session_id, EVENT_STOP_CAPTURE));
+ weak_factory_.GetWeakPtr(),
+ session_id,
+ EVENT_STOP_CAPTURE));
}
// Here begins the SpeechRecognitionEventListener interface implementation,
@@ -262,8 +275,7 @@
if (!context.devices.empty()) {
// Notify the UI the devices are being used.
BrowserMainLoop::GetMediaStreamManager()->NotifyUIDevicesOpened(
- context.label, context.render_process_id, context.render_view_id,
- context.devices);
+ context.label);
}
#endif // !defined(OS_IOS)
@@ -331,9 +343,12 @@
delegate_listener->OnAudioEnd(session_id);
if (SpeechRecognitionEventListener* listener = GetListener(session_id))
listener->OnAudioEnd(session_id);
- MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
base::Bind(&SpeechRecognitionManagerImpl::DispatchEvent,
- weak_factory_.GetWeakPtr(), session_id, EVENT_AUDIO_ENDED));
+ weak_factory_.GetWeakPtr(),
+ session_id,
+ EVENT_AUDIO_ENDED));
}
void SpeechRecognitionManagerImpl::OnRecognitionResults(
@@ -382,7 +397,7 @@
if (!context.devices.empty()) {
// Notify the UI the devices has been closed.
BrowserMainLoop::GetMediaStreamManager()->NotifyUIDevicesClosed(
- context.render_process_id, context.render_view_id, context.devices);
+ context.label);
}
#endif // !defined(OS_IOS)
@@ -390,7 +405,8 @@
delegate_listener->OnRecognitionEnd(session_id);
if (SpeechRecognitionEventListener* listener = GetListener(session_id))
listener->OnRecognitionEnd(session_id);
- MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
base::Bind(&SpeechRecognitionManagerImpl::DispatchEvent,
weak_factory_.GetWeakPtr(),
session_id,
diff --git a/content/browser/speech/speech_recognizer.cc b/content/browser/speech/speech_recognizer.cc
index cc66178..62c1b35 100644
--- a/content/browser/speech/speech_recognizer.cc
+++ b/content/browser/speech/speech_recognizer.cc
@@ -155,7 +155,7 @@
SpeechRecognizer::~SpeechRecognizer() {
endpointer_.EndSession();
- if (audio_controller_.get()) {
+ if (audio_controller_) {
audio_controller_->Close(base::Bind(&KeepAudioControllerRefcountedForDtor,
audio_controller_));
}
diff --git a/content/browser/speech/speech_recognizer_unittest.cc b/content/browser/speech/speech_recognizer_unittest.cc
index 2cc4db3..9b55ec5 100644
--- a/content/browser/speech/speech_recognizer_unittest.cc
+++ b/content/browser/speech/speech_recognizer_unittest.cc
@@ -56,7 +56,7 @@
recognizer_ = new SpeechRecognizer(
this, kTestingSessionId, kOneShotMode, sr_engine);
audio_manager_.reset(new media::MockAudioManager(
- MessageLoop::current()->message_loop_proxy()));
+ base::MessageLoop::current()->message_loop_proxy()));
recognizer_->SetAudioManagerForTests(audio_manager_.get());
int audio_packet_length_bytes =
@@ -162,7 +162,7 @@
}
protected:
- MessageLoopForIO message_loop_;
+ base::MessageLoopForIO message_loop_;
BrowserThreadImpl io_thread_;
scoped_refptr<SpeechRecognizer> recognizer_;
scoped_ptr<AudioManager> audio_manager_;
@@ -185,7 +185,7 @@
// Check for callbacks when stopping record before any audio gets recorded.
recognizer_->StartRecognition();
recognizer_->StopAudioCapture();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(recognition_started_);
EXPECT_FALSE(audio_started_);
EXPECT_FALSE(result_received_);
@@ -198,7 +198,7 @@
// recorded.
recognizer_->StartRecognition();
recognizer_->AbortRecognition();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(recognition_started_);
EXPECT_FALSE(audio_started_);
EXPECT_FALSE(result_received_);
@@ -210,7 +210,7 @@
// Start recording, give some data and then stop. This should wait for the
// network callback to arrive before completion.
recognizer_->StartRecognition();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
TestAudioInputController* controller =
audio_input_controller_factory_.controller();
ASSERT_TRUE(controller);
@@ -223,14 +223,14 @@
for (size_t i = 0; i < kNumChunks; ++i) {
controller->event_handler()->OnData(controller, &audio_packet_[0],
audio_packet_.size());
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
ASSERT_TRUE(fetcher);
EXPECT_EQ(i + 1, fetcher->upload_chunks().size());
}
recognizer_->StopAudioCapture();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(audio_started_);
EXPECT_TRUE(audio_ended_);
EXPECT_FALSE(recognition_ended_);
@@ -249,7 +249,7 @@
fetcher->SetResponseString(
"{\"status\":0,\"hypotheses\":[{\"utterance\":\"123\"}]}");
fetcher->delegate()->OnURLFetchComplete(fetcher);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(recognition_ended_);
EXPECT_TRUE(result_received_);
EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
@@ -259,15 +259,15 @@
TEST_F(SpeechRecognizerTest, CancelWithData) {
// Start recording, give some data and then cancel.
recognizer_->StartRecognition();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
TestAudioInputController* controller =
audio_input_controller_factory_.controller();
ASSERT_TRUE(controller);
controller->event_handler()->OnData(controller, &audio_packet_[0],
audio_packet_.size());
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
recognizer_->AbortRecognition();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
ASSERT_TRUE(url_fetcher_factory_.GetFetcherByID(0));
EXPECT_TRUE(recognition_started_);
EXPECT_TRUE(audio_started_);
@@ -280,18 +280,18 @@
// Start recording, give some data and then stop. Issue the network callback
// with a connection error and verify that the recognizer bubbles the error up
recognizer_->StartRecognition();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
TestAudioInputController* controller =
audio_input_controller_factory_.controller();
ASSERT_TRUE(controller);
controller->event_handler()->OnData(controller, &audio_packet_[0],
audio_packet_.size());
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
ASSERT_TRUE(fetcher);
recognizer_->StopAudioCapture();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(audio_started_);
EXPECT_TRUE(audio_ended_);
EXPECT_FALSE(recognition_ended_);
@@ -305,9 +305,9 @@
status.set_error(net::ERR_CONNECTION_REFUSED);
fetcher->set_status(status);
fetcher->set_response_code(0);
- fetcher->SetResponseString("");
+ fetcher->SetResponseString(std::string());
fetcher->delegate()->OnURLFetchComplete(fetcher);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(recognition_ended_);
EXPECT_FALSE(result_received_);
EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NETWORK, error_);
@@ -318,18 +318,18 @@
// Start recording, give some data and then stop. Issue the network callback
// with a 500 error and verify that the recognizer bubbles the error up
recognizer_->StartRecognition();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
TestAudioInputController* controller =
audio_input_controller_factory_.controller();
ASSERT_TRUE(controller);
controller->event_handler()->OnData(controller, &audio_packet_[0],
audio_packet_.size());
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
ASSERT_TRUE(fetcher);
recognizer_->StopAudioCapture();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(audio_started_);
EXPECT_TRUE(audio_ended_);
EXPECT_FALSE(recognition_ended_);
@@ -344,7 +344,7 @@
fetcher->set_response_code(500);
fetcher->SetResponseString("Internal Server Error");
fetcher->delegate()->OnURLFetchComplete(fetcher);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(recognition_ended_);
EXPECT_FALSE(result_received_);
EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NETWORK, error_);
@@ -354,12 +354,12 @@
TEST_F(SpeechRecognizerTest, AudioControllerErrorNoData) {
// Check if things tear down properly if AudioInputController threw an error.
recognizer_->StartRecognition();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
TestAudioInputController* controller =
audio_input_controller_factory_.controller();
ASSERT_TRUE(controller);
controller->event_handler()->OnError(controller);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(recognition_started_);
EXPECT_FALSE(audio_started_);
EXPECT_FALSE(result_received_);
@@ -371,14 +371,14 @@
// Check if things tear down properly if AudioInputController threw an error
// after giving some audio data.
recognizer_->StartRecognition();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
TestAudioInputController* controller =
audio_input_controller_factory_.controller();
ASSERT_TRUE(controller);
controller->event_handler()->OnData(controller, &audio_packet_[0],
audio_packet_.size());
controller->event_handler()->OnError(controller);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
ASSERT_TRUE(url_fetcher_factory_.GetFetcherByID(0));
EXPECT_TRUE(recognition_started_);
EXPECT_TRUE(audio_started_);
@@ -391,7 +391,7 @@
// Start recording and give a lot of packets with audio samples set to zero.
// This should trigger the no-speech detector and issue a callback.
recognizer_->StartRecognition();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
TestAudioInputController* controller =
audio_input_controller_factory_.controller();
ASSERT_TRUE(controller);
@@ -403,7 +403,7 @@
controller->event_handler()->OnData(controller, &audio_packet_[0],
audio_packet_.size());
}
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(recognition_started_);
EXPECT_TRUE(audio_started_);
EXPECT_FALSE(result_received_);
@@ -417,7 +417,7 @@
// treated as normal speech input and the no-speech detector should not get
// triggered.
recognizer_->StartRecognition();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
TestAudioInputController* controller =
audio_input_controller_factory_.controller();
ASSERT_TRUE(controller);
@@ -439,13 +439,13 @@
audio_packet_.size());
}
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
EXPECT_TRUE(audio_started_);
EXPECT_FALSE(audio_ended_);
EXPECT_FALSE(recognition_ended_);
recognizer_->AbortRecognition();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
CheckFinalEventsConsistency();
}
@@ -455,7 +455,7 @@
// get the callback during estimation phase, then get zero for the silence
// samples and proper volume for the loud audio.
recognizer_->StartRecognition();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
TestAudioInputController* controller =
audio_input_controller_factory_.controller();
ASSERT_TRUE(controller);
@@ -470,19 +470,19 @@
controller->event_handler()->OnData(controller, &audio_packet_[0],
audio_packet_.size());
}
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(-1.0f, volume_); // No audio volume set yet.
// The vector is already filled with zero value samples on create.
controller->event_handler()->OnData(controller, &audio_packet_[0],
audio_packet_.size());
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_FLOAT_EQ(0.74939233f, volume_);
FillPacketWithTestWaveform();
controller->event_handler()->OnData(controller, &audio_packet_[0],
audio_packet_.size());
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
EXPECT_FLOAT_EQ(0.89926866f, volume_);
EXPECT_FLOAT_EQ(0.75071919f, noise_volume_);
@@ -490,7 +490,7 @@
EXPECT_FALSE(audio_ended_);
EXPECT_FALSE(recognition_ended_);
recognizer_->AbortRecognition();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
CheckFinalEventsConsistency();
}
diff --git a/content/browser/ssl/ssl_cert_error_handler.cc b/content/browser/ssl/ssl_cert_error_handler.cc
index 268ccf7..b3bdb41 100644
--- a/content/browser/ssl/ssl_cert_error_handler.cc
+++ b/content/browser/ssl/ssl_cert_error_handler.cc
@@ -6,8 +6,8 @@
#include "content/browser/ssl/ssl_manager.h"
#include "content/browser/ssl/ssl_policy.h"
-#include "net/base/cert_status_flags.h"
-#include "net/base/x509_certificate.h"
+#include "net/cert/cert_status_flags.h"
+#include "net/cert/x509_certificate.h"
namespace content {
diff --git a/content/browser/ssl/ssl_client_auth_handler.cc b/content/browser/ssl/ssl_client_auth_handler.cc
index 97db658..1180269 100644
--- a/content/browser/ssl/ssl_client_auth_handler.cc
+++ b/content/browser/ssl/ssl_client_auth_handler.cc
@@ -9,7 +9,7 @@
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
-#include "net/base/x509_certificate.h"
+#include "net/cert/x509_certificate.h"
#include "net/http/http_transaction_factory.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
diff --git a/content/browser/ssl/ssl_host_state.h b/content/browser/ssl/ssl_host_state.h
index da3fe9c..d3b69c2 100644
--- a/content/browser/ssl/ssl_host_state.h
+++ b/content/browser/ssl/ssl_host_state.h
@@ -5,17 +5,17 @@
#ifndef CONTENT_BROWSER_SSL_SSL_HOST_STATE_H_
#define CONTENT_BROWSER_SSL_SSL_HOST_STATE_H_
-#include <string>
#include <map>
#include <set>
+#include <string>
-#include "base/compiler_specific.h"
#include "base/basictypes.h"
+#include "base/compiler_specific.h"
#include "base/supports_user_data.h"
#include "base/threading/non_thread_safe.h"
#include "content/common/content_export.h"
#include "googleurl/src/gurl.h"
-#include "net/base/x509_certificate.h"
+#include "net/cert/x509_certificate.h"
namespace content {
class BrowserContext;
diff --git a/content/browser/ssl/ssl_manager.h b/content/browser/ssl/ssl_manager.h
index 8cd1668..0ccedb2 100644
--- a/content/browser/ssl/ssl_manager.h
+++ b/content/browser/ssl/ssl_manager.h
@@ -17,7 +17,7 @@
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "googleurl/src/gurl.h"
-#include "net/base/cert_status_flags.h"
+#include "net/cert/cert_status_flags.h"
#include "net/base/net_errors.h"
namespace net {
diff --git a/content/browser/ssl/ssl_policy.cc b/content/browser/ssl/ssl_policy.cc
index 750bf47..1b0e424 100644
--- a/content/browser/ssl/ssl_policy.cc
+++ b/content/browser/ssl/ssl_policy.cc
@@ -8,8 +8,8 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/memory/singleton.h"
-#include "base/string_piece.h"
#include "base/string_util.h"
+#include "base/strings/string_piece.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/site_instance_impl.h"
diff --git a/content/browser/ssl/ssl_policy_backend.h b/content/browser/ssl/ssl_policy_backend.h
index 3d8f390..bef0469 100644
--- a/content/browser/ssl/ssl_policy_backend.h
+++ b/content/browser/ssl/ssl_policy_backend.h
@@ -10,7 +10,7 @@
#include "base/basictypes.h"
#include "base/string16.h"
-#include "net/base/x509_certificate.h"
+#include "net/cert/x509_certificate.h"
namespace content {
class NavigationControllerImpl;
diff --git a/content/browser/ssl/ssl_request_info.h b/content/browser/ssl/ssl_request_info.h
index 5e9428c..d5971ed 100644
--- a/content/browser/ssl/ssl_request_info.h
+++ b/content/browser/ssl/ssl_request_info.h
@@ -9,7 +9,7 @@
#include "base/memory/ref_counted.h"
#include "googleurl/src/gurl.h"
-#include "net/base/cert_status_flags.h"
+#include "net/cert/cert_status_flags.h"
#include "webkit/glue/resource_type.h"
namespace content {
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index fbee33d..ab0e7a5 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -6,6 +6,7 @@
#include "base/utf_string_conversions.h"
#include "content/browser/fileapi/browser_file_system_helper.h"
+#include "content/browser/gpu/shader_disk_cache.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/dom_storage_context.h"
@@ -74,6 +75,11 @@
origins,
quota::kStorageTypePersistent);
}
+ if (storage_mask & StoragePartition::kQuotaManagedSyncableStorage) {
+ ClearQuotaManagedOriginsOnIOThread(quota_manager,
+ origins,
+ quota::kStorageTypeSyncable);
+ }
}
void ClearAllDataOnIOThread(
@@ -102,6 +108,24 @@
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));
+ }
+}
+
+void ClearedShaderCacheOnIOThread(base::Closure callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
+}
+
+void ClearShaderCacheOnIOThread(base::FilePath path,
+ base::Time begin, base::Time end, base::Closure callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ ShaderCacheFactory::GetInstance()->ClearByPath(
+ path, begin, end,
+ base::Bind(&ClearedShaderCacheOnIOThread, callback));
}
void OnLocalStorageUsageInfo(
@@ -293,6 +317,20 @@
}
}
+void StoragePartitionImpl::AsyncClearDataBetween(uint32 storage_mask,
+ const base::Time& begin, const base::Time& end,
+ const base::Closure& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(storage_mask == kShaderStorage);
+
+ if (storage_mask & kShaderStorage) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&ClearShaderCacheOnIOThread, GetPath(), begin, end,
+ callback));
+ }
+}
+
void StoragePartitionImpl::SetURLRequestContext(
net::URLRequestContextGetter* url_request_context) {
url_request_context_ = url_request_context;
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index 07cea99..af206f5 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -10,14 +10,15 @@
#include "base/memory/ref_counted.h"
#include "content/browser/appcache/chrome_appcache_service.h"
#include "content/browser/dom_storage/dom_storage_context_impl.h"
-#include "content/browser/in_process_webkit/indexed_db_context_impl.h"
+#include "content/browser/indexed_db/indexed_db_context_impl.h"
+#include "content/common/content_export.h"
#include "content/public/browser/storage_partition.h"
namespace content {
class StoragePartitionImpl : public StoragePartition {
public:
- virtual ~StoragePartitionImpl();
+ CONTENT_EXPORT virtual ~StoragePartitionImpl();
// StoragePartition interface.
virtual base::FilePath GetPath() OVERRIDE;
@@ -34,9 +35,15 @@
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;
private:
friend class StoragePartitionImplMap;
+ FRIEND_TEST_ALL_PREFIXES(StoragePartitionShaderClearTest, ClearShaderCache);
// The |partition_path| is the absolute path to the root of this
// StoragePartition's on-disk storage.
@@ -48,7 +55,7 @@
bool in_memory,
const base::FilePath& profile_path);
- StoragePartitionImpl(
+ CONTENT_EXPORT StoragePartitionImpl(
const base::FilePath& partition_path,
quota::QuotaManager* quota_manager,
ChromeAppCacheService* appcache_service,
diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc
index 16111cf..94141d6 100644
--- a/content/browser/storage_partition_impl_map.cc
+++ b/content/browser/storage_partition_impl_map.cc
@@ -90,7 +90,7 @@
virtual net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
- net::NetworkDelegate* network_delegate) const {
+ net::NetworkDelegate* network_delegate) const OVERRIDE {
scoped_refptr<Stream> stream =
stream_context_->registry()->GetStream(request->url());
if (stream)
@@ -254,7 +254,7 @@
const std::vector<base::FilePath>& paths_to_keep,
const scoped_refptr<base::TaskRunner>& closure_runner,
const base::Closure& on_gc_required) {
- // Early exit required because file_util::AbsolutePath() will fail on POSIX
+ // Early exit required because MakeAbsoluteFilePath() will fail on POSIX
// if |unnormalized_root| does not exist. This is safe because there is
// nothing to do in this situation anwyays.
if (!file_util::PathExists(unnormalized_root)) {
@@ -263,12 +263,12 @@
// Never try to obliterate things outside of the browser context root or the
// browser context root itself. Die hard.
- base::FilePath root = unnormalized_root;
- base::FilePath browser_context_root = unnormalized_browser_context_root;
- CHECK(file_util::AbsolutePath(&root));
- CHECK(file_util::AbsolutePath(&browser_context_root));
- CHECK(file_util::ContainsPath(browser_context_root, root) &&
- browser_context_root != root);
+ base::FilePath root = base::MakeAbsoluteFilePath(unnormalized_root);
+ base::FilePath browser_context_root =
+ base::MakeAbsoluteFilePath(unnormalized_browser_context_root);
+ CHECK(!root.empty());
+ CHECK(!browser_context_root.empty());
+ CHECK(browser_context_root.IsParent(root) && browser_context_root != root);
// Reduce |paths_to_keep| set to those under the root and actually on disk.
std::vector<base::FilePath> valid_paths_to_keep;
@@ -426,8 +426,9 @@
browser_context_->IsOffTheRecord(),
partition->GetAppCacheService(),
blob_storage_context));
- std::vector<std::string> additional_webui_schemes =
- GetContentClient()->browser()->GetAdditionalWebUISchemes();
+ std::vector<std::string> additional_webui_schemes;
+ GetContentClient()->browser()->GetAdditionalWebUISchemes(
+ &additional_webui_schemes);
for (std::vector<std::string>::const_iterator it =
additional_webui_schemes.begin();
it != additional_webui_schemes.end();
diff --git a/content/browser/storage_partition_impl_map_unittest.cc b/content/browser/storage_partition_impl_map_unittest.cc
index 1c44fcc..04127cc 100644
--- a/content/browser/storage_partition_impl_map_unittest.cc
+++ b/content/browser/storage_partition_impl_map_unittest.cc
@@ -13,13 +13,18 @@
// Test that the Less comparison function is implemented properly to uniquely
// identify storage partitions used as keys in a std::map.
TEST_F(StoragePartitionConfigTest, OperatorLess) {
- StoragePartitionImplMap::StoragePartitionConfig c1("", "", false);
- StoragePartitionImplMap::StoragePartitionConfig c2("", "", false);
- StoragePartitionImplMap::StoragePartitionConfig c3("", "", true);
- StoragePartitionImplMap::StoragePartitionConfig c4("a", "", true);
- StoragePartitionImplMap::StoragePartitionConfig c5("b", "", true);
- StoragePartitionImplMap::StoragePartitionConfig c6("", "abc", false);
- StoragePartitionImplMap::StoragePartitionConfig c7("", "abc", true);
+ StoragePartitionImplMap::StoragePartitionConfig c1(
+ std::string(), std::string(), false);
+ StoragePartitionImplMap::StoragePartitionConfig c2(
+ std::string(), std::string(), false);
+ StoragePartitionImplMap::StoragePartitionConfig c3(
+ std::string(), std::string(), true);
+ StoragePartitionImplMap::StoragePartitionConfig c4("a", std::string(), true);
+ StoragePartitionImplMap::StoragePartitionConfig c5("b", std::string(), true);
+ StoragePartitionImplMap::StoragePartitionConfig c6(
+ std::string(), "abc", false);
+ StoragePartitionImplMap::StoragePartitionConfig c7(
+ std::string(), "abc", true);
StoragePartitionImplMap::StoragePartitionConfig c8("a", "abc", false);
StoragePartitionImplMap::StoragePartitionConfig c9("a", "abc", true);
diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc
new file mode 100644
index 0000000..631ac7b
--- /dev/null
+++ b/content/browser/storage_partition_impl_unittest.cc
@@ -0,0 +1,124 @@
+// 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/files/scoped_temp_dir.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/run_loop.h"
+#include "base/threading/thread.h"
+#include "content/browser/browser_thread_impl.h"
+#include "content/browser/gpu/shader_disk_cache.h"
+#include "content/browser/storage_partition_impl.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/test/test_browser_thread.h"
+#include "net/base/test_completion_callback.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+class TestClosureCallback {
+ public:
+ TestClosureCallback()
+ : callback_(base::Bind(
+ &TestClosureCallback::StopWaiting, base::Unretained(this))) {
+ }
+
+ void WaitForResult() {
+ wait_run_loop_.reset(new base::RunLoop());
+ wait_run_loop_->Run();
+ }
+
+ const base::Closure& callback() { return callback_; }
+
+ private:
+ void StopWaiting() {
+ wait_run_loop_->Quit();
+ }
+
+ base::Closure callback_;
+ scoped_ptr<base::RunLoop> wait_run_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestClosureCallback);
+};
+
+const int kDefaultClientId = 42;
+const char kCacheKey[] = "key";
+const char kCacheValue[] = "cached value";
+
+} // namespace
+
+class StoragePartitionShaderClearTest : public testing::Test {
+ public:
+ StoragePartitionShaderClearTest() :
+ ui_thread_(BrowserThread::UI, &message_loop_),
+ cache_thread_(BrowserThread::CACHE, &message_loop_),
+ io_thread_(BrowserThread::IO, &message_loop_) {
+ }
+
+ virtual ~StoragePartitionShaderClearTest() {}
+
+ const base::FilePath& cache_path() { return temp_dir_.path(); }
+
+ virtual void SetUp() OVERRIDE {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ ShaderCacheFactory::GetInstance()->SetCacheInfo(kDefaultClientId,
+ cache_path());
+
+ cache_ = ShaderCacheFactory::GetInstance()->Get(kDefaultClientId);
+ ASSERT_TRUE(cache_.get() != NULL);
+ }
+
+ void InitCache() {
+ net::TestCompletionCallback available_cb;
+ int rv = cache_->SetAvailableCallback(available_cb.callback());
+ ASSERT_EQ(net::OK, available_cb.GetResult(rv));
+ EXPECT_EQ(0, cache_->Size());
+
+ cache_->Cache(kCacheKey, kCacheValue);
+
+ net::TestCompletionCallback complete_cb;
+
+ rv = cache_->SetCacheCompleteCallback(complete_cb.callback());
+ ASSERT_EQ(net::OK, complete_cb.GetResult(rv));
+ }
+
+ size_t Size() { return cache_->Size(); }
+
+ base::MessageLoop* message_loop() { return &message_loop_; }
+
+ private:
+ virtual void TearDown() OVERRIDE {
+ cache_ = NULL;
+ ShaderCacheFactory::GetInstance()->RemoveCacheInfo(kDefaultClientId);
+ }
+
+ base::ScopedTempDir temp_dir_;
+ base::MessageLoopForIO message_loop_;
+ TestBrowserThread ui_thread_;
+ TestBrowserThread cache_thread_;
+ TestBrowserThread io_thread_;
+
+ scoped_refptr<ShaderDiskCache> cache_;
+};
+
+void ClearData(content::StoragePartitionImpl* sp,
+ const base::Closure& cb) {
+ base::Time time;
+ sp->AsyncClearDataBetween(content::StoragePartition::kShaderStorage,
+ time, time, cb);
+}
+
+TEST_F(StoragePartitionShaderClearTest, ClearShaderCache) {
+ InitCache();
+ EXPECT_EQ(1u, Size());
+
+ TestClosureCallback clear_cb;
+ StoragePartitionImpl sp(cache_path(), NULL, NULL, NULL, NULL, NULL, NULL);
+ message_loop()->PostTask(FROM_HERE,
+ base::Bind(&ClearData, &sp, clear_cb.callback()));
+ clear_cb.WaitForResult();
+ EXPECT_EQ(0u, Size());
+}
+
+} // namespace content
diff --git a/content/browser/streams/stream.cc b/content/browser/streams/stream.cc
index a0b8007..8a926a6 100644
--- a/content/browser/streams/stream.cc
+++ b/content/browser/streams/stream.cc
@@ -33,7 +33,7 @@
read_observer_(NULL),
write_observer_(write_observer),
stream_handle_(NULL),
- weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ weak_ptr_factory_(this) {
CreateByteStream(base::MessageLoopProxy::current(),
base::MessageLoopProxy::current(),
kDeferSizeThreshold,
@@ -125,6 +125,9 @@
}
void Stream::CloseHandle() {
+ // Prevent deletion until this function ends.
+ scoped_refptr<Stream> ref(this);
+
CHECK(stream_handle_);
stream_handle_ = NULL;
registry_->UnregisterStream(url());
diff --git a/content/browser/streams/stream_unittest.cc b/content/browser/streams/stream_unittest.cc
index 2c9f34c..3452553 100644
--- a/content/browser/streams/stream_unittest.cc
+++ b/content/browser/streams/stream_unittest.cc
@@ -32,7 +32,7 @@
}
protected:
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
scoped_ptr<StreamRegistry> registry_;
private:
@@ -138,7 +138,7 @@
writer.Write(stream, buffer, kBufferSize);
stream->Finalize();
reader.Read(stream);
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
ASSERT_EQ(reader.buffer()->capacity(), kBufferSize);
for (int i = 0; i < kBufferSize; i++)
diff --git a/content/browser/streams/stream_url_request_job.cc b/content/browser/streams/stream_url_request_job.cc
index da2e9ce..4478d16 100644
--- a/content/browser/streams/stream_url_request_job.cc
+++ b/content/browser/streams/stream_url_request_job.cc
@@ -37,7 +37,7 @@
net::NetworkDelegate* network_delegate,
scoped_refptr<Stream> stream)
: net::URLRequestJob(request, network_delegate),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+ weak_factory_(this),
stream_(stream),
headers_set_(false),
pending_buffer_size_(0),
@@ -72,7 +72,7 @@
// net::URLRequestJob methods.
void StreamURLRequestJob::Start() {
// Continue asynchronously.
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&StreamURLRequestJob::DidStart, weak_factory_.GetWeakPtr()));
}
@@ -117,7 +117,7 @@
}
bool StreamURLRequestJob::GetMimeType(std::string* mime_type) const {
- if (!response_info_.get())
+ if (!response_info_)
return false;
// TODO(zork): Support registered MIME types if needed.
@@ -125,12 +125,12 @@
}
void StreamURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) {
- if (response_info_.get())
+ if (response_info_)
*info = *response_info_;
}
int StreamURLRequestJob::GetResponseCode() const {
- if (!response_info_.get())
+ if (!response_info_)
return -1;
return response_info_->headers->response_code();
diff --git a/content/browser/streams/stream_url_request_job_unittest.cc b/content/browser/streams/stream_url_request_job_unittest.cc
index 10a02c9..37d9c4f 100644
--- a/content/browser/streams/stream_url_request_job_unittest.cc
+++ b/content/browser/streams/stream_url_request_job_unittest.cc
@@ -49,9 +49,7 @@
StreamRegistry* registry_;
};
- StreamURLRequestJobTest()
- : message_loop_(MessageLoop::TYPE_IO) {
- }
+ StreamURLRequestJobTest() : message_loop_(base::MessageLoop::TYPE_IO) {}
virtual void SetUp() {
registry_.reset(new StreamRegistry());
@@ -81,7 +79,7 @@
request_->SetExtraRequestHeaders(extra_headers);
request_->Start();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
// Verify response.
EXPECT_TRUE(request_->status().is_success());
@@ -91,7 +89,7 @@
}
protected:
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
scoped_ptr<StreamRegistry> registry_;
net::URLRequestContext url_request_context_;
@@ -135,7 +133,7 @@
request_->set_method("GET");
request_->Start();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
// Verify response.
EXPECT_FALSE(request_->status().is_success());
@@ -169,7 +167,7 @@
net::HttpRequestHeaders extra_headers;
extra_headers.SetHeader(net::HttpRequestHeaders::kRange, "bytes=1-3");
- TestRequest("GET", kStreamURL, extra_headers, 405, "");
+ TestRequest("GET", kStreamURL, extra_headers, 405, std::string());
}
} // namespace content
diff --git a/content/browser/system_message_window_win_unittest.cc b/content/browser/system_message_window_win_unittest.cc
index 38566b5..25c77c9d 100644
--- a/content/browser/system_message_window_win_unittest.cc
+++ b/content/browser/system_message_window_win_unittest.cc
@@ -25,7 +25,7 @@
system_monitor_.AddDevicesChangedObserver(&observer_);
}
- MessageLoop message_loop_;
+ base::MessageLoop message_loop_;
base::SystemMonitor system_monitor_;
base::MockDevicesChangedObserver observer_;
SystemMessageWindowWin window_;
diff --git a/content/browser/tracing/trace_controller_impl.cc b/content/browser/tracing/trace_controller_impl.cc
index e416126..d944299 100644
--- a/content/browser/tracing/trace_controller_impl.cc
+++ b/content/browser/tracing/trace_controller_impl.cc
@@ -54,7 +54,9 @@
pending_bpf_ack_count_(0),
maximum_bpf_(0.0f),
is_tracing_(false),
- is_get_categories_(false) {
+ is_get_category_groups_(false),
+ category_filter_(
+ base::debug::CategoryFilter::kDefaultCategoryFilterString) {
TraceLog::GetInstance()->SetNotificationCallback(
base::Bind(&TraceControllerImpl::OnTraceNotification,
base::Unretained(this)));
@@ -106,40 +108,23 @@
base::TimeDelta::FromSeconds(delay_secs));
}
-bool TraceControllerImpl::GetKnownCategoriesAsync(TraceSubscriber* subscriber) {
+bool TraceControllerImpl::GetKnownCategoryGroupsAsync(
+ TraceSubscriber* subscriber) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// Known categories come back from child processes with the EndTracingAck
// message. So to get known categories, just begin and end tracing immediately
// afterwards. This will ping all the child processes for categories.
- is_get_categories_ = true;
+ is_get_category_groups_ = true;
bool success = BeginTracing(subscriber, "*",
TraceLog::GetInstance()->trace_options()) &&
EndTracingAsync(subscriber);
- is_get_categories_ = success;
+ is_get_category_groups_ = success;
return success;
}
-bool TraceControllerImpl::BeginTracing(
- TraceSubscriber* subscriber,
- const std::vector<std::string>& included_categories,
- const std::vector<std::string>& excluded_categories,
- base::debug::TraceLog::Options options) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (!can_begin_tracing(subscriber))
- return false;
-
- // Enable tracing
- TraceLog::GetInstance()->SetEnabled(included_categories, excluded_categories,
- options);
- OnTracingBegan(subscriber);
-
- return true;
-}
-
bool TraceControllerImpl::BeginTracing(TraceSubscriber* subscriber,
- const std::string& categories,
+ const std::string& category_patterns,
base::debug::TraceLog::Options options) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -147,7 +132,8 @@
return false;
// Enable tracing
- TraceLog::GetInstance()->SetEnabled(categories, options);
+ TraceLog::GetInstance()->SetEnabled(
+ base::debug::CategoryFilter(category_patterns), options);
OnTracingBegan(subscriber);
@@ -170,11 +156,11 @@
// Handle special case of zero child processes.
if (pending_end_ack_count_ == 1) {
// Ack asynchronously now, because we don't have any children to wait for.
- std::vector<std::string> categories;
- TraceLog::GetInstance()->GetKnownCategories(&categories);
+ std::vector<std::string> category_groups;
+ TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&TraceControllerImpl::OnEndTracingAck,
- base::Unretained(this), categories));
+ base::Unretained(this), category_groups));
}
// Notify all child processes.
@@ -265,8 +251,8 @@
filters_.insert(filter);
if (is_tracing_enabled()) {
- filter->SendBeginTracing(included_categories_, excluded_categories_,
- trace_options_);
+ std::string cf_str = category_filter_.ToString();
+ filter->SendBeginTracing(cf_str, trace_options_);
if (!watch_category_.empty())
filter->SendSetWatchEvent(watch_category_, watch_name_);
}
@@ -288,28 +274,27 @@
subscriber_ = subscriber;
- TraceLog::GetInstance()->GetEnabledTraceCategories(&included_categories_,
- &excluded_categories_);
+ category_filter_ = TraceLog::GetInstance()->GetCurrentCategoryFilter();
trace_options_ = TraceLog::GetInstance()->trace_options();
// Notify all child processes.
for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) {
- it->get()->SendBeginTracing(included_categories_, excluded_categories_,
- trace_options_);
+ it->get()->SendBeginTracing(category_filter_.ToString(), trace_options_);
}
}
void TraceControllerImpl::OnEndTracingAck(
- const std::vector<std::string>& known_categories) {
+ const std::vector<std::string>& known_category_groups) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&TraceControllerImpl::OnEndTracingAck,
- base::Unretained(this), known_categories));
+ base::Unretained(this), known_category_groups));
return;
}
- // Merge known_categories with known_categories_
- known_categories_.insert(known_categories.begin(), known_categories.end());
+ // Merge known_category_groups with known_category_groups_
+ known_category_groups_.insert(known_category_groups.begin(),
+ known_category_groups.end());
if (pending_end_ack_count_ == 0)
return;
@@ -331,25 +316,25 @@
// Trigger callback if one is set.
if (subscriber_) {
- if (is_get_categories_)
- subscriber_->OnKnownCategoriesCollected(known_categories_);
+ if (is_get_category_groups_)
+ subscriber_->OnKnownCategoriesCollected(known_category_groups_);
else
subscriber_->OnEndTracingComplete();
// Clear subscriber so that others can use TraceController.
subscriber_ = NULL;
}
- is_get_categories_ = false;
+ is_get_category_groups_ = false;
}
if (pending_end_ack_count_ == 1) {
// The last ack represents local trace, so we need to ack it now. Note that
// this code only executes if there were child processes.
- std::vector<std::string> categories;
- TraceLog::GetInstance()->GetKnownCategories(&categories);
+ std::vector<std::string> category_groups;
+ TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&TraceControllerImpl::OnEndTracingAck,
- base::Unretained(this), categories));
+ base::Unretained(this), category_groups));
}
}
@@ -365,7 +350,7 @@
}
// Drop trace events if we are just getting categories.
- if (subscriber_ && !is_get_categories_)
+ if (subscriber_ && !is_get_category_groups_)
subscriber_->OnTraceDataCollected(events_str_ptr);
}
diff --git a/content/browser/tracing/trace_controller_impl.h b/content/browser/tracing/trace_controller_impl.h
index 248f131..f24d283 100644
--- a/content/browser/tracing/trace_controller_impl.h
+++ b/content/browser/tracing/trace_controller_impl.h
@@ -26,19 +26,9 @@
// startup tracing.
void InitStartupTracing(const CommandLine& command_line);
- // Same as above, but specifies which categories to trace.
- // If both included_categories and excluded_categories are empty,
- // all categories are traced.
- // Else if included_categories is non-empty, only those are traced.
- // Else if excluded_categories is non-empty, everything but those are traced.
- bool BeginTracing(TraceSubscriber* subscriber,
- const std::vector<std::string>& included_categories,
- const std::vector<std::string>& excluded_categories,
- base::debug::TraceLog::Options options);
-
// TraceController implementation:
virtual bool BeginTracing(TraceSubscriber* subscriber,
- const std::string& categories,
+ const std::string& category_patterns,
base::debug::TraceLog::Options options) OVERRIDE;
virtual bool EndTracingAsync(TraceSubscriber* subscriber) OVERRIDE;
virtual bool GetTraceBufferPercentFullAsync(
@@ -48,7 +38,8 @@
const std::string& event_name) OVERRIDE;
virtual bool CancelWatchEvent(TraceSubscriber* subscriber) OVERRIDE;
virtual void CancelSubscriber(TraceSubscriber* subscriber) OVERRIDE;
- virtual bool GetKnownCategoriesAsync(TraceSubscriber* subscriber) OVERRIDE;
+ virtual bool GetKnownCategoryGroupsAsync(TraceSubscriber* subscriber)
+ OVERRIDE;
private:
typedef std::set<scoped_refptr<TraceMessageFilter> > FilterMap;
@@ -84,7 +75,7 @@
void AddFilter(TraceMessageFilter* filter);
void RemoveFilter(TraceMessageFilter* filter);
void OnTracingBegan(TraceSubscriber* subscriber);
- void OnEndTracingAck(const std::vector<std::string>& known_categories);
+ void OnEndTracingAck(const std::vector<std::string>& known_category_groups);
void OnTraceDataCollected(
const scoped_refptr<base::RefCountedString>& events_str_ptr);
void OnTraceNotification(int notification);
@@ -98,13 +89,12 @@
int pending_bpf_ack_count_;
float maximum_bpf_;
bool is_tracing_;
- bool is_get_categories_;
- std::set<std::string> known_categories_;
- std::vector<std::string> included_categories_;
- std::vector<std::string> excluded_categories_;
+ bool is_get_category_groups_;
+ std::set<std::string> known_category_groups_;
std::string watch_category_;
std::string watch_name_;
base::debug::TraceLog::Options trace_options_;
+ base::debug::CategoryFilter category_filter_;
DISALLOW_COPY_AND_ASSIGN(TraceControllerImpl);
};
diff --git a/content/browser/tracing/trace_message_filter.cc b/content/browser/tracing/trace_message_filter.cc
index 8894cff..e75d786 100644
--- a/content/browser/tracing/trace_message_filter.cc
+++ b/content/browser/tracing/trace_message_filter.cc
@@ -55,11 +55,10 @@
}
void TraceMessageFilter::SendBeginTracing(
- const std::vector<std::string>& included_categories,
- const std::vector<std::string>& excluded_categories,
+ const std::string& category_filter_str,
base::debug::TraceLog::Options options) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- Send(new TracingMsg_BeginTracing(included_categories, excluded_categories,
+ Send(new TracingMsg_BeginTracing(category_filter_str,
base::TimeTicks::NowFromSystemTraceTime(),
options));
}
diff --git a/content/browser/tracing/trace_message_filter.h b/content/browser/tracing/trace_message_filter.h
index aa5f336..8da3453 100644
--- a/content/browser/tracing/trace_message_filter.h
+++ b/content/browser/tracing/trace_message_filter.h
@@ -28,8 +28,7 @@
virtual bool OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) OVERRIDE;
- void SendBeginTracing(const std::vector<std::string>& included_categories,
- const std::vector<std::string>& excluded_categories,
+ void SendBeginTracing(const std::string& category_filter_str,
base::debug::TraceLog::Options options);
void SendEndTracing();
void SendGetTraceBufferPercentFull();
diff --git a/content/browser/tracing/tracing_ui.cc b/content/browser/tracing/tracing_ui.cc
index aa2e529..5b7e359 100644
--- a/content/browser/tracing/tracing_ui.cc
+++ b/content/browser/tracing/tracing_ui.cc
@@ -12,6 +12,7 @@
#include "base/debug/trace_event.h"
#include "base/file_util.h"
#include "base/memory/scoped_ptr.h"
+#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/strings/string_number_conversions.h"
#include "base/utf_string_conversions.h"
@@ -40,8 +41,7 @@
namespace {
WebUIDataSource* CreateTracingHTMLSource() {
- WebUIDataSource* source =
- WebUIDataSource::Create(chrome::kChromeUITracingHost);
+ WebUIDataSource* source = WebUIDataSource::Create(kChromeUITracingHost);
source->SetJsonPath("strings.js");
source->SetDefaultResource(IDR_TRACING_HTML);
@@ -306,7 +306,7 @@
void TracingMessageHandler::OnLoadTraceFile(const base::ListValue* list) {
// Only allow a single dialog at a time.
- if (select_trace_file_dialog_.get())
+ if (select_trace_file_dialog_)
return;
select_trace_file_dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE;
select_trace_file_dialog_ = ui::SelectFileDialog::Create(
@@ -317,8 +317,11 @@
ui::SelectFileDialog::SELECT_OPEN_FILE,
string16(),
base::FilePath(),
- NULL, 0, FILE_PATH_LITERAL(""),
- web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(), NULL);
+ NULL,
+ 0,
+ base::FilePath::StringType(),
+ web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(),
+ NULL);
}
void TracingMessageHandler::LoadTraceFileComplete(string16* contents) {
@@ -342,13 +345,13 @@
rvh->ExecuteJavascriptInWebFrame(string16(), javascript);
}
rvh->ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(
- "tracingController.onLoadTraceFileComplete(JSON.parse(window.traceData));"
+ "tracingController.onLoadTraceFileComplete(window.traceData);"
"delete window.traceData;"));
}
void TracingMessageHandler::OnSaveTraceFile(const base::ListValue* list) {
// Only allow a single dialog at a time.
- if (select_trace_file_dialog_.get())
+ if (select_trace_file_dialog_)
return;
DCHECK(list->GetSize() == 1);
@@ -367,8 +370,11 @@
ui::SelectFileDialog::SELECT_SAVEAS_FILE,
string16(),
base::FilePath(),
- NULL, 0, FILE_PATH_LITERAL(""),
- web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(), NULL);
+ NULL,
+ 0,
+ base::FilePath::StringType(),
+ web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(),
+ NULL);
}
void TracingMessageHandler::SaveTraceFileComplete() {
@@ -420,6 +426,14 @@
void TracingMessageHandler::OnEndTracingAsync(const base::ListValue* list) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // This is really us beginning to end tracing, rather than tracing being truly
+ // over. When this function yields, we expect to get some number of
+ // OnTraceDataCollected callbacks, which will append data to window.traceData.
+ // To set up for this, set window.traceData to the empty string.
+ web_ui()->GetWebContents()->GetRenderViewHost()->
+ ExecuteJavascriptInWebFrame(string16(),
+ UTF8ToUTF16("window.traceData = '';"));
+
// TODO(nduca): fix javascript code to make sure trace_enabled_ is always true
// here. triggered a false condition by just clicking stop
// trace a few times when it was going slow, and maybe switching
@@ -450,7 +464,11 @@
return;
#endif
}
- web_ui()->CallJavascriptFunction("tracingController.onEndTracingComplete");
+
+ RenderViewHost* rvh = web_ui()->GetWebContents()->GetRenderViewHost();
+ rvh->ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(
+ "tracingController.onEndTracingComplete(window.traceData);"
+ "delete window.traceData;"));
}
void TracingMessageHandler::OnEndSystemTracingAck(
@@ -469,17 +487,19 @@
const scoped_refptr<base::RefCountedString>& trace_fragment) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- base::debug::TraceResultBuffer::SimpleOutput output;
- base::debug::TraceResultBuffer trace_buffer;
- trace_buffer.SetOutputCallback(output.GetCallback());
- output.Append("tracingController.onTraceDataCollected(");
- trace_buffer.Start();
- trace_buffer.AddFragment(trace_fragment->data());
- trace_buffer.Finish();
- output.Append(");");
+ std::string javascript("window.traceData += '");
+
+ std::string escaped_data;
+ ReplaceChars(trace_fragment->data(), "\\", "\\\\", &escaped_data);
+ javascript += escaped_data;
+
+ // Intentionally append a , to the traceData. This technically causes all
+ // traceData that we pass back to JS to end with a comma, but that is actually
+ // something the JS side strips away anyway
+ javascript += ",';";
web_ui()->GetWebContents()->GetRenderViewHost()->
- ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(output.json_output));
+ ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(javascript));
}
void TracingMessageHandler::OnTraceBufferPercentFullReply(float percent_full) {
@@ -491,7 +511,7 @@
void TracingMessageHandler::OnGetKnownCategories(const base::ListValue* list) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (!TraceController::GetInstance()->GetKnownCategoriesAsync(this)) {
+ if (!TraceController::GetInstance()->GetKnownCategoryGroupsAsync(this)) {
std::set<std::string> ret;
OnKnownCategoriesCollected(ret);
}
diff --git a/content/browser/udev_linux.cc b/content/browser/udev_linux.cc
index d9f31db..13f5494 100644
--- a/content/browser/udev_linux.cc
+++ b/content/browser/udev_linux.cc
@@ -32,8 +32,12 @@
monitor_fd_ = udev_monitor_get_fd(monitor_);
CHECK_GE(monitor_fd_, 0);
- bool success = MessageLoopForIO::current()->WatchFileDescriptor(monitor_fd_,
- true, MessageLoopForIO::WATCH_READ, &monitor_watcher_, this);
+ bool success = base::MessageLoopForIO::current()->WatchFileDescriptor(
+ monitor_fd_,
+ true,
+ base::MessageLoopForIO::WATCH_READ,
+ &monitor_watcher_,
+ this);
CHECK(success);
}
diff --git a/content/browser/web_contents/OWNERS b/content/browser/web_contents/OWNERS
index e5c12b0..4966076 100644
--- a/content/browser/web_contents/OWNERS
+++ b/content/browser/web_contents/OWNERS
@@ -1,2 +1,2 @@
-# for *aura.*
-ben@chromium.org
+# for *aura*
+per-file *aura*=ben@chromium.org
diff --git a/content/browser/web_contents/aura/image_window_delegate.cc b/content/browser/web_contents/aura/image_window_delegate.cc
new file mode 100644
index 0000000..1829f46
--- /dev/null
+++ b/content/browser/web_contents/aura/image_window_delegate.cc
@@ -0,0 +1,100 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_contents/aura/image_window_delegate.h"
+
+#include "ui/base/hit_test.h"
+#include "ui/compositor/compositor.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/rect.h"
+#include "ui/gfx/size.h"
+
+namespace content {
+
+ImageWindowDelegate::ImageWindowDelegate()
+ : size_mismatch_(false) {
+}
+
+ImageWindowDelegate::~ImageWindowDelegate() {
+}
+
+void ImageWindowDelegate::SetImage(const gfx::Image& image) {
+ image_ = image;
+ if (!window_size_.IsEmpty() && !image_.IsEmpty())
+ size_mismatch_ = window_size_ != image_.AsImageSkia().size();
+}
+
+gfx::Size ImageWindowDelegate::GetMinimumSize() const {
+ return gfx::Size();
+}
+
+gfx::Size ImageWindowDelegate::GetMaximumSize() const {
+ return gfx::Size();
+}
+
+void ImageWindowDelegate::OnBoundsChanged(const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) {
+ window_size_ = new_bounds.size();
+ if (!image_.IsEmpty())
+ size_mismatch_ = window_size_ != image_.AsImageSkia().size();
+}
+
+gfx::NativeCursor ImageWindowDelegate::GetCursor(const gfx::Point& point) {
+ return gfx::kNullCursor;
+}
+
+int ImageWindowDelegate::GetNonClientComponent(const gfx::Point& point) const {
+ return HTNOWHERE;
+}
+
+bool ImageWindowDelegate::ShouldDescendIntoChildForEventHandling(
+ aura::Window* child,
+ const gfx::Point& location) {
+ return false;
+}
+
+bool ImageWindowDelegate::CanFocus() {
+ return false;
+}
+
+void ImageWindowDelegate::OnCaptureLost() {
+}
+
+void ImageWindowDelegate::OnPaint(gfx::Canvas* canvas) {
+ if (image_.IsEmpty()) {
+ canvas->DrawColor(SK_ColorGRAY);
+ } else {
+ if (size_mismatch_)
+ canvas->DrawColor(SK_ColorWHITE);
+ canvas->DrawImageInt(image_.AsImageSkia(), 0, 0);
+ }
+}
+
+void ImageWindowDelegate::OnDeviceScaleFactorChanged(float scale_factor) {
+}
+
+void ImageWindowDelegate::OnWindowDestroying() {
+}
+
+void ImageWindowDelegate::OnWindowDestroyed() {
+ delete this;
+}
+
+void ImageWindowDelegate::OnWindowTargetVisibilityChanged(bool visible) {
+}
+
+bool ImageWindowDelegate::HasHitTestMask() const {
+ return false;
+}
+
+void ImageWindowDelegate::GetHitTestMask(gfx::Path* mask) const {
+}
+
+scoped_refptr<ui::Texture> ImageWindowDelegate::CopyTexture() {
+ return scoped_refptr<ui::Texture>();
+}
+
+} // namespace content
diff --git a/content/browser/web_contents/aura/image_window_delegate.h b/content/browser/web_contents/aura/image_window_delegate.h
new file mode 100644
index 0000000..ad92ce2
--- /dev/null
+++ b/content/browser/web_contents/aura/image_window_delegate.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEB_CONTENTS_AURA_IMAGE_WINDOW_DELEGATE_H_
+#define CONTENT_BROWSER_WEB_CONTENTS_AURA_IMAGE_WINDOW_DELEGATE_H_
+
+#include "ui/aura/window_delegate.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/size.h"
+
+namespace content {
+
+// An ImageWindowDelegate paints an image for a Window. The delegate destroys
+// itself when the Window is destroyed. The delegate does not consume any event.
+class ImageWindowDelegate : public aura::WindowDelegate {
+ public:
+ ImageWindowDelegate();
+
+ void SetImage(const gfx::Image& image);
+ bool has_image() const { return !image_.IsEmpty(); }
+
+ protected:
+ virtual ~ImageWindowDelegate();
+
+ // Overridden from aura::WindowDelegate:
+ virtual gfx::Size GetMinimumSize() const OVERRIDE;
+ virtual gfx::Size GetMaximumSize() const OVERRIDE;
+ virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) OVERRIDE;
+ virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE;
+ virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE;
+ virtual bool ShouldDescendIntoChildForEventHandling(
+ aura::Window* child,
+ const gfx::Point& location) OVERRIDE;
+ virtual bool CanFocus() OVERRIDE;
+ virtual void OnCaptureLost() OVERRIDE;
+ virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
+ virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
+ virtual void OnWindowDestroying() OVERRIDE;
+ virtual void OnWindowDestroyed() OVERRIDE;
+ virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE;
+ virtual bool HasHitTestMask() const OVERRIDE;
+ virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE;
+ virtual scoped_refptr<ui::Texture> CopyTexture() OVERRIDE;
+
+ protected:
+ gfx::Image image_;
+ gfx::Size window_size_;
+
+ // Keeps track of whether the window size matches the image size or not. If
+ // the image size is smaller than the window size, then the delegate paints a
+ // white background for the missing regions.
+ bool size_mismatch_;
+
+ DISALLOW_COPY_AND_ASSIGN(ImageWindowDelegate);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEB_CONTENTS_AURA_IMAGE_WINDOW_DELEGATE_H_
diff --git a/content/browser/web_contents/aura/shadow_layer_delegate.cc b/content/browser/web_contents/aura/shadow_layer_delegate.cc
new file mode 100644
index 0000000..8ff270b
--- /dev/null
+++ b/content/browser/web_contents/aura/shadow_layer_delegate.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_contents/aura/shadow_layer_delegate.h"
+
+#include "base/bind.h"
+#include "third_party/skia/include/effects/SkGradientShader.h"
+#include "ui/aura/window.h"
+#include "ui/compositor/layer.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/skia_util.h"
+
+namespace {
+
+const SkColor kShadowLightColor = SkColorSetARGB(0x0, 0, 0, 0);
+const SkColor kShadowDarkColor = SkColorSetARGB(0x70, 0, 0, 0);
+const int kShadowThick = 7;
+
+} // namespace
+
+namespace content {
+
+ShadowLayerDelegate::ShadowLayerDelegate(aura::Window* window)
+ : layer_(new ui::Layer(ui::LAYER_TEXTURED)) {
+ layer_->set_delegate(this);
+ layer_->SetBounds(gfx::Rect(-kShadowThick, 0, kShadowThick,
+ window->bounds().height()));
+ layer_->SetFillsBoundsOpaquely(false);
+ window->layer()->Add(layer_.get());
+}
+
+ShadowLayerDelegate::~ShadowLayerDelegate() {
+}
+
+void ShadowLayerDelegate::OnPaintLayer(gfx::Canvas* canvas) {
+ SkPoint points[2];
+ const SkColor kShadowColors[2] = { kShadowLightColor, kShadowDarkColor };
+
+ points[0].iset(0, 0);
+ points[1].iset(kShadowThick, 0);
+
+ skia::RefPtr<SkShader> shader = skia::AdoptRef(
+ SkGradientShader::CreateLinear(points, kShadowColors, NULL,
+ arraysize(points), SkShader::kRepeat_TileMode, NULL));
+
+ gfx::Rect paint_rect = gfx::Rect(0, 0, kShadowThick,
+ layer_->bounds().height());
+ SkPaint paint;
+ paint.setShader(shader.get());
+ canvas->sk_canvas()->drawRect(gfx::RectToSkRect(paint_rect), paint);
+}
+
+void ShadowLayerDelegate::OnDeviceScaleFactorChanged(float scale_factor) {
+}
+
+base::Closure ShadowLayerDelegate::PrepareForLayerBoundsChange() {
+ return base::Bind(&base::DoNothing);
+}
+
+} // namespace content
diff --git a/content/browser/web_contents/aura/shadow_layer_delegate.h b/content/browser/web_contents/aura/shadow_layer_delegate.h
new file mode 100644
index 0000000..25c2fb4
--- /dev/null
+++ b/content/browser/web_contents/aura/shadow_layer_delegate.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEB_CONTENTS_AURA_SHADOW_LAYER_DELEGATE_H_
+#define CONTENT_BROWSER_WEB_CONTENTS_AURA_SHADOW_LAYER_DELEGATE_H_
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/compositor/layer_delegate.h"
+
+namespace aura {
+class Window;
+}
+
+namespace ui {
+class Layer;
+}
+
+namespace content {
+
+// ShadowLayerDelegate takes care of drawing a shadow on the left edge of a
+// window.
+class ShadowLayerDelegate : public ui::LayerDelegate {
+ public:
+ explicit ShadowLayerDelegate(aura::Window* shadow_for);
+ virtual ~ShadowLayerDelegate();
+
+ // Returns the layer for the shadow. Note that the ShadowLayerDelegate owns
+ // the layer, and the layer is destroyed when the delegate is destroyed.
+ ui::Layer* layer() { return layer_.get(); }
+
+ private:
+ // Overridden from ui::LayerDelegate:
+ virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE;
+ virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
+ virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE;
+
+ scoped_ptr<ui::Layer> layer_;
+
+ DISALLOW_COPY_AND_ASSIGN(ShadowLayerDelegate);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEB_CONTENTS_AURA_SHADOW_LAYER_DELEGATE_H_
diff --git a/content/browser/web_contents/debug_urls.cc b/content/browser/web_contents/debug_urls.cc
index f62f0b3..c321b05 100644
--- a/content/browser/web_contents/debug_urls.cc
+++ b/content/browser/web_contents/debug_urls.cc
@@ -42,7 +42,7 @@
if (!(transition & PAGE_TRANSITION_FROM_ADDRESS_BAR))
return false;
- if (url.host() == chrome::kChromeUIBrowserCrashHost) {
+ if (url.host() == kChromeUIBrowserCrashHost) {
// Induce an intentional crash in the browser process.
CHECK(false);
return true;
diff --git a/content/browser/web_contents/interstitial_page_impl.cc b/content/browser/web_contents/interstitial_page_impl.cc
index 7e62376..9673e98 100644
--- a/content/browser/web_contents/interstitial_page_impl.cc
+++ b/content/browser/web_contents/interstitial_page_impl.cc
@@ -34,6 +34,7 @@
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/storage_partition.h"
+#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/page_transition_types.h"
#include "net/base/escape.h"
@@ -147,11 +148,10 @@
should_revert_web_contents_title_(false),
web_contents_was_loading_(false),
resource_dispatcher_host_notified_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(rvh_delegate_view_(
- new InterstitialPageRVHDelegateView(this))),
+ rvh_delegate_view_(new InterstitialPageRVHDelegateView(this)),
create_view_(true),
delegate_(delegate),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
+ weak_ptr_factory_(this) {
InitInterstitialPageMap();
// It would be inconsistent to create an interstitial with no new navigation
// (which is the case when the interstitial was triggered by a sub-resource on
@@ -268,7 +268,8 @@
// Shutdown the RVH asynchronously, as we may have been called from a RVH
// delegate method, and we can't delete the RVH out from under itself.
- MessageLoop::current()->PostNonNestableTask(FROM_HERE,
+ base::MessageLoop::current()->PostNonNestableTask(
+ FROM_HERE,
base::Bind(&InterstitialPageImpl::Shutdown,
weak_ptr_factory_.GetWeakPtr(),
render_view_host_));
@@ -357,9 +358,10 @@
return url_;
}
-void InterstitialPageImpl::RenderViewGone(RenderViewHost* render_view_host,
- base::TerminationStatus status,
- int error_code) {
+void InterstitialPageImpl::RenderViewTerminated(
+ RenderViewHost* render_view_host,
+ base::TerminationStatus status,
+ int error_code) {
// Our renderer died. This should not happen in normal cases.
// If we haven't already started shutdown, just dismiss the interstitial.
// We cannot check for enabled() here, because we may have called Disable
@@ -450,9 +452,9 @@
return renderer_preferences_;
}
-webkit_glue::WebPreferences InterstitialPageImpl::GetWebkitPrefs() {
+WebPreferences InterstitialPageImpl::GetWebkitPrefs() {
if (!enabled())
- return webkit_glue::WebPreferences();
+ return WebPreferences();
return WebContentsImpl::GetWebkitPrefs(render_view_host_, url_);
}
@@ -476,6 +478,13 @@
web_contents_->HandleKeyboardEvent(event);
}
+#if defined(OS_WIN) && defined(USE_AURA)
+gfx::NativeViewAccessible
+InterstitialPageImpl::GetParentNativeViewAccessible() {
+ return web_contents_->GetParentNativeViewAccessible();
+}
+#endif
+
WebContents* InterstitialPageImpl::web_contents() const {
return web_contents_;
}
@@ -775,6 +784,9 @@
}
void InterstitialPageImpl::InterstitialPageRVHDelegateView::GotFocus() {
+ WebContents* web_contents = interstitial_page_->web_contents();
+ if (web_contents && web_contents->GetDelegate())
+ web_contents->GetDelegate()->WebContentsFocused(web_contents);
}
void InterstitialPageImpl::InterstitialPageRVHDelegateView::TakeFocus(
diff --git a/content/browser/web_contents/interstitial_page_impl.h b/content/browser/web_contents/interstitial_page_impl.h
index 2d56015..2b3108a 100644
--- a/content/browser/web_contents/interstitial_page_impl.h
+++ b/content/browser/web_contents/interstitial_page_impl.h
@@ -92,9 +92,9 @@
// RenderViewHostDelegate implementation:
virtual RenderViewHostDelegateView* GetDelegateView() OVERRIDE;
virtual const GURL& GetURL() const OVERRIDE;
- virtual void RenderViewGone(RenderViewHost* render_view_host,
- base::TerminationStatus status,
- int error_code) OVERRIDE;
+ virtual void RenderViewTerminated(RenderViewHost* render_view_host,
+ base::TerminationStatus status,
+ int error_code) OVERRIDE;
virtual void DidNavigate(
RenderViewHost* render_view_host,
const ViewHostMsg_FrameNavigate_Params& params) OVERRIDE;
@@ -104,7 +104,7 @@
base::i18n::TextDirection title_direction) OVERRIDE;
virtual RendererPreferences GetRendererPrefs(
BrowserContext* browser_context) const OVERRIDE;
- virtual webkit_glue::WebPreferences GetWebkitPrefs() OVERRIDE;
+ virtual WebPreferences GetWebkitPrefs() OVERRIDE;
virtual gfx::Rect GetRootWindowResizerRect() const OVERRIDE;
virtual void CreateNewWindow(
int route_id,
@@ -132,6 +132,9 @@
bool* is_keyboard_shortcut) OVERRIDE;
virtual void HandleKeyboardEvent(
const NativeWebKeyboardEvent& event) OVERRIDE;
+#if defined(OS_WIN) && defined(USE_AURA)
+ virtual gfx::NativeViewAccessible GetParentNativeViewAccessible() OVERRIDE;
+#endif
bool enabled() const { return enabled_; }
WebContents* web_contents() const;
diff --git a/content/browser/web_contents/navigation_controller_impl.cc b/content/browser/web_contents/navigation_controller_impl.cc
index c8218af..f7c8215 100644
--- a/content/browser/web_contents/navigation_controller_impl.cc
+++ b/content/browser/web_contents/navigation_controller_impl.cc
@@ -5,7 +5,6 @@
#include "content/browser/web_contents/navigation_controller_impl.h"
#include "base/bind.h"
-#include "base/command_line.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/string_number_conversions.h" // Temporary
@@ -22,6 +21,7 @@
#include "content/browser/web_contents/interstitial_page_impl.h"
#include "content/browser/web_contents/navigation_entry_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/web_contents/web_contents_screenshot_manager.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
@@ -36,13 +36,11 @@
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_constants.h"
-#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "net/base/escape.h"
#include "net/base/mime_util.h"
#include "net/base/net_util.h"
#include "skia/ext/platform_canvas.h"
-#include "ui/gfx/codec/png_codec.h"
#include "webkit/glue/glue_serialize.h"
namespace content {
@@ -215,12 +213,12 @@
transient_entry_index_(-1),
web_contents_(web_contents),
max_restored_page_id_(-1),
- ALLOW_THIS_IN_INITIALIZER_LIST(ssl_manager_(this)),
+ ssl_manager_(this),
needs_reload_(false),
is_initial_navigation_(true),
pending_reload_(NO_RELOAD),
get_timestamp_callback_(base::Bind(&base::Time::Now)),
- ALLOW_THIS_IN_INITIALIZER_LIST(take_screenshot_factory_(this)) {
+ screenshot_manager_(new WebContentsScreenshotManager(this)) {
DCHECK(browser_context_);
}
@@ -476,151 +474,13 @@
}
void NavigationControllerImpl::TakeScreenshot() {
- static bool overscroll_enabled = !CommandLine::ForCurrentProcess()->
- HasSwitch(switches::kDisableOverscrollHistoryNavigation);
- if (!overscroll_enabled)
- return;
-
- NavigationEntryImpl* entry =
- NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry());
- if (!entry)
- return;
-
- RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
- if (!static_cast<RenderViewHostImpl*>
- (render_view_host)->overscroll_controller()) {
- return;
- }
- content::RenderWidgetHostView* view = render_view_host->GetView();
- if (!view)
- return;
-
- if (!take_screenshot_callback_.is_null())
- take_screenshot_callback_.Run(render_view_host);
-
- render_view_host->CopyFromBackingStore(gfx::Rect(),
- view->GetViewBounds().size(),
- base::Bind(&NavigationControllerImpl::OnScreenshotTaken,
- take_screenshot_factory_.GetWeakPtr(),
- entry->GetUniqueID()));
+ screenshot_manager_->TakeScreenshot();
}
-void NavigationControllerImpl::OnScreenshotTaken(
- int unique_id,
- bool success,
- const SkBitmap& bitmap) {
- NavigationEntryImpl* entry = NULL;
- for (NavigationEntries::iterator i = entries_.begin();
- i != entries_.end();
- ++i) {
- if ((*i)->GetUniqueID() == unique_id) {
- entry = (*i).get();
- break;
- }
- }
-
- if (!entry) {
- LOG(ERROR) << "Invalid entry with unique id: " << unique_id;
- return;
- }
-
- if (!success || bitmap.empty() || bitmap.isNull()) {
- ClearScreenshot(entry);
- return;
- }
-
- std::vector<unsigned char> data;
- if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &data)) {
- entry->SetScreenshotPNGData(data);
- PurgeScreenshotsIfNecessary();
- } else {
- ClearScreenshot(entry);
- }
-}
-
-bool NavigationControllerImpl::ClearScreenshot(NavigationEntryImpl* entry) {
- if (!entry->screenshot())
- return false;
-
- entry->SetScreenshotPNGData(std::vector<unsigned char>());
- return true;
-}
-
-void NavigationControllerImpl::PurgeScreenshotsIfNecessary() {
- // Allow only a certain number of entries to keep screenshots.
- const int kMaxScreenshots = 10;
- int screenshot_count = GetScreenshotCount();
- if (screenshot_count < kMaxScreenshots)
- return;
-
- const int current = GetCurrentEntryIndex();
- const int num_entries = GetEntryCount();
- int available_slots = kMaxScreenshots;
- if (NavigationEntryImpl::FromNavigationEntry(
- GetEntryAtIndex(current))->screenshot())
- --available_slots;
-
- // Keep screenshots closer to the current navigation entry, and purge the ones
- // that are farther away from it. So in each step, look at the entries at
- // each offset on both the back and forward history, and start counting them
- // to make sure that the correct number of screenshots are kept in memory.
- // Note that it is possible for some entries to be missing screenshots (e.g.
- // when taking the screenshot failed for some reason). So there may be a state
- // where there are a lot of entries in the back history, but none of them has
- // any screenshot. In such cases, keep the screenshots for |kMaxScreenshots|
- // entries in the forward history list.
- int back = current - 1;
- int forward = current + 1;
- while (available_slots > 0 && (back >= 0 || forward < num_entries)) {
- if (back >= 0) {
- NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
- GetEntryAtIndex(back));
- if (entry->screenshot())
- --available_slots;
- --back;
- }
-
- if (available_slots > 0 && forward < num_entries) {
- NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
- GetEntryAtIndex(forward));
- if (entry->screenshot())
- --available_slots;
- ++forward;
- }
- }
-
- // Purge any screenshot at |back| or lower indices, and |forward| or higher
- // indices.
-
- while (screenshot_count > kMaxScreenshots && back >= 0) {
- NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
- GetEntryAtIndex(back));
- if (ClearScreenshot(entry))
- --screenshot_count;
- --back;
- }
-
- while (screenshot_count > kMaxScreenshots && forward < num_entries) {
- NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
- GetEntryAtIndex(forward));
- if (ClearScreenshot(entry))
- --screenshot_count;
- ++forward;
- }
- CHECK_GE(screenshot_count, 0);
- CHECK_LE(screenshot_count, kMaxScreenshots);
-}
-
-int NavigationControllerImpl::GetScreenshotCount() const {
- int count = 0;
- for (NavigationEntries::const_iterator it = entries_.begin();
- it != entries_.end(); ++it) {
- NavigationEntryImpl* entry =
- NavigationEntryImpl::FromNavigationEntry(it->get());
- if (entry->screenshot())
- count++;
- }
- return count;
+void NavigationControllerImpl::SetScreenshotManager(
+ WebContentsScreenshotManager* manager) {
+ screenshot_manager_.reset(manager ? manager :
+ new WebContentsScreenshotManager(this));
}
bool NavigationControllerImpl::CanGoBack() const {
@@ -799,6 +659,7 @@
browser_context_));
if (params.is_cross_site_redirect)
entry->set_should_replace_entry(true);
+ entry->set_should_clear_history_list(params.should_clear_history_list);
entry->SetIsOverridingUserAgent(override);
entry->set_transferred_global_request_id(
params.transferred_global_request_id);
@@ -921,6 +782,10 @@
// the renderer.
active_entry->set_is_renderer_initiated(false);
+ // Once committed, we no longer need to track whether the session history was
+ // cleared. Navigating to this entry again shouldn't clear it again.
+ active_entry->set_should_clear_history_list(false);
+
// The active entry's SiteInstance should match our SiteInstance.
CHECK(active_entry->site_instance() == web_contents_->GetSiteInstance());
@@ -983,6 +848,9 @@
return NAVIGATION_TYPE_NEW_SUBFRAME;
}
+ // We only clear the session history when navigating to a new page.
+ DCHECK(!params.history_list_was_cleared);
+
// Now we know that the notification is for an existing page. Find that entry.
int existing_entry_index = GetEntryIndexWithPageID(
web_contents_->GetSiteInstance(),
@@ -1128,6 +996,16 @@
new_entry->SetOriginalRequestURL(params.original_request_url);
new_entry->SetIsOverridingUserAgent(params.is_overriding_user_agent);
+ DCHECK(!params.history_list_was_cleared || !replace_entry);
+ // The browser requested to clear the session history when it initiated the
+ // navigation. Now we know that the renderer has updated its state accordingly
+ // and it is safe to also clear the browser side history.
+ if (params.history_list_was_cleared) {
+ DiscardNonCommittedEntriesInternal();
+ entries_.clear();
+ last_committed_entry_index_ = -1;
+ }
+
InsertOrReplaceEntry(new_entry, replace_entry);
}
@@ -1458,14 +1336,8 @@
}
}
-// Implemented here and not in NavigationEntry because this controller caches
-// the total number of screen shots across all entries.
void NavigationControllerImpl::ClearAllScreenshots() {
- for (NavigationEntries::iterator it = entries_.begin();
- it != entries_.end();
- ++it)
- ClearScreenshot(it->get());
- DCHECK_EQ(GetScreenshotCount(), 0);
+ screenshot_manager_->ClearAllScreenshots();
}
void NavigationControllerImpl::SetSessionStorageNamespace(
@@ -1812,9 +1684,4 @@
get_timestamp_callback_ = get_timestamp_callback;
}
-void NavigationControllerImpl::SetTakeScreenshotCallbackForTest(
- const base::Callback<void(RenderViewHost*)>& take_screenshot_callback) {
- take_screenshot_callback_ = take_screenshot_callback;
-}
-
} // namespace content
diff --git a/content/browser/web_contents/navigation_controller_impl.h b/content/browser/web_contents/navigation_controller_impl.h
index 5027990..5e50d10 100644
--- a/content/browser/web_contents/navigation_controller_impl.h
+++ b/content/browser/web_contents/navigation_controller_impl.h
@@ -15,13 +15,13 @@
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_type.h"
-class SkBitmap;
struct ViewHostMsg_FrameNavigate_Params;
namespace content {
class NavigationEntryImpl;
class RenderViewHost;
class WebContentsImpl;
+class WebContentsScreenshotManager;
class SiteInstance;
struct LoadCommittedDetails;
@@ -188,8 +188,12 @@
// Takes a screenshot of the page at the current state.
void TakeScreenshot();
- void SetTakeScreenshotCallbackForTest(
- const base::Callback<void(RenderViewHost*)>& take_screenshot_callback);
+ // Sets the screenshot manager for this NavigationControllerImpl. The
+ // controller takes ownership of the screenshot manager and destroys it when
+ // a new screenshot-manager is set, or when the controller is destroyed.
+ // Setting a NULL manager recreates the default screenshot manager and uses
+ // that.
+ void SetScreenshotManager(WebContentsScreenshotManager* manager);
private:
friend class RestoreHelper;
@@ -311,24 +315,6 @@
// specified |offset|. The index returned is not guaranteed to be valid.
int GetIndexForOffset(int offset) const;
- // The callback invoked when taking the screenshot of the page is complete.
- // This sets the screenshot on the navigation entry.
- void OnScreenshotTaken(int unique_id,
- bool success,
- const SkBitmap& bitmap);
-
- // Removes the screenshot for the entry, returning true if the entry had a
- // screenshot.
- bool ClearScreenshot(NavigationEntryImpl* entry);
-
- // The screenshots in the NavigationEntryImpls can accumulate and consume a
- // large amount of memory. This function makes sure that the memory
- // consumption is within a certain limit.
- void PurgeScreenshotsIfNecessary();
-
- // Returns the number of entries with screenshots.
- int GetScreenshotCount() const;
-
// ---------------------------------------------------------------------------
// The user browser context associated with this controller.
@@ -399,15 +385,6 @@
// Used to get timestamps for newly-created navigation entries.
base::Callback<base::Time()> get_timestamp_callback_;
- // A callback that gets called before taking the screenshot of the page. This
- // is used only for testing.
- base::Callback<void(RenderViewHost*)> take_screenshot_callback_;
-
- // Taking a screenshot can be async. So use a weakptr for the callback to make
- // sure that the screenshot completion callback does not trigger on a
- // destroyed NavigationControllerImpl.
- base::WeakPtrFactory<NavigationControllerImpl> take_screenshot_factory_;
-
// Used to smooth out timestamps from |get_timestamp_callback_|.
// Without this, whenever there is a run of redirects or
// code-generated navigations, those navigations may occur within
@@ -415,6 +392,8 @@
// the wrong order in the history view.
TimeSmoother time_smoother_;
+ scoped_ptr<WebContentsScreenshotManager> screenshot_manager_;
+
DISALLOW_COPY_AND_ASSIGN(NavigationControllerImpl);
};
diff --git a/content/browser/web_contents/navigation_controller_impl_unittest.cc b/content/browser/web_contents/navigation_controller_impl_unittest.cc
index 0f25e2e..4a51897 100644
--- a/content/browser/web_contents/navigation_controller_impl_unittest.cc
+++ b/content/browser/web_contents/navigation_controller_impl_unittest.cc
@@ -24,6 +24,7 @@
#include "content/browser/web_contents/navigation_controller_impl.h"
#include "content/browser/web_contents/navigation_entry_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/web_contents/web_contents_screenshot_manager.h"
#include "content/common/view_messages.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/notification_registrar.h"
@@ -33,6 +34,7 @@
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_notification_tracker.h"
+#include "content/public/test/test_utils.h"
#include "content/test/test_web_contents.h"
#include "net/base/net_util.h"
#include "skia/ext/platform_canvas.h"
@@ -69,6 +71,57 @@
a_bitmap.getSize()) == 0;
}
+class MockScreenshotManager : public content::WebContentsScreenshotManager {
+ public:
+ explicit MockScreenshotManager(content::NavigationControllerImpl* owner)
+ : content::WebContentsScreenshotManager(owner),
+ encoding_screenshot_in_progress_(false) {
+ }
+
+ virtual ~MockScreenshotManager() {
+ }
+
+ void TakeScreenshotFor(content::NavigationEntryImpl* entry) {
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
+ bitmap.allocPixels();
+ bitmap.eraseRGB(0, 0, 0);
+ encoding_screenshot_in_progress_ = true;
+ OnScreenshotTaken(entry->GetUniqueID(), true, bitmap);
+ WaitUntilScreenshotIsReady();
+ }
+
+ int GetScreenshotCount() {
+ return content::WebContentsScreenshotManager::GetScreenshotCount();
+ }
+
+ void WaitUntilScreenshotIsReady() {
+ if (!encoding_screenshot_in_progress_)
+ return;
+ message_loop_runner_ = new content::MessageLoopRunner;
+ message_loop_runner_->Run();
+ }
+
+ private:
+ // Overridden from content::WebContentsScreenshotManager:
+ virtual void TakeScreenshotImpl(
+ content::RenderViewHost* host,
+ content::NavigationEntryImpl* entry) OVERRIDE {
+ }
+
+ virtual void OnScreenshotSet(content::NavigationEntryImpl* entry) OVERRIDE {
+ encoding_screenshot_in_progress_ = false;
+ WebContentsScreenshotManager::OnScreenshotSet(entry);
+ if (message_loop_runner_)
+ message_loop_runner_->Quit();
+ }
+
+ scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
+ bool encoding_screenshot_in_progress_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockScreenshotManager);
+};
+
} // namespace
namespace content {
@@ -3190,11 +3243,6 @@
TEST_F(NavigationControllerTest, MAYBE_PurgeScreenshot) {
NavigationControllerImpl& controller = controller_impl();
- // Prepare some data to use as screenshot for each navigation.
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
- ASSERT_TRUE(bitmap.allocPixels());
- bitmap.eraseRGB(0, 0, 0);
NavigationEntryImpl* entry;
// Navigate enough times to make sure that some screenshots are purged.
@@ -3204,10 +3252,13 @@
EXPECT_EQ(i, controller.GetCurrentEntryIndex());
}
+ MockScreenshotManager* screenshot_manager =
+ new MockScreenshotManager(&controller);
+ controller.SetScreenshotManager(screenshot_manager);
for (int i = 0; i < controller.GetEntryCount(); ++i) {
entry = NavigationEntryImpl::FromNavigationEntry(
controller.GetEntryAtIndex(i));
- controller.OnScreenshotTaken(entry->GetUniqueID(), true, bitmap);
+ screenshot_manager->TakeScreenshotFor(entry);
EXPECT_TRUE(entry->screenshot());
}
@@ -3215,7 +3266,7 @@
EXPECT_EQ(13, controller.GetEntryCount());
entry = NavigationEntryImpl::FromNavigationEntry(
controller.GetEntryAtIndex(11));
- controller.OnScreenshotTaken(entry->GetUniqueID(), true, bitmap);
+ screenshot_manager->TakeScreenshotFor(entry);
for (int i = 0; i < 2; ++i) {
entry = NavigationEntryImpl::FromNavigationEntry(
@@ -3236,14 +3287,14 @@
for (int i = 0; i < controller.GetEntryCount() - 1; ++i) {
entry = NavigationEntryImpl::FromNavigationEntry(
controller.GetEntryAtIndex(i));
- controller.OnScreenshotTaken(entry->GetUniqueID(), true, bitmap);
+ screenshot_manager->TakeScreenshotFor(entry);
}
for (int i = 10; i <= 12; ++i) {
entry = NavigationEntryImpl::FromNavigationEntry(
controller.GetEntryAtIndex(i));
EXPECT_FALSE(entry->screenshot()) << "Screenshot " << i << " not purged";
- controller.OnScreenshotTaken(entry->GetUniqueID(), true, bitmap);
+ screenshot_manager->TakeScreenshotFor(entry);
}
// Navigate to index 7 and assign screenshot to all entries.
@@ -3253,7 +3304,7 @@
for (int i = 0; i < controller.GetEntryCount() - 1; ++i) {
entry = NavigationEntryImpl::FromNavigationEntry(
controller.GetEntryAtIndex(i));
- controller.OnScreenshotTaken(entry->GetUniqueID(), true, bitmap);
+ screenshot_manager->TakeScreenshotFor(entry);
}
for (int i = 0; i < 2; ++i) {
@@ -3264,9 +3315,9 @@
// Clear all screenshots.
EXPECT_EQ(13, controller.GetEntryCount());
- EXPECT_EQ(10, controller.GetScreenshotCount());
+ EXPECT_EQ(10, screenshot_manager->GetScreenshotCount());
controller.ClearAllScreenshots();
- EXPECT_EQ(0, controller.GetScreenshotCount());
+ EXPECT_EQ(0, screenshot_manager->GetScreenshotCount());
for (int i = 0; i < controller.GetEntryCount(); ++i) {
entry = NavigationEntryImpl::FromNavigationEntry(
controller.GetEntryAtIndex(i));
@@ -3274,6 +3325,55 @@
}
}
+// Test that the navigation controller clears its session history when a
+// navigation commits with the clear history list flag set.
+TEST_F(NavigationControllerTest, ClearHistoryList) {
+ const GURL url1("http://foo1");
+ const GURL url2("http://foo2");
+ const GURL url3("http://foo3");
+ const GURL url4("http://foo4");
+
+ NavigationControllerImpl& controller = controller_impl();
+
+ // Create a session history with three entries, second entry is active.
+ NavigateAndCommit(url1);
+ NavigateAndCommit(url2);
+ NavigateAndCommit(url3);
+ controller.GoBack();
+ contents()->CommitPendingNavigation();
+ EXPECT_EQ(3, controller.GetEntryCount());
+ EXPECT_EQ(1, controller.GetCurrentEntryIndex());
+
+ // Create a new pending navigation, and indicate that the session history
+ // should be cleared.
+ NavigationController::LoadURLParams params(url4);
+ params.should_clear_history_list = true;
+ controller.LoadURLWithParams(params);
+
+ // Verify that the pending entry correctly indicates that the session history
+ // should be cleared.
+ NavigationEntryImpl* entry =
+ NavigationEntryImpl::FromNavigationEntry(
+ controller.GetPendingEntry());
+ ASSERT_TRUE(entry);
+ EXPECT_TRUE(entry->should_clear_history_list());
+
+ // Assume that the RV correctly cleared its history and commit the navigation.
+ static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost())->
+ set_simulate_history_list_was_cleared(true);
+ contents()->CommitPendingNavigation();
+
+ // Verify that the NavigationController's session history was correctly
+ // cleared.
+ EXPECT_EQ(1, controller.GetEntryCount());
+ EXPECT_EQ(0, controller.GetCurrentEntryIndex());
+ EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(-1, controller.GetPendingEntryIndex());
+ EXPECT_FALSE(controller.CanGoBack());
+ EXPECT_FALSE(controller.CanGoForward());
+ EXPECT_EQ(url4, controller.GetActiveEntry()->GetURL());
+}
+
/* TODO(brettw) These test pass on my local machine but fail on the XP buildbot
(but not Vista) cleaning up the directory after they run.
This should be fixed.
@@ -3322,8 +3422,8 @@
HistoryService* history = HistoryServiceFactory::GetForProfiles(
profile(), Profile::IMPLICIT_ACCESS);
if (history) {
- history->SetOnBackendDestroyTask(MessageLoop::QuitClosure());
- MessageLoop::current()->Run();
+ history->SetOnBackendDestroyTask(base::MessageLoop::QuitClosure());
+ base::MessageLoop::current()->Run();
}
// Do normal cleanup before deleting the profile directory below.
diff --git a/content/browser/web_contents/navigation_entry_impl.cc b/content/browser/web_contents/navigation_entry_impl.cc
index dafc2e0..b904acf 100644
--- a/content/browser/web_contents/navigation_entry_impl.cc
+++ b/content/browser/web_contents/navigation_entry_impl.cc
@@ -50,6 +50,7 @@
is_overriding_user_agent_(false),
is_renderer_initiated_(false),
should_replace_entry_(false),
+ should_clear_history_list_(false),
can_load_local_resources_(false) {
}
@@ -76,6 +77,7 @@
is_overriding_user_agent_(false),
is_renderer_initiated_(is_renderer_initiated),
should_replace_entry_(false),
+ should_clear_history_list_(false),
can_load_local_resources_(false) {
}
@@ -310,8 +312,8 @@
}
void NavigationEntryImpl::SetScreenshotPNGData(
- const std::vector<unsigned char>& png_data) {
- screenshot_ = png_data.empty() ? NULL : new base::RefCountedBytes(png_data);
+ scoped_refptr<base::RefCountedBytes> png_data) {
+ screenshot_ = png_data;
if (screenshot_)
UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size());
}
diff --git a/content/browser/web_contents/navigation_entry_impl.h b/content/browser/web_contents/navigation_entry_impl.h
index 62234bf..c956867 100644
--- a/content/browser/web_contents/navigation_entry_impl.h
+++ b/content/browser/web_contents/navigation_entry_impl.h
@@ -185,11 +185,20 @@
should_replace_entry_ = should_replace_entry;
}
- void SetScreenshotPNGData(const std::vector<unsigned char>& png_data);
+ void SetScreenshotPNGData(scoped_refptr<base::RefCountedBytes> png_data);
const scoped_refptr<base::RefCountedBytes> screenshot() const {
return screenshot_;
}
+ // Whether this (pending) navigation should clear the session history. Resets
+ // to false after commit.
+ bool should_clear_history_list() const {
+ return should_clear_history_list_;
+ }
+ void set_should_clear_history_list(bool should_clear_history_list) {
+ should_clear_history_list_ = should_clear_history_list;
+ }
+
private:
// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
// Session/Tab restore save portions of this class so that it can be recreated
@@ -275,6 +284,13 @@
// doing the redirect).
bool should_replace_entry_;
+ // This is set to true when this entry's navigation should clear the session
+ // history both on the renderer and browser side. The browser side history
+ // won't be cleared until the renderer has committed this navigation. This
+ // entry is not persisted by the session restore system, as it is always
+ // reset to false after commit.
+ bool should_clear_history_list_;
+
// Set when this entry should be able to access local file:// resources. This
// value is not needed after the entry commits and is not persisted.
bool can_load_local_resources_;
diff --git a/content/browser/web_contents/navigation_entry_impl_unittest.cc b/content/browser/web_contents/navigation_entry_impl_unittest.cc
index 00857ed..8bc5de1 100644
--- a/content/browser/web_contents/navigation_entry_impl_unittest.cc
+++ b/content/browser/web_contents/navigation_entry_impl_unittest.cc
@@ -61,23 +61,23 @@
EXPECT_EQ(GURL(), entry1_->GetURL());
EXPECT_EQ(GURL(), entry1_->GetVirtualURL());
- EXPECT_TRUE(entry1_->GetTitleForDisplay("").empty());
+ EXPECT_TRUE(entry1_->GetTitleForDisplay(std::string()).empty());
// Setting URL affects virtual_url and GetTitleForDisplay
entry1_->SetURL(GURL("http://www.google.com"));
EXPECT_EQ(GURL("http://www.google.com"), entry1_->GetURL());
EXPECT_EQ(GURL("http://www.google.com"), entry1_->GetVirtualURL());
EXPECT_EQ(ASCIIToUTF16("www.google.com"),
- entry1_->GetTitleForDisplay(""));
+ entry1_->GetTitleForDisplay(std::string()));
// file:/// URLs should only show the filename.
entry1_->SetURL(GURL("file:///foo/bar baz.txt"));
EXPECT_EQ(ASCIIToUTF16("bar baz.txt"),
- entry1_->GetTitleForDisplay(""));
+ entry1_->GetTitleForDisplay(std::string()));
// Title affects GetTitleForDisplay
entry1_->SetTitle(ASCIIToUTF16("Google"));
- EXPECT_EQ(ASCIIToUTF16("Google"), entry1_->GetTitleForDisplay(""));
+ EXPECT_EQ(ASCIIToUTF16("Google"), entry1_->GetTitleForDisplay(std::string()));
// Setting virtual_url doesn't affect URL
entry2_->SetVirtualURL(GURL("display:url"));
@@ -86,7 +86,7 @@
EXPECT_EQ(GURL("display:url"), entry2_->GetVirtualURL());
// Having a title set in constructor overrides virtual URL
- EXPECT_EQ(ASCIIToUTF16("title"), entry2_->GetTitleForDisplay(""));
+ EXPECT_EQ(ASCIIToUTF16("title"), entry2_->GetTitleForDisplay(std::string()));
// User typed URL is independent of the others
EXPECT_EQ(GURL(), entry1_->GetUserTypedURL());
diff --git a/content/browser/web_contents/render_view_host_manager.cc b/content/browser/web_contents/render_view_host_manager.cc
index 84694be..208829a 100644
--- a/content/browser/web_contents/render_view_host_manager.cc
+++ b/content/browser/web_contents/render_view_host_manager.cc
@@ -197,7 +197,8 @@
// false (meaning the navigation should not proceed), but we'll ignore it
// in this case because it took too long.
if (pending_render_view_host_->are_navigations_suspended())
- pending_render_view_host_->SetNavigationsSuspended(false);
+ pending_render_view_host_->SetNavigationsSuspended(
+ false, base::TimeTicks::Now());
} else {
// The request has been started and paused while we're waiting for the
// unload handler to finish. We'll pretend that it did, by notifying the
@@ -264,36 +265,6 @@
}
}
-void RenderViewHostManager::DidUpdateFrameTree(
- RenderViewHost* render_view_host) {
- // TODO(nasko): This used to be a CHECK_EQ, but it causes more crashes than
- // expected. Changing to if statement and the root cause will be tracked by
- // http://crbug.com/147613.
- if (render_view_host != current_host())
- return;
-
- RenderViewHostImpl* render_view_host_impl = static_cast<RenderViewHostImpl*>(
- render_view_host);
-
- for (RenderViewHostMap::iterator iter = swapped_out_hosts_.begin();
- iter != swapped_out_hosts_.end();
- ++iter) {
- DCHECK_NE(iter->second->GetSiteInstance(),
- current_host()->GetSiteInstance());
-
- // Send updates to the other swapped out RVHs, unless it's the pending RVH
- // (which is in the process of navigating).
- // TODO(nasko): Don't send updates across BrowsingInstances.
- // See http://crbug.com/150855.
- if (iter->second != pending_render_view_host_) {
- iter->second->UpdateFrameTree(
- render_view_host_impl->GetProcess()->GetID(),
- render_view_host_impl->GetRoutingID(),
- render_view_host_impl->frame_tree());
- }
- }
-}
-
void RenderViewHostManager::RendererAbortedProvisionalLoad(
RenderViewHost* render_view_host) {
// We used to cancel the pending renderer here for cross-site downloads.
@@ -346,10 +317,7 @@
// is ok to do nothing here.
if (pending_render_view_host_ &&
pending_render_view_host_->are_navigations_suspended()) {
- pending_render_view_host_->SetNavigationsSuspended(false);
- if (!proceed_time.is_null()) {
- pending_render_view_host_->SetNavigationStartTime(proceed_time);
- }
+ pending_render_view_host_->SetNavigationsSuspended(false, proceed_time);
}
} else {
// Current page says to cancel.
@@ -407,9 +375,13 @@
}
bool RenderViewHostManager::ShouldTransitionCrossSite() {
+ // False in the single-process mode, as it makes RVHs to accumulate
+ // in swapped_out_hosts_.
// True if we are using process-per-site-instance (default) or
// process-per-site (kProcessPerSite).
- return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab);
+ return
+ !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) &&
+ !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab);
}
bool RenderViewHostManager::ShouldSwapProcessesForNavigation(
@@ -480,10 +452,14 @@
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())
@@ -664,9 +640,6 @@
if (success) {
// Don't show the view until we get a DidNavigate from it.
new_render_view_host->GetView()->Hide();
-
- // TODO(nasko): Send a frame tree update when creating the RV
- // once http://crbug.com/153701 is fixed.
} else if (!swapped_out) {
CancelPending();
}
@@ -701,9 +674,9 @@
// |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or
// leave |web_ui_| as is if reusing it.
DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get()));
- if (pending_web_ui_.get())
+ if (pending_web_ui_)
web_ui_.reset(pending_web_ui_.release());
- else if (!pending_and_current_web_ui_.get())
+ else if (!pending_and_current_web_ui_)
web_ui_.reset();
// It's possible for the pending_render_view_host_ to be NULL when we aren't
@@ -863,26 +836,35 @@
render_view_host_->Send(
new ViewMsg_Stop(render_view_host_->GetRoutingID()));
+ // We need to wait until the beforeunload handler has run, unless we are
+ // transferring an existing request (in which case it has already run).
// Suspend the new render view (i.e., don't let it send the cross-site
// Navigate message) until we hear back from the old renderer's
- // onbeforeunload handler. If the handler returns false, we'll have to
+ // beforeunload handler. If the handler returns false, we'll have to
// cancel the request.
DCHECK(!pending_render_view_host_->are_navigations_suspended());
- pending_render_view_host_->SetNavigationsSuspended(true);
+ bool is_transfer =
+ entry.transferred_global_request_id() != GlobalRequestID();
+ if (!is_transfer) {
+ pending_render_view_host_->SetNavigationsSuspended(true,
+ base::TimeTicks());
+ }
// Tell the CrossSiteRequestManager that this RVH has a pending cross-site
// request, so that ResourceDispatcherHost will know to tell us to run the
- // old page's onunload handler before it sends the response.
+ // old page's unload handler before it sends the response.
pending_render_view_host_->SetHasPendingCrossSiteRequest(true, -1);
// We now have a pending RVH.
DCHECK(!cross_navigation_pending_);
cross_navigation_pending_ = true;
- // Tell the old render view to run its onbeforeunload handler, since it
+ // Unless we are transferring an existing request, we should now
+ // tell the old render view to run its beforeunload handler, since it
// doesn't otherwise know that the cross-site request is happening. This
// will trigger a call to ShouldClosePage with the reply.
- render_view_host_->FirePageBeforeUnload(true);
+ if (!is_transfer)
+ render_view_host_->FirePageBeforeUnload(true);
return pending_render_view_host_;
} else {
@@ -929,7 +911,7 @@
// swap it back in and then canceled. If so, make sure it gets swapped out
// again. If it's not on the swapped out list (e.g., aborting a pending
// load), then it's safe to shut down.
- if (IsSwappedOut(pending_render_view_host)) {
+ if (IsOnSwappedOutList(pending_render_view_host)) {
// Any currently suspended navigations are no longer needed.
pending_render_view_host->CancelSuspendedNavigations();
@@ -973,12 +955,16 @@
}
}
-bool RenderViewHostManager::IsSwappedOut(RenderViewHost* rvh) {
+bool RenderViewHostManager::IsOnSwappedOutList(RenderViewHost* rvh) const {
if (!rvh->GetSiteInstance())
return false;
- return swapped_out_hosts_.find(rvh->GetSiteInstance()->GetId()) !=
- swapped_out_hosts_.end();
+ RenderViewHostMap::const_iterator iter = swapped_out_hosts_.find(
+ rvh->GetSiteInstance()->GetId());
+ if (iter == swapped_out_hosts_.end())
+ return false;
+
+ return iter->second == rvh;
}
RenderViewHostImpl* RenderViewHostManager::GetSwappedOutRenderViewHost(
diff --git a/content/browser/web_contents/render_view_host_manager.h b/content/browser/web_contents/render_view_host_manager.h
index 3e31c08..d8b4001 100644
--- a/content/browser/web_contents/render_view_host_manager.h
+++ b/content/browser/web_contents/render_view_host_manager.h
@@ -171,9 +171,6 @@
// Called when a renderer sets its opener to null.
void DidDisownOpener(RenderViewHost* render_view_host);
- // Called when a renderer has navigated and when its frame tree is updated.
- void DidUpdateFrameTree(RenderViewHost* render_view_host);
-
// Helper method to create a RenderViewHost. If |swapped_out| is true, it
// will be initially placed on the swapped out hosts list. Otherwise, it
// will be used for a pending cross-site navigation.
@@ -221,7 +218,7 @@
// Returns whether the given RenderViewHost is on the list of swapped out
// RenderViewHosts.
- bool IsSwappedOut(RenderViewHost* rvh);
+ bool IsOnSwappedOutList(RenderViewHost* rvh) const;
// Returns the swapped out RenderViewHost for the given SiteInstance, if any.
RenderViewHostImpl* GetSwappedOutRenderViewHost(SiteInstance* instance);
@@ -326,6 +323,6 @@
DISALLOW_COPY_AND_ASSIGN(RenderViewHostManager);
};
-} // namespace content
+} // namespace content
#endif // CONTENT_BROWSER_WEB_CONTENTS_RENDER_VIEW_HOST_MANAGER_H_
diff --git a/content/browser/web_contents/render_view_host_manager_unittest.cc b/content/browser/web_contents/render_view_host_manager_unittest.cc
index f9f3f09..c4fd94a 100644
--- a/content/browser/web_contents/render_view_host_manager_unittest.cc
+++ b/content/browser/web_contents/render_view_host_manager_unittest.cc
@@ -130,7 +130,7 @@
// a regression test for bug 9364.
TEST_F(RenderViewHostManagerTest, NewTabPageProcesses) {
set_should_create_webui(true);
- BrowserThreadImpl ui_thread(BrowserThread::UI, MessageLoop::current());
+ BrowserThreadImpl ui_thread(BrowserThread::UI, base::MessageLoop::current());
const GURL kChromeUrl("chrome://foo");
const GURL kDestUrl("http://www.google.com/");
@@ -195,7 +195,7 @@
// for synchronous messages, which cannot be ignored without leaving the
// renderer in a stuck state. See http://crbug.com/93427.
TEST_F(RenderViewHostManagerTest, FilterMessagesWhileSwappedOut) {
- BrowserThreadImpl ui_thread(BrowserThread::UI, MessageLoop::current());
+ BrowserThreadImpl ui_thread(BrowserThread::UI, base::MessageLoop::current());
const GURL kChromeURL("chrome://foo");
const GURL kDestUrl("http://www.google.com/");
@@ -272,7 +272,7 @@
// EnableViewSourceMode message is sent on every navigation regardless
// RenderView is being newly created or reused.
TEST_F(RenderViewHostManagerTest, AlwaysSendEnableViewSourceMode) {
- BrowserThreadImpl ui_thread(BrowserThread::UI, MessageLoop::current());
+ BrowserThreadImpl ui_thread(BrowserThread::UI, base::MessageLoop::current());
const GURL kChromeUrl("chrome://foo");
const GURL kUrl("view-source:http://foo");
@@ -288,8 +288,9 @@
controller().LoadURL(
kUrl, Referrer(), PAGE_TRANSITION_TYPED, std::string());
// Simulate response from RenderView for FirePageBeforeUnload.
+ base::TimeTicks now = base::TimeTicks::Now();
test_rvh()->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(
- rvh()->GetRoutingID(), true, base::TimeTicks(), base::TimeTicks()));
+ rvh()->GetRoutingID(), true, now, now));
ASSERT_TRUE(pending_rvh()); // New pending RenderViewHost will be created.
RenderViewHost* last_rvh = pending_rvh();
int32 new_id = contents()->GetMaxPageIDForSiteInstance(
@@ -590,7 +591,7 @@
// Tests WebUI creation.
TEST_F(RenderViewHostManagerTest, WebUI) {
set_should_create_webui(true);
- BrowserThreadImpl ui_thread(BrowserThread::UI, MessageLoop::current());
+ BrowserThreadImpl ui_thread(BrowserThread::UI, base::MessageLoop::current());
SiteInstance* instance = SiteInstance::Create(browser_context());
scoped_ptr<TestWebContents> web_contents(
@@ -814,20 +815,20 @@
rvh2->GetSiteInstance()));
// Ensure rvh1 is placed on swapped out list of the current tab.
- EXPECT_TRUE(manager->IsSwappedOut(rvh1));
+ EXPECT_TRUE(manager->IsOnSwappedOutList(rvh1));
EXPECT_EQ(rvh1,
manager->GetSwappedOutRenderViewHost(rvh1->GetSiteInstance()));
// Ensure a swapped out RVH is created in the first opener tab.
TestRenderViewHost* opener1_rvh = static_cast<TestRenderViewHost*>(
opener1_manager->GetSwappedOutRenderViewHost(rvh2->GetSiteInstance()));
- EXPECT_TRUE(opener1_manager->IsSwappedOut(opener1_rvh));
+ EXPECT_TRUE(opener1_manager->IsOnSwappedOutList(opener1_rvh));
EXPECT_TRUE(opener1_rvh->is_swapped_out());
// Ensure a swapped out RVH is created in the second opener tab.
TestRenderViewHost* opener2_rvh = static_cast<TestRenderViewHost*>(
opener2_manager->GetSwappedOutRenderViewHost(rvh2->GetSiteInstance()));
- EXPECT_TRUE(opener2_manager->IsSwappedOut(opener2_rvh));
+ EXPECT_TRUE(opener2_manager->IsOnSwappedOutList(opener2_rvh));
EXPECT_TRUE(opener2_rvh->is_swapped_out());
// Navigate to a cross-BrowsingInstance URL.
@@ -879,7 +880,7 @@
// Ensure a swapped out RVH is created in the first opener tab.
TestRenderViewHost* opener1_rvh = static_cast<TestRenderViewHost*>(
opener1_manager->GetSwappedOutRenderViewHost(rvh2->GetSiteInstance()));
- EXPECT_TRUE(opener1_manager->IsSwappedOut(opener1_rvh));
+ EXPECT_TRUE(opener1_manager->IsOnSwappedOutList(opener1_rvh));
EXPECT_TRUE(opener1_rvh->is_swapped_out());
// Ensure the new RVH has WebUI bindings.
diff --git a/content/browser/web_contents/touch_editable_impl_aura.cc b/content/browser/web_contents/touch_editable_impl_aura.cc
new file mode 100644
index 0000000..d782b8c
--- /dev/null
+++ b/content/browser/web_contents/touch_editable_impl_aura.cc
@@ -0,0 +1,310 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_contents/touch_editable_impl_aura.h"
+
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_aura.h"
+#include "content/common/view_messages.h"
+#include "content/public/browser/render_widget_host.h"
+#include "grit/ui_strings.h"
+#include "ui/aura/client/activation_client.h"
+#include "ui/aura/client/screen_position_client.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/window.h"
+#include "ui/base/clipboard/clipboard.h"
+#include "ui/base/range/range.h"
+#include "ui/base/ui_base_switches_util.h"
+
+namespace content {
+
+////////////////////////////////////////////////////////////////////////////////
+// TouchEditableImplAura, public:
+
+TouchEditableImplAura::~TouchEditableImplAura() {
+ Cleanup();
+}
+
+// static
+TouchEditableImplAura* TouchEditableImplAura::Create() {
+ if (switches::IsTouchEditingEnabled())
+ return new TouchEditableImplAura();
+ return NULL;
+}
+
+void TouchEditableImplAura::AttachToView(RenderWidgetHostViewAura* view) {
+ if (rwhva_ == view)
+ return;
+
+ Cleanup();
+ if (!view)
+ return;
+
+ rwhva_ = view;
+ rwhva_->set_touch_editing_client(this);
+}
+
+void TouchEditableImplAura::UpdateEditingController() {
+ if (!rwhva_)
+ return;
+
+ // If touch editing handles were not visible, we bring them up only if
+ // there is non-zero selection on the page. And the current event is a
+ // gesture event (we dont want to show handles if the user is selecting
+ // using mouse or keyboard).
+ if (selection_gesture_in_process_ &&
+ selection_anchor_rect_ != selection_focus_rect_)
+ StartTouchEditing();
+
+ if (text_input_type_ != ui::TEXT_INPUT_TYPE_NONE ||
+ selection_anchor_rect_ != selection_focus_rect_) {
+ if (touch_selection_controller_)
+ touch_selection_controller_->SelectionChanged();
+ } else {
+ EndTouchEditing();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TouchEditableImplAura, RenderWidgetHostViewAura::TouchEditingClient
+// implementation:
+
+void TouchEditableImplAura::StartTouchEditing() {
+ if (!touch_selection_controller_) {
+ touch_selection_controller_.reset(
+ ui::TouchSelectionController::create(this));
+ }
+ if (touch_selection_controller_)
+ touch_selection_controller_->SelectionChanged();
+}
+
+void TouchEditableImplAura::EndTouchEditing() {
+ if (touch_selection_controller_) {
+ if (touch_selection_controller_->IsHandleDragInProgress())
+ touch_selection_controller_->SelectionChanged();
+ else
+ touch_selection_controller_.reset();
+ }
+}
+
+void TouchEditableImplAura::OnSelectionOrCursorChanged(const gfx::Rect& anchor,
+ const gfx::Rect& focus) {
+ selection_anchor_rect_ = anchor;
+ selection_focus_rect_ = focus;
+ UpdateEditingController();
+}
+
+void TouchEditableImplAura::OnTextInputTypeChanged(ui::TextInputType type) {
+ text_input_type_ = type;
+}
+
+bool TouchEditableImplAura::HandleInputEvent(const ui::Event* event) {
+ DCHECK(rwhva_);
+ if (event->IsTouchEvent())
+ return false;
+
+ if (!event->IsGestureEvent()) {
+ EndTouchEditing();
+ return false;
+ }
+
+ const ui::GestureEvent* gesture_event =
+ static_cast<const ui::GestureEvent*>(event);
+ switch (event->type()) {
+ case ui::ET_GESTURE_TAP:
+ if (gesture_event->details().tap_count() > 1)
+ selection_gesture_in_process_ = true;
+ // When the user taps, we want to show touch editing handles if user
+ // tapped on selected text.
+ if (selection_anchor_rect_ != selection_focus_rect_) {
+ // UnionRects only works for rects with non-zero width.
+ gfx::Rect anchor(selection_anchor_rect_.origin(),
+ gfx::Size(1, selection_anchor_rect_.height()));
+ gfx::Rect focus(selection_focus_rect_.origin(),
+ gfx::Size(1, selection_focus_rect_.height()));
+ gfx::Rect selection_rect = gfx::UnionRects(anchor, focus);
+ if (selection_rect.Contains(gesture_event->location())) {
+ StartTouchEditing();
+ return true;
+ }
+ }
+ break;
+ case ui::ET_GESTURE_LONG_PRESS:
+ selection_gesture_in_process_ = true;
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+void TouchEditableImplAura::GestureEventAck(int gesture_event_type) {
+ DCHECK(rwhva_);
+ if (gesture_event_type == WebKit::WebInputEvent::GestureTap &&
+ text_input_type_ != ui::TEXT_INPUT_TYPE_NONE) {
+ StartTouchEditing();
+ if (touch_selection_controller_)
+ touch_selection_controller_->SelectionChanged();
+ }
+
+ if (gesture_event_type == WebKit::WebInputEvent::GestureLongPress ||
+ gesture_event_type == WebKit::WebInputEvent::GestureTap)
+ selection_gesture_in_process_ = false;
+}
+
+void TouchEditableImplAura::OnViewDestroyed() {
+ Cleanup();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TouchEditableImplAura, ui::TouchEditable implementation:
+
+void TouchEditableImplAura::SelectRect(const gfx::Point& start,
+ const gfx::Point& end) {
+ if (!rwhva_)
+ return;
+
+ RenderWidgetHostImpl* host = RenderWidgetHostImpl::From(
+ rwhva_->GetRenderWidgetHost());
+ host->SelectRange(start, end);
+}
+
+void TouchEditableImplAura::MoveCaretTo(const gfx::Point& point) {
+ if (!rwhva_)
+ return;
+
+ RenderWidgetHostImpl* host = RenderWidgetHostImpl::From(
+ rwhva_->GetRenderWidgetHost());
+ host->MoveCaret(point);
+}
+
+void TouchEditableImplAura::GetSelectionEndPoints(gfx::Rect* p1,
+ gfx::Rect* p2) {
+ *p1 = selection_anchor_rect_;
+ *p2 = selection_focus_rect_;
+}
+
+gfx::Rect TouchEditableImplAura::GetBounds() {
+ return rwhva_ ? rwhva_->GetNativeView()->bounds() : gfx::Rect();
+}
+
+gfx::NativeView TouchEditableImplAura::GetNativeView() {
+ return rwhva_ ? rwhva_->GetNativeView()->GetRootWindow() : NULL;
+}
+
+void TouchEditableImplAura::ConvertPointToScreen(gfx::Point* point) {
+ if (!rwhva_)
+ return;
+ aura::Window* window = rwhva_->GetNativeView();
+ aura::client::ScreenPositionClient* screen_position_client =
+ aura::client::GetScreenPositionClient(window->GetRootWindow());
+ if (screen_position_client)
+ screen_position_client->ConvertPointToScreen(window, point);
+}
+
+void TouchEditableImplAura::ConvertPointFromScreen(gfx::Point* point) {
+ if (!rwhva_)
+ return;
+ aura::Window* window = rwhva_->GetNativeView();
+ aura::client::ScreenPositionClient* screen_position_client =
+ aura::client::GetScreenPositionClient(window->GetRootWindow());
+ if (screen_position_client)
+ screen_position_client->ConvertPointFromScreen(window, point);
+}
+
+bool TouchEditableImplAura::DrawsHandles() {
+ return false;
+}
+
+void TouchEditableImplAura::OpenContextMenu(const gfx::Point anchor) {
+ if (!rwhva_)
+ return;
+ RenderWidgetHost* host = rwhva_->GetRenderWidgetHost();
+ host->Send(new ViewMsg_ShowContextMenu(host->GetRoutingID()));
+ EndTouchEditing();
+}
+
+bool TouchEditableImplAura::IsCommandIdChecked(int command_id) const {
+ NOTREACHED();
+ return false;
+}
+
+bool TouchEditableImplAura::IsCommandIdEnabled(int command_id) const {
+ if (!rwhva_)
+ return false;
+ bool editable = rwhva_->GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE;
+ ui::Range selection_range;
+ rwhva_->GetSelectionRange(&selection_range);
+ bool has_selection = !selection_range.is_empty();
+ switch (command_id) {
+ case IDS_APP_CUT:
+ return editable && has_selection;
+ case IDS_APP_COPY:
+ return has_selection;
+ case IDS_APP_PASTE: {
+ string16 result;
+ ui::Clipboard::GetForCurrentThread()->ReadText(
+ ui::Clipboard::BUFFER_STANDARD, &result);
+ return editable && !result.empty();
+ }
+ case IDS_APP_DELETE:
+ return editable && has_selection;
+ case IDS_APP_SELECT_ALL:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool TouchEditableImplAura::GetAcceleratorForCommandId(
+ int command_id,
+ ui::Accelerator* accelerator) {
+ return false;
+}
+
+void TouchEditableImplAura::ExecuteCommand(int command_id, int event_flags) {
+ if (!rwhva_)
+ return;
+ RenderWidgetHost* host = rwhva_->GetRenderWidgetHost();
+ switch (command_id) {
+ case IDS_APP_CUT:
+ host->Cut();
+ break;
+ case IDS_APP_COPY:
+ host->Copy();
+ break;
+ case IDS_APP_PASTE:
+ host->Paste();
+ break;
+ case IDS_APP_DELETE:
+ host->Delete();
+ break;
+ case IDS_APP_SELECT_ALL:
+ host->SelectAll();
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ EndTouchEditing();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TouchEditableImplAura, private:
+
+TouchEditableImplAura::TouchEditableImplAura()
+ : text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
+ rwhva_(NULL),
+ selection_gesture_in_process_(false) {
+}
+
+void TouchEditableImplAura::Cleanup() {
+ if (rwhva_) {
+ rwhva_->set_touch_editing_client(NULL);
+ rwhva_ = NULL;
+ }
+ touch_selection_controller_.reset();
+}
+
+} // namespace content
diff --git a/content/browser/web_contents/touch_editable_impl_aura.h b/content/browser/web_contents/touch_editable_impl_aura.h
new file mode 100644
index 0000000..f29dfd3
--- /dev/null
+++ b/content/browser/web_contents/touch_editable_impl_aura.h
@@ -0,0 +1,95 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEB_CONTENTS_TOUCH_EDITABLE_IMPL_AURA_H_
+#define CONTENT_BROWSER_WEB_CONTENTS_TOUCH_EDITABLE_IMPL_AURA_H_
+
+#include <deque>
+#include <map>
+
+#include "content/browser/renderer_host/render_widget_host_view_aura.h"
+#include "ui/aura/window_observer.h"
+#include "ui/base/touch/touch_editing_controller.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/point.h"
+#include "ui/gfx/rect.h"
+
+namespace ui {
+class Accelerator;
+}
+
+namespace content {
+class TouchEditableImplAuraTest;
+
+// Aura specific implementation of ui::TouchEditable for a RenderWidgetHostView.
+class CONTENT_EXPORT TouchEditableImplAura
+ : public ui::TouchEditable,
+ public NON_EXPORTED_BASE(RenderWidgetHostViewAura::TouchEditingClient) {
+ public:
+ virtual ~TouchEditableImplAura();
+
+ static TouchEditableImplAura* Create();
+
+ void AttachToView(RenderWidgetHostViewAura* view);
+
+ // Updates the |touch_selection_controller_| or ends touch editing session
+ // depending on the current selection and cursor state.
+ void UpdateEditingController();
+
+ // Overridden from RenderWidgetHostViewAura::TouchEditingClient.
+ virtual void StartTouchEditing() OVERRIDE;
+ virtual void EndTouchEditing() OVERRIDE;
+ virtual void OnSelectionOrCursorChanged(const gfx::Rect& anchor,
+ const gfx::Rect& focus) OVERRIDE;
+ virtual void OnTextInputTypeChanged(ui::TextInputType type) OVERRIDE;
+ virtual bool HandleInputEvent(const ui::Event* event) OVERRIDE;
+ virtual void GestureEventAck(int gesture_event_type) OVERRIDE;
+ virtual void OnViewDestroyed() OVERRIDE;
+
+ // Overridden from ui::TouchEditable:
+ virtual void SelectRect(const gfx::Point& start,
+ const gfx::Point& end) OVERRIDE;
+ virtual void MoveCaretTo(const gfx::Point& point) OVERRIDE;
+ virtual void GetSelectionEndPoints(gfx::Rect* p1, gfx::Rect* p2) OVERRIDE;
+ virtual gfx::Rect GetBounds() OVERRIDE;
+ virtual gfx::NativeView GetNativeView() OVERRIDE;
+ virtual void ConvertPointToScreen(gfx::Point* point) OVERRIDE;
+ virtual void ConvertPointFromScreen(gfx::Point* point) OVERRIDE;
+ virtual bool DrawsHandles() OVERRIDE;
+ virtual void OpenContextMenu(const gfx::Point anchor) OVERRIDE;
+ virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
+ virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
+ virtual bool GetAcceleratorForCommandId(
+ int command_id,
+ ui::Accelerator* accelerator) OVERRIDE;
+ virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
+
+ protected:
+ TouchEditableImplAura();
+
+ private:
+ friend class TouchEditableImplAuraTest;
+
+ void Cleanup();
+
+ // Rectangles for the selection anchor and focus.
+ gfx::Rect selection_anchor_rect_;
+ gfx::Rect selection_focus_rect_;
+
+ // The current text input type.
+ ui::TextInputType text_input_type_;
+
+ RenderWidgetHostViewAura* rwhva_;
+ scoped_ptr<ui::TouchSelectionController> touch_selection_controller_;
+
+ // True if |rwhva_| is currently handling a gesture that could result in a
+ // change in selection.
+ bool selection_gesture_in_process_;
+
+ DISALLOW_COPY_AND_ASSIGN(TouchEditableImplAura);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEB_CONTENTS_TOUCH_EDITABLE_IMPL_AURA_H_
diff --git a/content/browser/web_contents/touch_editable_impl_aura_browsertest.cc b/content/browser/web_contents/touch_editable_impl_aura_browsertest.cc
new file mode 100644
index 0000000..12fa687
--- /dev/null
+++ b/content/browser/web_contents/touch_editable_impl_aura_browsertest.cc
@@ -0,0 +1,285 @@
+// 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/web_contents/touch_editable_impl_aura.h"
+
+#include "base/command_line.h"
+#include "base/run_loop.h"
+#include "base/test/test_timeouts.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/web_contents/web_contents_view_aura.h"
+#include "content/public/browser/web_contents_view.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/shell.h"
+#include "content/test/content_browser_test.h"
+#include "content/test/content_browser_test_utils.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/test/event_generator.h"
+#include "ui/aura/window.h"
+#include "ui/base/events/event_utils.h"
+#include "ui/base/ui_base_switches.h"
+#include "ui/compositor/scoped_animation_duration_scale_mode.h"
+
+namespace content {
+
+class TestTouchEditableImplAura : public TouchEditableImplAura {
+ public:
+ TestTouchEditableImplAura()
+ : selection_changed_callback_arrived_(false),
+ waiting_for_selection_changed_callback_(false),
+ gesture_ack_callback_arrived_(false),
+ waiting_for_gesture_ack_callback_(false) {}
+
+ void Reset() {
+ selection_changed_callback_arrived_ = false;
+ waiting_for_selection_changed_callback_ = false;
+ gesture_ack_callback_arrived_ = false;
+ waiting_for_gesture_ack_callback_ = false;
+ }
+
+ void OnSelectionOrCursorChanged(const gfx::Rect& anchor,
+ const gfx::Rect& focus) OVERRIDE {
+ selection_changed_callback_arrived_ = true;
+ TouchEditableImplAura::OnSelectionOrCursorChanged(anchor, focus);
+ if (waiting_for_selection_changed_callback_)
+ selection_changed_wait_run_loop_->Quit();
+ }
+
+ void GestureEventAck(int gesture_event_type) OVERRIDE {
+ gesture_ack_callback_arrived_ = true;
+ TouchEditableImplAura::GestureEventAck(gesture_event_type);
+ if (waiting_for_gesture_ack_callback_)
+ gesture_ack_wait_run_loop_->Quit();
+ }
+
+ void WaitForSelectionChangeCallback() {
+ if (selection_changed_callback_arrived_)
+ return;
+ waiting_for_selection_changed_callback_ = true;
+ selection_changed_wait_run_loop_.reset(new base::RunLoop());
+ selection_changed_wait_run_loop_->Run();
+ }
+
+ void WaitForGestureAck() {
+ if (gesture_ack_callback_arrived_)
+ return;
+ waiting_for_gesture_ack_callback_ = true;
+ gesture_ack_wait_run_loop_.reset(new base::RunLoop());
+ gesture_ack_wait_run_loop_->Run();
+ }
+
+ protected:
+ virtual ~TestTouchEditableImplAura() {}
+
+ private:
+ bool selection_changed_callback_arrived_;
+ bool waiting_for_selection_changed_callback_;
+ bool gesture_ack_callback_arrived_;
+ bool waiting_for_gesture_ack_callback_;
+ scoped_ptr<base::RunLoop> selection_changed_wait_run_loop_;
+ scoped_ptr<base::RunLoop> gesture_ack_wait_run_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestTouchEditableImplAura);
+};
+
+class TouchEditableImplAuraTest : public ContentBrowserTest {
+ public:
+ TouchEditableImplAuraTest() {}
+
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ command_line->AppendSwitch(switches::kEnableTouchEditing);
+ }
+
+ // Executes the javascript synchronously and makes sure the returned value is
+ // freed properly.
+ void ExecuteSyncJSFunction(RenderViewHost* rvh, const std::string& jscript) {
+ scoped_ptr<base::Value> value =
+ content::ExecuteScriptAndGetValue(rvh, jscript);
+ }
+
+ // Starts the test server and navigates to the given url. Sets a large enough
+ // size to the root window. Returns after the navigation to the url is
+ // complete.
+ void StartTestWithPage(const std::string& url) {
+ ASSERT_TRUE(test_server()->Start());
+ GURL test_url(test_server()->GetURL(url));
+ NavigateToURL(shell(), test_url);
+ aura::Window* content =
+ shell()->web_contents()->GetView()->GetContentNativeView();
+ content->GetRootWindow()->SetHostSize(gfx::Size(800, 600));
+ }
+
+ void TestTouchSelectionOriginatingFromWebpage() {
+ ASSERT_NO_FATAL_FAILURE(
+ StartTestWithPage("files/touch_selection.html"));
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
+ web_contents->GetRenderViewHost());
+ WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>(
+ web_contents->GetView());
+ TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura;
+ view_aura->SetTouchEditableForTest(touch_editable);
+ RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
+ web_contents->GetRenderWidgetHostView());
+ aura::Window* content = web_contents->GetView()->GetContentNativeView();
+ aura::test::EventGenerator generator(content->GetRootWindow(), content);
+ gfx::Rect bounds = content->GetBoundsInRootWindow();
+
+ touch_editable->Reset();
+ ExecuteSyncJSFunction(view_host, "select_all_text()");
+ touch_editable->WaitForSelectionChangeCallback();
+
+ // Tap inside selection to bring up selection handles.
+ generator.GestureTapAt(gfx::Point(bounds.x() + 10, bounds.y() + 10));
+ EXPECT_EQ(touch_editable->rwhva_, rwhva);
+
+ scoped_ptr<base::Value> value =
+ content::ExecuteScriptAndGetValue(view_host, "get_selection()");
+ std::string selection;
+ value->GetAsString(&selection);
+
+ // Check if selection handles are showing.
+ EXPECT_TRUE(touch_editable->touch_selection_controller_.get());
+ EXPECT_STREQ("Some text we can select", selection.c_str());
+
+ // Lets move the handles a bit to modify the selection
+ touch_editable->Reset();
+ generator.GestureScrollSequence(
+ gfx::Point(10, 37),
+ gfx::Point(30, 37),
+ base::TimeDelta::FromMilliseconds(20),
+ 1);
+ EXPECT_TRUE(touch_editable->touch_selection_controller_.get());
+ value = content::ExecuteScriptAndGetValue(view_host, "get_selection()");
+ value->GetAsString(&selection);
+
+ // It is hard to tell what exactly the selection would be now. But it would
+ // definitely be less than whatever was selected before.
+ EXPECT_GT(std::strlen("Some text we can select"), selection.size());
+ }
+
+ void TestTouchSelectionOnLongPress() {
+ ASSERT_NO_FATAL_FAILURE(
+ StartTestWithPage("files/touch_selection.html"));
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
+ web_contents->GetRenderViewHost());
+ WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>(
+ web_contents->GetView());
+ TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura;
+ view_aura->SetTouchEditableForTest(touch_editable);
+ RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
+ web_contents->GetRenderWidgetHostView());
+ aura::Window* content = web_contents->GetView()->GetContentNativeView();
+ aura::test::EventGenerator generator(content->GetRootWindow(), content);
+ gfx::Rect bounds = content->GetBoundsInRootWindow();
+ EXPECT_EQ(touch_editable->rwhva_, rwhva);
+
+ // Long press to select word.
+ ui::GestureEvent long_press(ui::ET_GESTURE_LONG_PRESS,
+ 10,
+ 10,
+ 0,
+ ui::EventTimeForNow(),
+ ui::GestureEventDetails(
+ ui::ET_GESTURE_LONG_PRESS, 0, 0),
+ 1);
+ touch_editable->Reset();
+ rwhva->OnGestureEvent(&long_press);
+ touch_editable->WaitForSelectionChangeCallback();
+
+ // Check if selection handles are showing.
+ ui::TouchSelectionController* controller =
+ touch_editable->touch_selection_controller_.get();
+ EXPECT_TRUE(controller);
+
+ scoped_ptr<base::Value> value =
+ content::ExecuteScriptAndGetValue(view_host, "get_selection()");
+ std::string selection;
+ value->GetAsString(&selection);
+ EXPECT_STREQ("Some", selection.c_str());
+ }
+
+ void TestTouchCursorInTextfield() {
+ ASSERT_NO_FATAL_FAILURE(
+ StartTestWithPage("files/touch_selection.html"));
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
+ web_contents->GetRenderViewHost());
+ WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>(
+ web_contents->GetView());
+ TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura;
+ view_aura->SetTouchEditableForTest(touch_editable);
+ RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
+ web_contents->GetRenderWidgetHostView());
+ aura::Window* content = web_contents->GetView()->GetContentNativeView();
+ aura::test::EventGenerator generator(content->GetRootWindow(), content);
+ gfx::Rect bounds = content->GetBoundsInRootWindow();
+ EXPECT_EQ(touch_editable->rwhva_, rwhva);
+ ExecuteSyncJSFunction(view_host, "focus_textfield()");
+
+ // Tap textfield
+ touch_editable->Reset();
+ generator.GestureTapAt(gfx::Point(bounds.x() + 50, bounds.y() + 40));
+ touch_editable->WaitForGestureAck(); // Wait for Tap Down Ack
+ touch_editable->Reset();
+ touch_editable->WaitForGestureAck(); // Wait for Tap Ack.
+
+ // Check if cursor handle is showing.
+ ui::TouchSelectionController* controller =
+ touch_editable->touch_selection_controller_.get();
+ EXPECT_NE(ui::TEXT_INPUT_TYPE_NONE, touch_editable->text_input_type_);
+ EXPECT_TRUE(controller);
+
+ scoped_ptr<base::Value> value =
+ content::ExecuteScriptAndGetValue(view_host, "get_cursor_position()");
+ int cursor_pos = -1;
+ value->GetAsInteger(&cursor_pos);
+ EXPECT_NE(-1, cursor_pos);
+
+ // Move the cursor handle.
+ generator.GestureScrollSequence(
+ gfx::Point(50, 59),
+ gfx::Point(10, 59),
+ base::TimeDelta::FromMilliseconds(20),
+ 1);
+ EXPECT_TRUE(touch_editable->touch_selection_controller_.get());
+ value = content::ExecuteScriptAndGetValue(
+ view_host, "get_cursor_position()");
+ int new_cursor_pos = -1;
+ value->GetAsInteger(&new_cursor_pos);
+ EXPECT_NE(-1, new_cursor_pos);
+ // Cursor should have moved.
+ EXPECT_NE(new_cursor_pos, cursor_pos);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TouchEditableImplAuraTest);
+};
+
+IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest,
+ TouchSelectionOriginatingFromWebpageTest) {
+ TestTouchSelectionOriginatingFromWebpage();
+}
+
+IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest,
+ TouchSelectionOnLongPressTest) {
+ TestTouchSelectionOnLongPress();
+}
+
+// TODO(miu): Disabled test due to flakiness. http://crbug.com/235991
+IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest,
+ DISABLED_TouchCursorInTextfieldTest) {
+ TestTouchCursorInTextfield();
+}
+
+} // namespace content
diff --git a/content/browser/web_contents/web_contents_drag_win.cc b/content/browser/web_contents/web_contents_drag_win.cc
index 0b7fac4..8174c97 100644
--- a/content/browser/web_contents/web_contents_drag_win.cc
+++ b/content/browser/web_contents/web_contents_drag_win.cc
@@ -46,6 +46,8 @@
namespace content {
namespace {
+bool run_do_drag_drop = true;
+
HHOOK msg_hook = NULL;
DWORD drag_out_thread_id = 0;
bool mouse_up_received = false;
@@ -176,7 +178,7 @@
DCHECK(!drag_drop_thread_.get());
drag_drop_thread_.reset(new DragDropThread(this));
base::Thread::Options options;
- options.message_loop_type = MessageLoop::TYPE_UI;
+ options.message_loop_type = base::MessageLoop::TYPE_UI;
if (drag_drop_thread_->StartWithOptions(options)) {
drag_drop_thread_->message_loop()->PostTask(
FROM_HERE,
@@ -353,18 +355,22 @@
// We need to enable recursive tasks on the message loop so we can get
// updates while in the system DoDragDrop loop.
- DWORD effect;
- {
+ DWORD effect = DROPEFFECT_NONE;
+ if (run_do_drag_drop) {
// Keep a reference count such that |drag_source_| will not get deleted
// if the contents view window is gone in the nested message loop invoked
// from DoDragDrop.
- scoped_refptr<WebDragSource> retain_this(drag_source_);
+ scoped_refptr<WebDragSource> retain_source(drag_source_);
+ retain_source->set_data(&data);
+ data.SetInDragLoop(true);
- MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
+ base::MessageLoop::ScopedNestableTaskAllower allow(
+ base::MessageLoop::current());
DoDragDrop(ui::OSExchangeDataProviderWin::GetIDataObject(data),
drag_source_,
WebDragOpMaskToWinDragOpMask(ops),
&effect);
+ retain_source->set_data(NULL);
}
// Bail out immediately if the contents view window is gone.
@@ -430,4 +436,9 @@
base::Bind(&WebContentsDragWin::CloseThread, this));
}
+// static
+void WebContentsDragWin::DisableDragDropForTesting() {
+ run_do_drag_drop = false;
+}
+
} // namespace content
diff --git a/content/browser/web_contents/web_contents_drag_win.h b/content/browser/web_contents/web_contents_drag_win.h
index 12f07cc..b7ffb30 100644
--- a/content/browser/web_contents/web_contents_drag_win.h
+++ b/content/browser/web_contents/web_contents_drag_win.h
@@ -56,6 +56,9 @@
virtual void OnWaitForData();
virtual void OnDataObjectDisposed();
+ // Don't invoke OLE DoDragDrop during tests.
+ static void DisableDragDropForTesting();
+
private:
// Called on either UI thread or drag-and-drop thread.
void PrepareDragForDownload(const WebDropData& drop_data,
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 12c4c07..43ec8e5 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -42,7 +42,7 @@
#include "content/browser/webui/web_ui_impl.h"
#include "content/common/browser_plugin/browser_plugin_constants.h"
#include "content/common/browser_plugin/browser_plugin_messages.h"
-#include "content/common/icon_messages.h"
+#include "content/common/image_messages.h"
#include "content/common/ssl_status_serialization.h"
#include "content/common/view_messages.h"
#include "content/port/browser/render_view_host_delegate_view.h"
@@ -86,6 +86,7 @@
#include "webkit/glue/webpreferences.h"
#if defined(OS_ANDROID)
+#include "content/public/browser/android/content_view_core.h"
#include "content/browser/android/date_time_chooser_android.h"
#endif
@@ -140,8 +141,6 @@
// the user goes back. The process only stays live if another tab is using
// it, but if so, the existing frame relationships will be maintained.
-using webkit_glue::WebPreferences;
-
namespace content {
namespace {
@@ -157,13 +156,13 @@
const GURL& url,
bool is_favicon,
int image_size) {
- static int g_next_favicon_download_id = 0;
- rvh->Send(new IconMsg_DownloadFavicon(rvh->GetRoutingID(),
- ++g_next_favicon_download_id,
- url,
- is_favicon,
- image_size));
- return g_next_favicon_download_id;
+ static int g_next_image_download_id = 0;
+ rvh->Send(new ImageMsg_DownloadImage(rvh->GetRoutingID(),
+ ++g_next_image_download_id,
+ url,
+ is_favicon,
+ image_size));
+ return g_next_image_download_id;
}
ViewMsg_Navigate_Type::Value GetNavigationType(
@@ -198,9 +197,20 @@
NavigationController::ReloadType reload_type,
ViewMsg_Navigate_Params* params) {
params->page_id = entry.GetPageID();
- params->pending_history_list_offset = controller.GetIndexOfEntry(&entry);
- params->current_history_list_offset = controller.GetLastCommittedEntryIndex();
- params->current_history_list_length = controller.GetEntryCount();
+ params->should_clear_history_list = entry.should_clear_history_list();
+ if (entry.should_clear_history_list()) {
+ // Set the history list related parameters to the same values a
+ // NavigationController would return before its first navigation. This will
+ // fully clear the RenderView's view of the session history.
+ params->pending_history_list_offset = -1;
+ params->current_history_list_offset = -1;
+ params->current_history_list_length = 0;
+ } else {
+ params->pending_history_list_offset = controller.GetIndexOfEntry(&entry);
+ params->current_history_list_offset =
+ controller.GetLastCommittedEntryIndex();
+ params->current_history_list_length = controller.GetEntryCount();
+ }
if (!entry.GetBaseURLForDataURL().is_empty()) {
params->base_url_for_data_url = entry.GetBaseURLForDataURL();
params->history_url_for_data_url = entry.GetVirtualURL();
@@ -280,10 +290,13 @@
BrowserContext* browser_context,
WebContentsImpl* opener)
: delegate_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(controller_(this, browser_context)),
+ controller_(this, browser_context),
render_view_host_delegate_view_(NULL),
opener_(opener),
- ALLOW_THIS_IN_INITIALIZER_LIST(render_manager_(this, this, this)),
+#if defined(OS_WIN) && defined(USE_AURA)
+ accessible_parent_(NULL),
+#endif
+ render_manager_(this, this, this),
is_loading_(false),
crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING),
crashed_error_code_(0),
@@ -399,7 +412,6 @@
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- prefs.developer_extras_enabled = true;
prefs.javascript_enabled =
!command_line.HasSwitch(switches::kDisableJavaScript);
prefs.web_security_enabled =
@@ -409,8 +421,6 @@
prefs.java_enabled =
!command_line.HasSwitch(switches::kDisableJava);
- prefs.uses_page_cache =
- command_line.HasSwitch(switches::kEnableFastback);
prefs.remote_fonts_enabled =
!command_line.HasSwitch(switches::kDisableRemoteFonts);
prefs.xss_auditor_enabled =
@@ -501,8 +511,18 @@
command_line.HasSwitch(switches::kEnableExperimentalWebKitFeatures);
prefs.css_grid_layout_enabled =
command_line.HasSwitch(switches::kEnableExperimentalWebKitFeatures);
+ prefs.lazy_layout_enabled =
+ command_line.HasSwitch(switches::kEnableExperimentalWebKitFeatures);
+
+ // TODO(abarth, eseidel): Enable threaded_html_parser by default on Android
+ // once crbug 230542 is resolved.
+#if defined(OS_ANDROID)
+ prefs.threaded_html_parser = false;
+#else
prefs.threaded_html_parser =
!command_line.HasSwitch(switches::kDisableThreadedHTMLParser);
+#endif
+
#if defined(OS_ANDROID)
prefs.user_gesture_required_for_media_playback = !command_line.HasSwitch(
switches::kDisableGestureRequirementForMediaPlayback);
@@ -546,42 +566,8 @@
prefs.visual_word_movement_enabled =
command_line.HasSwitch(switches::kEnableVisualWordMovement);
- { // Certain GPU features might have been blacklisted.
- GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance();
- DCHECK(gpu_data_manager);
- uint32 blacklist_type = gpu_data_manager->GetBlacklistedFeatures();
- if (blacklist_type & GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)
- prefs.accelerated_compositing_enabled = false;
- if (blacklist_type & GPU_FEATURE_TYPE_WEBGL)
- prefs.experimental_webgl_enabled = false;
- if (blacklist_type & GPU_FEATURE_TYPE_FLASH3D)
- prefs.flash_3d_enabled = false;
- if (blacklist_type & GPU_FEATURE_TYPE_FLASH_STAGE3D) {
- prefs.flash_stage3d_enabled = false;
- prefs.flash_stage3d_baseline_enabled = false;
- }
- if (blacklist_type & GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE)
- prefs.flash_stage3d_baseline_enabled = false;
- if (blacklist_type & GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)
- prefs.accelerated_2d_canvas_enabled = false;
- if (blacklist_type & GPU_FEATURE_TYPE_MULTISAMPLING)
- prefs.gl_multisampling_enabled = false;
- if (blacklist_type & GPU_FEATURE_TYPE_3D_CSS) {
- prefs.accelerated_compositing_for_3d_transforms_enabled = false;
- prefs.accelerated_compositing_for_animation_enabled = false;
- }
- if (blacklist_type & GPU_FEATURE_TYPE_ACCELERATED_VIDEO)
- prefs.accelerated_compositing_for_video_enabled = false;
-
- // Accelerated video and animation are slower than regular when using a
- // software 3d rasterizer. 3D CSS may also be too slow to be worthwhile.
- if (gpu_data_manager->ShouldUseSoftwareRendering()) {
- prefs.accelerated_compositing_for_video_enabled = false;
- prefs.accelerated_compositing_for_animation_enabled = false;
- prefs.accelerated_compositing_for_3d_transforms_enabled = false;
- prefs.accelerated_compositing_for_plugins_enabled = false;
- }
- }
+ // Certain GPU features might have been blacklisted.
+ GpuDataManagerImpl::GetInstance()->UpdateRendererWebPrefs(&prefs);
if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
rvh->GetProcess()->GetID())) {
@@ -623,6 +609,9 @@
command_line.HasSwitch(switches::kEnableDeferredImageDecoding) ||
cc::switches::IsImplSidePaintingEnabled();
+ prefs.spatial_navigation_enabled = command_line.HasSwitch(
+ switches::kEnableSpatialNavigation);
+
GetContentClient()->browser()->OverrideWebkitPrefs(rvh, url, &prefs);
// Disable compositing in guests until we have compositing path implemented
@@ -695,8 +684,8 @@
OnBrowserPluginMessage(message))
IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginHostMsg_Attach,
OnBrowserPluginMessage(message))
- IPC_MESSAGE_HANDLER(IconHostMsg_DidDownloadFavicon, OnDidDownloadFavicon)
- IPC_MESSAGE_HANDLER(IconHostMsg_UpdateFaviconURL, OnUpdateFaviconURL)
+ IPC_MESSAGE_HANDLER(ImageHostMsg_DidDownloadImage, OnDidDownloadImage)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFaviconURL, OnUpdateFaviconURL)
#if defined(OS_ANDROID)
IPC_MESSAGE_HANDLER(ViewHostMsg_FindMatchRects_Reply,
OnFindMatchRectsReply)
@@ -869,6 +858,13 @@
return renderer_preferences_.user_agent_override;
}
+#if defined(OS_WIN) && defined(USE_AURA)
+void WebContentsImpl::SetParentNativeViewAccessible(
+gfx::NativeViewAccessible accessible_parent) {
+ accessible_parent_ = accessible_parent;
+}
+#endif
+
const string16& WebContentsImpl::GetTitle() const {
// Transient entries take precedence. They are used for interstitial pages
// that are shown on top of existing pages.
@@ -1141,13 +1137,13 @@
view_.reset(GetContentClient()->browser()->
OverrideCreateWebContentsView(this, &render_view_host_delegate_view_));
- if (view_.get()) {
+ if (view_) {
CHECK(render_view_host_delegate_view_);
} else {
WebContentsViewDelegate* delegate =
GetContentClient()->browser()->GetWebContentsViewDelegate(this);
- if (browser_plugin_guest_.get()) {
+ if (browser_plugin_guest_) {
WebContentsViewPort* platform_view = CreateWebContentsView(
this, delegate, &render_view_host_delegate_view_);
@@ -1267,16 +1263,30 @@
bool WebContentsImpl::PreHandleWheelEvent(
const WebKit::WebMouseWheelEvent& event) {
+#if !defined(OS_MACOSX)
+ // On platforms other than Mac, control+mousewheel changes zoom. On Mac, this
+ // isn't done for two reasons:
+ // -the OS already has a gesture to do this through pinch-zoom
+ // -if a user starts an inertial scroll, let's go, and presses control
+ // (i.e. control+tab) then the OS's buffered scroll events will come in
+ // with control key set which isn't what the user wants
if (delegate_ &&
event.wheelTicksY &&
(event.modifiers & WebKit::WebInputEvent::ControlKey)) {
delegate_->ContentsZoomChange(event.wheelTicksY > 0);
return true;
}
+#endif
return false;
}
+#if defined(OS_WIN) && defined(USE_AURA)
+gfx::NativeViewAccessible WebContentsImpl::GetParentNativeViewAccessible() {
+ return accessible_parent_;
+}
+#endif
+
void WebContentsImpl::HandleMouseDown() {
if (delegate_)
delegate_->HandleMouseDown();
@@ -1383,20 +1393,21 @@
WebContentsImpl* new_contents_impl =
static_cast<WebContentsImpl*>(new_contents);
new_contents_impl->browser_plugin_guest_.reset(
- BrowserPluginGuest::Create(instance_id, new_contents_impl));
+ BrowserPluginGuest::CreateWithOpener(instance_id, new_contents_impl,
+ GetBrowserPluginGuest(), !!new_contents_impl->opener()));
}
new_contents->Init(create_params);
// Save the window for later if we're not suppressing the opener (since it
- // will be shown immediately) and if it's not a guest (since we separately
- // track when to show guests).
- if (!params.opener_suppressed && !is_guest) {
- WebContentsViewPort* new_view = new_contents->view_.get();
+ // will be shown immediately).
+ if (!params.opener_suppressed) {
+ if (!is_guest) {
+ WebContentsViewPort* new_view = new_contents->view_.get();
- // TODO(brettw): It seems bogus that we have to call this function on the
- // newly created object and give it one of its own member variables.
- new_view->CreateViewForWidget(new_contents->GetRenderViewHost());
-
+ // TODO(brettw): It seems bogus that we have to call this function on the
+ // newly created object and give it one of its own member variables.
+ new_view->CreateViewForWidget(new_contents->GetRenderViewHost());
+ }
// Save the created window associated with the route so we can show it
// later.
DCHECK_NE(MSG_ROUTING_NONE, route_id);
@@ -1540,6 +1551,10 @@
registrar_.Remove(this, NOTIFICATION_WEB_CONTENTS_DESTROYED,
Source<WebContents>(new_contents));
+ // Don't initialize the guest WebContents immediately.
+ if (new_contents->GetRenderProcessHost()->IsGuest())
+ return new_contents;
+
if (!new_contents->GetRenderProcessHost()->HasConnection() ||
!new_contents->GetRenderViewHost()->GetView())
return NULL;
@@ -1584,7 +1599,7 @@
if (delegate_)
delegate_->RequestMediaAccessPermission(this, request, callback);
else
- callback.Run(MediaStreamDevices());
+ callback.Run(MediaStreamDevices(), scoped_ptr<MediaStreamUI>());
}
void WebContentsImpl::UpdatePreferredSize(const gfx::Size& pref_size) {
@@ -1839,11 +1854,33 @@
close_start_time_ = base::TimeTicks::Now();
}
+void WebContentsImpl::DragSourceEndedAt(int client_x, int client_y,
+ int screen_x, int screen_y, WebKit::WebDragOperation operation) {
+ if (browser_plugin_embedder_.get())
+ browser_plugin_embedder_->DragSourceEndedAt(client_x, client_y,
+ screen_x, screen_y, operation);
+ if (GetRenderViewHost())
+ GetRenderViewHostImpl()->DragSourceEndedAt(client_x, client_y,
+ screen_x, screen_y, operation);
+}
+
+void WebContentsImpl::DragSourceMovedTo(int client_x, int client_y,
+ int screen_x, int screen_y) {
+ if (browser_plugin_embedder_.get())
+ browser_plugin_embedder_->DragSourceMovedTo(client_x, client_y,
+ screen_x, screen_y);
+ if (GetRenderViewHost())
+ GetRenderViewHostImpl()->DragSourceMovedTo(client_x, client_y,
+ screen_x, screen_y);
+}
+
void WebContentsImpl::SystemDragEnded() {
if (GetRenderViewHost())
GetRenderViewHostImpl()->DragSourceSystemDragEnded();
if (delegate_)
delegate_->DragEnded();
+ if (browser_plugin_embedder_.get())
+ browser_plugin_embedder_->SystemDragEnded();
}
void WebContentsImpl::UserGestureDone() {
@@ -1927,46 +1964,6 @@
return content_restrictions_;
}
-WebUI* WebContentsImpl::GetWebUIForCurrentState() {
- // When there is a pending navigation entry, we want to use the pending WebUI
- // that goes along with it to control the basic flags. For example, we want to
- // show the pending URL in the URL bar, so we want the display_url flag to
- // be from the pending entry.
- //
- // The confusion comes because there are multiple possibilities for the
- // initial load in a tab as a side effect of the way the RenderViewHostManager
- // works.
- //
- // - For the very first tab the load looks "normal". The new tab Web UI is
- // the pending one, and we want it to apply here.
- //
- // - For subsequent new tabs, they'll get a new SiteInstance which will then
- // get switched to the one previously associated with the new tab pages.
- // This switching will cause the manager to commit the RVH/WebUI. So we'll
- // have a committed Web UI in this case.
- //
- // This condition handles all of these cases:
- //
- // - First load in first tab: no committed nav entry + pending nav entry +
- // pending dom ui:
- // -> Use pending Web UI if any.
- //
- // - First load in second tab: no committed nav entry + pending nav entry +
- // no pending Web UI:
- // -> Use the committed Web UI if any.
- //
- // - Second navigation in any tab: committed nav entry + pending nav entry:
- // -> Use pending Web UI if any.
- //
- // - Normal state with no load: committed nav entry + no pending nav entry:
- // -> Use committed Web UI.
- if (controller_.GetPendingEntry() &&
- (controller_.GetLastCommittedEntry() ||
- render_manager_.pending_web_ui()))
- return render_manager_.pending_web_ui();
- return render_manager_.web_ui();
-}
-
bool WebContentsImpl::GotResponseToLockMouseRequest(bool allowed) {
return GetRenderViewHost() ?
GetRenderViewHostImpl()->GotResponseToLockMouseRequest(allowed) : false;
@@ -1989,20 +1986,17 @@
color_chooser_ = NULL;
}
-int WebContentsImpl::DownloadFavicon(const GURL& url,
- bool is_favicon,
- int image_size,
- const FaviconDownloadCallback& callback) {
+int WebContentsImpl::DownloadImage(const GURL& url,
+ bool is_favicon,
+ int image_size,
+ const ImageDownloadCallback& callback) {
RenderViewHost* host = GetRenderViewHost();
int id = StartDownload(host, url, is_favicon, image_size);
- favicon_download_map_[id] = callback;
+ image_download_map_[id] = callback;
return id;
}
bool WebContentsImpl::FocusLocationBarByDefault() {
- WebUI* web_ui = GetWebUIForCurrentState();
- if (web_ui)
- return web_ui->ShouldFocusLocationBarByDefault();
NavigationEntry* entry = controller_.GetActiveEntry();
if (entry && entry->GetURL() == GURL(chrome::kAboutBlankURL))
return true;
@@ -2313,8 +2307,8 @@
void WebContentsImpl::OnOpenDateTimeDialog(
const ViewHostMsg_DateTimeDialogValue_Params& value) {
date_time_chooser_->ShowDialog(
- view_->GetContentNativeView(), GetRenderViewHost(), value.dialog_type,
- value.year, value.month, value.day, value.hour,
+ ContentViewCore::FromWebContents(this), GetRenderViewHost(),
+ value.dialog_type, value.year, value.month, value.day, value.hour,
value.minute, value.second);
}
@@ -2407,13 +2401,13 @@
browser_plugin_embedder_->OnMessageReceived(message);
}
-void WebContentsImpl::OnDidDownloadFavicon(
+void WebContentsImpl::OnDidDownloadImage(
int id,
const GURL& image_url,
int requested_size,
const std::vector<SkBitmap>& bitmaps) {
- FaviconDownloadMap::iterator iter = favicon_download_map_.find(id);
- if (iter == favicon_download_map_.end()) {
+ ImageDownloadMap::iterator iter = image_download_map_.find(id);
+ if (iter == image_download_map_.end()) {
// Currently WebContents notifies us of ANY downloads so that it is
// possible to get here.
return;
@@ -2421,7 +2415,7 @@
if (!iter->second.is_null()) {
iter->second.Run(id, image_url, requested_size, bitmaps);
}
- favicon_download_map_.erase(id);
+ image_download_map_.erase(id);
}
void WebContentsImpl::OnUpdateFaviconURL(
@@ -2640,7 +2634,7 @@
}
void WebContentsImpl::RemoveBrowserPluginEmbedder() {
- if (browser_plugin_embedder_.get())
+ if (browser_plugin_embedder_)
browser_plugin_embedder_.reset();
}
@@ -2700,9 +2694,9 @@
FOR_EACH_OBSERVER(WebContentsObserver, observers_, RenderViewReady());
}
-void WebContentsImpl::RenderViewGone(RenderViewHost* rvh,
- base::TerminationStatus status,
- int error_code) {
+void WebContentsImpl::RenderViewTerminated(RenderViewHost* rvh,
+ base::TerminationStatus status,
+ int error_code) {
if (rvh != GetRenderViewHost()) {
// The pending page's RenderViewHost is gone.
return;
@@ -2810,7 +2804,7 @@
const std::string& state) {
// Ensure that this state update comes from either the active RVH or one of
// the swapped out RVHs. We don't expect to hear from any other RVHs.
- DCHECK(rvh == GetRenderViewHost() || render_manager_.IsSwappedOut(rvh));
+ DCHECK(rvh == GetRenderViewHost() || render_manager_.IsOnSwappedOutList(rvh));
// We must be prepared to handle state updates for any page, these occur
// when the user is scrolling and entering form data, as well as when we're
@@ -2912,7 +2906,10 @@
void WebContentsImpl::DidStopLoading(RenderViewHost* render_view_host) {
scoped_ptr<LoadNotificationDetails> details;
- NavigationEntry* entry = controller_.GetActiveEntry();
+ // Use the last committed entry rather than the active one, in case a
+ // pending entry has been created.
+ NavigationEntry* entry = controller_.GetLastCommittedEntry();
+
// An entry may not exist for a stop when loading an initial blank page or
// if an iframe injected by script into a blank page finishes loading.
if (entry) {
@@ -2948,11 +2945,13 @@
}
void WebContentsImpl::DidDisownOpener(RenderViewHost* rvh) {
- // Clear our opener so that future cross-process navigations don't have an
- // opener assigned.
- registrar_.Remove(this, NOTIFICATION_WEB_CONTENTS_DESTROYED,
- Source<WebContents>(opener_));
- opener_ = NULL;
+ if (opener_) {
+ // Clear our opener so that future cross-process navigations don't have an
+ // opener assigned.
+ registrar_.Remove(this, NOTIFICATION_WEB_CONTENTS_DESTROYED,
+ Source<WebContents>(opener_));
+ opener_ = NULL;
+ }
// Notify all swapped out RenderViewHosts for this tab. This is important
// in case we go back to them, or if another window in those processes tries
@@ -2960,10 +2959,6 @@
render_manager_.DidDisownOpener(rvh);
}
-void WebContentsImpl::DidUpdateFrameTree(RenderViewHost* rvh) {
- render_manager_.DidUpdateFrameTree(rvh);
-}
-
void WebContentsImpl::DocumentAvailableInMainFrame(
RenderViewHost* render_view_host) {
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
@@ -3067,11 +3062,6 @@
ViewMsg_PostMessage_Params new_params(params);
- // If the renderer has changed while the post message is being routed,
- // drop the message, as it will not be delivered to the right target.
- // TODO(nasko): Check for process ID and target frame id mismatch, once
- // http://crbug.com/153701 is fixed.
-
// If there is a source_routing_id, translate it to the routing ID for
// the equivalent swapped out RVH in the target process. If we need
// to create a swapped out RVH for the source tab, we create its opener
@@ -3294,7 +3284,7 @@
void WebContentsImpl::RenderViewGoneFromRenderManager(
RenderViewHost* render_view_host) {
DCHECK(crashed_status_ != base::TERMINATION_STATUS_STILL_RUNNING);
- RenderViewGone(render_view_host, crashed_status_, crashed_error_code_);
+ RenderViewTerminated(render_view_host, crashed_status_, crashed_error_code_);
}
void WebContentsImpl::UpdateRenderViewSizeForRenderManager() {
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index c9d6443..39cf2ae 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -25,6 +25,7 @@
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/three_d_api_types.h"
#include "net/base/load_states.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDragOperation.h"
#include "ui/gfx/rect_f.h"
#include "ui/gfx/size.h"
#include "webkit/glue/resource_type.h"
@@ -91,7 +92,7 @@
int guest_instance_id);
// Returns the content specific prefs for the given RVH.
- static webkit_glue::WebPreferences GetWebkitPrefs(
+ static WebPreferences GetWebkitPrefs(
RenderViewHost* rvh, const GURL& url);
// Creates a swapped out RenderView. This is used by the browser plugin to
@@ -172,6 +173,17 @@
// Invoked before a form repost warning is shown.
void NotifyBeforeFormRepostWarningShow();
+
+ // Informs the render view host and the BrowserPluginEmbedder, if present, of
+ // a Drag Source End.
+ void DragSourceEndedAt(int client_x, int client_y, int screen_x,
+ int screen_y, WebKit::WebDragOperation operation);
+
+ // Informs the render view host and the BrowserPluginEmbedder, if present, of
+ // a Drag Source Move.
+ void DragSourceMovedTo(int client_x, int client_y,
+ int screen_x, int screen_y);
+
// WebContents ------------------------------------------------------
virtual WebContentsDelegate* GetDelegate() OVERRIDE;
virtual void SetDelegate(WebContentsDelegate* delegate) OVERRIDE;
@@ -194,6 +206,10 @@
virtual WebUI* GetCommittedWebUI() const OVERRIDE;
virtual void SetUserAgentOverride(const std::string& override) OVERRIDE;
virtual const std::string& GetUserAgentOverride() const OVERRIDE;
+#if defined(OS_WIN) && defined(USE_AURA)
+ virtual void SetParentNativeViewAccessible(
+ gfx::NativeViewAccessible accessible_parent) OVERRIDE;
+#endif
virtual const string16& GetTitle() const OVERRIDE;
virtual int32 GetMaxPageID() OVERRIDE;
virtual int32 GetMaxPageIDForSiteInstance(
@@ -259,16 +275,15 @@
virtual int GetMaximumZoomPercent() const OVERRIDE;
virtual gfx::Size GetPreferredSize() const OVERRIDE;
virtual int GetContentRestrictions() const OVERRIDE;
- virtual WebUI* GetWebUIForCurrentState() OVERRIDE;
virtual bool GotResponseToLockMouseRequest(bool allowed) OVERRIDE;
virtual bool HasOpener() const OVERRIDE;
virtual void DidChooseColorInColorChooser(int color_chooser_id,
SkColor color) OVERRIDE;
virtual void DidEndColorChooser(int color_chooser_id) OVERRIDE;
- virtual int DownloadFavicon(const GURL& url,
- bool is_favicon,
- int image_size,
- const FaviconDownloadCallback& callback) OVERRIDE;
+ virtual int DownloadImage(const GURL& url,
+ bool is_favicon,
+ int image_size,
+ const ImageDownloadCallback& callback) OVERRIDE;
// Implementation of PageNavigator.
virtual WebContents* OpenURL(const OpenURLParams& params) OVERRIDE;
@@ -288,9 +303,9 @@
virtual gfx::Rect GetRootWindowResizerRect() const OVERRIDE;
virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE;
virtual void RenderViewReady(RenderViewHost* render_view_host) OVERRIDE;
- virtual void RenderViewGone(RenderViewHost* render_view_host,
- base::TerminationStatus status,
- int error_code) OVERRIDE;
+ virtual void RenderViewTerminated(RenderViewHost* render_view_host,
+ base::TerminationStatus status,
+ int error_code) OVERRIDE;
virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE;
virtual void DidStartProvisionalLoadForFrame(
RenderViewHost* render_view_host,
@@ -328,7 +343,6 @@
virtual void DidCancelLoading() OVERRIDE;
virtual void DidChangeLoadProgress(double progress) OVERRIDE;
virtual void DidDisownOpener(RenderViewHost* rvh) OVERRIDE;
- virtual void DidUpdateFrameTree(RenderViewHost* rvh) OVERRIDE;
virtual void DocumentAvailableInMainFrame(
RenderViewHost* render_view_host) OVERRIDE;
virtual void DocumentOnLoadCompletedInMainFrame(
@@ -368,7 +382,7 @@
const string16& source_id) OVERRIDE;
virtual RendererPreferences GetRendererPrefs(
BrowserContext* browser_context) const OVERRIDE;
- virtual webkit_glue::WebPreferences GetWebkitPrefs() OVERRIDE;
+ virtual WebPreferences GetWebkitPrefs() OVERRIDE;
virtual void OnUserGesture() OVERRIDE;
virtual void OnIgnoredUIEvent() OVERRIDE;
virtual void RendererUnresponsive(RenderViewHost* render_view_host,
@@ -429,6 +443,9 @@
const NativeWebKeyboardEvent& event) OVERRIDE;
virtual bool PreHandleWheelEvent(
const WebKit::WebMouseWheelEvent& event) OVERRIDE;
+#if defined(OS_WIN) && defined(USE_AURA)
+ virtual gfx::NativeViewAccessible GetParentNativeViewAccessible() OVERRIDE;
+#endif
// RenderViewHostManager::Delegate -------------------------------------------
@@ -565,10 +582,10 @@
const GURL& url,
const base::FilePath& plugin_path);
void OnBrowserPluginMessage(const IPC::Message& message);
- void OnDidDownloadFavicon(int id,
- const GURL& image_url,
- int requested_size,
- const std::vector<SkBitmap>& bitmaps);
+ void OnDidDownloadImage(int id,
+ const GURL& image_url,
+ int requested_size,
+ const std::vector<SkBitmap>& bitmaps);
void OnUpdateFaviconURL(int32 page_id,
const std::vector<FaviconURL>& candidates);
void OnFrameDetached(int64 frame_id);
@@ -719,6 +736,10 @@
// is closed.
WebContentsImpl* opener_;
+#if defined(OS_WIN) && defined(USE_AURA)
+ gfx::NativeViewAccessible accessible_parent_;
+#endif
+
// Helper classes ------------------------------------------------------------
// Manages creation and swapping of render views.
@@ -871,9 +892,9 @@
// Routing id of the shown fullscreen widget or MSG_ROUTING_NONE otherwise.
int fullscreen_widget_routing_id_;
- // Maps the ids of pending favicon downloads to their callbacks
- typedef std::map<int, FaviconDownloadCallback> FaviconDownloadMap;
- FaviconDownloadMap favicon_download_map_;
+ // Maps the ids of pending image downloads to their callbacks
+ typedef std::map<int, ImageDownloadCallback> ImageDownloadMap;
+ ImageDownloadMap image_download_map_;
DISALLOW_COPY_AND_ASSIGN(WebContentsImpl);
};
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc
new file mode 100644
index 0000000..f3830f1
--- /dev/null
+++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -0,0 +1,124 @@
+// 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/values.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/load_notification_details.h"
+#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/shell.h"
+#include "content/test/content_browser_test.h"
+#include "content/test/content_browser_test_utils.h"
+#include "net/test/spawned_test_server.h"
+
+namespace content {
+
+class WebContentsImplBrowserTest : public ContentBrowserTest {
+ public:
+ WebContentsImplBrowserTest() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WebContentsImplBrowserTest);
+};
+
+// Keeps track of data from LoadNotificationDetails so we can later verify that
+// they are correct, after the LoadNotificationDetails object is deleted.
+class LoadStopNotificationObserver : public WindowedNotificationObserver {
+ public:
+ LoadStopNotificationObserver(NavigationController* controller)
+ : WindowedNotificationObserver(NOTIFICATION_LOAD_STOP,
+ Source<NavigationController>(controller)),
+ session_index_(-1),
+ controller_(NULL) {
+ }
+ virtual void Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) OVERRIDE {
+ if (type == NOTIFICATION_LOAD_STOP) {
+ const Details<LoadNotificationDetails> load_details(details);
+ url_ = load_details->url;
+ session_index_ = load_details->session_index;
+ controller_ = load_details->controller;
+ }
+ WindowedNotificationObserver::Observe(type, source, details);
+ }
+
+ GURL url_;
+ int session_index_;
+ NavigationController* controller_;
+};
+
+// Starts a new navigation as soon as the current one commits, but does not
+// wait for it to complete. This allows us to observe DidStopLoading while
+// a pending entry is present.
+class NavigateOnCommitObserver : public WindowedNotificationObserver {
+ public:
+ NavigateOnCommitObserver(Shell* shell, GURL url)
+ : WindowedNotificationObserver(
+ NOTIFICATION_NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(
+ &shell->web_contents()->GetController())),
+ shell_(shell),
+ url_(url),
+ done_(false) {
+ }
+ virtual void Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) OVERRIDE {
+ if (type == NOTIFICATION_NAV_ENTRY_COMMITTED && !done_) {
+ done_ = true;
+ shell_->LoadURL(url_);
+ }
+ WindowedNotificationObserver::Observe(type, source, details);
+ }
+
+ Shell* shell_;
+ GURL url_;
+ bool done_;
+};
+
+// Test that DidStopLoading includes the correct URL in the details.
+IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, DidStopLoadingDetails) {
+ ASSERT_TRUE(test_server()->Start());
+
+ LoadStopNotificationObserver load_observer(
+ &shell()->web_contents()->GetController());
+ NavigateToURL(shell(), test_server()->GetURL("files/title1.html"));
+ load_observer.Wait();
+
+ EXPECT_EQ("/files/title1.html", load_observer.url_.path());
+ EXPECT_EQ(0, load_observer.session_index_);
+ EXPECT_EQ(&shell()->web_contents()->GetController(),
+ load_observer.controller_);
+}
+
+// Test that DidStopLoading includes the correct URL in the details when a
+// pending entry is present.
+IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
+ DidStopLoadingDetailsWithPending) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // Listen for the first load to stop.
+ LoadStopNotificationObserver load_observer(
+ &shell()->web_contents()->GetController());
+ // Start a new pending navigation as soon as the first load commits.
+ // We will hear a DidStopLoading from the first load as the new load
+ // is started.
+ NavigateOnCommitObserver commit_observer(
+ shell(), test_server()->GetURL("files/title2.html"));
+ NavigateToURL(shell(), test_server()->GetURL("files/title1.html"));
+ commit_observer.Wait();
+ load_observer.Wait();
+
+ EXPECT_EQ("/files/title1.html", load_observer.url_.path());
+ EXPECT_EQ(0, load_observer.session_index_);
+ EXPECT_EQ(&shell()->web_contents()->GetController(),
+ load_observer.controller_);
+}
+
+} // namespace content
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc
index 80b8713..cb702a4 100644
--- a/content/browser/web_contents/web_contents_impl_unittest.cc
+++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -156,8 +156,9 @@
DidNavigate(GetRenderViewHostForTesting(), params);
}
- void TestRenderViewGone(base::TerminationStatus status, int error_code) {
- RenderViewGone(GetRenderViewHostForTesting(), status, error_code);
+ void TestRenderViewTerminated(base::TerminationStatus status,
+ int error_code) {
+ RenderViewTerminated(GetRenderViewHostForTesting(), status, error_code);
}
bool is_showing() const {
@@ -438,7 +439,8 @@
EXPECT_NE(instance1, instance2);
EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
// We keep the original RVH around, swapped out.
- EXPECT_TRUE(contents()->GetRenderManagerForTesting()->IsSwappedOut(orig_rvh));
+ EXPECT_TRUE(contents()->GetRenderManagerForTesting()->IsOnSwappedOutList(
+ orig_rvh));
EXPECT_EQ(orig_rvh_delete_count, 0);
// Going back should switch SiteInstances again. The first SiteInstance is
@@ -463,7 +465,7 @@
EXPECT_EQ(instance1, contents()->GetSiteInstance());
// The pending RVH should now be swapped out, not deleted.
EXPECT_TRUE(contents()->GetRenderManagerForTesting()->
- IsSwappedOut(pending_rvh));
+ IsOnSwappedOutList(pending_rvh));
EXPECT_EQ(pending_rvh_delete_count, 0);
// Close contents and ensure RVHs are deleted.
@@ -682,8 +684,8 @@
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
- orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(
- 0, false, base::TimeTicks(), base::TimeTicks()));
+ base::TimeTicks now = base::TimeTicks::Now();
+ orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, false, now, now));
EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
EXPECT_FALSE(contents()->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents()->GetRenderViewHost());
@@ -692,8 +694,8 @@
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
- orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(
- 0, true, base::TimeTicks(), base::TimeTicks()));
+ now = base::TimeTicks::Now();
+ orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
EXPECT_TRUE(contents()->cross_navigation_pending());
TestRenderViewHost* pending_rvh = static_cast<TestRenderViewHost*>(
@@ -734,8 +736,8 @@
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
- orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(
- 0, true, base::TimeTicks(), base::TimeTicks()));
+ base::TimeTicks now = base::TimeTicks::Now();
+ orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
EXPECT_TRUE(contents()->cross_navigation_pending());
// Suppose the original renderer navigates before the new one is ready.
@@ -779,8 +781,8 @@
// Simulate beforeunload approval.
EXPECT_TRUE(ntp_rvh->is_waiting_for_beforeunload_ack());
- ntp_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(
- 0, true, base::TimeTicks(), base::TimeTicks()));
+ base::TimeTicks now = base::TimeTicks::Now();
+ ntp_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
// DidNavigate from the pending page.
contents()->TestDidNavigate(
@@ -828,8 +830,8 @@
// Simulate beforeunload approval.
EXPECT_TRUE(google_rvh->is_waiting_for_beforeunload_ack());
- google_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(
- 0, true, base::TimeTicks(), base::TimeTicks()));
+ now = base::TimeTicks::Now();
+ google_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
// DidNavigate from the first back. This aborts the second back's pending RVH.
contents()->TestDidNavigate(google_rvh, 1, url2, PAGE_TRANSITION_TYPED);
@@ -877,8 +879,8 @@
// Now simulate the onbeforeunload approval and verify the navigation is
// not canceled.
- orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(
- 0, true, base::TimeTicks(), base::TimeTicks()));
+ base::TimeTicks now = base::TimeTicks::Now();
+ orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
EXPECT_FALSE(orig_rvh->is_waiting_for_beforeunload_ack());
EXPECT_TRUE(contents()->cross_navigation_pending());
}
@@ -941,8 +943,8 @@
const GURL url2("http://www.yahoo.com");
controller().LoadURL(
url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
- orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(
- 0, true, base::TimeTicks(), base::TimeTicks()));
+ base::TimeTicks now = base::TimeTicks::Now();
+ orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
EXPECT_TRUE(contents()->cross_navigation_pending());
TestRenderViewHost* pending_rvh = static_cast<TestRenderViewHost*>(
contents()->GetPendingRenderViewHost());
@@ -993,8 +995,8 @@
const GURL url2("http://www.yahoo.com");
controller().LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
EXPECT_TRUE(orig_rvh->is_waiting_for_beforeunload_ack());
- orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(
- 0, true, base::TimeTicks(), base::TimeTicks()));
+ base::TimeTicks now = base::TimeTicks::Now();
+ orig_rvh->OnMessageReceived(ViewHostMsg_ShouldClose_ACK(0, true, now, now));
EXPECT_TRUE(contents()->cross_navigation_pending());
// Simulate swap out message when the response arrives.
@@ -1805,7 +1807,7 @@
TestInterstitialPageStateGuard state_guard(interstitial);
interstitial->Show();
// Simulate a renderer crash before the interstitial is shown.
- interstitial->TestRenderViewGone(
+ interstitial->TestRenderViewTerminated(
base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
// The interstitial should have been dismissed.
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
@@ -1818,7 +1820,7 @@
interstitial->Show();
interstitial->TestDidNavigate(1, url);
// Simulate a renderer crash.
- interstitial->TestRenderViewGone(
+ interstitial->TestRenderViewTerminated(
base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
// The interstitial should have been dismissed.
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
diff --git a/content/browser/web_contents/web_contents_screenshot_manager.cc b/content/browser/web_contents/web_contents_screenshot_manager.cc
new file mode 100644
index 0000000..49cb0c6
--- /dev/null
+++ b/content/browser/web_contents/web_contents_screenshot_manager.cc
@@ -0,0 +1,272 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_contents/web_contents_screenshot_manager.h"
+
+#include "base/command_line.h"
+#include "base/threading/worker_pool.h"
+#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/web_contents/navigation_controller_impl.h"
+#include "content/browser/web_contents/navigation_entry_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/render_widget_host.h"
+#include "content/public/browser/render_widget_host_view.h"
+#include "content/public/common/content_switches.h"
+#include "ui/gfx/codec/png_codec.h"
+
+namespace {
+
+// Minimum delay between taking screenshots.
+const int kMinScreenshotIntervalMS = 1000;
+
+}
+
+namespace content {
+
+// Encodes an SkBitmap to PNG data in a worker thread.
+class ScreenshotData : public base::RefCountedThreadSafe<ScreenshotData> {
+ public:
+ ScreenshotData() {
+ }
+
+ void EncodeScreenshot(const SkBitmap& bitmap, base::Closure callback) {
+ if (!base::WorkerPool::PostTaskAndReply(FROM_HERE,
+ base::Bind(&ScreenshotData::EncodeOnWorker,
+ this,
+ bitmap),
+ callback,
+ true)) {
+ callback.Run();
+ }
+ }
+
+ scoped_refptr<base::RefCountedBytes> data() const { return data_; }
+
+ private:
+ friend class base::RefCountedThreadSafe<ScreenshotData>;
+ virtual ~ScreenshotData() {
+ }
+
+ void EncodeOnWorker(const SkBitmap& bitmap) {
+ std::vector<unsigned char> data;
+ if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &data))
+ data_ = new base::RefCountedBytes(data);
+ }
+
+ scoped_refptr<base::RefCountedBytes> data_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScreenshotData);
+};
+
+WebContentsScreenshotManager::WebContentsScreenshotManager(
+ NavigationControllerImpl* owner)
+ : owner_(owner),
+ screenshot_factory_(this),
+ min_screenshot_interval_ms_(kMinScreenshotIntervalMS) {
+}
+
+WebContentsScreenshotManager::~WebContentsScreenshotManager() {
+}
+
+void WebContentsScreenshotManager::TakeScreenshot() {
+ static bool overscroll_enabled = CommandLine::ForCurrentProcess()->
+ GetSwitchValueASCII(switches::kOverscrollHistoryNavigation) != "0";
+ if (!overscroll_enabled)
+ return;
+
+ NavigationEntryImpl* entry =
+ NavigationEntryImpl::FromNavigationEntry(owner_->GetLastCommittedEntry());
+ if (!entry)
+ return;
+
+ RenderViewHost* render_view_host =
+ owner_->web_contents()->GetRenderViewHost();
+ if (!static_cast<RenderViewHostImpl*>
+ (render_view_host)->overscroll_controller()) {
+ return;
+ }
+ content::RenderWidgetHostView* view = render_view_host->GetView();
+ if (!view)
+ return;
+
+ // Make sure screenshots aren't taken too frequently.
+ base::Time now = base::Time::Now();
+ if (now - last_screenshot_time_ <
+ base::TimeDelta::FromMilliseconds(min_screenshot_interval_ms_)) {
+ return;
+ }
+
+ last_screenshot_time_ = now;
+
+ TakeScreenshotImpl(render_view_host, entry);
+}
+
+// Implemented here and not in NavigationEntry because this manager keeps track
+// of the total number of screen shots across all entries.
+void WebContentsScreenshotManager::ClearAllScreenshots() {
+ int count = owner_->GetEntryCount();
+ for (int i = 0; i < count; ++i) {
+ ClearScreenshot(NavigationEntryImpl::FromNavigationEntry(
+ owner_->GetEntryAtIndex(i)));
+ }
+ DCHECK_EQ(GetScreenshotCount(), 0);
+}
+
+void WebContentsScreenshotManager::TakeScreenshotImpl(
+ RenderViewHost* host,
+ NavigationEntryImpl* entry) {
+ DCHECK(host && host->GetView());
+ DCHECK(entry);
+ host->CopyFromBackingStore(gfx::Rect(),
+ host->GetView()->GetViewBounds().size(),
+ base::Bind(&WebContentsScreenshotManager::OnScreenshotTaken,
+ screenshot_factory_.GetWeakPtr(),
+ entry->GetUniqueID()));
+}
+
+void WebContentsScreenshotManager::SetMinScreenshotIntervalMS(int interval_ms) {
+ DCHECK_GE(interval_ms, 0);
+ min_screenshot_interval_ms_ = interval_ms;
+}
+
+void WebContentsScreenshotManager::OnScreenshotTaken(int unique_id,
+ bool success,
+ const SkBitmap& bitmap) {
+ NavigationEntryImpl* entry = NULL;
+ int entry_count = owner_->GetEntryCount();
+ for (int i = 0; i < entry_count; ++i) {
+ NavigationEntry* iter = owner_->GetEntryAtIndex(i);
+ if (iter->GetUniqueID() == unique_id) {
+ entry = NavigationEntryImpl::FromNavigationEntry(iter);
+ break;
+ }
+ }
+
+ if (!entry) {
+ LOG(ERROR) << "Invalid entry with unique id: " << unique_id;
+ return;
+ }
+
+ if (!success || bitmap.empty() || bitmap.isNull()) {
+ ClearScreenshot(entry);
+ return;
+ }
+
+ scoped_refptr<ScreenshotData> screenshot = new ScreenshotData();
+ screenshot->EncodeScreenshot(
+ bitmap,
+ base::Bind(&WebContentsScreenshotManager::OnScreenshotEncodeComplete,
+ screenshot_factory_.GetWeakPtr(),
+ unique_id,
+ screenshot));
+}
+
+int WebContentsScreenshotManager::GetScreenshotCount() const {
+ int screenshot_count = 0;
+ int entry_count = owner_->GetEntryCount();
+ for (int i = 0; i < entry_count; ++i) {
+ NavigationEntryImpl* entry =
+ NavigationEntryImpl::FromNavigationEntry(owner_->GetEntryAtIndex(i));
+ if (entry->screenshot())
+ screenshot_count++;
+ }
+ return screenshot_count;
+}
+
+void WebContentsScreenshotManager::OnScreenshotEncodeComplete(
+ int unique_id,
+ scoped_refptr<ScreenshotData> screenshot) {
+ NavigationEntryImpl* entry = NULL;
+ int entry_count = owner_->GetEntryCount();
+ for (int i = 0; i < entry_count; ++i) {
+ NavigationEntry* iter = owner_->GetEntryAtIndex(i);
+ if (iter->GetUniqueID() == unique_id) {
+ entry = NavigationEntryImpl::FromNavigationEntry(iter);
+ break;
+ }
+ }
+ if (!entry)
+ return;
+ entry->SetScreenshotPNGData(screenshot->data());
+ OnScreenshotSet(entry);
+}
+
+void WebContentsScreenshotManager::OnScreenshotSet(NavigationEntryImpl* entry) {
+ PurgeScreenshotsIfNecessary();
+}
+
+bool WebContentsScreenshotManager::ClearScreenshot(NavigationEntryImpl* entry) {
+ if (!entry->screenshot())
+ return false;
+
+ entry->SetScreenshotPNGData(NULL);
+ return true;
+}
+
+void WebContentsScreenshotManager::PurgeScreenshotsIfNecessary() {
+ // Allow only a certain number of entries to keep screenshots.
+ const int kMaxScreenshots = 10;
+ int screenshot_count = GetScreenshotCount();
+ if (screenshot_count < kMaxScreenshots)
+ return;
+
+ const int current = owner_->GetCurrentEntryIndex();
+ const int num_entries = owner_->GetEntryCount();
+ int available_slots = kMaxScreenshots;
+ if (NavigationEntryImpl::FromNavigationEntry(
+ owner_->GetEntryAtIndex(current))->screenshot()) {
+ --available_slots;
+ }
+
+ // Keep screenshots closer to the current navigation entry, and purge the ones
+ // that are farther away from it. So in each step, look at the entries at
+ // each offset on both the back and forward history, and start counting them
+ // to make sure that the correct number of screenshots are kept in memory.
+ // Note that it is possible for some entries to be missing screenshots (e.g.
+ // when taking the screenshot failed for some reason). So there may be a state
+ // where there are a lot of entries in the back history, but none of them has
+ // any screenshot. In such cases, keep the screenshots for |kMaxScreenshots|
+ // entries in the forward history list.
+ int back = current - 1;
+ int forward = current + 1;
+ while (available_slots > 0 && (back >= 0 || forward < num_entries)) {
+ if (back >= 0) {
+ NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
+ owner_->GetEntryAtIndex(back));
+ if (entry->screenshot())
+ --available_slots;
+ --back;
+ }
+
+ if (available_slots > 0 && forward < num_entries) {
+ NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
+ owner_->GetEntryAtIndex(forward));
+ if (entry->screenshot())
+ --available_slots;
+ ++forward;
+ }
+ }
+
+ // Purge any screenshot at |back| or lower indices, and |forward| or higher
+ // indices.
+ while (screenshot_count > kMaxScreenshots && back >= 0) {
+ NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
+ owner_->GetEntryAtIndex(back));
+ if (ClearScreenshot(entry))
+ --screenshot_count;
+ --back;
+ }
+
+ while (screenshot_count > kMaxScreenshots && forward < num_entries) {
+ NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
+ owner_->GetEntryAtIndex(forward));
+ if (ClearScreenshot(entry))
+ --screenshot_count;
+ ++forward;
+ }
+ CHECK_GE(screenshot_count, 0);
+ CHECK_LE(screenshot_count, kMaxScreenshots);
+}
+
+} // namespace content
diff --git a/content/browser/web_contents/web_contents_screenshot_manager.h b/content/browser/web_contents/web_contents_screenshot_manager.h
new file mode 100644
index 0000000..2162cf4
--- /dev/null
+++ b/content/browser/web_contents/web_contents_screenshot_manager.h
@@ -0,0 +1,89 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_SCREENSHOT_MANAGER_H_
+#define CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_SCREENSHOT_MANAGER_H_
+
+#include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
+#include "base/time.h"
+#include "content/common/content_export.h"
+
+class SkBitmap;
+
+namespace content {
+
+class NavigationControllerImpl;
+class NavigationEntryImpl;
+class RenderViewHost;
+class ScreenshotData;
+
+// WebContentsScreenshotManager takes care of taking image-captures for the
+// current navigation entry of a NavigationControllerImpl, and managing these
+// captured images. These image-captures are used for history navigation using
+// overscroll gestures.
+class CONTENT_EXPORT WebContentsScreenshotManager {
+ public:
+ explicit WebContentsScreenshotManager(NavigationControllerImpl* controller);
+ virtual ~WebContentsScreenshotManager();
+
+ // Takes a screenshot of the last-committed entry of the controller.
+ void TakeScreenshot();
+
+ // Clears screenshots of all navigation entries.
+ void ClearAllScreenshots();
+
+ protected:
+ virtual void TakeScreenshotImpl(RenderViewHost* host,
+ NavigationEntryImpl* entry);
+
+ // Called after a screenshot has been set on an NavigationEntryImpl.
+ // Overridden in tests to get notified of when a screenshot is set.
+ virtual void OnScreenshotSet(NavigationEntryImpl* entry);
+
+ NavigationControllerImpl* owner() { return owner_; }
+
+ void SetMinScreenshotIntervalMS(int interval_ms);
+
+ // The callback invoked when taking the screenshot of the page is complete.
+ // This sets the screenshot on the navigation entry.
+ void OnScreenshotTaken(int unique_id,
+ bool success,
+ const SkBitmap& bitmap);
+
+ // Returns the number of entries with screenshots.
+ int GetScreenshotCount() const;
+
+ private:
+ // This is called when the screenshot data has beene encoded to PNG in a
+ // worker thread.
+ void OnScreenshotEncodeComplete(int unique_id,
+ scoped_refptr<ScreenshotData> data);
+
+ // Removes the screenshot for the entry, returning true if the entry had a
+ // screenshot.
+ bool ClearScreenshot(NavigationEntryImpl* entry);
+
+ // The screenshots in the NavigationEntryImpls can accumulate and consume a
+ // large amount of memory. This function makes sure that the memory
+ // consumption is within a certain limit.
+ void PurgeScreenshotsIfNecessary();
+
+ // The navigation controller that owns this screenshot-manager.
+ NavigationControllerImpl* owner_;
+
+ // Taking a screenshot and encoding them can be async. So use a weakptr for
+ // the callback to make sure that the screenshot/encoding completion callback
+ // does not trigger on a destroyed WebContentsScreenshotManager.
+ base::WeakPtrFactory<WebContentsScreenshotManager> screenshot_factory_;
+
+ base::Time last_screenshot_time_;
+ int min_screenshot_interval_ms_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebContentsScreenshotManager);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_SCREENSHOT_MANAGER_H_
diff --git a/content/browser/web_contents/web_contents_view_android.cc b/content/browser/web_contents/web_contents_view_android.cc
index 28ce304..1540d95 100644
--- a/content/browser/web_contents/web_contents_view_android.cc
+++ b/content/browser/web_contents/web_contents_view_android.cc
@@ -6,7 +6,7 @@
#include "base/logging.h"
#include "content/browser/android/content_view_core_impl.h"
-#include "content/browser/android/media_player_manager_android.h"
+#include "content/browser/android/media_player_manager_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h"
#include "content/browser/renderer_host/render_view_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -54,17 +54,25 @@
}
}
+#if defined(GOOGLE_TV)
void WebContentsViewAndroid::RequestExternalVideoSurface(int player_id) {
if (content_view_core_)
content_view_core_->RequestExternalVideoSurface(player_id);
}
+void WebContentsViewAndroid::NotifyGeometryChange(int player_id,
+ const gfx::RectF& rect) {
+ if (content_view_core_)
+ content_view_core_->NotifyGeometryChange(player_id, rect);
+}
+#endif
+
gfx::NativeView WebContentsViewAndroid::GetNativeView() const {
- return content_view_core_;
+ return content_view_core_->GetViewAndroid();
}
gfx::NativeView WebContentsViewAndroid::GetContentNativeView() const {
- return content_view_core_;
+ return content_view_core_->GetViewAndroid();
}
gfx::NativeWindow WebContentsViewAndroid::GetTopLevelNativeWindow() const {
@@ -177,7 +185,7 @@
void WebContentsViewAndroid::ShowContextMenu(
const ContextMenuParams& params,
ContextMenuSourceType type) {
- if (delegate_.get())
+ if (delegate_)
delegate_->ShowContextMenu(params, type);
}
diff --git a/content/browser/web_contents/web_contents_view_android.h b/content/browser/web_contents/web_contents_view_android.h
index a882ae5..dcfaf39 100644
--- a/content/browser/web_contents/web_contents_view_android.h
+++ b/content/browser/web_contents/web_contents_view_android.h
@@ -11,6 +11,7 @@
#include "content/port/browser/web_contents_view_port.h"
#include "content/public/browser/web_contents_view_delegate.h"
#include "content/public/common/context_menu_params.h"
+#include "ui/gfx/rect_f.h"
namespace content {
class ContentViewCoreImpl;
@@ -28,7 +29,10 @@
// by the UI frontend.
void SetContentViewCore(ContentViewCoreImpl* content_view_core);
+#if defined(GOOGLE_TV)
void RequestExternalVideoSurface(int player_id);
+ void NotifyGeometryChange(int player_id, const gfx::RectF& rect);
+#endif
// WebContentsView implementation --------------------------------------------
virtual gfx::NativeView GetNativeView() const OVERRIDE;
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
index 791bbd3..7fe338c 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -13,8 +13,11 @@
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
+#include "content/browser/web_contents/aura/image_window_delegate.h"
+#include "content/browser/web_contents/aura/shadow_layer_delegate.h"
#include "content/browser/web_contents/interstitial_page_impl.h"
#include "content/browser/web_contents/navigation_entry_impl.h"
+#include "content/browser/web_contents/touch_editable_impl_aura.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
@@ -29,7 +32,6 @@
#include "content/public/browser/web_contents_view_delegate.h"
#include "content/public/browser/web_drag_dest_delegate.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
-#include "third_party/skia/include/effects/SkGradientShader.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/drag_drop_client.h"
#include "ui/aura/client/drag_drop_delegate.h"
@@ -51,7 +53,6 @@
#include "ui/gfx/image/image_png_rep.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/screen.h"
-#include "ui/gfx/skia_util.h"
#include "webkit/glue/webdropdata.h"
#if defined(OS_WIN)
@@ -70,18 +71,6 @@
namespace {
-const SkColor kShadowLightColor = SkColorSetARGB(0x0, 0, 0, 0);
-const SkColor kShadowDarkColor = SkColorSetARGB(0x70, 0, 0, 0);
-const int kShadowThick = 7;
-
-enum ShadowEdge {
- SHADOW_NONE,
- SHADOW_LEFT,
- SHADOW_RIGHT,
- SHADOW_TOP,
- SHADOW_BOTTOM
-};
-
bool ShouldNavigateForward(const NavigationController& controller,
OverscrollMode mode) {
return mode == (base::i18n::IsRTL() ? OVERSCROLL_EAST : OVERSCROLL_WEST) &&
@@ -94,15 +83,25 @@
controller.CanGoBack();
}
+RenderWidgetHostViewAura* ToRenderWidgetHostViewAura(
+ RenderWidgetHostView* view) {
+ if (!view || RenderViewHostFactory::has_factory())
+ return NULL; // Can't cast to RenderWidgetHostViewAura in unit tests.
+ RenderProcessHostImpl* process = static_cast<RenderProcessHostImpl*>(
+ view->GetRenderWidgetHost()->GetProcess());
+ if (process->IsGuest())
+ return NULL;
+ return static_cast<RenderWidgetHostViewAura*>(view);
+}
+
// The window delegate for the overscroll window. This redirects trackpad events
// to the web-contents window. The delegate destroys itself when the window is
// destroyed.
-class OverscrollWindowDelegate : public aura::WindowDelegate {
+class OverscrollWindowDelegate : public ImageWindowDelegate {
public:
OverscrollWindowDelegate(WebContentsImpl* web_contents,
OverscrollMode overscroll_mode)
: web_contents_(web_contents),
- show_shadow_(false),
forward_events_(true) {
const NavigationControllerImpl& controller = web_contents->GetController();
const NavigationEntryImpl* entry = NULL;
@@ -113,21 +112,15 @@
entry = NavigationEntryImpl::FromNavigationEntry(
controller.GetEntryAtOffset(-1));
}
- if (!entry || !entry->screenshot())
- return;
- std::vector<gfx::ImagePNGRep> image_reps;
- image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(),
- ui::GetScaleFactorForNativeView(web_contents_window())));
- image_ = gfx::Image(image_reps);
- if (image_.AsImageSkia().size() != web_contents_window()->bounds().size())
- image_ = gfx::Image();
- }
-
- bool has_screenshot() const { return !image_.IsEmpty(); }
-
- void set_show_shadow(bool show) {
- show_shadow_ = show;
+ gfx::Image image;
+ if (entry && entry->screenshot()) {
+ std::vector<gfx::ImagePNGRep> image_reps;
+ image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(),
+ ui::GetScaleFactorForNativeView(web_contents_window())));
+ image = gfx::Image(image_reps);
+ }
+ SetImage(image);
}
void stop_forwarding_events() { forward_events_ = false; }
@@ -139,94 +132,6 @@
return web_contents_->GetView()->GetContentNativeView();
}
- // aura::WindowDelegate implementation:
- virtual gfx::Size GetMinimumSize() const OVERRIDE {
- return gfx::Size();
- }
-
- virtual gfx::Size GetMaximumSize() const OVERRIDE {
- return gfx::Size();
- }
-
- virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) OVERRIDE {
- }
-
- virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE {
- return gfx::kNullCursor;
- }
-
- virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE {
- return HTNOWHERE;
- }
-
- virtual bool ShouldDescendIntoChildForEventHandling(
- aura::Window* child,
- const gfx::Point& location) OVERRIDE {
- return false;
- }
-
- virtual bool CanFocus() OVERRIDE {
- return false;
- }
-
- virtual void OnCaptureLost() OVERRIDE {
- }
-
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
- if (show_shadow_) {
- canvas->Save();
- canvas->Translate(gfx::Vector2d(kShadowThick, 0));
- }
- if (image_.IsEmpty())
- canvas->DrawColor(SK_ColorGRAY);
- else
- canvas->DrawImageInt(image_.AsImageSkia(), 0, 0);
-
- if (show_shadow_) {
- canvas->Restore();
- SkPoint points[2];
- points[0].iset(0, 0);
- points[1].iset(kShadowThick, 0);
- SkColor colors[2] = { kShadowLightColor, kShadowDarkColor };
- skia::RefPtr<SkShader> shader = skia::AdoptRef(
- SkGradientShader::CreateLinear(points, colors, NULL,
- arraysize(points), SkShader::kRepeat_TileMode, NULL));
-
- SkRect rect = { SkIntToScalar(0),
- SkIntToScalar(0),
- SkIntToScalar(kShadowThick),
- SkIntToScalar(web_contents_window()->bounds().height()) };
- SkPaint paint;
- paint.setShader(shader.get());
- canvas->sk_canvas()->drawRect(rect, paint);
- }
- }
-
- virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
- }
-
- virtual void OnWindowDestroying() OVERRIDE {
- }
-
- virtual void OnWindowDestroyed() OVERRIDE {
- delete this;
- }
-
- virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {
- }
-
- virtual bool HasHitTestMask() const OVERRIDE {
- return false;
- }
-
- virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE {
- }
-
- virtual scoped_refptr<ui::Texture> CopyTexture() OVERRIDE {
- return scoped_refptr<ui::Texture>();
- }
-
// Overridden from ui::EventHandler.
virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
if (forward_events_ && web_contents_window())
@@ -239,8 +144,6 @@
}
WebContents* web_contents_;
- gfx::Image image_;
- bool show_shadow_;
// The window is displayed both during the gesture, and after the gesture
// while the navigation is in progress. During the gesture, it is necessary to
@@ -255,19 +158,20 @@
// Listens to all mouse drag events during a drag and drop and sends them to
// the renderer.
-class WebDragSourceAura : public MessageLoopForUI::Observer,
+class WebDragSourceAura : public base::MessageLoopForUI::Observer,
public NotificationObserver {
public:
WebDragSourceAura(aura::Window* window, WebContentsImpl* contents)
: window_(window),
contents_(contents) {
- MessageLoopForUI::current()->AddObserver(this);
- registrar_.Add(this, NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
+ base::MessageLoopForUI::current()->AddObserver(this);
+ registrar_.Add(this,
+ NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
Source<WebContents>(contents));
}
virtual ~WebDragSourceAura() {
- MessageLoopForUI::current()->RemoveObserver(this);
+ base::MessageLoopForUI::current()->RemoveObserver(this);
}
// MessageLoop::Observer implementation:
@@ -291,7 +195,7 @@
aura::Window* window = rvh->GetView()->GetNativeView();
aura::Window::ConvertPointToTarget(window->GetRootWindow(),
window, &client_loc);
- rvh->DragSourceMovedTo(client_loc.x(), client_loc.y(),
+ contents_->DragSourceMovedTo(client_loc.x(), client_loc.y(),
screen_loc.x(), screen_loc.y());
}
break;
@@ -446,142 +350,6 @@
} // namespace
-// ShadowWindow is used to paint shadows around a content window.
-// A ShadowWindow destroys itself when the content window is destroyed, and
-// updates its bounds to make sure the shadows are painted in the correct size.
-class ShadowWindow : public aura::Window,
- public aura::WindowObserver {
- public:
- explicit ShadowWindow(aura::Window* window)
- : aura::Window(NULL),
- window_(window),
- edge_(SHADOW_NONE) {
- SetType(aura::client::WINDOW_TYPE_CONTROL);
- SetTransparent(true);
- set_owned_by_parent(false);
- Init(ui::LAYER_NOT_DRAWN);
- layer()->SetMasksToBounds(false);
-
- AddChild(window);
- window_->AddObserver(this);
-
- SetBounds(gfx::Rect(window->bounds().size()));
- Show();
- }
-
- void SetShadowEdge(ShadowEdge edge) {
- edge_ = edge;
- if (edge_ == SHADOW_NONE) {
- shadow_.reset();
- return;
- }
-
- shadow_.reset(new ui::Layer(ui::LAYER_TEXTURED));
- shadow_->set_delegate(this);
- shadow_->SetFillsBoundsOpaquely(false);
- layer()->Add(shadow_.get());
- layer()->StackBelow(shadow_.get(), window_->layer());
- UpdateShadowBounds();
- }
-
- private:
- friend class base::DeleteHelper<content::ShadowWindow>;
-
- virtual ~ShadowWindow() {
- }
-
- void UpdateShadowBounds() {
- if (!shadow_.get())
- return;
- gfx::Rect bound;
- switch (edge_) {
- case SHADOW_LEFT:
- bound.SetRect(-kShadowThick, 0, kShadowThick, bounds().height());
- break;
- case SHADOW_RIGHT:
- bound.SetRect(bounds().right(), 0, kShadowThick, bounds().height());
- break;
- case SHADOW_TOP:
- bound.SetRect(0, -kShadowThick, bounds().width(), kShadowThick);
- break;
- case SHADOW_BOTTOM:
- bound.SetRect(0, bounds().bottom(), bounds().width(), kShadowThick);
- break;
- case SHADOW_NONE:
- NOTREACHED();
- }
- shadow_->SetBounds(bound);
- }
-
- // Overridden from aura::WindowObserver:
- virtual void OnWindowBoundsChanged(Window* window,
- const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) OVERRIDE {
- SetBounds(gfx::Rect(new_bounds.size()));
- UpdateShadowBounds();
- }
-
- virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
- DCHECK_EQ(window, window_);
- window_->RemoveObserver(this);
- window_ = NULL;
- MessageLoop::current()->DeleteSoon(FROM_HERE, this);
- }
-
- // Overridden from ui::LayerDelegate:
- virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
- SkPoint points[2];
- SkColor colors[2];
-
- points[0].iset(0, 0);
- switch (edge_) {
- case SHADOW_LEFT:
- case SHADOW_RIGHT:
- points[1].iset(shadow_->bounds().width(), 0);
- break;
-
- case SHADOW_TOP:
- case SHADOW_BOTTOM:
- points[1].iset(0, shadow_->bounds().height());
- break;
-
- default:
- NOTREACHED();
- }
-
- switch (edge_) {
- case SHADOW_LEFT:
- case SHADOW_TOP:
- colors[0] = kShadowLightColor;
- colors[1] = kShadowDarkColor;
- break;
-
- case SHADOW_RIGHT:
- case SHADOW_BOTTOM:
- colors[0] = kShadowDarkColor;
- colors[1] = kShadowLightColor;
- break;
-
- default:
- NOTREACHED();
- }
-
- skia::RefPtr<SkShader> shader = skia::AdoptRef(
- SkGradientShader::CreateLinear(points, colors, NULL,
- arraysize(points), SkShader::kRepeat_TileMode, NULL));
-
- SkPaint paint;
- paint.setShader(shader.get());
- canvas->sk_canvas()->drawRect(gfx::RectToSkRect(bounds()), paint);
- }
-
- aura::Window* window_;
- scoped_ptr<ui::Layer> shadow_;
- ShadowEdge edge_;
-
- DISALLOW_COPY_AND_ASSIGN(ShadowWindow);
-};
-
// When a history navigation is triggered at the end of an overscroll
// navigation, it is necessary to show the history-screenshot until the page is
// done navigating and painting. This class accomplishes this by showing the
@@ -614,7 +382,8 @@
received_paint_update_ = false;
compositor_updated_ = false;
view_ = view;
- view_->set_paint_observer(this);
+ if (view_)
+ view_->set_paint_observer(this);
// Make sure the overlay window is on top.
if (window_.get() && window_->parent())
@@ -727,6 +496,8 @@
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) OVERRIDE {
SendScreenRects();
+ if (view_->touch_editable_)
+ view_->touch_editable_->UpdateEditingController();
}
virtual void OnWindowAddedToRootWindow(aura::Window* window) OVERRIDE {
@@ -788,16 +559,22 @@
// We also start watching them to know when their size is updated. Of
// course, ignore the shadow window that contains the RWHV and child windows
// of the child windows that we are watching.
+ RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
+ view_->web_contents_->GetRenderWidgetHostView());
+ aura::Window* content_window = view ? view->GetNativeView() : NULL;
if (new_window->parent() == view_->window_ &&
- new_window != view_->content_container_) {
+ new_window != content_window) {
new_window->AddObserver(this);
UpdateConstrainedWindows(NULL);
}
}
virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE {
+ RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
+ view_->web_contents_->GetRenderWidgetHostView());
+ aura::Window* content_window = view ? view->GetNativeView() : NULL;
if (window->parent() == view_->window_ &&
- window != view_->content_container_) {
+ window != content_window) {
window->RemoveObserver(this);
UpdateConstrainedWindows(window);
}
@@ -807,7 +584,7 @@
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) OVERRIDE {
if (window->parent() == view_->window_ &&
- window != view_->content_container_) {
+ window != view_->GetContentNativeView()) {
UpdateConstrainedWindows(NULL);
}
}
@@ -819,21 +596,19 @@
private:
void UpdateConstrainedWindows(aura::Window* exclude) {
- if (RenderViewHostFactory::has_factory())
- return; // Can't cast to RenderWidgetHostViewAura in unit tests.
-
if (web_contents_destroyed_)
return;
- RenderWidgetHostViewAura* view = static_cast<RenderWidgetHostViewAura*>(
+ RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
view_->web_contents_->GetRenderWidgetHostView());
if (!view)
return;
std::vector<gfx::Rect> constrained_windows;
const aura::Window::Windows& children = view_->window_->children();
+ aura::Window* content = view_->GetContentNativeView();
for (size_t i = 0; i < children.size(); ++i) {
- if (children[i] != view_->content_container_ && children[i] != exclude)
+ if (children[i] != content && children[i] != exclude)
constrained_windows.push_back(children[i]->GetBoundsInRootWindow());
}
@@ -858,10 +633,10 @@
current_drag_op_(WebKit::WebDragOperationNone),
drag_dest_delegate_(NULL),
current_rvh_for_drag_(NULL),
- content_container_(NULL),
overscroll_change_brightness_(false),
current_overscroll_gesture_(OVERSCROLL_NONE),
- completed_overscroll_gesture_(OVERSCROLL_NONE) {
+ completed_overscroll_gesture_(OVERSCROLL_NONE),
+ touch_editable_(TouchEditableImplAura::Create()) {
}
////////////////////////////////////////////////////////////////////////////////
@@ -881,10 +656,16 @@
}
void WebContentsViewAura::SetupOverlayWindowForTesting() {
- if (navigation_overlay_.get())
+ if (navigation_overlay_)
navigation_overlay_->SetupForTesting();
}
+void WebContentsViewAura::SetTouchEditableForTest(
+ TouchEditableImplAura* touch_editable) {
+ touch_editable_.reset(touch_editable);
+ AttachTouchEditableToRenderView();
+}
+
void WebContentsViewAura::SizeChangedCommon(const gfx::Size& size) {
if (web_contents_->GetInterstitialPage())
web_contents_->GetInterstitialPage()->SetSize(size);
@@ -902,8 +683,10 @@
RenderViewHost* rvh = web_contents_->GetRenderViewHost();
aura::Window* window = rvh->GetView()->GetNativeView();
aura::Window::ConvertPointToTarget(root_window, window, &client_loc);
- rvh->DragSourceEndedAt(client_loc.x(), client_loc.y(), screen_loc.x(),
- screen_loc.y(), ops);
+ if (!web_contents_)
+ return;
+ web_contents_->DragSourceEndedAt(client_loc.x(), client_loc.y(),
+ screen_loc.x(), screen_loc.y(), ops);
}
void WebContentsViewAura::PrepareOverscrollWindow() {
@@ -912,7 +695,7 @@
// completed immidiately, which triggers |OnImplicitAnimationsCompleted()|
// callback, and that tries to reset |overscroll_window_| again, causing a
// double-free. So use a temporary variable here.
- if (overscroll_window_.get()) {
+ if (overscroll_window_) {
base::AutoReset<OverscrollMode> reset_state(¤t_overscroll_gesture_,
current_overscroll_gesture_);
scoped_ptr<aura::Window> reset_window(overscroll_window_.release());
@@ -925,10 +708,10 @@
overscroll_window_->SetType(aura::client::WINDOW_TYPE_CONTROL);
overscroll_window_->SetTransparent(true);
overscroll_window_->Init(ui::LAYER_TEXTURED);
- overscroll_window_->layer()->SetMasksToBounds(true);
+ overscroll_window_->layer()->SetMasksToBounds(false);
overscroll_window_->SetName("OverscrollOverlay");
- overscroll_change_brightness_ = overscroll_delegate->has_screenshot();
+ overscroll_change_brightness_ = overscroll_delegate->has_image();
window_->AddChild(overscroll_window_.get());
gfx::Rect bounds = gfx::Rect(window_->bounds().size());
@@ -940,46 +723,22 @@
bounds.Offset(base::i18n::IsRTL() ? -bounds.width() : bounds.width(), 0);
}
- if (GetWindowToAnimateForOverscroll() == overscroll_window_.get()) {
- overscroll_delegate->set_show_shadow(true);
- window_->StackChildAbove(overscroll_window_.get(), content_container_);
- } else {
- window_->StackChildBelow(overscroll_window_.get(), content_container_);
-
- switch (current_overscroll_gesture_) {
- case OVERSCROLL_EAST:
- content_container_->SetShadowEdge(SHADOW_LEFT);
- break;
-
- case OVERSCROLL_WEST:
- content_container_->SetShadowEdge(SHADOW_RIGHT);
- break;
-
- case OVERSCROLL_NORTH:
- content_container_->SetShadowEdge(SHADOW_BOTTOM);
- break;
-
- case OVERSCROLL_SOUTH:
- content_container_->SetShadowEdge(SHADOW_TOP);
- break;
-
- case OVERSCROLL_NONE:
- case OVERSCROLL_COUNT:
- NOTREACHED();
- }
- }
+ aura::Window* animate_window = GetWindowToAnimateForOverscroll();
+ if (animate_window == overscroll_window_)
+ window_->StackChildAbove(overscroll_window_.get(), GetContentNativeView());
+ else
+ window_->StackChildBelow(overscroll_window_.get(), GetContentNativeView());
UpdateOverscrollWindowBrightness(0.f);
overscroll_window_->SetBounds(bounds);
overscroll_window_->Show();
+
+ overscroll_shadow_.reset(new ShadowLayerDelegate(animate_window));
}
void WebContentsViewAura::PrepareContentWindowForOverscroll() {
- DCHECK(content_container_);
- DCHECK_EQ(content_container_, GetContentNativeView()->parent());
-
- aura::Window* content = content_container_;
+ aura::Window* content = GetContentNativeView();
ui::ScopedLayerAnimationSettings settings(content->layer()->GetAnimator());
settings.SetPreemptionStrategy(ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET);
content->SetTransform(gfx::Transform());
@@ -1043,7 +802,7 @@
return ShouldNavigateForward(web_contents_->GetController(),
current_overscroll_gesture_) ?
- overscroll_window_.get() : content_container_;
+ overscroll_window_.get() : GetContentNativeView();
}
gfx::Vector2d WebContentsViewAura::GetTranslationForOverscroll(int delta_x,
@@ -1069,14 +828,13 @@
void WebContentsViewAura::PrepareOverscrollNavigationOverlay() {
OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>(
overscroll_window_->delegate());
- delegate->set_show_shadow(false);
delegate->stop_forwarding_events();
overscroll_window_->SchedulePaintInRect(
gfx::Rect(overscroll_window_->bounds().size()));
navigation_overlay_->SetOverlayWindow(overscroll_window_.Pass(),
- delegate->has_screenshot());
- navigation_overlay_->StartObservingView(static_cast<
- RenderWidgetHostViewAura*>(web_contents_->GetRenderWidgetHostView()));
+ delegate->has_image());
+ navigation_overlay_->StartObservingView(ToRenderWidgetHostViewAura(
+ web_contents_->GetRenderWidgetHostView()));
}
void WebContentsViewAura::UpdateOverscrollWindowBrightness(float delta_x) {
@@ -1099,6 +857,14 @@
window->layer()->SetLayerBrightness(brightness);
}
+void WebContentsViewAura::AttachTouchEditableToRenderView() {
+ if (!touch_editable_)
+ return;
+ RenderWidgetHostViewAura* rwhva = ToRenderWidgetHostViewAura(
+ web_contents_->GetRenderWidgetHostView());
+ touch_editable_->AttachToView(rwhva);
+}
+
////////////////////////////////////////////////////////////////////////////////
// WebContentsViewAura, WebContentsView implementation:
@@ -1161,12 +927,12 @@
}
void WebContentsViewAura::StoreFocus() {
- if (delegate_.get())
+ if (delegate_)
delegate_->StoreFocus();
}
void WebContentsViewAura::RestoreFocus() {
- if (delegate_.get())
+ if (delegate_)
delegate_->RestoreFocus();
}
@@ -1218,7 +984,7 @@
// delegate_->GetDragDestDelegate() creates a new delegate on every call.
// Hence, we save a reference to it locally. Similar model is used on other
// platforms as well.
- if (delegate_.get())
+ if (delegate_)
drag_dest_delegate_ = delegate_->GetDragDestDelegate();
}
@@ -1237,12 +1003,10 @@
RenderWidgetHostView* view =
RenderWidgetHostView::CreateViewForWidget(render_widget_host);
view->InitAsChild(NULL);
- content_container_ = new ShadowWindow(view->GetNativeView());
- GetNativeView()->AddChild(content_container_);
+ GetNativeView()->AddChild(view->GetNativeView());
if (navigation_overlay_.get() && navigation_overlay_->has_window()) {
- navigation_overlay_->StartObservingView(static_cast<
- RenderWidgetHostViewAura*>(view));
+ navigation_overlay_->StartObservingView(ToRenderWidgetHostViewAura(view));
}
view->Show();
@@ -1256,10 +1020,11 @@
(!web_contents_->GetDelegate() ||
web_contents_->GetDelegate()->CanOverscrollContent())) {
host_impl->overscroll_controller()->set_delegate(this);
- if (!navigation_overlay_.get())
+ if (!navigation_overlay_)
navigation_overlay_.reset(new OverscrollNavigationOverlay());
}
+ AttachTouchEditableToRenderView();
return view;
}
@@ -1277,9 +1042,10 @@
void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) {
if (navigation_overlay_.get() && navigation_overlay_->has_window()) {
- navigation_overlay_->StartObservingView(static_cast<
- RenderWidgetHostViewAura*>(host->GetView()));
+ navigation_overlay_->StartObservingView(
+ ToRenderWidgetHostViewAura(host->GetView()));
}
+ AttachTouchEditableToRenderView();
}
void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) {
@@ -1298,8 +1064,11 @@
void WebContentsViewAura::ShowContextMenu(
const ContextMenuParams& params,
ContextMenuSourceType type) {
- if (delegate_.get())
+ if (delegate_)
delegate_->ShowContextMenu(params, type);
+ if (touch_editable_)
+ touch_editable_->EndTouchEditing();
+
}
void WebContentsViewAura::ShowPopupMenu(const gfx::Rect& bounds,
@@ -1320,8 +1089,13 @@
const gfx::Vector2d& image_offset,
const DragEventSourceInfo& event_info) {
aura::RootWindow* root_window = GetNativeView()->GetRootWindow();
- if (!aura::client::GetDragDropClient(root_window))
+ if (!aura::client::GetDragDropClient(root_window)) {
+ web_contents_->SystemDragEnded();
return;
+ }
+
+ if (touch_editable_)
+ touch_editable_->EndTouchEditing();
ui::OSExchangeData::Provider* provider = ui::OSExchangeData::CreateProvider();
PrepareDragData(drop_data, provider);
@@ -1341,23 +1115,29 @@
int result_op = 0;
{
gfx::NativeView content_native_view = GetContentNativeView();
- MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
- result_op = aura::client::GetDragDropClient(root_window)->StartDragAndDrop(
- data, root_window, content_native_view,
- event_info.event_location, ConvertFromWeb(operations),
- event_info.event_source);
+ base::MessageLoop::ScopedNestableTaskAllower allow(
+ base::MessageLoop::current());
+ result_op = aura::client::GetDragDropClient(root_window)
+ ->StartDragAndDrop(data,
+ root_window,
+ content_native_view,
+ event_info.event_location,
+ ConvertFromWeb(operations),
+ event_info.event_source);
}
// Bail out immediately if the contents view window is gone. Note that it is
- // not safe to access any class members after system drag-and-drop returns
- // since the class instance might be gone. The local variable |drag_source|
- // is still valid and we can check its window property that is set to NULL
- // when the contents are gone.
- if (!drag_source->window())
+ // not safe to access any class members in this case since |this| may already
+ // be destroyed. The local variable |drag_source| will still be valid though,
+ // so we can use it to determine if the window is gone.
+ if (!drag_source->window()) {
+ // Note that in this case, we don't need to call SystemDragEnded() since the
+ // renderer is going away.
return;
+ }
EndDrag(ConvertToWeb(result_op));
- web_contents_->GetRenderViewHost()->DragSourceSystemDragEnded();
+ web_contents_->SystemDragEnded();
}
void WebContentsViewAura::UpdateDragCursor(WebKit::WebDragOperation operation) {
@@ -1413,15 +1193,8 @@
// Reset any in-progress overscroll animation first.
ResetOverscrollTransform();
- // Make sure the content window has been prepared correctly before allowing
- // overscroll.
- bool content_window_ready =
- content_container_ &&
- GetContentNativeView() &&
- GetContentNativeView()->parent() == content_container_;
-
if (new_mode == OVERSCROLL_NONE ||
- !content_window_ready ||
+ !GetContentNativeView() ||
(navigation_overlay_.get() && navigation_overlay_->has_window())) {
current_overscroll_gesture_ = OVERSCROLL_NONE;
} else {
@@ -1441,6 +1214,8 @@
// WebContentsViewAura, ui::ImplicitAnimationObserver implementation:
void WebContentsViewAura::OnImplicitAnimationsCompleted() {
+ overscroll_shadow_.reset();
+
if (ShouldNavigateForward(web_contents_->GetController(),
completed_overscroll_gesture_)) {
PrepareOverscrollNavigationOverlay();
@@ -1451,10 +1226,10 @@
web_contents_->GetController().GoBack();
}
- if (GetContentNativeView()) {
- content_container_->SetTransform(gfx::Transform());
- content_container_->layer()->SetLayerBrightness(0.f);
- content_container_->SetShadowEdge(SHADOW_NONE);
+ aura::Window* content = GetContentNativeView();
+ if (content) {
+ content->SetTransform(gfx::Transform());
+ content->layer()->SetLayerBrightness(0.f);
}
current_overscroll_gesture_ = OVERSCROLL_NONE;
completed_overscroll_gesture_ = OVERSCROLL_NONE;
@@ -1475,7 +1250,7 @@
void WebContentsViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) {
SizeChangedCommon(new_bounds.size());
- if (delegate_.get())
+ if (delegate_)
delegate_->SizeChanged(new_bounds.size());
// Constrained web dialogs, need to be kept centered over our content area.
diff --git a/content/browser/web_contents/web_contents_view_aura.h b/content/browser/web_contents/web_contents_view_aura.h
index f619352..54425e2 100644
--- a/content/browser/web_contents/web_contents_view_aura.h
+++ b/content/browser/web_contents/web_contents_view_aura.h
@@ -27,7 +27,8 @@
namespace content {
class OverscrollNavigationOverlay;
-class ShadowWindow;
+class ShadowLayerDelegate;
+class TouchEditableImplAura;
class WebContentsViewDelegate;
class WebContentsImpl;
class WebDragDestDelegate;
@@ -45,6 +46,8 @@
void SetupOverlayWindowForTesting();
+ void SetTouchEditableForTest(TouchEditableImplAura* touch_editable);
+
private:
class WindowObserver;
#if defined(OS_WIN)
@@ -92,6 +95,8 @@
// overscroll (|delta_x|, in pixels).
void UpdateOverscrollWindowBrightness(float delta_x);
+ void AttachTouchEditableToRenderView();
+
// Overridden from WebContentsView:
virtual gfx::NativeView GetNativeView() const OVERRIDE;
virtual gfx::NativeView GetContentNativeView() const OVERRIDE;
@@ -207,10 +212,6 @@
// pointers.
void* current_rvh_for_drag_;
- // The container for the content-window. The doc for ShadowWindow explains its
- // lifetime and ownership.
- ShadowWindow* content_container_;
-
bool overscroll_change_brightness_;
// The overscroll gesture currently in progress.
@@ -224,6 +225,10 @@
// navigation triggered by the overscroll gesture.
scoped_ptr<OverscrollNavigationOverlay> navigation_overlay_;
+ scoped_ptr<ShadowLayerDelegate> overscroll_shadow_;
+
+ scoped_ptr<TouchEditableImplAura> touch_editable_;
+
DISALLOW_COPY_AND_ASSIGN(WebContentsViewAura);
};
diff --git a/content/browser/web_contents/web_contents_view_aura_browsertest.cc b/content/browser/web_contents/web_contents_view_aura_browsertest.cc
index 476bec6..a5cdf57 100644
--- a/content/browser/web_contents/web_contents_view_aura_browsertest.cc
+++ b/content/browser/web_contents/web_contents_view_aura_browsertest.cc
@@ -13,6 +13,7 @@
#include "content/browser/web_contents/navigation_controller_impl.h"
#include "content/browser/web_contents/navigation_entry_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/web_contents/web_contents_screenshot_manager.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
@@ -27,24 +28,16 @@
namespace content {
-// A dummy callback to reset the screenshot-taker callback.
-void DummyCallback(RenderViewHost* host) {
-}
-
// This class keeps track of the RenderViewHost whose screenshot was captured.
-class ScreenshotTracker {
+class ScreenshotTracker : public WebContentsScreenshotManager {
public:
explicit ScreenshotTracker(NavigationControllerImpl* controller)
- : screenshot_taken_for_(NULL),
- controller_(controller) {
- controller_->SetTakeScreenshotCallbackForTest(
- base::Bind(&ScreenshotTracker::TakeScreenshotCallback,
- base::Unretained(this)));
+ : WebContentsScreenshotManager(controller),
+ screenshot_taken_for_(NULL),
+ waiting_for_screenshots_(0) {
}
virtual ~ScreenshotTracker() {
- controller_->SetTakeScreenshotCallbackForTest(
- base::Bind(&DummyCallback));
}
RenderViewHost* screenshot_taken_for() { return screenshot_taken_for_; }
@@ -53,20 +46,45 @@
screenshot_taken_for_ = NULL;
}
+ void SetScreenshotInterval(int interval_ms) {
+ SetMinScreenshotIntervalMS(interval_ms);
+ }
+
+ void WaitUntilScreenshotIsReady() {
+ if (!waiting_for_screenshots_)
+ return;
+ message_loop_runner_ = new content::MessageLoopRunner;
+ message_loop_runner_->Run();
+ }
+
private:
- void TakeScreenshotCallback(RenderViewHost* host) {
+ // Overridden from WebContentsScreenshotManager:
+ virtual void TakeScreenshotImpl(RenderViewHost* host,
+ NavigationEntryImpl* entry) OVERRIDE {
+ ++waiting_for_screenshots_;
screenshot_taken_for_ = host;
+ WebContentsScreenshotManager::TakeScreenshotImpl(host, entry);
+ }
+
+ virtual void OnScreenshotSet(NavigationEntryImpl* entry) OVERRIDE {
+ --waiting_for_screenshots_;
+ WebContentsScreenshotManager::OnScreenshotSet(entry);
+ if (waiting_for_screenshots_ == 0 && message_loop_runner_)
+ message_loop_runner_->Quit();
}
RenderViewHost* screenshot_taken_for_;
- NavigationControllerImpl* controller_;
+ scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
+ int waiting_for_screenshots_;
DISALLOW_COPY_AND_ASSIGN(ScreenshotTracker);
};
class WebContentsViewAuraTest : public ContentBrowserTest {
public:
- WebContentsViewAuraTest() {}
+ WebContentsViewAuraTest()
+ : screenshot_manager_(NULL) {
+ }
// Executes the javascript synchronously and makes sure the returned value is
// freed properly.
@@ -85,6 +103,13 @@
aura::Window* content =
shell()->web_contents()->GetView()->GetContentNativeView();
content->GetRootWindow()->SetHostSize(gfx::Size(800, 600));
+
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ NavigationControllerImpl* controller = &web_contents->GetController();
+
+ screenshot_manager_ = new ScreenshotTracker(controller);
+ controller->SetScreenshotManager(screenshot_manager_);
}
void TestOverscrollNavigation(bool touch_handler) {
@@ -190,7 +215,15 @@
return index;
}
+ protected:
+ ScreenshotTracker* screenshot_manager() { return screenshot_manager_; }
+ void set_min_screenshot_interval(int interval_ms) {
+ screenshot_manager_->SetScreenshotInterval(interval_ms);
+ }
+
private:
+ ScreenshotTracker* screenshot_manager_;
+
DISALLOW_COPY_AND_ASSIGN(WebContentsViewAuraTest);
};
@@ -299,11 +332,14 @@
RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
web_contents->GetRenderViewHost());
+ set_min_screenshot_interval(0);
+
// Do a few navigations initiated by the page.
ExecuteSyncJSFunction(view_host, "navigate_next()");
EXPECT_EQ(1, GetCurrentIndex());
ExecuteSyncJSFunction(view_host, "navigate_next()");
EXPECT_EQ(2, GetCurrentIndex());
+ screenshot_manager()->WaitUntilScreenshotIsReady();
// The current entry won't have any screenshots. But the entries in the
// history should now have screenshots.
@@ -322,6 +358,7 @@
// Navigate again. Index 2 should now have a screenshot.
ExecuteSyncJSFunction(view_host, "navigate_next()");
EXPECT_EQ(3, GetCurrentIndex());
+ screenshot_manager()->WaitUntilScreenshotIsReady();
entry = NavigationEntryImpl::FromNavigationEntry(
web_contents->GetController().GetEntryAtIndex(2));
@@ -347,6 +384,7 @@
string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
EXPECT_EQ(2, GetCurrentIndex());
+ screenshot_manager()->WaitUntilScreenshotIsReady();
entry = NavigationEntryImpl::FromNavigationEntry(
web_contents->GetController().GetEntryAtIndex(3));
EXPECT_TRUE(entry->screenshot().get());
@@ -357,6 +395,7 @@
EXPECT_EQ(3, GetCurrentIndex());
ExecuteSyncJSFunction(view_host, "navigate_next()");
EXPECT_EQ(4, GetCurrentIndex());
+ screenshot_manager()->WaitUntilScreenshotIsReady();
entry = NavigationEntryImpl::FromNavigationEntry(
web_contents->GetController().GetEntryAtIndex(4));
EXPECT_FALSE(entry->screenshot().get());
@@ -369,6 +408,7 @@
string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
EXPECT_EQ(3, GetCurrentIndex());
+ screenshot_manager()->WaitUntilScreenshotIsReady();
entry = NavigationEntryImpl::FromNavigationEntry(
web_contents->GetController().GetEntryAtIndex(4));
EXPECT_TRUE(entry->screenshot().get());
@@ -382,14 +422,15 @@
ASSERT_NO_FATAL_FAILURE(
StartTestWithPage("files/overscroll_navigation.html"));
// Create a new server with a different site.
- net::TestServer https_server(
- net::TestServer::TYPE_HTTPS,
- net::TestServer::kLocalhost,
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
+ set_min_screenshot_interval(0);
struct {
GURL url;
@@ -404,7 +445,7 @@
{ GURL(), 0 }
};
- ScreenshotTracker tracker(&web_contents->GetController());
+ screenshot_manager()->Reset();
for (int i = 0; !navigations[i].url.is_empty(); ++i) {
// Navigate via the user initiating a navigation from the UI.
NavigationController::LoadURLParams params(navigations[i].url);
@@ -413,11 +454,12 @@
RenderViewHost* old_host = web_contents->GetRenderViewHost();
web_contents->GetController().LoadURLWithParams(params);
WaitForLoadStop(web_contents);
+ screenshot_manager()->WaitUntilScreenshotIsReady();
EXPECT_NE(old_host, web_contents->GetRenderViewHost())
<< navigations[i].url.spec();
- EXPECT_EQ(old_host, tracker.screenshot_taken_for());
- tracker.Reset();
+ EXPECT_EQ(old_host, screenshot_manager()->screenshot_taken_for());
+ screenshot_manager()->Reset();
NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
web_contents->GetController().GetEntryAtOffset(-1));
@@ -427,6 +469,66 @@
web_contents->GetController().GetActiveEntry());
EXPECT_FALSE(entry->screenshot().get());
}
+
+ // Increase the minimum interval between taking screenshots.
+ set_min_screenshot_interval(60000);
+
+ // Navigate again. This should not take any screenshot because of the
+ // increased screenshot interval.
+ NavigationController::LoadURLParams params(navigations[0].url);
+ params.transition_type = PageTransitionFromInt(navigations[0].transition);
+ web_contents->GetController().LoadURLWithParams(params);
+ WaitForLoadStop(web_contents);
+ screenshot_manager()->WaitUntilScreenshotIsReady();
+
+ EXPECT_EQ(NULL, screenshot_manager()->screenshot_taken_for());
+}
+
+IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
+ ContentWindowReparent) {
+ ASSERT_NO_FATAL_FAILURE(
+ StartTestWithPage("files/overscroll_navigation.html"));
+
+ scoped_ptr<aura::Window> window(new aura::Window(NULL));
+ window->Init(ui::LAYER_NOT_DRAWN);
+
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ ExecuteSyncJSFunction(web_contents->GetRenderViewHost(), "navigate_next()");
+ EXPECT_EQ(1, GetCurrentIndex());
+
+ aura::Window* content = web_contents->GetView()->GetContentNativeView();
+ gfx::Rect bounds = content->GetBoundsInRootWindow();
+ aura::test::EventGenerator generator(content->GetRootWindow(), content);
+ generator.GestureScrollSequence(
+ gfx::Point(bounds.x() + 2, bounds.y() + 10),
+ gfx::Point(bounds.right() - 10, bounds.y() + 10),
+ base::TimeDelta::FromMilliseconds(20),
+ 1);
+
+ window->AddChild(shell()->web_contents()->GetView()->GetContentNativeView());
+}
+
+IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
+ ContentWindowClose) {
+ ASSERT_NO_FATAL_FAILURE(
+ StartTestWithPage("files/overscroll_navigation.html"));
+
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ ExecuteSyncJSFunction(web_contents->GetRenderViewHost(), "navigate_next()");
+ EXPECT_EQ(1, GetCurrentIndex());
+
+ aura::Window* content = web_contents->GetView()->GetContentNativeView();
+ gfx::Rect bounds = content->GetBoundsInRootWindow();
+ aura::test::EventGenerator generator(content->GetRootWindow(), content);
+ generator.GestureScrollSequence(
+ gfx::Point(bounds.x() + 2, bounds.y() + 10),
+ gfx::Point(bounds.right() - 10, bounds.y() + 10),
+ base::TimeDelta::FromMilliseconds(20),
+ 1);
+
+ delete web_contents->GetView()->GetContentNativeView();
}
} // namespace content
diff --git a/content/browser/web_contents/web_contents_view_gtk.cc b/content/browser/web_contents/web_contents_view_gtk.cc
index 4e529b4..9cb9212 100644
--- a/content/browser/web_contents/web_contents_view_gtk.cc
+++ b/content/browser/web_contents/web_contents_view_gtk.cc
@@ -100,7 +100,7 @@
gtk_widget_show(expanded_.get());
drag_source_.reset(new WebDragSourceGtk(web_contents));
- if (delegate_.get())
+ if (delegate_)
delegate_->Initialize(expanded_.get(), &focus_store_);
}
@@ -109,7 +109,7 @@
}
gfx::NativeView WebContentsViewGtk::GetNativeView() const {
- if (delegate_.get())
+ if (delegate_)
return delegate_->GetNativeView();
return expanded_.get();
@@ -151,7 +151,7 @@
void WebContentsViewGtk::Focus() {
if (web_contents_->ShowingInterstitialPage()) {
web_contents_->GetInterstitialPage()->Focus();
- } else if (delegate_.get()) {
+ } else if (delegate_) {
delegate_->Focus();
}
}
@@ -314,7 +314,7 @@
// Create the new drag_dest_.
drag_dest_.reset(new WebDragDestGtk(web_contents_, content_view));
- if (delegate_.get())
+ if (delegate_)
drag_dest_->set_delegate(delegate_->GetDragDestDelegate());
}
@@ -326,7 +326,7 @@
gboolean WebContentsViewGtk::OnFocus(GtkWidget* widget,
GtkDirectionType focus) {
// Give our view wrapper first chance at this event.
- if (delegate_.get()) {
+ if (delegate_) {
gboolean return_value = FALSE;
if (delegate_->OnNativeViewFocusEvent(widget, focus, &return_value))
return return_value;
@@ -347,7 +347,7 @@
void WebContentsViewGtk::ShowContextMenu(
const ContextMenuParams& params,
ContextMenuSourceType type) {
- if (delegate_.get())
+ if (delegate_)
delegate_->ShowContextMenu(params, type);
else
DLOG(ERROR) << "Cannot show context menus without a delegate.";
@@ -375,11 +375,11 @@
RenderWidgetHostViewGtk* view_gtk = static_cast<RenderWidgetHostViewGtk*>(
web_contents_->GetRenderWidgetHostView());
- if (!view_gtk || !view_gtk->GetLastMouseDown())
- return;
-
- drag_source_->StartDragging(drop_data, ops, view_gtk->GetLastMouseDown(),
- *image.bitmap(), image_offset);
+ if (!view_gtk || !view_gtk->GetLastMouseDown() ||
+ !drag_source_->StartDragging(drop_data, ops, view_gtk->GetLastMouseDown(),
+ *image.bitmap(), image_offset)) {
+ web_contents_->SystemDragEnded();
+ }
}
// -----------------------------------------------------------------------------
diff --git a/content/browser/web_contents/web_contents_view_guest.cc b/content/browser/web_contents/web_contents_view_guest.cc
index 088ebfd..f6c42a9 100644
--- a/content/browser/web_contents/web_contents_view_guest.cc
+++ b/content/browser/web_contents/web_contents_view_guest.cc
@@ -5,12 +5,14 @@
#include "content/browser/web_contents/web_contents_view_guest.h"
#include "build/build_config.h"
+#include "content/browser/browser_plugin/browser_plugin_embedder.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/renderer_host/render_view_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_guest.h"
#include "content/browser/web_contents/interstitial_page_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/drag_messages.h"
#include "content/public/browser/web_contents_delegate.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/point.h"
@@ -36,7 +38,7 @@
}
gfx::NativeView WebContentsViewGuest::GetNativeView() const {
- return NULL;
+ return platform_view_->GetNativeView();
}
gfx::NativeView WebContentsViewGuest::GetContentNativeView() const {
@@ -51,11 +53,14 @@
}
void WebContentsViewGuest::GetContainerBounds(gfx::Rect* out) const {
- platform_view_->GetContainerBounds(out);
+ out->SetRect(0, 0, size_.width(), size_.height());
}
void WebContentsViewGuest::SizeContents(const gfx::Size& size) {
- platform_view_->SizeContents(size);
+ size_ = size;
+ RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
+ if (rwhv)
+ rwhv->SetSize(size);
}
void WebContentsViewGuest::SetInitialFocus() {
@@ -63,7 +68,7 @@
}
gfx::Rect WebContentsViewGuest::GetViewBounds() const {
- return platform_view_->GetViewBounds();
+ return gfx::Rect(size_);
}
#if defined(OS_MACOSX)
@@ -75,6 +80,7 @@
void WebContentsViewGuest::CreateView(const gfx::Size& initial_size,
gfx::NativeView context) {
platform_view_->CreateView(initial_size, context);
+ size_ = initial_size;
}
RenderWidgetHostView* WebContentsViewGuest::CreateViewForWidget(
@@ -155,7 +161,14 @@
}
void WebContentsViewGuest::UpdateDragCursor(WebDragOperation operation) {
- NOTIMPLEMENTED();
+ RenderViewHostImpl* embedder_render_view_host =
+ static_cast<RenderViewHostImpl*>(
+ guest_->embedder_web_contents()->GetRenderViewHost());
+ CHECK(embedder_render_view_host);
+ RenderViewHostDelegateView* view =
+ embedder_render_view_host->GetDelegate()->GetDelegateView();
+ if (view)
+ view->UpdateDragCursor(operation);
}
void WebContentsViewGuest::GotFocus() {
@@ -187,7 +200,18 @@
const gfx::ImageSkia& image,
const gfx::Vector2d& image_offset,
const DragEventSourceInfo& event_info) {
- NOTIMPLEMENTED();
+ WebContentsImpl* embedder_web_contents = guest_->embedder_web_contents();
+ embedder_web_contents->GetBrowserPluginEmbedder()->StartDrag(guest_);
+ RenderViewHostImpl* embedder_render_view_host =
+ static_cast<RenderViewHostImpl*>(
+ embedder_web_contents->GetRenderViewHost());
+ CHECK(embedder_render_view_host);
+ RenderViewHostDelegateView* view =
+ embedder_render_view_host->GetDelegate()->GetDelegateView();
+ if (view)
+ view->StartDragging(drop_data, ops, image, image_offset, event_info);
+ else
+ embedder_web_contents->SystemDragEnded();
}
} // namespace content
diff --git a/content/browser/web_contents/web_contents_view_guest.h b/content/browser/web_contents/web_contents_view_guest.h
index 93abb1d..e92a200 100644
--- a/content/browser/web_contents/web_contents_view_guest.h
+++ b/content/browser/web_contents/web_contents_view_guest.h
@@ -97,6 +97,7 @@
// The platform dependent view backing this WebContentsView.
// Calls to this WebContentsViewGuest are forwarded to |platform_view_|.
WebContentsViewPort* platform_view_;
+ gfx::Size size_;
DISALLOW_COPY_AND_ASSIGN(WebContentsViewGuest);
};
diff --git a/content/browser/web_contents/web_contents_view_mac.h b/content/browser/web_contents/web_contents_view_mac.h
index fdba569..53888b0 100644
--- a/content/browser/web_contents/web_contents_view_mac.h
+++ b/content/browser/web_contents/web_contents_view_mac.h
@@ -12,6 +12,7 @@
#include "base/memory/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
+#include "content/common/content_export.h"
#include "content/common/drag_event_source_info.h"
#include "content/port/browser/render_view_host_delegate_view.h"
#include "content/port/browser/web_contents_view_port.h"
@@ -33,6 +34,7 @@
class Vector2d;
}
+CONTENT_EXPORT
@interface WebContentsViewCocoa : BaseView {
@private
content::WebContentsViewMac* webContentsView_; // WEAK; owns us
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm
index c22a840..cd4120e 100644
--- a/content/browser/web_contents/web_contents_view_mac.mm
+++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -138,7 +138,8 @@
// The drag invokes a nested event loop, arrange to continue
// processing events.
- MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
+ base::MessageLoop::ScopedNestableTaskAllower allow(
+ base::MessageLoop::current());
NSDragOperation mask = static_cast<NSDragOperation>(allowed_operations);
NSPoint offset = NSPointFromCGPoint(
gfx::PointAtOffsetFromOrigin(image_offset).ToCGPoint());
@@ -483,7 +484,7 @@
// Returns what kind of drag operations are available. This is a required
// method for NSDraggingSource.
- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal {
- if (dragSource_.get())
+ if (dragSource_)
return [dragSource_ draggingSourceOperationMaskForLocal:isLocal];
// No web drag source - this is the case for dragging a file from the
// downloads manager. Default to copy operation. Note: It is desirable to
diff --git a/content/browser/web_contents/web_contents_view_win.cc b/content/browser/web_contents/web_contents_view_win.cc
index 28f489a..3ceeb0f 100644
--- a/content/browser/web_contents/web_contents_view_win.cc
+++ b/content/browser/web_contents/web_contents_view_win.cc
@@ -155,7 +155,7 @@
// Remove the root view drop target so we can register our own.
RevokeDragDrop(GetNativeView());
drag_dest_ = new WebDragDest(hwnd(), web_contents_);
- if (delegate_.get()) {
+ if (delegate_) {
WebDragDestDelegate* delegate = delegate_->GetDragDestDelegate();
if (delegate)
drag_dest_->set_delegate(delegate);
@@ -184,12 +184,12 @@
}
void WebContentsViewWin::StoreFocus() {
- if (delegate_.get())
+ if (delegate_)
delegate_->StoreFocus();
}
void WebContentsViewWin::RestoreFocus() {
- if (delegate_.get())
+ if (delegate_)
delegate_->RestoreFocus();
}
@@ -246,7 +246,7 @@
void WebContentsViewWin::ShowContextMenu(
const ContextMenuParams& params,
ContextMenuSourceType type) {
- if (delegate_.get())
+ if (delegate_)
delegate_->ShowContextMenu(params, type);
}
@@ -310,11 +310,11 @@
LRESULT WebContentsViewWin::OnDestroy(
UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) {
- if (drag_dest_.get()) {
+ if (drag_dest_) {
RevokeDragDrop(GetNativeView());
drag_dest_ = NULL;
}
- if (drag_handler_.get()) {
+ if (drag_handler_) {
drag_handler_->CancelDrag();
drag_handler_ = NULL;
}
@@ -357,7 +357,7 @@
if (rwhv)
rwhv->SetSize(size);
- if (delegate_.get())
+ if (delegate_)
delegate_->SizeChanged(size);
return 0;
diff --git a/content/browser/web_contents/web_drag_dest_gtk.cc b/content/browser/web_contents/web_drag_dest_gtk.cc
index fd2763f..6973821 100644
--- a/content/browser/web_contents/web_drag_dest_gtk.cc
+++ b/content/browser/web_contents/web_drag_dest_gtk.cc
@@ -284,7 +284,8 @@
// preceded by a drag-leave. The renderer doesn't like getting the signals
// in this order so delay telling it about the drag-leave till we are sure
// we are not getting a drop as well.
- MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
base::Bind(&WebDragDestGtk::DragLeave, method_factory_.GetWeakPtr()));
}
diff --git a/content/browser/web_contents/web_drag_dest_gtk.h b/content/browser/web_contents/web_drag_dest_gtk.h
index fb9a6b3..96d7aa3 100644
--- a/content/browser/web_contents/web_drag_dest_gtk.h
+++ b/content/browser/web_contents/web_drag_dest_gtk.h
@@ -96,7 +96,7 @@
// signal handlers when this WebDragDestGtk is deleted so that if, later on,
// we re-create the drag dest with the same widget, we don't get callbacks to
// deleted functions.
- scoped_array<int> handlers_;
+ scoped_ptr<int[]> handlers_;
// A delegate that can receive drag information about drag events.
WebDragDestDelegate* delegate_;
diff --git a/content/browser/web_contents/web_drag_dest_mac.h b/content/browser/web_contents/web_drag_dest_mac.h
index 4358e2b..a344a4c 100644
--- a/content/browser/web_contents/web_drag_dest_mac.h
+++ b/content/browser/web_contents/web_drag_dest_mac.h
@@ -6,6 +6,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
+#include "content/common/content_export.h"
#include "webkit/glue/webdropdata.h"
@@ -21,7 +22,7 @@
// A class that handles tracking and event processing for a drag and drop
// over the content area. Assumes something else initiates the drag, this is
// only for processing during a drag.
-
+CONTENT_EXPORT
@interface WebDragDest : NSObject {
@private
// Our associated WebContentsImpl. Weak reference.
diff --git a/content/browser/web_contents/web_drag_dest_mac.mm b/content/browser/web_contents/web_drag_dest_mac.mm
index a292e3b..e3f7a0e 100644
--- a/content/browser/web_contents/web_drag_dest_mac.mm
+++ b/content/browser/web_contents/web_drag_dest_mac.mm
@@ -6,7 +6,7 @@
#import <Carbon/Carbon.h>
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/web_drag_dest_delegate.h"
@@ -248,9 +248,11 @@
// Get HTML. If there's no HTML, try RTF.
if ([types containsObject:NSHTMLPboardType]) {
- data->html = NullableString16(
- base::SysNSStringToUTF16([pboard stringForType:NSHTMLPboardType]),
- false);
+ NSString* html = [pboard stringForType:NSHTMLPboardType];
+ data->html = NullableString16(base::SysNSStringToUTF16(html), false);
+ } else if ([types containsObject:ui::kChromeDragImageHTMLPboardType]) {
+ NSString* html = [pboard stringForType:ui::kChromeDragImageHTMLPboardType];
+ data->html = NullableString16(base::SysNSStringToUTF16(html), false);
} else if ([types containsObject:NSRTFPboardType]) {
NSString* html = [pboard htmlFromRtf];
data->html = NullableString16(base::SysNSStringToUTF16(html), false);
diff --git a/content/browser/web_contents/web_drag_dest_mac_unittest.mm b/content/browser/web_contents/web_drag_dest_mac_unittest.mm
index 43fb8a3..204a2ae 100644
--- a/content/browser/web_contents/web_drag_dest_mac_unittest.mm
+++ b/content/browser/web_contents/web_drag_dest_mac_unittest.mm
@@ -4,7 +4,7 @@
#include "base/mac/scoped_nsautorelease_pool.h"
#import "base/memory/scoped_nsobject.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "content/browser/renderer_host/test_render_view_host.h"
#import "content/browser/web_contents/web_drag_dest_mac.h"
diff --git a/content/browser/web_contents/web_drag_source_gtk.cc b/content/browser/web_contents/web_drag_source_gtk.cc
index c3a786f..05af3f5 100644
--- a/content/browser/web_contents/web_drag_source_gtk.cc
+++ b/content/browser/web_contents/web_drag_source_gtk.cc
@@ -36,7 +36,7 @@
namespace content {
WebDragSourceGtk::WebDragSourceGtk(WebContents* web_contents)
- : web_contents_(web_contents),
+ : web_contents_(static_cast<WebContentsImpl*>(web_contents)),
drag_pixbuf_(NULL),
drag_failed_(false),
drag_widget_(gtk_invisible_new()),
@@ -58,10 +58,10 @@
WebDragSourceGtk::~WebDragSourceGtk() {
// Break the current drag, if any.
- if (drop_data_.get()) {
+ if (drop_data_) {
gtk_grab_add(drag_widget_);
gtk_grab_remove(drag_widget_);
- MessageLoopForUI::current()->RemoveObserver(this);
+ base::MessageLoopForUI::current()->RemoveObserver(this);
drop_data_.reset();
}
@@ -69,7 +69,7 @@
gtk_widget_destroy(drag_icon_);
}
-void WebDragSourceGtk::StartDragging(const WebDropData& drop_data,
+bool WebDragSourceGtk::StartDragging(const WebDropData& drop_data,
WebDragOperationsMask allowed_ops,
GdkEventButton* last_mouse_down,
const SkBitmap& image,
@@ -77,8 +77,7 @@
// Guard against re-starting before previous drag completed.
if (drag_context_) {
NOTREACHED();
- web_contents_->SystemDragEnded();
- return;
+ return false;
}
int targets_mask = 0;
@@ -146,11 +145,11 @@
if (!drag_context_) {
drag_failed_ = true;
drop_data_.reset();
- web_contents_->SystemDragEnded();
- return;
+ return false;
}
- MessageLoopForUI::current()->AddObserver(this);
+ base::MessageLoopForUI::current()->AddObserver(this);
+ return true;
}
void WebDragSourceGtk::WillProcessEvent(GdkEvent* event) {
@@ -164,8 +163,8 @@
GdkEventMotion* event_motion = reinterpret_cast<GdkEventMotion*>(event);
gfx::Point client = ui::ClientPoint(GetContentNativeView());
- if (GetRenderViewHost()) {
- GetRenderViewHost()->DragSourceMovedTo(
+ if (web_contents_) {
+ web_contents_->DragSourceMovedTo(
client.x(), client.y(),
static_cast<int>(event_motion->x_root),
static_cast<int>(event_motion->y_root));
@@ -246,7 +245,7 @@
CreateFileStreamForDrop(
&file_path,
GetContentClient()->browser()->GetNetLog()));
- if (file_stream.get()) {
+ if (file_stream) {
// Start downloading the file to the stream.
scoped_refptr<DragDownloadFile> drag_file_downloader =
new DragDownloadFile(
@@ -300,8 +299,8 @@
gfx::Point root = ui::ScreenPoint(GetContentNativeView());
gfx::Point client = ui::ClientPoint(GetContentNativeView());
- if (GetRenderViewHost()) {
- GetRenderViewHost()->DragSourceEndedAt(
+ if (web_contents_) {
+ web_contents_->DragSourceEndedAt(
client.x(), client.y(), root.x(), root.y(),
WebDragOperationNone);
}
@@ -361,7 +360,7 @@
drag_pixbuf_ = NULL;
}
- MessageLoopForUI::current()->RemoveObserver(this);
+ base::MessageLoopForUI::current()->RemoveObserver(this);
if (!download_url_.is_empty()) {
gdk_property_delete(drag_context->source_window,
@@ -372,8 +371,8 @@
gfx::Point root = ui::ScreenPoint(GetContentNativeView());
gfx::Point client = ui::ClientPoint(GetContentNativeView());
- if (GetRenderViewHost()) {
- GetRenderViewHost()->DragSourceEndedAt(
+ if (web_contents_) {
+ web_contents_->DragSourceEndedAt(
client.x(), client.y(), root.x(), root.y(),
GdkDragActionToWebDragOp(drag_context->action));
}
@@ -385,10 +384,6 @@
drag_context_ = NULL;
}
-RenderViewHostImpl* WebDragSourceGtk::GetRenderViewHost() const {
- return static_cast<RenderViewHostImpl*>(web_contents_->GetRenderViewHost());
-}
-
gfx::NativeView WebDragSourceGtk::GetContentNativeView() const {
return web_contents_->GetView()->GetContentNativeView();
}
diff --git a/content/browser/web_contents/web_drag_source_gtk.h b/content/browser/web_contents/web_drag_source_gtk.h
index d95b40e..4c3381f 100644
--- a/content/browser/web_contents/web_drag_source_gtk.h
+++ b/content/browser/web_contents/web_drag_source_gtk.h
@@ -12,6 +12,7 @@
#include "base/message_loop.h"
#include "base/string16.h"
#include "content/common/content_export.h"
+#include "content/public/browser/web_contents.h"
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDragOperation.h"
#include "ui/base/gtk/gtk_signal.h"
@@ -25,17 +26,19 @@
namespace content {
class RenderViewHostImpl;
-class WebContents;
+class WebContentsImpl;
// WebDragSourceGtk takes care of managing the drag from a WebContents
// with Gtk.
-class CONTENT_EXPORT WebDragSourceGtk : public MessageLoopForUI::Observer {
+class CONTENT_EXPORT WebDragSourceGtk :
+ public base::MessageLoopForUI::Observer {
public:
explicit WebDragSourceGtk(WebContents* web_contents);
virtual ~WebDragSourceGtk();
// Starts a drag for the WebContents this WebDragSourceGtk was created for.
- void StartDragging(const WebDropData& drop_data,
+ // Returns false if the drag could not be started.
+ bool StartDragging(const WebDropData& drop_data,
WebKit::WebDragOperationsMask allowed_ops,
GdkEventButton* last_mouse_down,
const SkBitmap& image,
@@ -57,11 +60,10 @@
CHROMEGTK_CALLBACK_1(WebDragSourceGtk, gboolean, OnDragIconExpose,
GdkEventExpose*);
- RenderViewHostImpl* GetRenderViewHost() const;
gfx::NativeView GetContentNativeView() const;
// The tab we're manging the drag for.
- WebContents* web_contents_;
+ WebContentsImpl* web_contents_;
// The drop data for the current drag (for drags that originate in the render
// view). Non-NULL iff there is a current drag.
diff --git a/content/browser/web_contents/web_drag_source_mac.h b/content/browser/web_contents/web_drag_source_mac.h
index a8f1f00..8e2f02c 100644
--- a/content/browser/web_contents/web_drag_source_mac.h
+++ b/content/browser/web_contents/web_drag_source_mac.h
@@ -8,6 +8,7 @@
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
+#include "content/common/content_export.h"
#include "googleurl/src/gurl.h"
struct WebDropData;
@@ -17,6 +18,7 @@
// A class that handles tracking and event processing for a drag and drop
// originating from the content area.
+CONTENT_EXPORT
@interface WebDragSource : NSObject {
@private
// Our contents. Weak reference (owns or co-owns us).
diff --git a/content/browser/web_contents/web_drag_source_mac.mm b/content/browser/web_contents/web_drag_source_mac.mm
index 83521f1..86b2f23 100644
--- a/content/browser/web_contents/web_drag_source_mac.mm
+++ b/content/browser/web_contents/web_drag_source_mac.mm
@@ -11,7 +11,7 @@
#include "base/mac/mac_util.h"
#include "base/pickle.h"
#include "base/string_util.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "base/utf_string_conversions.h"
@@ -150,17 +150,18 @@
"<meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\">");
// Be extra paranoid; avoid crashing.
- if (!dropData_.get()) {
+ if (!dropData_) {
NOTREACHED();
return;
}
// HTML.
- if ([type isEqualToString:NSHTMLPboardType]) {
+ if ([type isEqualToString:NSHTMLPboardType] ||
+ [type isEqualToString:ui::kChromeDragImageHTMLPboardType]) {
DCHECK(!dropData_->html.string().empty());
// See comment on |kHtmlHeader| above.
[pboard setString:SysUTF16ToNSString(kHtmlHeader + dropData_->html.string())
- forType:NSHTMLPboardType];
+ forType:type];
// URL.
} else if ([type isEqualToString:NSURLPboardType]) {
@@ -186,7 +187,7 @@
forType:kNSURLTitlePboardType];
// File contents.
- } else if ([type isEqualToString:base::mac::CFToNSCast(fileUTI_.get())]) {
+ } else if ([type isEqualToString:base::mac::CFToNSCast(fileUTI_)]) {
[pboard setData:[NSData dataWithBytes:dropData_->file_contents.data()
length:dropData_->file_contents.length()]
forType:base::mac::CFToNSCast(fileUTI_.get())];
@@ -282,9 +283,8 @@
if (operation == (NSDragOperationMove | NSDragOperationCopy))
operation &= ~NSDragOperationMove;
- rvh->DragSourceEndedAt(localPoint.x, localPoint.y,
- screenPoint.x, screenPoint.y,
- static_cast<WebKit::WebDragOperation>(operation));
+ contents_->DragSourceEndedAt(localPoint.x, localPoint.y, screenPoint.x,
+ screenPoint.y, static_cast<WebKit::WebDragOperation>(operation));
}
// Make sure the pasteboard owner isn't us.
@@ -307,14 +307,14 @@
NSRect screenFrame = [[[contentsView_ window] screen] frame];
screenPoint.y = screenFrame.size.height - screenPoint.y;
- rvh->DragSourceMovedTo(localPoint.x, localPoint.y,
- screenPoint.x, screenPoint.y);
+ contents_->DragSourceMovedTo(localPoint.x, localPoint.y,
+ screenPoint.x, screenPoint.y);
}
}
- (NSString*)dragPromisedFileTo:(NSString*)path {
// Be extra paranoid; avoid crashing.
- if (!dropData_.get()) {
+ if (!dropData_) {
NOTREACHED() << "No drag-and-drop data available for promised file.";
return nil;
}
@@ -330,7 +330,7 @@
base::ThreadRestrictions::ScopedAllowIO allowIO;
scoped_ptr<FileStream> fileStream(content::CreateFileStreamForDrop(
&filePath, content::GetContentClient()->browser()->GetNetLog()));
- if (!fileStream.get())
+ if (!fileStream)
return nil;
if (downloadURL_.is_valid()) {
@@ -365,15 +365,14 @@
- (void)fillPasteboard {
DCHECK(pasteboard_.get());
- [pasteboard_
- declareTypes:[NSArray arrayWithObject:ui::kChromeDragDummyPboardType]
- owner:contentsView_];
+ [pasteboard_ declareTypes:@[ui::kChromeDragDummyPboardType]
+ owner:contentsView_];
// URL (and title).
- if (dropData_->url.is_valid())
- [pasteboard_ addTypes:[NSArray arrayWithObjects:NSURLPboardType,
- kNSURLTitlePboardType, nil]
+ if (dropData_->url.is_valid()) {
+ [pasteboard_ addTypes:@[NSURLPboardType, kNSURLTitlePboardType]
owner:contentsView_];
+ }
// MIME type.
std::string mimeType;
@@ -437,25 +436,32 @@
bool hasHTMLData = !dropData_->html.string().empty();
// Mail.app and TextEdit accept drags that have both HTML and image flavors on
// them, but don't process them correctly <http://crbug.com/55879>. Therefore,
- // omit the HTML flavor if there is an image flavor. (The only time that
- // WebKit fills in the WebDropData::file_contents is with an image drop, but
- // the MIME time is tested anyway for paranoia's sake.)
+ // if there is an image flavor, don't put the HTML data on as HTML, but rather
+ // put it on as this Chrome-only flavor.
+ //
+ // (The only time that Blink fills in the WebDropData::file_contents is with
+ // an image drop, but the MIME time is tested anyway for paranoia's sake.)
bool hasImageData = !dropData_->file_contents.empty() &&
fileUTI_ &&
UTTypeConformsTo(fileUTI_.get(), kUTTypeImage);
- if (hasHTMLData && !hasImageData)
- [pasteboard_ addTypes:[NSArray arrayWithObject:NSHTMLPboardType]
- owner:contentsView_];
+ if (hasHTMLData) {
+ if (hasImageData) {
+ [pasteboard_ addTypes:@[ui::kChromeDragImageHTMLPboardType]
+ owner:contentsView_];
+ } else {
+ [pasteboard_ addTypes:@[NSHTMLPboardType] owner:contentsView_];
+ }
+ }
// Plain text.
- if (!dropData_->text.string().empty())
- [pasteboard_ addTypes:[NSArray arrayWithObject:NSStringPboardType]
+ if (!dropData_->text.string().empty()) {
+ [pasteboard_ addTypes:@[NSStringPboardType]
owner:contentsView_];
+ }
if (!dropData_->custom_data.empty()) {
- [pasteboard_
- addTypes:[NSArray arrayWithObject:ui::kWebCustomDataPboardType]
- owner:contentsView_];
+ [pasteboard_ addTypes:@[ui::kWebCustomDataPboardType]
+ owner:contentsView_];
}
}
diff --git a/content/browser/web_contents/web_drag_source_win.cc b/content/browser/web_contents/web_drag_source_win.cc
index 18c1881..53df4e8 100644
--- a/content/browser/web_contents/web_drag_source_win.cc
+++ b/content/browser/web_contents/web_drag_source_win.cc
@@ -6,11 +6,12 @@
#include "base/bind.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_contents/web_drag_utils_win.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
-#include "content/public/browser/web_contents.h"
+#include "ui/base/dragdrop/os_exchange_data.h"
using WebKit::WebDragOperationNone;
@@ -35,8 +36,9 @@
WebContents* web_contents)
: ui::DragSourceWin(),
source_wnd_(source_wnd),
- render_view_host_(web_contents->GetRenderViewHost()),
- effect_(DROPEFFECT_NONE) {
+ web_contents_(static_cast<WebContentsImpl*>(web_contents)),
+ effect_(DROPEFFECT_NONE),
+ data_(NULL) {
registrar_.Add(this, NOTIFICATION_WEB_CONTENTS_SWAPPED,
Source<WebContents>(web_contents));
registrar_.Add(this, NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
@@ -55,18 +57,20 @@
return;
}
- if (!render_view_host_)
+ if (!web_contents_)
return;
gfx::Point client;
gfx::Point screen;
GetCursorPositions(source_wnd_, &client, &screen);
- render_view_host_->DragSourceEndedAt(client.x(), client.y(),
- screen.x(), screen.y(),
- WebDragOperationNone);
+ web_contents_->DragSourceEndedAt(client.x(), client.y(),
+ screen.x(), screen.y(),
+ WebDragOperationNone);
}
void WebDragSource::OnDragSourceDrop() {
+ DCHECK(data_);
+ data_->SetInDragLoop(false);
// On Windows, we check for drag end in IDropSource::QueryContinueDrag which
// happens before IDropTarget::Drop is called. HTML5 requires the "dragend"
// event to happen after the "drop" event. Since Windows calls these two
@@ -78,15 +82,14 @@
}
void WebDragSource::DelayedOnDragSourceDrop() {
- if (!render_view_host_)
+ if (!web_contents_)
return;
gfx::Point client;
gfx::Point screen;
GetCursorPositions(source_wnd_, &client, &screen);
- render_view_host_->DragSourceEndedAt(
- client.x(), client.y(), screen.x(), screen.y(),
- WinDragOpToWebDragOp(effect_));
+ web_contents_->DragSourceEndedAt(client.x(), client.y(), screen.x(),
+ screen.y(), WinDragOpToWebDragOp(effect_));
}
void WebDragSource::OnDragSourceMove() {
@@ -98,14 +101,14 @@
return;
}
- if (!render_view_host_)
+ if (!web_contents_)
return;
gfx::Point client;
gfx::Point screen;
GetCursorPositions(source_wnd_, &client, &screen);
- render_view_host_->DragSourceMovedTo(client.x(), client.y(),
- screen.x(), screen.y());
+ web_contents_->DragSourceMovedTo(client.x(), client.y(),
+ screen.x(), screen.y());
}
void WebDragSource::Observe(int type,
@@ -115,12 +118,12 @@
// When the WebContents get swapped, our render view host goes away.
// That's OK, we can continue the drag, we just can't send messages back to
// our drag source.
- render_view_host_ = NULL;
+ web_contents_ = NULL;
} else if (type == NOTIFICATION_WEB_CONTENTS_DISCONNECTED) {
// This could be possible when we close the tab and the source is still
// being used in DoDragDrop at the time that the virtual file is being
// downloaded.
- render_view_host_ = NULL;
+ web_contents_ = NULL;
}
}
diff --git a/content/browser/web_contents/web_drag_source_win.h b/content/browser/web_contents/web_drag_source_win.h
index 898f3c3..72d4a16 100644
--- a/content/browser/web_contents/web_drag_source_win.h
+++ b/content/browser/web_contents/web_drag_source_win.h
@@ -12,9 +12,14 @@
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/point.h"
+namespace ui {
+class OSExchangeData;
+} // namespace ui
+
namespace content {
class RenderViewHost;
class WebContents;
+class WebContentsImpl;
// An IDropSource implementation for a WebContentsImpl. Handles notifications
// sent by an active drag-drop operation as the user mouses over other drop
@@ -33,6 +38,10 @@
const NotificationDetails& details);
void set_effect(DWORD effect) { effect_ = effect; }
+ // Used to set the active data object for the current drag operation. The
+ // caller must ensure that |data| is not destroyed before the nested drag loop
+ // terminates.
+ void set_data(ui::OSExchangeData* data) { data_ = data; }
protected:
// ui::DragSourceWin
@@ -54,12 +63,14 @@
// We use this as a channel to the renderer to tell it about various drag
// drop events that it needs to know about (such as when a drag operation it
// initiated terminates).
- RenderViewHost* render_view_host_;
+ WebContentsImpl* web_contents_;
NotificationRegistrar registrar_;
DWORD effect_;
+ ui::OSExchangeData* data_;
+
DISALLOW_COPY_AND_ASSIGN(WebDragSource);
};
diff --git a/content/browser/webui/content_web_ui_controller_factory.cc b/content/browser/webui/content_web_ui_controller_factory.cc
index 7f486d8..45a38ad 100644
--- a/content/browser/webui/content_web_ui_controller_factory.cc
+++ b/content/browser/webui/content_web_ui_controller_factory.cc
@@ -6,6 +6,7 @@
#include "content/browser/accessibility/accessibility_ui.h"
#include "content/browser/gpu/gpu_internals_ui.h"
+#include "content/browser/indexed_db/indexed_db_internals_ui.h"
#include "content/browser/media/media_internals_ui.h"
#include "content/browser/media/webrtc_internals_ui.h"
#include "content/browser/tracing/tracing_ui.h"
@@ -17,13 +18,14 @@
WebUI::TypeID ContentWebUIControllerFactory::GetWebUIType(
BrowserContext* browser_context, const GURL& url) const {
- if (url.host() == chrome::kChromeUIWebRTCInternalsHost ||
+ if (url.host() == kChromeUIWebRTCInternalsHost ||
#if !defined(OS_ANDROID)
- url.host() == chrome::kChromeUITracingHost ||
+ url.host() == kChromeUITracingHost ||
#endif
- url.host() == chrome::kChromeUIGpuHost ||
- url.host() == chrome::kChromeUIMediaInternalsHost ||
- url.host() == chrome::kChromeUIAccessibilityHost) {
+ url.host() == kChromeUIGpuHost ||
+ url.host() == kChromeUIIndexedDBInternalsHost ||
+ url.host() == kChromeUIMediaInternalsHost ||
+ url.host() == kChromeUIAccessibilityHost) {
return const_cast<ContentWebUIControllerFactory*>(this);
}
return WebUI::kNoWebUI;
@@ -41,16 +43,18 @@
WebUIController* ContentWebUIControllerFactory::CreateWebUIControllerForURL(
WebUI* web_ui, const GURL& url) const {
- if (url.host() == chrome::kChromeUIWebRTCInternalsHost)
+ if (url.host() == kChromeUIWebRTCInternalsHost)
return new WebRTCInternalsUI(web_ui);
- if (url.host() == chrome::kChromeUIGpuHost)
+ if (url.host() == kChromeUIGpuHost)
return new GpuInternalsUI(web_ui);
- if (url.host() == chrome::kChromeUIMediaInternalsHost)
+ if (url.host() == kChromeUIIndexedDBInternalsHost)
+ return new IndexedDBInternalsUI(web_ui);
+ if (url.host() == kChromeUIMediaInternalsHost)
return new MediaInternalsUI(web_ui);
- if (url.host() == chrome::kChromeUIAccessibilityHost)
+ if (url.host() == kChromeUIAccessibilityHost)
return new AccessibilityUI(web_ui);
#if !defined(OS_ANDROID)
- if (url.host() == chrome::kChromeUITracingHost)
+ if (url.host() == kChromeUITracingHost)
return new TracingUI(web_ui);
#endif
diff --git a/content/browser/webui/shared_resources_data_source.cc b/content/browser/webui/shared_resources_data_source.cc
index 54c0c4c..fc390b2 100644
--- a/content/browser/webui/shared_resources_data_source.cc
+++ b/content/browser/webui/shared_resources_data_source.cc
@@ -34,13 +34,14 @@
SharedResourcesDataSource::~SharedResourcesDataSource() {
}
-std::string SharedResourcesDataSource::GetSource() {
- return chrome::kChromeUIResourcesHost;
+std::string SharedResourcesDataSource::GetSource() const {
+ return content::kChromeUIResourcesHost;
}
void SharedResourcesDataSource::StartDataRequest(
const std::string& path,
- bool is_incognito,
+ int render_process_id,
+ int render_view_id,
const content::URLDataSource::GotDataCallback& callback) {
int idr = PathToIDR(path);
DCHECK_NE(-1, idr) << " path: " << path;
diff --git a/content/browser/webui/shared_resources_data_source.h b/content/browser/webui/shared_resources_data_source.h
index b5c20b7..cf9c24c 100644
--- a/content/browser/webui/shared_resources_data_source.h
+++ b/content/browser/webui/shared_resources_data_source.h
@@ -15,10 +15,11 @@
SharedResourcesDataSource();
// content::URLDataSource implementation.
- virtual std::string GetSource() OVERRIDE;
+ virtual std::string GetSource() const OVERRIDE;
virtual void StartDataRequest(
const std::string& path,
- bool is_incognito,
+ int render_process_id,
+ int render_view_id,
const content::URLDataSource::GotDataCallback& callback) OVERRIDE;
virtual std::string GetMimeType(const std::string&) const OVERRIDE;
diff --git a/content/browser/webui/url_data_manager_backend.cc b/content/browser/webui/url_data_manager_backend.cc
index 2f28b2a..fc1a706 100644
--- a/content/browser/webui/url_data_manager_backend.cc
+++ b/content/browser/webui/url_data_manager_backend.cc
@@ -28,11 +28,14 @@
#include "content/browser/webui/url_data_source_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/resource_request_info.h"
#include "content/public/common/url_constants.h"
#include "googleurl/src/url_util.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
+#include "net/http/http_status_code.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_job.h"
@@ -61,11 +64,12 @@
// is the hostname and |path| is the remaining portion of the URL.
void URLToRequest(const GURL& url, std::string* source_name,
std::string* path) {
+ std::vector<std::string> additional_schemes;
DCHECK(url.SchemeIs(chrome::kChromeDevToolsScheme) ||
url.SchemeIs(chrome::kChromeUIScheme) ||
- SchemeIsInSchemes(
- url.scheme(),
- GetContentClient()->browser()->GetAdditionalWebUISchemes()));
+ (GetContentClient()->browser()->GetAdditionalWebUISchemes(
+ &additional_schemes),
+ SchemeIsInSchemes(url.scheme(), additional_schemes)));
if (!url.is_valid()) {
NOTREACHED();
@@ -108,6 +112,7 @@
int buf_size,
int* bytes_read) OVERRIDE;
virtual bool GetMimeType(std::string* mime_type) const OVERRIDE;
+ virtual int GetResponseCode() const OVERRIDE;
virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE;
// Used to notify that the requested data's |mime_type| is ready.
@@ -209,7 +214,7 @@
deny_xframe_options_(true),
is_incognito_(is_incognito),
backend_(backend),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ weak_factory_(this) {
DCHECK(backend);
}
@@ -220,10 +225,9 @@
void URLRequestChromeJob::Start() {
// Start reading asynchronously so that all error reporting and data
// callbacks happen as they would for network requests.
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&URLRequestChromeJob::StartAsync,
- weak_factory_.GetWeakPtr()));
+ base::Bind(&URLRequestChromeJob::StartAsync, weak_factory_.GetWeakPtr()));
TRACE_EVENT_ASYNC_BEGIN1("browser", "DataManager:Request", this, "URL",
request_->url().possibly_invalid_spec());
@@ -238,6 +242,10 @@
return !mime_type_.empty();
}
+int URLRequestChromeJob::GetResponseCode() const {
+ return net::HTTP_OK;
+}
+
void URLRequestChromeJob::GetResponseInfo(net::HttpResponseInfo* info) {
DCHECK(!info->headers);
// Set the headers so that requests serviced by ChromeURLDataManager return a
@@ -276,7 +284,7 @@
data_ = bytes;
int bytes_read;
- if (pending_buf_.get()) {
+ if (pending_buf_) {
CHECK(pending_buf_->data());
CompleteRead(pending_buf_, pending_buf_size_, &bytes_read);
pending_buf_ = NULL;
@@ -291,7 +299,7 @@
bool URLRequestChromeJob::ReadRawData(net::IOBuffer* buf, int buf_size,
int* bytes_read) {
- if (!data_.get()) {
+ if (!data_) {
SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
DCHECK(!pending_buf_.get());
CHECK(buf->data());
@@ -373,7 +381,7 @@
// Next check for chrome://appcache-internals/, which uses its own job type.
if (request->url().SchemeIs(chrome::kChromeUIScheme) &&
- request->url().host() == chrome::kChromeUIAppCacheInternalsHost) {
+ request->url().host() == kChromeUIAppCacheInternalsHost) {
return appcache::ViewAppCacheInternalsJobFactory::CreateJobForRequest(
request, network_delegate, appcache_service_);
}
@@ -387,14 +395,14 @@
#if defined(USE_TCMALLOC)
// Next check for chrome://tcmalloc/, which uses its own job type.
if (request->url().SchemeIs(chrome::kChromeUIScheme) &&
- request->url().host() == chrome::kChromeUITcmallocHost) {
+ request->url().host() == kChromeUITcmallocHost) {
return new TcmallocInternalsRequestJob(request, network_delegate);
}
#endif
// Next check for chrome://histograms/, which uses its own job type.
if (request->url().SchemeIs(chrome::kChromeUIScheme) &&
- request->url().host() == chrome::kChromeUIHistogramHost) {
+ request->url().host() == kChromeUIHistogramHost) {
return new HistogramInternalsRequestJob(request, network_delegate);
}
@@ -485,6 +493,7 @@
if (!source->source()->ShouldServiceRequest(request))
return false;
+ source->source()->WillServiceRequest(request, &path);
// Save this request so we know where to send the data.
RequestID request_id = next_request_id_++;
@@ -500,11 +509,17 @@
job->set_deny_xframe_options(
source->source()->ShouldDenyXFrameOptions());
+ // Look up additional request info to pass down.
+ int render_process_id = -1;
+ int render_view_id = -1;
+ ResourceRequestInfo::GetRenderViewForRequest(request,
+ &render_process_id,
+ &render_view_id);
+
// Forward along the request to the data source.
- MessageLoop* target_message_loop =
+ base::MessageLoop* target_message_loop =
source->source()->MessageLoopForRequestPath(path);
if (!target_message_loop) {
- bool is_incognito = job->is_incognito();
job->MimeTypeAvailable(source->source()->GetMimeType(path));
// Eliminate potentially dangling pointer to avoid future use.
job = NULL;
@@ -513,7 +528,7 @@
// on for this path. Call directly into it from this thread, the IO
// thread.
source->source()->StartDataRequest(
- path, is_incognito,
+ path, render_process_id, render_view_id,
base::Bind(&URLDataSourceImpl::SendResponse, source, request_id));
} else {
// URLRequestChromeJob should receive mime type before data. This
@@ -531,8 +546,8 @@
target_message_loop->PostTask(
FROM_HERE,
base::Bind(&URLDataManagerBackend::CallStartRequest,
- make_scoped_refptr(source), path, job->is_incognito(),
- request_id));
+ make_scoped_refptr(source), path, render_process_id,
+ render_view_id, request_id));
}
return true;
}
@@ -540,11 +555,21 @@
void URLDataManagerBackend::CallStartRequest(
scoped_refptr<URLDataSourceImpl> source,
const std::string& path,
- bool is_incognito,
+ int render_process_id,
+ int render_view_id,
int request_id) {
+ if (BrowserThread::CurrentlyOn(BrowserThread::UI) &&
+ !RenderProcessHost::FromID(render_process_id)) {
+ // Make the request fail if its initiating renderer is no longer valid.
+ // This can happen when the IO thread posts this task just before the
+ // renderer shuts down.
+ source->SendResponse(request_id, NULL);
+ return;
+ }
source->source()->StartDataRequest(
path,
- is_incognito,
+ render_process_id,
+ render_view_id,
base::Bind(&URLDataSourceImpl::SendResponse, source, request_id));
}
diff --git a/content/browser/webui/url_data_manager_backend.h b/content/browser/webui/url_data_manager_backend.h
index 3181369..e38fe1e 100644
--- a/content/browser/webui/url_data_manager_backend.h
+++ b/content/browser/webui/url_data_manager_backend.h
@@ -13,6 +13,7 @@
#include "base/compiler_specific.h"
#include "base/supports_user_data.h"
#include "content/browser/webui/url_data_manager.h"
+#include "content/public/browser/url_data_source.h"
#include "net/url_request/url_request_job_factory.h"
class GURL;
@@ -75,7 +76,8 @@
// need to add a refcount on the source.
static void CallStartRequest(scoped_refptr<URLDataSourceImpl> source,
const std::string& path,
- bool is_incognito,
+ int render_process_id,
+ int render_view_id,
int request_id);
// Remove a request from the list of pending requests.
diff --git a/content/browser/webui/web_ui_data_source_impl.cc b/content/browser/webui/web_ui_data_source_impl.cc
index 5f17e53..7ca34d2 100644
--- a/content/browser/webui/web_ui_data_source_impl.cc
+++ b/content/browser/webui/web_ui_data_source_impl.cc
@@ -35,7 +35,7 @@
}
// URLDataSource implementation.
- virtual std::string GetSource() OVERRIDE {
+ virtual std::string GetSource() const OVERRIDE {
return parent_->GetSource();
}
virtual std::string GetMimeType(const std::string& path) const OVERRIDE {
@@ -43,9 +43,11 @@
}
virtual void StartDataRequest(
const std::string& path,
- bool is_incognito,
+ int render_process_id,
+ int render_view_id,
const URLDataSource::GotDataCallback& callback) OVERRIDE {
- return parent_->StartDataRequest(path, is_incognito, callback);
+ return parent_->StartDataRequest(path, render_process_id, render_view_id,
+ callback);
}
virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE {
return parent_->add_csp_;
@@ -71,7 +73,7 @@
WebUIDataSourceImpl::WebUIDataSourceImpl(const std::string& source_name)
: URLDataSourceImpl(
source_name,
- new InternalDataSource(ALLOW_THIS_IN_INITIALIZER_LIST(this))),
+ new InternalDataSource(this)),
source_name_(source_name),
default_resource_(-1),
json_js_format_v2_(false),
@@ -152,7 +154,7 @@
deny_xframe_options_ = false;
}
-std::string WebUIDataSourceImpl::GetSource() {
+std::string WebUIDataSourceImpl::GetSource() const {
return source_name_;
}
@@ -171,7 +173,8 @@
void WebUIDataSourceImpl::StartDataRequest(
const std::string& path,
- bool is_incognito,
+ int render_process_id,
+ int render_view_id,
const URLDataSource::GotDataCallback& callback) {
if (!filter_callback_.is_null() &&
filter_callback_.Run(path, callback)) {
diff --git a/content/browser/webui/web_ui_data_source_impl.h b/content/browser/webui/web_ui_data_source_impl.h
index 9553a03..98f0a89 100644
--- a/content/browser/webui/web_ui_data_source_impl.h
+++ b/content/browser/webui/web_ui_data_source_impl.h
@@ -70,11 +70,12 @@
// Methods that match URLDataSource which are called by
// InternalDataSource.
- std::string GetSource();
+ std::string GetSource() const;
std::string GetMimeType(const std::string& path) const;
void StartDataRequest(
const std::string& path,
- bool is_incognito,
+ int render_process_id,
+ int render_view_id,
const URLDataSource::GotDataCallback& callback);
void disable_set_font_strings_for_testing() {
diff --git a/content/browser/webui/web_ui_data_source_unittest.cc b/content/browser/webui/web_ui_data_source_unittest.cc
index b58161c..1a5efb7 100644
--- a/content/browser/webui/web_ui_data_source_unittest.cc
+++ b/content/browser/webui/web_ui_data_source_unittest.cc
@@ -52,14 +52,14 @@
class WebUIDataSourceTest : public testing::Test {
public:
- WebUIDataSourceTest() : result_data_(NULL), old_client_(NULL) {}
+ WebUIDataSourceTest() : result_data_(NULL) {}
virtual ~WebUIDataSourceTest() {}
WebUIDataSourceImpl* source() { return source_.get(); }
void StartDataRequest(const std::string& path) {
source_->StartDataRequest(
path,
- false,
+ 0, 0,
base::Bind(&WebUIDataSourceTest::SendResult,
base::Unretained(this)));
}
@@ -72,7 +72,6 @@
private:
virtual void SetUp() {
- old_client_ = GetContentClient();
SetContentClient(&client_);
WebUIDataSource* source = WebUIDataSourceImpl::Create("host");
WebUIDataSourceImpl* source_impl = static_cast<WebUIDataSourceImpl*>(
@@ -81,10 +80,6 @@
source_ = make_scoped_refptr(source_impl);
}
- virtual void TearDown() {
- SetContentClient(old_client_);
- }
-
// Store response for later comparisons.
void SendResult(base::RefCountedMemory* data) {
result_data_ = data;
@@ -92,7 +87,6 @@
scoped_refptr<WebUIDataSourceImpl> source_;
TestClient client_;
- ContentClient* old_client_;
};
TEST_F(WebUIDataSourceTest, EmptyStrings) {
@@ -147,7 +141,7 @@
TEST_F(WebUIDataSourceTest, MimeType) {
const char* html = "text/html";
const char* js = "application/javascript";
- EXPECT_EQ(GetMimeType(""), html);
+ EXPECT_EQ(GetMimeType(std::string()), html);
EXPECT_EQ(GetMimeType("foo"), html);
EXPECT_EQ(GetMimeType("foo.html"), html);
EXPECT_EQ(GetMimeType(".js"), js);
diff --git a/content/browser/webui/web_ui_impl.cc b/content/browser/webui/web_ui_impl.cc
index 5155702..88b181b 100644
--- a/content/browser/webui/web_ui_impl.cc
+++ b/content/browser/webui/web_ui_impl.cc
@@ -45,10 +45,7 @@
}
WebUIImpl::WebUIImpl(WebContents* contents)
- : hide_favicon_(false),
- focus_location_bar_by_default_(false),
- should_hide_url_(false),
- link_transition_type_(PAGE_TRANSITION_LINK),
+ : link_transition_type_(PAGE_TRANSITION_LINK),
bindings_(BINDINGS_POLICY_WEB_UI),
web_contents_(contents) {
DCHECK(contents);
@@ -111,30 +108,6 @@
return GetScaleFactorForView(web_contents_->GetRenderWidgetHostView());
}
-bool WebUIImpl::ShouldHideFavicon() const {
- return hide_favicon_;
-}
-
-void WebUIImpl::HideFavicon() {
- hide_favicon_ = true;
-}
-
-bool WebUIImpl::ShouldFocusLocationBarByDefault() const {
- return focus_location_bar_by_default_;
-}
-
-void WebUIImpl::FocusLocationBarByDefault() {
- focus_location_bar_by_default_ = true;
-}
-
-bool WebUIImpl::ShouldHideURL() const {
- return should_hide_url_;
-}
-
-void WebUIImpl::HideURL() {
- should_hide_url_ = true;
-}
-
const string16& WebUIImpl::GetOverriddenTitle() const {
return overridden_title_;
}
diff --git a/content/browser/webui/web_ui_impl.h b/content/browser/webui/web_ui_impl.h
index 49d9b4b..1be3674 100644
--- a/content/browser/webui/web_ui_impl.h
+++ b/content/browser/webui/web_ui_impl.h
@@ -32,12 +32,6 @@
virtual WebUIController* GetController() const OVERRIDE;
virtual void SetController(WebUIController* controller) OVERRIDE;
virtual ui::ScaleFactor GetDeviceScaleFactor() const OVERRIDE;
- virtual bool ShouldHideFavicon() const OVERRIDE;
- virtual void HideFavicon() OVERRIDE;
- virtual bool ShouldFocusLocationBarByDefault() const OVERRIDE;
- virtual void FocusLocationBarByDefault() OVERRIDE;
- virtual bool ShouldHideURL() const OVERRIDE;
- virtual void HideURL() OVERRIDE;
virtual const string16& GetOverriddenTitle() const OVERRIDE;
virtual void OverrideTitle(const string16& title) OVERRIDE;
virtual PageTransition GetLinkTransitionType() const OVERRIDE;
@@ -91,9 +85,6 @@
// Options that may be overridden by individual Web UI implementations. The
// bool options default to false. See the public getters for more information.
- bool hide_favicon_;
- bool focus_location_bar_by_default_;
- bool should_hide_url_;
string16 overridden_title_; // Defaults to empty string.
PageTransition link_transition_type_; // Defaults to LINK.
int bindings_; // The bindings from BindingsPolicy that should be enabled for
diff --git a/content/browser/worker_host/test/worker_browsertest.cc b/content/browser/worker_host/test/worker_browsertest.cc
index 7928718..b6ab62f 100644
--- a/content/browser/worker_host/test/worker_browsertest.cc
+++ b/content/browser/worker_host/test/worker_browsertest.cc
@@ -24,7 +24,7 @@
#include "content/test/layout_browsertest.h"
#include "googleurl/src/gurl.h"
#include "net/base/test_data_directory.h"
-#include "net/test/test_server.h"
+#include "net/test/spawned_test_server.h"
namespace content {
@@ -260,7 +260,7 @@
for (WorkerProcessHostIterator iter; !iter.Done(); ++iter)
(*cur_process_count)++;
BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure());
+ BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure());
}
bool WaitForWorkerProcessCount(int count) {
@@ -289,7 +289,7 @@
void NavigateAndWaitForAuth(const GURL& url) {
ShellContentBrowserClient* browser_client =
- static_cast<ShellContentBrowserClient*>(GetContentClient()->browser());
+ ShellContentBrowserClient::Get();
scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner();
browser_client->resource_dispatcher_host_delegate()->
set_login_request_callback(
@@ -300,11 +300,11 @@
};
IN_PROC_BROWSER_TEST_F(WorkerTest, SingleWorker) {
- RunTest("single_worker.html", "");
+ RunTest("single_worker.html", std::string());
}
IN_PROC_BROWSER_TEST_F(WorkerTest, MultipleWorkers) {
- RunTest("multi_worker.html", "");
+ RunTest("multi_worker.html", std::string());
}
IN_PROC_BROWSER_TEST_F(WorkerTest, SingleSharedWorker) {
@@ -320,10 +320,10 @@
// http://crbug.com/30021
IN_PROC_BROWSER_TEST_F(WorkerTest, IncognitoSharedWorkers) {
// Load a non-incognito tab and have it create a shared worker
- RunTest("incognito_worker.html", "");
+ RunTest("incognito_worker.html", std::string());
// Incognito worker should not share with non-incognito
- RunTest(CreateOffTheRecordBrowser(), "incognito_worker.html", "");
+ RunTest(CreateOffTheRecordBrowser(), "incognito_worker.html", std::string());
}
// Make sure that auth dialog is displayed from worker context.
@@ -399,7 +399,7 @@
// Flaky, http://crbug.com/59786.
IN_PROC_BROWSER_TEST_F(WorkerTest, WorkerClose) {
- RunTest("worker_close.html", "");
+ RunTest("worker_close.html", std::string());
ASSERT_TRUE(WaitForWorkerProcessCount(0));
}
@@ -466,9 +466,9 @@
IN_PROC_BROWSER_TEST_F(WorkerTest, WebSocketSharedWorker) {
// Launch WebSocket server.
- net::TestServer ws_server(net::TestServer::TYPE_WS,
- net::TestServer::kLocalhost,
- net::GetWebSocketTestDataDirectory());
+ net::SpawnedTestServer ws_server(net::SpawnedTestServer::TYPE_WS,
+ net::SpawnedTestServer::kLocalhost,
+ net::GetWebSocketTestDataDirectory());
ASSERT_TRUE(ws_server.Start());
// Generate test URL.
diff --git a/content/browser/worker_host/worker_process_host.cc b/content/browser/worker_host/worker_process_host.cc
index faad9e2..f340df7 100644
--- a/content/browser/worker_host/worker_process_host.cc
+++ b/content/browser/worker_host/worker_process_host.cc
@@ -174,7 +174,6 @@
#endif
switches::kDisableFileSystem,
switches::kDisableSeccompFilterSandbox,
- switches::kDisableWebSockets,
#if defined(OS_MACOSX)
switches::kEnableSandboxLogging,
#endif
diff --git a/content/browser/worker_host/worker_storage_partition.cc b/content/browser/worker_host/worker_storage_partition.cc
index f9d47d1..994f729 100644
--- a/content/browser/worker_host/worker_storage_partition.cc
+++ b/content/browser/worker_host/worker_storage_partition.cc
@@ -7,7 +7,7 @@
#include <string>
#include "content/browser/appcache/chrome_appcache_service.h"
-#include "content/browser/in_process_webkit/indexed_db_context_impl.h"
+#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "net/url_request/url_request_context_getter.h"
#include "webkit/database/database_tracker.h"
#include "webkit/fileapi/file_system_context.h"
diff --git a/content/browser/zygote_host/zygote_host_impl_linux.cc b/content/browser/zygote_host/zygote_host_impl_linux.cc
index 2251b12..ba7884f 100644
--- a/content/browser/zygote_host/zygote_host_impl_linux.cc
+++ b/content/browser/zygote_host/zygote_host_impl_linux.cc
@@ -101,9 +101,7 @@
switches::kV,
switches::kVModule,
switches::kRegisterPepperPlugins,
- switches::kDisableSeccompSandbox,
switches::kDisableSeccompFilterSandbox,
- switches::kEnableSeccompSandbox,
// Zygote process needs to know what resources to have loaded when it
// becomes a renderer process.
@@ -373,9 +371,12 @@
if (!selinux_valid) {
const base::FilePath kSelinuxPath("/selinux");
+ file_util::FileEnumerator en(kSelinuxPath, false,
+ file_util::FileEnumerator::FILES);
+ bool has_selinux_files = !en.Next().empty();
+
selinux = access(kSelinuxPath.value().c_str(), X_OK) == 0 &&
- file_util::CountFilesCreatedAfter(kSelinuxPath,
- base::Time::UnixEpoch()) > 0;
+ has_selinux_files;
selinux_valid = true;
}
diff --git a/content/common/DEPS b/content/common/DEPS
index e09f27a..a03ed69 100644
--- a/content/common/DEPS
+++ b/content/common/DEPS
@@ -3,5 +3,4 @@
"+components/tracing",
"+media/audio",
"+media/base",
- "+sandbox/linux/seccomp-legacy",
]
diff --git a/content/common/OWNERS b/content/common/OWNERS
index af049b9..0d10d79 100644
--- a/content/common/OWNERS
+++ b/content/common/OWNERS
@@ -3,9 +3,9 @@
jln@chromium.org
# For security review of sandboxes
-per-file sandbox_policy.cc=set noparent
-per-file sandbox_policy.cc=jschuh@chromium.org
-per-file sandbox_policy.cc=cpu@chromium.org
+per-file sandbox_win.cc=set noparent
+per-file sandbox_win.cc=jschuh@chromium.org
+per-file sandbox_win.cc=cpu@chromium.org
# Mac Sandbox.
per-file sandbox_init_mac.*=jeremy@chromium.org
@@ -20,6 +20,7 @@
per-file *_messages.h=jschuh@chromium.org
per-file *_messages.h=palmer@chromium.org
per-file *_messages.h=tsepez@chromium.org
+per-file *_messages.h=kenrb@chromium.org
# Accessibility
per-file accessibility_node_data.*=dmazzoni@chromium.org
diff --git a/content/common/accessibility_node_data.cc b/content/common/accessibility_node_data.cc
index a34b376..cf00e06 100644
--- a/content/common/accessibility_node_data.cc
+++ b/content/common/accessibility_node_data.cc
@@ -336,16 +336,31 @@
case ATTR_TABLE_CELL_ROW_SPAN:
result += " rowspan=" + value;
break;
- case ATTR_TITLE_UI_ELEMENT:
+ case ATTR_TABLE_COLUMN_HEADER_ID:
+ result += " column_header_id=" + value;
+ break;
+ case ATTR_TABLE_COLUMN_INDEX:
+ result += " column_index=" + value;
+ break;
+ case ATTR_TABLE_HEADER_ID:
+ result += " header_id=" + value;
+ break;
+ case ATTR_TABLE_ROW_HEADER_ID:
+ result += " row_header_id=" + value;
+ break;
+ case ATTR_TABLE_ROW_INDEX:
+ result += " row_index=" + value;
+ break;
+ case ATTR_TITLE_UI_ELEMENT:
result += " title_elem=" + value;
break;
- case ATTR_COLOR_VALUE_RED:
+ case ATTR_COLOR_VALUE_RED:
result += " color_value_red=" + value;
break;
- case ATTR_COLOR_VALUE_GREEN:
+ case ATTR_COLOR_VALUE_GREEN:
result += " color_value_green=" + value;
break;
- case ATTR_COLOR_VALUE_BLUE:
+ case ATTR_COLOR_VALUE_BLUE:
result += " color_value_blue=" + value;
break;
}
@@ -459,9 +474,12 @@
case ATTR_ARIA_READONLY:
result += " aria_readonly=" + value;
break;
- case ATTR_CAN_SET_VALUE:
+ case ATTR_CAN_SET_VALUE:
result += " can_set_value=" + value;
break;
+ case ATTR_UPDATE_LOCATION_ONLY:
+ result += " update_location_only=" + value;
+ break;
}
}
diff --git a/content/common/accessibility_node_data.h b/content/common/accessibility_node_data.h
index 94eeb2e..6b9f8cd 100644
--- a/content/common/accessibility_node_data.h
+++ b/content/common/accessibility_node_data.h
@@ -214,6 +214,15 @@
// Table attributes.
ATTR_TABLE_ROW_COUNT,
ATTR_TABLE_COLUMN_COUNT,
+ ATTR_TABLE_HEADER_ID,
+
+ // Table row attributes.
+ ATTR_TABLE_ROW_INDEX,
+ ATTR_TABLE_ROW_HEADER_ID,
+
+ // Table column attributes.
+ ATTR_TABLE_COLUMN_INDEX,
+ ATTR_TABLE_COLUMN_HEADER_ID,
// Table cell attributes.
ATTR_TABLE_CELL_COLUMN_INDEX,
@@ -261,6 +270,10 @@
// Writeable attributes
ATTR_CAN_SET_VALUE,
+
+ // If this is set, all of the other fields in this struct should
+ // be ignored and only the locations should change.
+ ATTR_UPDATE_LOCATION_ONLY,
};
AccessibilityNodeData();
diff --git a/content/common/android/common_jni_registrar.cc b/content/common/android/common_jni_registrar.cc
index bf774e6..fd7f2a6 100644
--- a/content/common/android/common_jni_registrar.cc
+++ b/content/common/android/common_jni_registrar.cc
@@ -9,7 +9,6 @@
#include "content/common/android/command_line.h"
#include "content/common/android/device_telephony_info.h"
#include "content/common/android/hash_set.h"
-#include "content/common/android/surface_texture_listener.h"
#include "content/common/android/trace_event_binding.h"
#include "webkit/glue/fling_animator_impl_android.h"
@@ -20,8 +19,6 @@
content::DeviceTelephonyInfo::RegisterDeviceTelephonyInfo },
{ "FlingAnimator", webkit_glue::FlingAnimatorImpl::RegisterJni },
{ "HashSet", content::RegisterHashSet },
- { "SurfaceTextureListener",
- content::SurfaceTextureListener::RegisterSurfaceTextureListener },
{ "TraceEvent", RegisterTraceEvent },
};
diff --git a/content/common/android/scoped_java_surface.cc b/content/common/android/scoped_java_surface.cc
deleted file mode 100644
index ca84f72..0000000
--- a/content/common/android/scoped_java_surface.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/common/android/scoped_java_surface.h"
-
-#include "base/logging.h"
-#include "content/common/android/surface_texture_bridge.h"
-#include "jni/Surface_jni.h"
-
-namespace {
-
-bool g_jni_initialized = false;
-
-void RegisterNativesIfNeeded(JNIEnv* env) {
- if (!g_jni_initialized) {
- JNI_Surface::RegisterNativesImpl(env);
- g_jni_initialized = true;
- }
-}
-
-} // anonymous namespace
-
-namespace content {
-
-ScopedJavaSurface::ScopedJavaSurface() {
-}
-
-ScopedJavaSurface::ScopedJavaSurface(
- const base::android::JavaRef<jobject>& surface) {
- JNIEnv* env = base::android::AttachCurrentThread();
- RegisterNativesIfNeeded(env);
- DCHECK(env->IsInstanceOf(surface.obj(), g_Surface_clazz));
- j_surface_.Reset(surface);
-}
-
-ScopedJavaSurface::ScopedJavaSurface(
- const SurfaceTextureBridge* surface_texture) {
- JNIEnv* env = base::android::AttachCurrentThread();
- RegisterNativesIfNeeded(env);
- ScopedJavaLocalRef<jobject> tmp(JNI_Surface::Java_Surface_Constructor(
- env, surface_texture->j_surface_texture().obj()));
- DCHECK(!tmp.is_null());
- j_surface_.Reset(tmp);
-}
-
-ScopedJavaSurface::~ScopedJavaSurface() {
- if (!j_surface_.is_null()) {
- JNIEnv* env = base::android::AttachCurrentThread();
- JNI_Surface::Java_Surface_release(env, j_surface_.obj());
- }
-}
-
-} // namespace content
diff --git a/content/common/android/scoped_java_surface.h b/content/common/android/scoped_java_surface.h
deleted file mode 100644
index de0b673..0000000
--- a/content/common/android/scoped_java_surface.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_COMMON_ANDROID_SCOPED_JAVA_SURFACE_H_
-#define CONTENT_COMMON_ANDROID_SCOPED_JAVA_SURFACE_H_
-
-#include <jni.h>
-
-#include "base/android/scoped_java_ref.h"
-
-namespace content {
-
-class SurfaceTextureBridge;
-
-// A helper class for holding a scoped reference to a Java Surface instance.
-// When going out of scope, Surface.release() is called on the Java object to
-// make sure server-side references (esp. wrt graphics memory) are released.
-class ScopedJavaSurface {
- public:
- ScopedJavaSurface();
-
- // Wraps an existing Java Surface object in a ScopedJavaSurface.
- explicit ScopedJavaSurface(const base::android::JavaRef<jobject>& surface);
-
- // Creates a Java Surface from a SurfaceTexture and wraps it in a
- // ScopedJavaSurface.
- explicit ScopedJavaSurface(const SurfaceTextureBridge* surface_texture);
-
- ~ScopedJavaSurface();
-
- const base::android::JavaRef<jobject>& j_surface() const {
- return j_surface_;
- }
-
- private:
- base::android::ScopedJavaGlobalRef<jobject> j_surface_;
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_ANDROID_SCOPED_JAVA_SURFACE_H_
diff --git a/content/common/android/surface_texture_bridge.cc b/content/common/android/surface_texture_bridge.cc
deleted file mode 100644
index 7f9d710..0000000
--- a/content/common/android/surface_texture_bridge.cc
+++ /dev/null
@@ -1,147 +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/common/android/surface_texture_bridge.h"
-
-#include <android/native_window_jni.h>
-
-// TODO(boliu): Remove this include when we move off ICS.
-#include "base/android/build_info.h"
-#include "base/android/jni_android.h"
-#include "base/logging.h"
-#include "content/common/android/scoped_java_surface.h"
-#include "content/common/android/surface_texture_listener.h"
-#include "jni/SurfaceTexture_jni.h"
-
-using base::android::AttachCurrentThread;
-using base::android::CheckException;
-using base::android::GetClass;
-using base::android::ScopedJavaLocalRef;
-
-namespace {
-bool g_jni_initialized = false;
-
-void RegisterNativesIfNeeded(JNIEnv* env) {
- if (!g_jni_initialized) {
- JNI_SurfaceTexture::RegisterNativesImpl(env);
- g_jni_initialized = true;
- }
-}
-
-// TODO(boliu): Remove this method when when we move off ICS. See
-// http://crbug.com/161864.
-bool GlContextMethodsAvailable() {
- bool available = base::android::BuildInfo::GetInstance()->sdk_int() >= 16;
- if (!available)
- LOG(WARNING) << "Running on unsupported device: rendering may not work";
- return available;
-}
-
-} // namespace
-
-namespace content {
-
-SurfaceTextureBridge::SurfaceTextureBridge(int texture_id)
- : texture_id_(texture_id) {
- JNIEnv* env = AttachCurrentThread();
- CHECK(env);
- RegisterNativesIfNeeded(env);
-
- ScopedJavaLocalRef<jobject> tmp(
- JNI_SurfaceTexture::Java_SurfaceTexture_Constructor(
- env, texture_id));
- DCHECK(!tmp.is_null());
- j_surface_texture_.Reset(tmp);
-}
-
-SurfaceTextureBridge::~SurfaceTextureBridge() {
- JNIEnv* env = AttachCurrentThread();
- CHECK(env);
-
- // Release the listener.
- JNI_SurfaceTexture::Java_SurfaceTexture_setOnFrameAvailableListener(
- env, j_surface_texture_.obj(), NULL);
-
- // Release graphics memory.
- JNI_SurfaceTexture::Java_SurfaceTexture_release(
- env, j_surface_texture_.obj());
-}
-
-void SurfaceTextureBridge::SetFrameAvailableCallback(
- const base::Closure& callback) {
- JNIEnv* env = AttachCurrentThread();
- CHECK(env);
-
- // Since the listener is owned by the Java SurfaceTexture object, setting
- // a new listener here will release an existing one at the same time.
- ScopedJavaLocalRef<jobject> j_listener(
- env,
- SurfaceTextureListener::CreateSurfaceTextureListener(env, callback));
- DCHECK(!j_listener.is_null());
-
- // Set it as the onFrameAvailableListener for our SurfaceTexture instance.
- JNI_SurfaceTexture::Java_SurfaceTexture_setOnFrameAvailableListener(
- env, j_surface_texture_.obj(), j_listener.obj());
-}
-
-void SurfaceTextureBridge::UpdateTexImage() {
- JNIEnv* env = AttachCurrentThread();
- CHECK(env);
-
- JNI_SurfaceTexture::Java_SurfaceTexture_updateTexImage(
- env, j_surface_texture_.obj());
-}
-
-void SurfaceTextureBridge::GetTransformMatrix(float mtx[16]) {
- JNIEnv* env = AttachCurrentThread();
- CHECK(env);
-
- ScopedJavaLocalRef<jfloatArray> jmatrix(env, env->NewFloatArray(16));
- JNI_SurfaceTexture::Java_SurfaceTexture_getTransformMatrix(
- env, j_surface_texture_.obj(), jmatrix.obj());
-
- jboolean is_copy;
- jfloat* elements = env->GetFloatArrayElements(jmatrix.obj(), &is_copy);
- for (int i = 0; i < 16; ++i) {
- mtx[i] = static_cast<float>(elements[i]);
- }
- env->ReleaseFloatArrayElements(jmatrix.obj(), elements, JNI_ABORT);
-}
-
-void SurfaceTextureBridge::SetDefaultBufferSize(int width, int height) {
- JNIEnv* env = AttachCurrentThread();
- CHECK(env);
-
- JNI_SurfaceTexture::Java_SurfaceTexture_setDefaultBufferSize(
- env, j_surface_texture_.obj(), static_cast<jint>(width),
- static_cast<jint>(height));
-}
-
-void SurfaceTextureBridge::AttachToGLContext(int texture_id) {
- if (GlContextMethodsAvailable()) {
- JNIEnv* env = AttachCurrentThread();
- // Note: This method is only available on JB and greater.
- JNI_SurfaceTexture::Java_SurfaceTexture_attachToGLContext(
- env, j_surface_texture_.obj(), texture_id);
- }
-}
-
-void SurfaceTextureBridge::DetachFromGLContext() {
- if (GlContextMethodsAvailable()) {
- JNIEnv* env = AttachCurrentThread();
- // Note: This method is only available on JB and greater.
- JNI_SurfaceTexture::Java_SurfaceTexture_detachFromGLContext(
- env, j_surface_texture_.obj());
- }
-}
-
-ANativeWindow* SurfaceTextureBridge::CreateSurface() {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaSurface surface(this);
- ANativeWindow* native_window =
- ANativeWindow_fromSurface(env, surface.j_surface().obj());
- return native_window;
-}
-
-} // namespace content
diff --git a/content/common/android/surface_texture_bridge.h b/content/common/android/surface_texture_bridge.h
deleted file mode 100644
index 0779196..0000000
--- a/content/common/android/surface_texture_bridge.h
+++ /dev/null
@@ -1,77 +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_COMMON_ANDROID_SURFACE_TEXTURE_BRIDGE_H_
-#define CONTENT_COMMON_ANDROID_SURFACE_TEXTURE_BRIDGE_H_
-
-#include <jni.h>
-
-#include "base/android/scoped_java_ref.h"
-#include "base/callback.h"
-#include "base/memory/ref_counted.h"
-
-struct ANativeWindow;
-
-namespace content {
-
-// This class serves as a bridge for native code to call java functions inside
-// android SurfaceTexture class.
-class SurfaceTextureBridge
- : public base::RefCountedThreadSafe<SurfaceTextureBridge>{
- public:
- explicit SurfaceTextureBridge(int texture_id);
-
- // Set the listener callback, which will be invoked on the same thread that
- // is being called from here for registration.
- // Note: Since callbacks come in from Java objects that might outlive objects
- // being referenced from the callback, the only robust way here is to create
- // the callback from a weak pointer to your object.
- void SetFrameAvailableCallback(const base::Closure& callback);
-
- // Update the texture image to the most recent frame from the image stream.
- void UpdateTexImage();
-
- // Retrieve the 4x4 texture coordinate transform matrix associated with the
- // texture image set by the most recent call to updateTexImage.
- void GetTransformMatrix(float mtx[16]);
-
- // Set the default size of the image buffers.
- void SetDefaultBufferSize(int width, int height);
-
- // Attach the SurfaceTexture to the given texture in the GL context that is
- // current on the calling thread.
- void AttachToGLContext(int texture_id);
-
- // Detaches the SurfaceTexture from the context that owns its current GL
- // texture. Must be called with that context current on the calling thread.
- void DetachFromGLContext();
-
- // Creates a native render surface for this surface texture.
- // The caller must release the underlying reference when done with the handle
- // by calling ANativeWindow_release().
- ANativeWindow* CreateSurface();
-
- int texture_id() const {
- return texture_id_;
- }
-
- const base::android::JavaRef<jobject>& j_surface_texture() const {
- return j_surface_texture_;
- }
-
- private:
- friend class base::RefCountedThreadSafe<SurfaceTextureBridge>;
- ~SurfaceTextureBridge();
-
- const int texture_id_;
-
- // Java SurfaceTexture instance.
- base::android::ScopedJavaGlobalRef<jobject> j_surface_texture_;
-
- DISALLOW_COPY_AND_ASSIGN(SurfaceTextureBridge);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_ANDROID_SURFACE_TEXTURE_BRIDGE_H_
diff --git a/content/common/android/surface_texture_listener.cc b/content/common/android/surface_texture_listener.cc
deleted file mode 100644
index 4440c5c..0000000
--- a/content/common/android/surface_texture_listener.cc
+++ /dev/null
@@ -1,53 +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/common/android/surface_texture_listener.h"
-
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/message_loop_proxy.h"
-#include "content/common/android/surface_texture_bridge.h"
-#include "jni/SurfaceTextureListener_jni.h"
-
-namespace content {
-
-// static
-jobject SurfaceTextureListener::CreateSurfaceTextureListener(
- JNIEnv* env,
- const base::Closure& callback) {
- // The java listener object owns and releases the native instance.
- // This is necessary to avoid races with incoming notifications.
- ScopedJavaLocalRef<jobject> listener(Java_SurfaceTextureListener_create(env,
- reinterpret_cast<int>(new SurfaceTextureListener(callback))));
-
- DCHECK(!listener.is_null());
- return listener.Release();
-}
-
-SurfaceTextureListener::SurfaceTextureListener(const base::Closure& callback)
- : callback_(callback),
- browser_loop_(base::MessageLoopProxy::current()) {
-}
-
-SurfaceTextureListener::~SurfaceTextureListener() {
-}
-
-void SurfaceTextureListener::Destroy(JNIEnv* env, jobject obj) {
- delete this;
-}
-
-void SurfaceTextureListener::FrameAvailable(JNIEnv* env, jobject obj) {
- if (!browser_loop_->BelongsToCurrentThread()) {
- browser_loop_->PostTask(FROM_HERE, callback_);
- } else {
- callback_.Run();
- }
-}
-
-// static
-bool SurfaceTextureListener::RegisterSurfaceTextureListener(JNIEnv* env) {
- return RegisterNativesImpl(env);
-}
-
-} // namespace content
diff --git a/content/common/android/surface_texture_listener.h b/content/common/android/surface_texture_listener.h
deleted file mode 100644
index 32cad7f..0000000
--- a/content/common/android/surface_texture_listener.h
+++ /dev/null
@@ -1,51 +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_COMMON_ANDROID_SURFACE_TEXTURE_LISTENER_H_
-#define CONTENT_COMMON_ANDROID_SURFACE_TEXTURE_LISTENER_H_
-
-#include <jni.h>
-#include "base/callback.h"
-#include "base/memory/ref_counted.h"
-
-namespace base {
-class MessageLoopProxy;
-}
-
-namespace content {
-
-// Listener class for all the callbacks from android SurfaceTexture.
-class SurfaceTextureListener {
-public:
- // Destroy this listener.
- void Destroy(JNIEnv* env, jobject obj);
-
- // A new frame is available to consume.
- void FrameAvailable(JNIEnv* env, jobject obj);
-
- static bool RegisterSurfaceTextureListener(JNIEnv* env);
-
-private:
- SurfaceTextureListener(const base::Closure& callback);
- ~SurfaceTextureListener();
-
- friend class SurfaceTextureBridge;
-
- // Static factory method for the creation of a SurfaceTextureListener.
- // The native code should not hold any reference to the returned object,
- // but only use it to pass it up to Java for being referenced by a
- // SurfaceTexture instance.
- static jobject CreateSurfaceTextureListener(JNIEnv* env,
- const base::Closure& callback);
-
- base::Closure callback_;
-
- scoped_refptr<base::MessageLoopProxy> browser_loop_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(SurfaceTextureListener);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_ANDROID_SURFACE_TEXTURE_LISTENER_H_
diff --git a/content/common/android/surface_texture_peer.h b/content/common/android/surface_texture_peer.h
index 921ff4c..0e1fbcc 100644
--- a/content/common/android/surface_texture_peer.h
+++ b/content/common/android/surface_texture_peer.h
@@ -6,7 +6,7 @@
#define CONTENT_COMMON_ANDROID_SURFACE_TEXTURE_PEER_H_
#include "base/process.h"
-#include "content/common/android/surface_texture_bridge.h"
+#include "ui/gl/android/surface_texture_bridge.h"
namespace content {
@@ -20,7 +20,7 @@
// process.
virtual void EstablishSurfaceTexturePeer(
base::ProcessHandle pid,
- scoped_refptr<SurfaceTextureBridge> surface_texture_bridge,
+ scoped_refptr<gfx::SurfaceTextureBridge> surface_texture_bridge,
int primary_id,
int secondary_id) = 0;
diff --git a/content/common/android/trace_event_binding.cc b/content/common/android/trace_event_binding.cc
index 04607ed..ec70335 100644
--- a/content/common/android/trace_event_binding.cc
+++ b/content/common/android/trace_event_binding.cc
@@ -89,9 +89,11 @@
TraceEventDataConverter converter(env, jname, jarg);
if (converter.arg()) {
TRACE_EVENT_COPY_INSTANT1(kJavaCategory, converter.name(),
+ TRACE_EVENT_SCOPE_THREAD,
converter.arg_name(), converter.arg());
} else {
- TRACE_EVENT_COPY_INSTANT0(kJavaCategory, converter.name());
+ TRACE_EVENT_COPY_INSTANT0(kJavaCategory, converter.name(),
+ TRACE_EVENT_SCOPE_THREAD);
}
}
diff --git a/content/common/browser_plugin/browser_plugin_constants.cc b/content/common/browser_plugin/browser_plugin_constants.cc
index f486917..4c11cff 100644
--- a/content/common/browser_plugin/browser_plugin_constants.cc
+++ b/content/common/browser_plugin/browser_plugin_constants.cc
@@ -37,6 +37,8 @@
const char kAttributeSrc[] = "src";
// Events.
+const char kEventClose[] = "close";
+const char kEventConsoleMessage[] = "consolemessage";
const char kEventExit[] = "exit";
const char kEventLoadAbort[] = "loadabort";
const char kEventLoadCommit[] = "loadcommit";
@@ -54,6 +56,9 @@
const char kInitialWidth[] = "initialWidth";
const char kIsTopLevel[] = "isTopLevel";
const char kLastUnlockedBySelf[] = "lastUnlockedBySelf";
+const char kLevel[] = "level";
+const char kLine[] = "line";
+const char kMessage[] = "message";
const char kName[] = "name";
const char kNewURL[] = "newUrl";
const char kNewHeight[] = "newHeight";
@@ -62,6 +67,7 @@
const char kOldHeight[] = "oldHeight";
const char kOldWidth[] = "oldWidth";
const char kPermission[] = "permission";
+const char kPermissionTypeDownload[] = "download";
const char kPermissionTypeGeolocation[] = "geolocation";
const char kPermissionTypeMedia[] = "media";
const char kPermissionTypeNewWindow[] = "newwindow";
@@ -70,6 +76,8 @@
const char kProcessId[] = "processId";
const char kReason[] = "reason";
const char kRequestId[] = "requestId";
+const char kRequestMethod[] = "requestMethod";
+const char kSourceId[] = "sourceId";
const char kTargetURL[] = "targetUrl";
const char kURL[] = "url";
const char kWindowID[] = "windowId";
diff --git a/content/common/browser_plugin/browser_plugin_constants.h b/content/common/browser_plugin/browser_plugin_constants.h
index 3dc489d..98af916 100644
--- a/content/common/browser_plugin/browser_plugin_constants.h
+++ b/content/common/browser_plugin/browser_plugin_constants.h
@@ -38,6 +38,8 @@
extern const char kAttributeSrc[];
// Events.
+extern const char kEventClose[];
+extern const char kEventConsoleMessage[];
extern const char kEventExit[];
extern const char kEventLoadAbort[];
extern const char kEventLoadCommit[];
@@ -55,6 +57,9 @@
extern const char kInitialWidth[];
extern const char kIsTopLevel[];
extern const char kLastUnlockedBySelf[];
+extern const char kLevel[];
+extern const char kLine[];
+extern const char kMessage[];
extern const char kName[];
extern const char kNewURL[];
extern const char kNewHeight[];
@@ -63,6 +68,7 @@
extern const char kOldHeight[];
extern const char kOldWidth[];
extern const char kPermission[];
+extern const char kPermissionTypeDownload[];
extern const char kPermissionTypeGeolocation[];
extern const char kPermissionTypeMedia[];
extern const char kPermissionTypeNewWindow[];
@@ -71,6 +77,8 @@
extern const char kProcessId[];
extern const char kReason[];
extern const char kRequestId[];
+extern const char kRequestMethod[];
+extern const char kSourceId[];
extern const char kTargetURL[];
extern const char kURL[];
extern const char kUserGesture[];
diff --git a/content/common/browser_plugin/browser_plugin_message_enums.h b/content/common/browser_plugin/browser_plugin_message_enums.h
index c4ea346..9fe045a 100644
--- a/content/common/browser_plugin/browser_plugin_message_enums.h
+++ b/content/common/browser_plugin/browser_plugin_message_enums.h
@@ -9,20 +9,24 @@
// Unknown type of permission request.
BrowserPluginPermissionTypeUnknown,
+ // Download.
+ BrowserPluginPermissionTypeDownload,
+
+ // Geolocation.
+ BrowserPluginPermissionTypeGeolocation,
+
+ // Media access (audio/video) permission request type.
+ BrowserPluginPermissionTypeMedia,
+
+ // PointerLock
+ BrowserPluginPermissionTypePointerLock,
+
+
// New window requests.
// Note: Even though new windows don't use the permission API, the new window
// API is sufficiently similar that it's convenient to consider it a
// permission type for code reuse.
BrowserPluginPermissionTypeNewWindow,
-
- // Media access (audio/video) permission request type.
- BrowserPluginPermissionTypeMedia,
-
- // Geolocation.
- BrowserPluginPermissionTypeGeolocation,
-
- // PointerLock
- BrowserPluginPermissionTypePointerLock,
};
#endif // CONTENT_COMMON_BROWSER_PLUGIN_BROWSER_PLUGIN_MESSAGE_ENUMS_H_
diff --git a/content/common/browser_plugin/browser_plugin_messages.h b/content/common/browser_plugin/browser_plugin_messages.h
index 86d04f8..eb668e6 100644
--- a/content/common/browser_plugin/browser_plugin_messages.h
+++ b/content/common/browser_plugin/browser_plugin_messages.h
@@ -10,6 +10,8 @@
#include "base/process.h"
#include "base/shared_memory.h"
#include "base/values.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/output/compositor_frame_ack.h"
#include "content/common/browser_plugin/browser_plugin_message_enums.h"
#include "content/common/content_export.h"
#include "content/common/content_param_traits.h"
@@ -58,7 +60,7 @@
IPC_STRUCT_MEMBER(bool, repaint)
IPC_STRUCT_END()
-IPC_STRUCT_BEGIN(BrowserPluginHostMsg_CreateGuest_Params)
+IPC_STRUCT_BEGIN(BrowserPluginHostMsg_Attach_Params)
IPC_STRUCT_MEMBER(std::string, storage_partition_id)
IPC_STRUCT_MEMBER(bool, persist_storage)
IPC_STRUCT_MEMBER(bool, focused)
@@ -70,6 +72,12 @@
resize_guest_params)
IPC_STRUCT_END()
+IPC_STRUCT_BEGIN(BrowserPluginMsg_Attach_ACK_Params)
+ IPC_STRUCT_MEMBER(std::string, storage_partition_id)
+ IPC_STRUCT_MEMBER(bool, persist_storage)
+ IPC_STRUCT_MEMBER(std::string, name)
+IPC_STRUCT_END()
+
IPC_STRUCT_BEGIN(BrowserPluginMsg_LoadCommit_Params)
// The current URL of the guest.
IPC_STRUCT_MEMBER(GURL, url)
@@ -138,6 +146,12 @@
IPC_MESSAGE_ROUTED1(BrowserPluginHostMsg_AllocateInstanceID,
int /* request_id */)
+// This message is sent from BrowserPlugin to BrowserPluginGuest to issue an
+// edit command.
+IPC_MESSAGE_ROUTED2(BrowserPluginHostMsg_ExecuteEditCommand,
+ int /* instance_id */,
+ std::string /* command */)
+
// This message is sent to the browser process to enable or disable autosize
// mode.
IPC_MESSAGE_ROUTED3(
@@ -146,21 +160,14 @@
BrowserPluginHostMsg_AutoSize_Params /* auto_size_params */,
BrowserPluginHostMsg_ResizeGuest_Params /* resize_guest_params */)
-
-// This message is sent to the browser process to create the browser plugin
-// embedder and helper. It is sent once prior to sending the first
-// BrowserPluginHostMsg_NavigateGuest message.
-IPC_MESSAGE_ROUTED2(BrowserPluginHostMsg_CreateGuest,
- int /* instance_id */,
- BrowserPluginHostMsg_CreateGuest_Params /* params */)
-
// This message is sent to the browser process to indicate that a BrowserPlugin
// has taken ownership of the lifetime of the guest of the given |instance_id|.
-// |params| is the size information of the BrowserPlugin taking ownership of
-// the guest.
+// |params| is the state of the BrowserPlugin taking ownership of
+// the guest. If a guest doesn't already exist with the given |instance_id|,
+// a new one will be created.
IPC_MESSAGE_ROUTED2(BrowserPluginHostMsg_Attach,
int /* instance_id */,
- BrowserPluginHostMsg_CreateGuest_Params /* params */)
+ BrowserPluginHostMsg_Attach_Params /* params */)
// Tells the browser process to terminate the guest associated with the
// browser plugin associated with the provided |instance_id|.
@@ -220,6 +227,13 @@
std::string /* mailbox_name */,
uint32 /* sync_point */)
+// Acknowledge that we presented an ubercomp frame.
+IPC_MESSAGE_ROUTED4(BrowserPluginHostMsg_CompositorFrameACK,
+ int /* instance_id */,
+ int /* route_id */,
+ int /* renderer_host_id */,
+ cc::CompositorFrameAck /* ack */)
+
// When a BrowserPlugin has been removed from the embedder's DOM, it informs
// the browser process to cleanup the guest.
IPC_MESSAGE_ROUTED1(BrowserPluginHostMsg_PluginDestroyed,
@@ -290,6 +304,22 @@
int /* request_id */,
int /* instance_id */)
+IPC_MESSAGE_CONTROL2(BrowserPluginMsg_AddMessageToConsole,
+ int /* instance_id */,
+ DictionaryValue /* message_info */)
+
+// This message is sent in response to a completed attachment of a guest
+// to a BrowserPlugin. This message carries information about the guest
+// that is used to update the attributes of the browser plugin.
+IPC_MESSAGE_CONTROL2(BrowserPluginMsg_Attach_ACK,
+ int /* instance_id */,
+ BrowserPluginMsg_Attach_ACK_Params /* params */)
+
+// When the guest's window requests to close, the embedder is informed through
+// the BrowserPluginMsg_Close message.
+IPC_MESSAGE_CONTROL1(BrowserPluginMsg_Close,
+ int /* instance_id */)
+
// Once the swapped out guest RenderView has been created in the embedder render
// process, the browser process informs the embedder of its routing ID.
IPC_MESSAGE_CONTROL2(BrowserPluginMsg_GuestContentWindowReady,
@@ -398,6 +428,12 @@
int /* route_id */,
int /* gpu_host_id */)
+IPC_MESSAGE_CONTROL4(BrowserPluginMsg_CompositorFrameSwapped,
+ int /* instance_id */,
+ cc::CompositorFrame /* frame */,
+ int /* route_id */,
+ int /* renderer_host_id */)
+
// When the guest requests permission, the browser process forwards this
// request to the embeddder through this message.
IPC_MESSAGE_CONTROL4(BrowserPluginMsg_RequestPermission,
diff --git a/content/common/cc_messages.cc b/content/common/cc_messages.cc
index 5ec8ae8..f8e0d74 100644
--- a/content/common/cc_messages.cc
+++ b/content/common/cc_messages.cc
@@ -320,6 +320,9 @@
case cc::DrawQuad::IO_SURFACE_CONTENT:
WriteParam(m, *cc::IOSurfaceDrawQuad::MaterialCast(quad));
break;
+ case cc::DrawQuad::PICTURE_CONTENT:
+ NOTREACHED();
+ break;
case cc::DrawQuad::TEXTURE_CONTENT:
WriteParam(m, *cc::TextureDrawQuad::MaterialCast(quad));
break;
@@ -434,6 +437,9 @@
case cc::DrawQuad::IO_SURFACE_CONTENT:
draw_quad = ReadDrawQuad<cc::IOSurfaceDrawQuad>(m, iter);
break;
+ case cc::DrawQuad::PICTURE_CONTENT:
+ NOTREACHED();
+ return false;
case cc::DrawQuad::TEXTURE_CONTENT:
draw_quad = ReadDrawQuad<cc::TextureDrawQuad>(m, iter);
break;
@@ -513,6 +519,9 @@
case cc::DrawQuad::IO_SURFACE_CONTENT:
LogParam(*cc::IOSurfaceDrawQuad::MaterialCast(quad), l);
break;
+ case cc::DrawQuad::PICTURE_CONTENT:
+ NOTREACHED();
+ break;
case cc::DrawQuad::TEXTURE_CONTENT:
LogParam(*cc::TextureDrawQuad::MaterialCast(quad), l);
break;
@@ -618,7 +627,7 @@
void ParamTraits<cc::CompositorFrameAck>::Write(Message* m,
const param_type& p) {
WriteParam(m, p.resources);
- WriteParam(m, p.last_content_dib);
+ WriteParam(m, p.last_dib_id);
if (p.gl_frame_data) {
WriteParam(m, static_cast<int>(GL_FRAME));
WriteParam(m, *p.gl_frame_data);
@@ -633,7 +642,7 @@
if (!ReadParam(m, iter, &p->resources))
return false;
- if (!ReadParam(m, iter, &p->last_content_dib))
+ if (!ReadParam(m, iter, &p->last_dib_id))
return false;
int compositor_frame_type;
@@ -659,7 +668,7 @@
l->append("CompositorFrameAck(");
LogParam(p.resources, l);
l->append(", ");
- LogParam(p.last_content_dib, l);
+ LogParam(p.last_dib_id, l);
l->append(", ");
if (p.gl_frame_data)
LogParam(*p.gl_frame_data, l);
diff --git a/content/common/cc_messages.h b/content/common/cc_messages.h
index 5cb76f7..08b831f 100644
--- a/content/common/cc_messages.h
+++ b/content/common/cc_messages.h
@@ -4,13 +4,14 @@
//
// IPC Messages sent between compositor instances.
-#include "cc/layers/video_layer_impl.h"
+#include "cc/debug/latency_info.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/compositor_frame_ack.h"
#include "cc/quads/checkerboard_draw_quad.h"
#include "cc/quads/debug_border_draw_quad.h"
#include "cc/quads/draw_quad.h"
#include "cc/quads/io_surface_draw_quad.h"
+#include "cc/quads/picture_draw_quad.h"
#include "cc/quads/render_pass.h"
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/shared_quad_state.h"
@@ -107,6 +108,7 @@
IPC_ENUM_TRAITS(cc::DrawQuad::Material)
IPC_ENUM_TRAITS(cc::IOSurfaceDrawQuad::Orientation)
+IPC_ENUM_TRAITS(cc::LatencyComponentType)
IPC_ENUM_TRAITS(WebKit::WebFilterOperation::FilterType)
IPC_STRUCT_TRAITS_BEGIN(cc::RenderPass::Id)
@@ -114,12 +116,6 @@
IPC_STRUCT_TRAITS_MEMBER(index)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(cc::VideoLayerImpl::FramePlane)
- IPC_STRUCT_TRAITS_MEMBER(resource_id)
- IPC_STRUCT_TRAITS_MEMBER(size)
- IPC_STRUCT_TRAITS_MEMBER(format)
-IPC_STRUCT_TRAITS_END()
-
IPC_STRUCT_TRAITS_BEGIN(cc::DrawQuad)
IPC_STRUCT_TRAITS_MEMBER(material)
IPC_STRUCT_TRAITS_MEMBER(rect)
@@ -142,12 +138,13 @@
IPC_STRUCT_TRAITS_BEGIN(cc::IOSurfaceDrawQuad)
IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad)
IPC_STRUCT_TRAITS_MEMBER(io_surface_size)
- IPC_STRUCT_TRAITS_MEMBER(io_surface_texture_id)
+ IPC_STRUCT_TRAITS_MEMBER(io_surface_resource_id)
IPC_STRUCT_TRAITS_MEMBER(orientation)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(cc::RenderPassDrawQuad)
IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad)
+ IPC_STRUCT_TRAITS_MEMBER(render_pass_id)
IPC_STRUCT_TRAITS_MEMBER(is_replica)
IPC_STRUCT_TRAITS_MEMBER(mask_resource_id)
IPC_STRUCT_TRAITS_MEMBER(contents_changed_since_last_frame)
@@ -161,11 +158,12 @@
IPC_STRUCT_TRAITS_BEGIN(cc::SolidColorDrawQuad)
IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad)
IPC_STRUCT_TRAITS_MEMBER(color)
+ IPC_STRUCT_TRAITS_MEMBER(force_anti_aliasing_off)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(cc::StreamVideoDrawQuad)
IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad)
- IPC_STRUCT_TRAITS_MEMBER(texture_id)
+ IPC_STRUCT_TRAITS_MEMBER(resource_id)
IPC_STRUCT_TRAITS_MEMBER(matrix)
IPC_STRUCT_TRAITS_END()
@@ -193,9 +191,9 @@
IPC_STRUCT_TRAITS_BEGIN(cc::YUVVideoDrawQuad)
IPC_STRUCT_TRAITS_PARENT(cc::DrawQuad)
IPC_STRUCT_TRAITS_MEMBER(tex_scale)
- IPC_STRUCT_TRAITS_MEMBER(y_plane)
- IPC_STRUCT_TRAITS_MEMBER(u_plane)
- IPC_STRUCT_TRAITS_MEMBER(v_plane)
+ IPC_STRUCT_TRAITS_MEMBER(y_plane_resource_id)
+ IPC_STRUCT_TRAITS_MEMBER(u_plane_resource_id)
+ IPC_STRUCT_TRAITS_MEMBER(v_plane_resource_id)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(cc::SharedQuadState)
@@ -216,6 +214,17 @@
IPC_STRUCT_TRAITS_MEMBER(mailbox)
IPC_STRUCT_TRAITS_END()
+IPC_STRUCT_TRAITS_BEGIN(cc::LatencyInfo::LatencyComponent)
+ IPC_STRUCT_TRAITS_MEMBER(sequence_number)
+ IPC_STRUCT_TRAITS_MEMBER(event_time)
+ IPC_STRUCT_TRAITS_MEMBER(event_count)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(cc::LatencyInfo)
+ IPC_STRUCT_TRAITS_MEMBER(latency_components)
+ IPC_STRUCT_TRAITS_MEMBER(swap_timestamp)
+IPC_STRUCT_TRAITS_END()
+
IPC_STRUCT_TRAITS_BEGIN(cc::CompositorFrameMetadata)
IPC_STRUCT_TRAITS_MEMBER(device_scale_factor)
IPC_STRUCT_TRAITS_MEMBER(root_scroll_offset)
@@ -226,6 +235,7 @@
IPC_STRUCT_TRAITS_MEMBER(max_page_scale_factor)
IPC_STRUCT_TRAITS_MEMBER(location_bar_offset)
IPC_STRUCT_TRAITS_MEMBER(location_bar_content_translation)
+ IPC_STRUCT_TRAITS_MEMBER(overdraw_bottom_height)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(cc::GLFrameData)
@@ -237,5 +247,5 @@
IPC_STRUCT_TRAITS_BEGIN(cc::SoftwareFrameData)
IPC_STRUCT_TRAITS_MEMBER(size)
IPC_STRUCT_TRAITS_MEMBER(damage_rect)
- IPC_STRUCT_TRAITS_MEMBER(content_dib)
+ IPC_STRUCT_TRAITS_MEMBER(dib_id)
IPC_STRUCT_TRAITS_END()
diff --git a/content/common/cc_messages_unittest.cc b/content/common/cc_messages_unittest.cc
index d843e4b..7d20b8c 100644
--- a/content/common/cc_messages_unittest.cc
+++ b/content/common/cc_messages_unittest.cc
@@ -15,6 +15,7 @@
using cc::DebugBorderDrawQuad;
using cc::DrawQuad;
using cc::IOSurfaceDrawQuad;
+using cc::PictureDrawQuad;
using cc::RenderPass;
using cc::RenderPassDrawQuad;
using cc::ResourceProvider;
@@ -77,6 +78,10 @@
Compare(IOSurfaceDrawQuad::MaterialCast(a),
IOSurfaceDrawQuad::MaterialCast(b));
break;
+ case DrawQuad::PICTURE_CONTENT:
+ Compare(PictureDrawQuad::MaterialCast(a),
+ PictureDrawQuad::MaterialCast(b));
+ break;
case DrawQuad::RENDER_PASS:
Compare(RenderPassDrawQuad::MaterialCast(a),
RenderPassDrawQuad::MaterialCast(b));
@@ -117,11 +122,12 @@
void Compare(const IOSurfaceDrawQuad* a, const IOSurfaceDrawQuad* b) {
EXPECT_EQ(a->io_surface_size.ToString(), b->io_surface_size.ToString());
- EXPECT_EQ(a->io_surface_texture_id, b->io_surface_texture_id);
+ EXPECT_EQ(a->io_surface_resource_id, b->io_surface_resource_id);
EXPECT_EQ(a->orientation, b->orientation);
}
void Compare(const RenderPassDrawQuad* a, const RenderPassDrawQuad* b) {
+ EXPECT_EQ(a->render_pass_id, b->render_pass_id);
EXPECT_EQ(a->is_replica, b->is_replica);
EXPECT_EQ(a->mask_resource_id, b->mask_resource_id);
EXPECT_EQ(a->contents_changed_since_last_frame,
@@ -134,10 +140,11 @@
void Compare(const SolidColorDrawQuad* a, const SolidColorDrawQuad* b) {
EXPECT_EQ(a->color, b->color);
+ EXPECT_EQ(a->force_anti_aliasing_off, b->force_anti_aliasing_off);
}
void Compare(const StreamVideoDrawQuad* a, const StreamVideoDrawQuad* b) {
- EXPECT_EQ(a->texture_id, b->texture_id);
+ EXPECT_EQ(a->resource_id, b->resource_id);
EXPECT_EQ(a->matrix, b->matrix);
}
@@ -162,15 +169,9 @@
void Compare(const YUVVideoDrawQuad* a, const YUVVideoDrawQuad* b) {
EXPECT_EQ(a->tex_scale, b->tex_scale);
- EXPECT_EQ(a->y_plane.resource_id, b->y_plane.resource_id);
- EXPECT_EQ(a->y_plane.size.ToString(), b->y_plane.size.ToString());
- EXPECT_EQ(a->y_plane.format, b->y_plane.format);
- EXPECT_EQ(a->u_plane.resource_id, b->u_plane.resource_id);
- EXPECT_EQ(a->u_plane.size.ToString(), b->u_plane.size.ToString());
- EXPECT_EQ(a->u_plane.format, b->u_plane.format);
- EXPECT_EQ(a->v_plane.resource_id, b->v_plane.resource_id);
- EXPECT_EQ(a->v_plane.size.ToString(), b->v_plane.size.ToString());
- EXPECT_EQ(a->v_plane.format, b->v_plane.format);
+ EXPECT_EQ(a->y_plane_resource_id, b->y_plane_resource_id);
+ EXPECT_EQ(a->u_plane_resource_id, b->u_plane_resource_id);
+ EXPECT_EQ(a->v_plane_resource_id, b->v_plane_resource_id);
}
void Compare(const TransferableResource& a, const TransferableResource& b) {
@@ -213,22 +214,9 @@
IOSurfaceDrawQuad::Orientation arbitrary_orientation =
IOSurfaceDrawQuad::UNFLIPPED;
RenderPass::Id arbitrary_id(10, 14);
- ResourceProvider::ResourceId arbitrary_resourceid = 55;
-
- VideoLayerImpl::FramePlane arbitrary_plane1;
- arbitrary_plane1.resource_id = arbitrary_resourceid;
- arbitrary_plane1.size = arbitrary_size1;
- arbitrary_plane1.format = arbitrary_int;
-
- VideoLayerImpl::FramePlane arbitrary_plane2;
- arbitrary_plane2.resource_id = arbitrary_resourceid;
- arbitrary_plane2.size = arbitrary_size2;
- arbitrary_plane2.format = arbitrary_int;
-
- VideoLayerImpl::FramePlane arbitrary_plane3;
- arbitrary_plane3.resource_id = arbitrary_resourceid;
- arbitrary_plane3.size = arbitrary_size3;
- arbitrary_plane3.format = arbitrary_int;
+ ResourceProvider::ResourceId arbitrary_resourceid1 = 55;
+ ResourceProvider::ResourceId arbitrary_resourceid2 = 47;
+ ResourceProvider::ResourceId arbitrary_resourceid3 = 23;
WebFilterOperations arbitrary_filters1;
arbitrary_filters1.append(WebFilterOperation::createGrayscaleFilter(
@@ -281,7 +269,7 @@
arbitrary_rect1,
arbitrary_bool1,
arbitrary_size1,
- arbitrary_int,
+ arbitrary_resourceid3,
arbitrary_orientation);
scoped_ptr<DrawQuad> iosurface_cmp = iosurface_in->Copy(
iosurface_in->shared_quad_state);
@@ -295,11 +283,11 @@
arbitrary_bool1,
arbitrary_id,
arbitrary_bool2,
- arbitrary_resourceid,
+ arbitrary_resourceid2,
arbitrary_rect1,
arbitrary_rectf1,
arbitrary_filters1,
- arbitrary_filter, // TODO(piman): not serialized.
+ arbitrary_filter, // TODO(piman): not serialized.
arbitrary_filters2);
scoped_ptr<RenderPassDrawQuad> renderpass_cmp = renderpass_in->Copy(
renderpass_in->shared_quad_state, renderpass_in->render_pass_id);
@@ -329,7 +317,8 @@
arbitrary_rect1,
arbitrary_rect2,
arbitrary_bool1,
- arbitrary_color);
+ arbitrary_color,
+ arbitrary_bool2);
scoped_ptr<DrawQuad> solidcolor_cmp = solidcolor_in->Copy(
solidcolor_in->shared_quad_state);
@@ -340,7 +329,7 @@
arbitrary_rect3,
arbitrary_rect1,
arbitrary_bool1,
- arbitrary_int,
+ arbitrary_resourceid2,
arbitrary_matrix);
scoped_ptr<DrawQuad> streamvideo_cmp = streamvideo_in->Copy(
streamvideo_in->shared_quad_state);
@@ -351,7 +340,7 @@
arbitrary_rect3,
arbitrary_rect1,
arbitrary_bool1,
- arbitrary_resourceid,
+ arbitrary_resourceid1,
arbitrary_bool2,
arbitrary_pointf1,
arbitrary_pointf2,
@@ -366,7 +355,7 @@
arbitrary_rect3,
arbitrary_rect1,
arbitrary_bool1,
- arbitrary_resourceid,
+ arbitrary_resourceid3,
arbitrary_rectf1,
arbitrary_size1,
arbitrary_bool2);
@@ -381,9 +370,9 @@
arbitrary_rect3,
arbitrary_bool1,
arbitrary_sizef1,
- arbitrary_plane1,
- arbitrary_plane2,
- arbitrary_plane3);
+ arbitrary_resourceid1,
+ arbitrary_resourceid2,
+ arbitrary_resourceid3);
scoped_ptr<DrawQuad> yuvvideo_cmp = yuvvideo_in->Copy(
yuvvideo_in->shared_quad_state);
diff --git a/content/common/child_histogram_message_filter.cc b/content/common/child_histogram_message_filter.cc
index 25f9180..752d767 100644
--- a/content/common/child_histogram_message_filter.cc
+++ b/content/common/child_histogram_message_filter.cc
@@ -18,7 +18,7 @@
ChildHistogramMessageFilter::ChildHistogramMessageFilter()
: channel_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(histogram_snapshot_manager_(this)) {
+ histogram_snapshot_manager_(this) {
}
ChildHistogramMessageFilter::~ChildHistogramMessageFilter() {
diff --git a/content/common/child_histogram_message_filter.h b/content/common/child_histogram_message_filter.h
index 4955d49..9339d8e 100644
--- a/content/common/child_histogram_message_filter.h
+++ b/content/common/child_histogram_message_filter.h
@@ -14,8 +14,6 @@
#include "base/metrics/histogram_snapshot_manager.h"
#include "ipc/ipc_channel_proxy.h"
-class MessageLoop;
-
namespace base {
class HistogramSamples;
} // namespace base
diff --git a/content/common/child_process.cc b/content/common/child_process.cc
index 75c80ec..95bc331 100644
--- a/content/common/child_process.cc
+++ b/content/common/child_process.cc
@@ -51,7 +51,7 @@
// We can't recover from failing to start the IO thread.
CHECK(io_thread_.StartWithOptions(
- base::Thread::Options(MessageLoop::TYPE_IO, 0)));
+ base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
#if defined(OS_ANDROID)
// TODO(epenner): Move thread priorities to base. (crbug.com/170549)
@@ -71,7 +71,10 @@
// Kill the main thread object before nulling child_process_, since
// destruction code might depend on it.
- main_thread_.reset();
+ if (main_thread_) { // null in unittests.
+ main_thread_->Shutdown();
+ main_thread_.reset();
+ }
child_process_ = NULL;
}
@@ -86,19 +89,19 @@
void ChildProcess::AddRefProcess() {
DCHECK(!main_thread_.get() || // null in unittests.
- MessageLoop::current() == main_thread_->message_loop());
+ base::MessageLoop::current() == main_thread_->message_loop());
ref_count_++;
}
void ChildProcess::ReleaseProcess() {
DCHECK(!main_thread_.get() || // null in unittests.
- MessageLoop::current() == main_thread_->message_loop());
+ base::MessageLoop::current() == main_thread_->message_loop());
DCHECK(ref_count_);
DCHECK(child_process_);
if (--ref_count_)
return;
- if (main_thread_.get()) // null in unittests.
+ if (main_thread_) // null in unittests.
main_thread_->OnProcessFinalRelease();
}
diff --git a/content/common/child_process.h b/content/common/child_process.h
index 09e97d9..dc7df53 100644
--- a/content/common/child_process.h
+++ b/content/common/child_process.h
@@ -30,7 +30,7 @@
// Takes ownership of the pointer.
void set_main_thread(ChildThread* thread);
- MessageLoop* io_message_loop() { return io_thread_.message_loop(); }
+ base::MessageLoop* io_message_loop() { return io_thread_.message_loop(); }
base::MessageLoopProxy* io_message_loop_proxy() {
return io_thread_.message_loop_proxy();
}
diff --git a/content/common/child_process_host_impl.cc b/content/common/child_process_host_impl.cc
index 606811d..bb0fdfd 100644
--- a/content/common/child_process_host_impl.cc
+++ b/content/common/child_process_host_impl.cc
@@ -149,7 +149,7 @@
void ChildProcessHostImpl::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
filters_.push_back(filter);
- if (channel_.get())
+ if (channel_)
filter->OnFilterAdded(channel_.get());
}
@@ -189,7 +189,7 @@
#endif
bool ChildProcessHostImpl::Send(IPC::Message* message) {
- if (!channel_.get()) {
+ if (!channel_) {
delete message;
return false;
}
@@ -262,7 +262,7 @@
}
void ChildProcessHostImpl::OnChannelConnected(int32 peer_pid) {
- if (!base::OpenProcessHandle(peer_pid, &peer_handle_)) {
+ if (!base::OpenPrivilegedProcessHandle(peer_pid, &peer_handle_)) {
NOTREACHED();
}
opening_channel_ = false;
diff --git a/content/common/child_process_sandbox_support_impl_linux.cc b/content/common/child_process_sandbox_support_impl_linux.cc
index 984f796..6eec6fe 100644
--- a/content/common/child_process_sandbox_support_impl_linux.cc
+++ b/content/common/child_process_sandbox_support_impl_linux.cc
@@ -10,6 +10,8 @@
#include "base/pickle.h"
#include "base/posix/eintr_wrapper.h"
#include "base/posix/unix_domain_socket_linux.h"
+#include "base/safe_numerics.h"
+#include "base/sys_byteorder.h"
#include "content/common/sandbox_linux.h"
#include "third_party/WebKit/Source/Platform/chromium/public/linux/WebFontFamily.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/linux/WebFontRenderStyle.h"
@@ -99,79 +101,74 @@
return fd;
}
-bool GetFontTable(int fd, uint32_t table, uint8_t* output,
- size_t* output_length) {
- if (table == 0) {
+bool GetFontTable(int fd, uint32_t table_tag, off_t offset,
+ uint8_t* output, size_t* output_length) {
+ if (offset < 0)
+ return false;
+
+ size_t data_length = 0; // the length of the file data.
+ off_t data_offset = 0; // the offset of the data in the file.
+ if (table_tag == 0) {
+ // Get the entire font file.
struct stat st;
if (fstat(fd, &st) < 0)
return false;
- size_t length = st.st_size;
- if (!output) {
- *output_length = length;
- return true;
- }
- if (*output_length < length)
+ data_length = base::checked_numeric_cast<size_t>(st.st_size);
+ } else {
+ // Get a font table. Read the header to find its offset in the file.
+ uint16_t num_tables;
+ ssize_t n = HANDLE_EINTR(pread(fd, &num_tables, sizeof(num_tables),
+ 4 /* skip the font type */));
+ if (n != sizeof(num_tables))
return false;
- *output_length = length;
- ssize_t n = HANDLE_EINTR(pread(fd, output, length, 0));
- if (n != static_cast<ssize_t>(length))
+ // Font data is stored in net (big-endian) order.
+ num_tables = base::NetToHost16(num_tables);
+
+ // Read the table directory.
+ static const size_t kTableEntrySize = 16;
+ const size_t directory_size = num_tables * kTableEntrySize;
+ scoped_ptr<uint8_t[]> table_entries(new uint8_t[directory_size]);
+ n = HANDLE_EINTR(pread(fd, table_entries.get(), directory_size,
+ 12 /* skip the SFNT header */));
+ if (n != base::checked_numeric_cast<ssize_t>(directory_size))
return false;
- return true;
- }
- unsigned num_tables;
- uint8_t num_tables_buf[2];
-
- ssize_t n = HANDLE_EINTR(pread(fd, &num_tables_buf, sizeof(num_tables_buf),
- 4 /* skip the font type */));
- if (n != sizeof(num_tables_buf))
- return false;
-
- num_tables = static_cast<unsigned>(num_tables_buf[0]) << 8 |
- num_tables_buf[1];
-
- // The size in bytes of an entry in the table directory.
- static const unsigned kTableEntrySize = 16;
- scoped_array<uint8_t> table_entries(
- new uint8_t[num_tables * kTableEntrySize]);
- n = HANDLE_EINTR(pread(fd, table_entries.get(), num_tables * kTableEntrySize,
- 12 /* skip the SFNT header */));
- if (n != static_cast<ssize_t>(num_tables * kTableEntrySize))
- return false;
-
- size_t offset;
- size_t length = 0;
- for (unsigned i = 0; i < num_tables; i++) {
- const uint8_t* entry = table_entries.get() + i * kTableEntrySize;
- if (memcmp(entry, &table, sizeof(table)) == 0) {
- offset = static_cast<size_t>(entry[8]) << 24 |
- static_cast<size_t>(entry[9]) << 16 |
- static_cast<size_t>(entry[10]) << 8 |
- static_cast<size_t>(entry[11]);
- length = static_cast<size_t>(entry[12]) << 24 |
- static_cast<size_t>(entry[13]) << 16 |
- static_cast<size_t>(entry[14]) << 8 |
- static_cast<size_t>(entry[15]);
-
- break;
+ for (uint16_t i = 0; i < num_tables; ++i) {
+ uint8_t* entry = table_entries.get() + i * kTableEntrySize;
+ uint32_t tag = *reinterpret_cast<uint32_t*>(entry);
+ if (tag == table_tag) {
+ // Font data is stored in net (big-endian) order.
+ data_offset =
+ base::NetToHost32(*reinterpret_cast<uint32_t*>(entry + 8));
+ data_length =
+ base::NetToHost32(*reinterpret_cast<uint32_t*>(entry + 12));
+ break;
+ }
}
}
- if (!length)
+ if (!data_length)
return false;
+ // Clamp |offset| inside the allowable range. This allows the read to succeed
+ // but return 0 bytes.
+ offset = std::min(offset, base::checked_numeric_cast<off_t>(data_length));
+ // Make sure it's safe to add the data offset and the caller's logical offset.
+ // Define the maximum positive offset on 32 bit systems.
+ static const off_t kMaxPositiveOffset32 = 0x7FFFFFFF; // 2 GB - 1.
+ if ((offset > kMaxPositiveOffset32 / 2) ||
+ (data_offset > kMaxPositiveOffset32 / 2))
+ return false;
+ data_offset += offset;
+ data_length -= offset;
- if (!output) {
- *output_length = length;
- return true;
+ if (output) {
+ // 'output_length' holds the maximum amount of data the caller can accept.
+ data_length = std::min(data_length, *output_length);
+ ssize_t n = HANDLE_EINTR(pread(fd, output, data_length, data_offset));
+ if (n != base::checked_numeric_cast<ssize_t>(data_length))
+ return false;
}
-
- if (*output_length < length)
- return false;
-
- *output_length = length;
- n = HANDLE_EINTR(pread(fd, output, length, offset));
- if (n != static_cast<ssize_t>(length))
- return false;
+ *output_length = data_length;
return true;
}
diff --git a/content/common/child_thread.cc b/content/common/child_thread.cc
index 4540b15..b301ab7 100644
--- a/content/common/child_thread.cc
+++ b/content/common/child_thread.cc
@@ -82,7 +82,7 @@
} // namespace
ChildThread::ChildThread()
- : ALLOW_THIS_IN_INITIALIZER_LIST(channel_connected_factory_(this)) {
+ : channel_connected_factory_(this) {
channel_name_ = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kProcessChannelID);
Init();
@@ -90,17 +90,20 @@
ChildThread::ChildThread(const std::string& channel_name)
: channel_name_(channel_name),
- ALLOW_THIS_IN_INITIALIZER_LIST(channel_connected_factory_(this)) {
+ channel_connected_factory_(this) {
Init();
}
void ChildThread::Init() {
on_channel_error_called_ = false;
- message_loop_ = MessageLoop::current();
- channel_.reset(new IPC::SyncChannel(channel_name_,
- IPC::Channel::MODE_CLIENT, this,
- ChildProcess::current()->io_message_loop_proxy(), true,
- ChildProcess::current()->GetShutDownEvent()));
+ message_loop_ = base::MessageLoop::current();
+ channel_.reset(
+ new IPC::SyncChannel(channel_name_,
+ IPC::Channel::MODE_CLIENT,
+ this,
+ ChildProcess::current()->io_message_loop_proxy(),
+ true,
+ ChildProcess::current()->GetShutDownEvent()));
#ifdef IPC_MESSAGE_LOG_ENABLED
IPC::Logging::GetInstance()->SetIPCSender(this);
#endif
@@ -129,7 +132,7 @@
channel_->AddFilter(new SuicideOnChannelErrorFilter());
#endif
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&ChildThread::EnsureConnected,
channel_connected_factory_.GetWeakPtr()),
@@ -161,12 +164,12 @@
void ChildThread::OnChannelError() {
set_on_channel_error_called(true);
- MessageLoop::current()->Quit();
+ base::MessageLoop::current()->Quit();
}
bool ChildThread::Send(IPC::Message* msg) {
- DCHECK(MessageLoop::current() == message_loop());
- if (!channel_.get()) {
+ DCHECK(base::MessageLoop::current() == message_loop());
+ if (!channel_) {
delete msg;
return false;
}
@@ -175,23 +178,17 @@
}
void ChildThread::AddRoute(int32 routing_id, IPC::Listener* listener) {
- DCHECK(MessageLoop::current() == message_loop());
+ DCHECK(base::MessageLoop::current() == message_loop());
router_.AddRoute(routing_id, listener);
}
void ChildThread::RemoveRoute(int32 routing_id) {
- DCHECK(MessageLoop::current() == message_loop());
+ DCHECK(base::MessageLoop::current() == message_loop());
router_.RemoveRoute(routing_id);
}
-IPC::Listener* ChildThread::ResolveRoute(int32 routing_id) {
- DCHECK(MessageLoop::current() == message_loop());
-
- return router_.ResolveRoute(routing_id);
-}
-
webkit_glue::ResourceLoaderBridge* ChildThread::CreateBridge(
const webkit_glue::ResourceLoaderBridge::RequestInfo& request_info) {
return resource_dispatcher()->CreateBridge(request_info);
@@ -279,7 +276,7 @@
}
void ChildThread::OnShutdown() {
- MessageLoop::current()->Quit();
+ base::MessageLoop::current()->Quit();
}
#if defined(IPC_MESSAGE_LOG_ENABLED)
@@ -339,7 +336,7 @@
void ChildThread::OnProcessFinalRelease() {
if (on_channel_error_called_) {
- MessageLoop::current()->Quit();
+ base::MessageLoop::current()->Quit();
return;
}
diff --git a/content/common/child_thread.h b/content/common/child_thread.h
index ed9e684..bd23cc9 100644
--- a/content/common/child_thread.h
+++ b/content/common/child_thread.h
@@ -15,7 +15,9 @@
#include "ipc/ipc_message.h" // For IPC_MESSAGE_LOG_ENABLED.
#include "webkit/glue/resource_loader_bridge.h"
+namespace base {
class MessageLoop;
+}
namespace IPC {
class SyncChannel;
@@ -41,7 +43,13 @@
ChildThread();
// Used for single-process mode.
explicit ChildThread(const std::string& channel_name);
+ // ChildProcess::main_thread() is reset after Shutdown(), and before the
+ // destructor, so any subsystem that relies on ChildProcess::main_thread()
+ // must be terminated before Shutdown returns. In particular, if a subsystem
+ // has a thread that post tasks to ChildProcess::main_thread(), that thread
+ // should be joined in Shutdown().
virtual ~ChildThread();
+ virtual void Shutdown() = 0;
// IPC::Sender implementation:
virtual bool Send(IPC::Message* msg) OVERRIDE;
@@ -50,8 +58,6 @@
void AddRoute(int32 routing_id, IPC::Listener* listener);
void RemoveRoute(int32 routing_id);
- IPC::Listener* ResolveRoute(int32 routing_id);
-
IPC::SyncChannel* channel() { return channel_.get(); }
// Creates a ResourceLoaderBridge.
@@ -104,7 +110,7 @@
return histogram_message_filter_.get();
}
- MessageLoop* message_loop() const { return message_loop_; }
+ base::MessageLoop* message_loop() const { return message_loop_; }
// Returns the one child thread.
static ChildThread* current();
@@ -166,7 +172,7 @@
// attempt to communicate.
bool on_channel_error_called_;
- MessageLoop* message_loop_;
+ base::MessageLoop* message_loop_;
scoped_ptr<FileSystemDispatcher> file_system_dispatcher_;
diff --git a/content/common/common_param_traits_unittest.cc b/content/common/common_param_traits_unittest.cc
index 0540032..432f8f9 100644
--- a/content/common/common_param_traits_unittest.cc
+++ b/content/common/common_param_traits_unittest.cc
@@ -113,7 +113,7 @@
bad_msg.WriteData(fixed_data, fixed_data_size);
// Add some bogus pixel data.
const size_t bogus_pixels_size = bitmap.getSize() * 2;
- scoped_array<char> bogus_pixels(new char[bogus_pixels_size]);
+ scoped_ptr<char[]> bogus_pixels(new char[bogus_pixels_size]);
memset(bogus_pixels.get(), 'B', bogus_pixels_size);
bad_msg.WriteData(bogus_pixels.get(), bogus_pixels_size);
// Make sure we don't read out the bitmap!
diff --git a/content/common/content_constants_internal.cc b/content/common/content_constants_internal.cc
index 3295a53..45316c3 100644
--- a/content/common/content_constants_internal.cc
+++ b/content/common/content_constants_internal.cc
@@ -6,10 +6,6 @@
namespace content {
-const char kFrameTreeNodeNameKey[] = "name";
-const char kFrameTreeNodeIdKey[] = "id";
-const char kFrameTreeNodeSubtreeKey[] = "subtree";
-
const int kHungRendererDelayMs = 30000;
} // namespace content
diff --git a/content/common/content_constants_internal.h b/content/common/content_constants_internal.h
index 7ee5b0d..b69bb4a 100644
--- a/content/common/content_constants_internal.h
+++ b/content/common/content_constants_internal.h
@@ -5,16 +5,12 @@
#ifndef CONTENT_COMMON_CONTENT_CONSTANTS_INTERNAL_H_
#define CONTENT_COMMON_CONTENT_CONSTANTS_INTERNAL_H_
+#include "content/common/content_export.h"
+
namespace content {
-// Keys used for serializing the frame tree of a renderer process, used for
-// ViewMsg_UpdateFrameTree and ViewHostMsg_FrameTreeUpdated.
-extern const char kFrameTreeNodeNameKey[];
-extern const char kFrameTreeNodeIdKey[];
-extern const char kFrameTreeNodeSubtreeKey[];
-
// How long to wait before we consider a renderer hung.
-extern const int kHungRendererDelayMs;
+CONTENT_EXPORT extern const int kHungRendererDelayMs;
} // namespace content
diff --git a/content/common/content_message_generator.h b/content/common/content_message_generator.h
index 9b0d4d4..e553480 100644
--- a/content/common/content_message_generator.h
+++ b/content/common/content_message_generator.h
@@ -26,14 +26,16 @@
#include "content/common/geolocation_messages.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/common/hyphenator_messages.h"
-#include "content/common/icon_messages.h"
+#include "content/common/image_messages.h"
#include "content/common/indexed_db/indexed_db_messages.h"
+#include "content/common/input_messages.h"
#include "content/common/java_bridge_messages.h"
#include "content/common/media/audio_messages.h"
#include "content/common/media/media_player_messages.h"
#include "content/common/media/media_stream_messages.h"
#include "content/common/media/peer_connection_tracker_messages.h"
#include "content/common/media/video_capture_messages.h"
+#include "content/common/media/webrtc_logging_messages.h"
#include "content/common/mime_registry_messages.h"
#include "content/common/p2p_messages.h"
#include "content/common/pepper_messages.h"
diff --git a/content/common/fileapi/OWNERS b/content/common/fileapi/OWNERS
index a59ea28..9e9046e 100644
--- a/content/common/fileapi/OWNERS
+++ b/content/common/fileapi/OWNERS
@@ -11,3 +11,4 @@
per-file *_messages.h=jschuh@chromium.org
per-file *_messages.h=palmer@chromium.org
per-file *_messages.h=tsepez@chromium.org
+per-file *_messages.h=kenrb@chromium.org
diff --git a/content/common/fileapi/file_system_dispatcher.cc b/content/common/fileapi/file_system_dispatcher.cc
index e80bc04..425b00c 100644
--- a/content/common/fileapi/file_system_dispatcher.cc
+++ b/content/common/fileapi/file_system_dispatcher.cc
@@ -247,9 +247,9 @@
return true;
}
-bool FileSystemDispatcher::NotifyCloseFile(const GURL& file_path) {
+bool FileSystemDispatcher::NotifyCloseFile(int file_open_id) {
return ChildThread::current()->Send(
- new FileSystemHostMsg_NotifyCloseFile(file_path));
+ new FileSystemHostMsg_NotifyCloseFile(file_open_id));
}
bool FileSystemDispatcher::CreateSnapshotFile(
@@ -265,20 +265,6 @@
return true;
}
-bool FileSystemDispatcher::CreateSnapshotFile_Deprecated(
- const GURL& blob_url,
- const GURL& file_path,
- fileapi::FileSystemCallbackDispatcher* dispatcher) {
- int request_id = dispatchers_.Add(dispatcher);
- if (!ChildThread::current()->Send(
- new FileSystemHostMsg_CreateSnapshotFile_Deprecated(
- request_id, blob_url, file_path))) {
- dispatchers_.Remove(request_id); // destroys |dispatcher|
- return false;
- }
- return true;
-}
-
void FileSystemDispatcher::OnDidOpenFileSystem(int request_id,
const std::string& name,
const GURL& root) {
@@ -351,11 +337,16 @@
}
void FileSystemDispatcher::OnDidOpenFile(
- int request_id, IPC::PlatformFileForTransit file) {
+ int request_id,
+ IPC::PlatformFileForTransit file,
+ int file_open_id,
+ quota::QuotaLimitType quota_policy) {
fileapi::FileSystemCallbackDispatcher* dispatcher =
dispatchers_.Lookup(request_id);
DCHECK(dispatcher);
- dispatcher->DidOpenFile(IPC::PlatformFileForTransitToPlatformFile(file));
+ dispatcher->DidOpenFile(IPC::PlatformFileForTransitToPlatformFile(file),
+ file_open_id,
+ quota_policy);
dispatchers_.Remove(request_id);
}
diff --git a/content/common/fileapi/file_system_dispatcher.h b/content/common/fileapi/file_system_dispatcher.h
index 9732b09..f38cd0d 100644
--- a/content/common/fileapi/file_system_dispatcher.h
+++ b/content/common/fileapi/file_system_dispatcher.h
@@ -16,6 +16,7 @@
#include "ipc/ipc_platform_file.h"
#include "webkit/fileapi/file_system_callback_dispatcher.h"
#include "webkit/fileapi/file_system_types.h"
+#include "webkit/quota/quota_types.h"
namespace base {
class FilePath;
@@ -89,16 +90,11 @@
fileapi::FileSystemCallbackDispatcher* dispatcher);
// This must be paired with OpenFile, and called after finished using the
// raw PlatformFile returned from OpenFile.
- bool NotifyCloseFile(const GURL& file_path);
+ bool NotifyCloseFile(int file_open_id);
bool CreateSnapshotFile(const GURL& file_path,
fileapi::FileSystemCallbackDispatcher* dispatcher);
- bool CreateSnapshotFile_Deprecated(
- const GURL& blod_url,
- const GURL& file_path,
- fileapi::FileSystemCallbackDispatcher* dispatcher);
-
private:
// Message handlers.
void OnDidOpenFileSystem(int request_id,
@@ -119,7 +115,9 @@
void OnDidWrite(int request_id, int64 bytes, bool complete);
void OnDidOpenFile(
int request_id,
- IPC::PlatformFileForTransit file);
+ IPC::PlatformFileForTransit file,
+ int file_open_id,
+ quota::QuotaLimitType quota_policy);
IDMap<fileapi::FileSystemCallbackDispatcher, IDMapOwnPointer> dispatchers_;
diff --git a/content/common/fileapi/file_system_messages.h b/content/common/fileapi/file_system_messages.h
index ef2f8bb..ee25545 100644
--- a/content/common/fileapi/file_system_messages.h
+++ b/content/common/fileapi/file_system_messages.h
@@ -10,6 +10,7 @@
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_platform_file.h"
#include "webkit/fileapi/file_system_types.h"
+#include "webkit/quota/quota_types.h"
#define IPC_MESSAGE_START FileSystemMsgStart
@@ -19,6 +20,7 @@
IPC_STRUCT_TRAITS_END()
IPC_ENUM_TRAITS(fileapi::FileSystemType)
+IPC_ENUM_TRAITS(quota::QuotaLimitType)
// File system messages sent from the browser to the child process.
@@ -47,9 +49,11 @@
int /* request_id */,
int64 /* byte count */,
bool /* complete */)
-IPC_MESSAGE_CONTROL2(FileSystemMsg_DidOpenFile,
+IPC_MESSAGE_CONTROL4(FileSystemMsg_DidOpenFile,
int /* request_id */,
- IPC::PlatformFileForTransit)
+ IPC::PlatformFileForTransit,
+ int /* file_open_id */,
+ quota::QuotaLimitType /* quota_policy */)
IPC_MESSAGE_CONTROL2(FileSystemMsg_DidFail,
int /* request_id */,
base::PlatformFileError /* error_code */)
@@ -145,13 +149,7 @@
// Pepper's NotifyCloseFile message.
IPC_MESSAGE_CONTROL1(FileSystemHostMsg_NotifyCloseFile,
- GURL /* file path */)
-
-// DEPRECATED
-IPC_MESSAGE_CONTROL3(FileSystemHostMsg_CreateSnapshotFile_Deprecated,
- int /* request_id */,
- GURL /* blob_url */,
- GURL /* file_path */)
+ int /* file_open_id */)
// WebFileSystem::createSnapshotFileAndReadMetadata() message.
IPC_MESSAGE_CONTROL2(FileSystemHostMsg_CreateSnapshotFile,
diff --git a/content/common/fileapi/webblobregistry_impl.cc b/content/common/fileapi/webblobregistry_impl.cc
index c657684..529d7ac 100644
--- a/content/common/fileapi/webblobregistry_impl.cc
+++ b/content/common/fileapi/webblobregistry_impl.cc
@@ -31,7 +31,8 @@
void WebBlobRegistryImpl::registerBlobURL(
const WebURL& url, WebBlobData& data) {
- DCHECK(ChildThread::current()->message_loop() == MessageLoop::current());
+ DCHECK(ChildThread::current()->message_loop() ==
+ base::MessageLoop::current());
const size_t kLargeThresholdBytes = 250 * 1024;
const size_t kMaxSharedMemoryBytes = 10 * 1024 * 1024;
@@ -111,12 +112,14 @@
void WebBlobRegistryImpl::registerBlobURL(
const WebURL& url, const WebURL& src_url) {
- DCHECK(ChildThread::current()->message_loop() == MessageLoop::current());
+ DCHECK(ChildThread::current()->message_loop() ==
+ base::MessageLoop::current());
sender_->Send(new BlobHostMsg_CloneBlob(url, src_url));
}
void WebBlobRegistryImpl::unregisterBlobURL(const WebURL& url) {
- DCHECK(ChildThread::current()->message_loop() == MessageLoop::current());
+ DCHECK(ChildThread::current()->message_loop() ==
+ base::MessageLoop::current());
sender_->Send(new BlobHostMsg_RemoveBlob(url));
}
diff --git a/content/common/fileapi/webfilesystem_impl.cc b/content/common/fileapi/webfilesystem_impl.cc
index e9b27ce..0fcd7a3 100644
--- a/content/common/fileapi/webfilesystem_impl.cc
+++ b/content/common/fileapi/webfilesystem_impl.cc
@@ -128,16 +128,4 @@
GURL(path), new WebFileSystemCallbackDispatcher(callbacks));
}
-// DEPRECATED
-void WebFileSystemImpl::createSnapshotFileAndReadMetadata(
- const WebKit::WebURL& blobURL,
- const WebKit::WebURL& path,
- WebKit::WebFileSystemCallbacks* callbacks) {
- FileSystemDispatcher* dispatcher =
- ChildThread::current()->file_system_dispatcher();
- dispatcher->CreateSnapshotFile_Deprecated(
- GURL(blobURL), GURL(path),
- new WebFileSystemCallbackDispatcher(callbacks));
-}
-
} // namespace content
diff --git a/content/common/fileapi/webfilesystem_impl.h b/content/common/fileapi/webfilesystem_impl.h
index a02ad21..fc742b4 100644
--- a/content/common/fileapi/webfilesystem_impl.h
+++ b/content/common/fileapi/webfilesystem_impl.h
@@ -62,12 +62,6 @@
virtual void createSnapshotFileAndReadMetadata(
const WebKit::WebURL& path,
WebKit::WebFileSystemCallbacks*);
-
- // DEPRECATED variant being replaced by the above.
- virtual void createSnapshotFileAndReadMetadata(
- const WebKit::WebURL& blobURL,
- const WebKit::WebURL& path,
- WebKit::WebFileSystemCallbacks*);
};
} // namespace content
diff --git a/content/common/font_list.cc b/content/common/font_list.cc
new file mode 100644
index 0000000..398ee80
--- /dev/null
+++ b/content/common/font_list.cc
@@ -0,0 +1,9 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/font_list.h"
+
+namespace content {
+const char kFontListSequenceToken[] = "_font_list_sequence_token_";
+}
diff --git a/content/common/font_list.h b/content/common/font_list.h
index 4f59e6d..dd14ce7 100644
--- a/content/common/font_list.h
+++ b/content/common/font_list.h
@@ -13,6 +13,11 @@
namespace content {
+// Getting the list of fonts on the system is non-threadsafe on Linux for
+// versions of Pango predating 2013. This sequence token can be used to enforce
+// serial execution of get font list tasks.
+extern const char kFontListSequenceToken[];
+
// Retrieves the fonts available on the current platform and returns them.
// The caller will own the returned pointer. Each entry will be a list of
// two strings, the first being the font family, and the second being the
@@ -21,6 +26,9 @@
// This function is potentially slow (the system may do a bunch of I/O) so be
// sure not to call this on a time-critical thread like the UI or I/O threads.
//
+// Since getting the fonts is not threadsafe on Linux, use
+// |kFontListSequenceToken| to prevent race conditions.
+//
// Most callers will want to use the GetFontListAsync function in
// content/browser/font_list_async.h which does an asynchronous call.
scoped_ptr<base::ListValue> GetFontList_SlowBlocking();
diff --git a/content/common/font_list_mac.mm b/content/common/font_list_mac.mm
index c5405e2..4ffb3de 100644
--- a/content/common/font_list_mac.mm
+++ b/content/common/font_list_mac.mm
@@ -7,7 +7,7 @@
#import <Cocoa/Cocoa.h>
#include "base/mac/scoped_nsautorelease_pool.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/values.h"
namespace content {
diff --git a/content/common/gpu/OWNERS b/content/common/gpu/OWNERS
index fd5d45c..7a88280 100644
--- a/content/common/gpu/OWNERS
+++ b/content/common/gpu/OWNERS
@@ -12,3 +12,4 @@
per-file *_messages.h=jschuh@chromium.org
per-file *_messages.h=palmer@chromium.org
per-file *_messages.h=tsepez@chromium.org
+per-file *_messages.h=kenrb@chromium.org
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.cc b/content/common/gpu/client/command_buffer_proxy_impl.cc
index 61f8922..156626a 100644
--- a/content/common/gpu/client/command_buffer_proxy_impl.cc
+++ b/content/common/gpu/client/command_buffer_proxy_impl.cc
@@ -13,6 +13,7 @@
#include "content/common/child_process_messages.h"
#include "content/common/gpu/gpu_memory_allocation.h"
#include "content/common/gpu/client/gpu_channel_host.h"
+#include "content/common/gpu/client/gpu_video_decode_accelerator_host.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/common/plugin_messages.h"
#include "content/common/view_messages.h"
@@ -33,6 +34,10 @@
}
CommandBufferProxyImpl::~CommandBufferProxyImpl() {
+ FOR_EACH_OBSERVER(DeletionObserver,
+ deletion_observers_,
+ OnWillDeleteImpl());
+
// Delete all the locally cached shared memory objects, closing the handle
// in this process.
for (TransferBufferMap::iterator it = transfer_buffers_.begin();
@@ -41,11 +46,6 @@
delete it->second.shared_memory;
it->second.shared_memory = NULL;
}
- for (Decoders::iterator it = video_decoder_hosts_.begin();
- it != video_decoder_hosts_.end(); ++it) {
- if (it->second)
- it->second->OnChannelError();
- }
}
bool CommandBufferProxyImpl::OnMessageReceived(const IPC::Message& message) {
@@ -110,6 +110,15 @@
route_id_, !memory_allocation_changed_callback_.is_null()));
}
+void CommandBufferProxyImpl::AddDeletionObserver(DeletionObserver* observer) {
+ deletion_observers_.AddObserver(observer);
+}
+
+void CommandBufferProxyImpl::RemoveDeletionObserver(
+ DeletionObserver* observer) {
+ deletion_observers_.RemoveObserver(observer);
+}
+
void CommandBufferProxyImpl::OnSetMemoryAllocation(
const GpuMemoryAllocationForRenderer& allocation) {
if (!memory_allocation_changed_callback_.is_null())
@@ -132,7 +141,7 @@
bool CommandBufferProxyImpl::Initialize() {
shared_state_shm_.reset(channel_->factory()->AllocateSharedMemory(
sizeof(*shared_state())).release());
- if (!shared_state_shm_.get())
+ if (!shared_state_shm_)
return false;
if (!shared_state_shm_->Map(sizeof(*shared_state())))
@@ -144,7 +153,7 @@
// will leak. In otherwords, do not early out on error between here and the
// sending of the Initialize IPC below.
base::SharedMemoryHandle handle =
- channel_->ShareToGpuProcess(shared_state_shm_.get());
+ channel_->ShareToGpuProcess(shared_state_shm_->handle());
if (!base::SharedMemory::IsHandleValid(handle))
return false;
@@ -202,6 +211,13 @@
++flush_count_));
}
+void CommandBufferProxyImpl::SetLatencyInfo(
+ const cc::LatencyInfo& latency_info) {
+ if (last_state_.error != gpu::error::kNoError)
+ return;
+ Send(new GpuCommandBufferMsg_SetLatencyInfo(route_id_, latency_info));
+}
+
gpu::CommandBuffer::State CommandBufferProxyImpl::FlushSync(
int32 put_offset,
int32 last_known_get) {
@@ -248,7 +264,7 @@
scoped_ptr<base::SharedMemory> shared_memory(
channel_->factory()->AllocateSharedMemory(size));
- if (!shared_memory.get())
+ if (!shared_memory)
return gpu::Buffer();
DCHECK(!shared_memory->memory());
@@ -259,7 +275,7 @@
// will leak. In otherwords, do not early out on error between here and the
// sending of the RegisterTransferBuffer IPC below.
base::SharedMemoryHandle handle =
- channel_->ShareToGpuProcess(shared_memory.get());
+ channel_->ShareToGpuProcess(shared_memory->handle());
if (!base::SharedMemory::IsHandleValid(handle))
return gpu::Buffer();
@@ -420,6 +436,9 @@
bool CommandBufferProxyImpl::GenerateMailboxNames(
unsigned num,
std::vector<gpu::Mailbox>* names) {
+ if (last_state_.error != gpu::error::kNoError)
+ return false;
+
return channel_->GenerateMailboxNames(num, names);
}
@@ -451,31 +470,28 @@
return result;
}
-GpuVideoDecodeAcceleratorHost*
+scoped_ptr<media::VideoDecodeAccelerator>
CommandBufferProxyImpl::CreateVideoDecoder(
media::VideoCodecProfile profile,
media::VideoDecodeAccelerator::Client* client) {
int decoder_route_id;
+ scoped_ptr<media::VideoDecodeAccelerator> vda;
if (!Send(new GpuCommandBufferMsg_CreateVideoDecoder(route_id_, profile,
&decoder_route_id))) {
LOG(ERROR) << "Send(GpuCommandBufferMsg_CreateVideoDecoder) failed";
- return NULL;
+ return vda.Pass();
}
if (decoder_route_id < 0) {
DLOG(ERROR) << "Failed to Initialize GPU decoder on profile: " << profile;
- return NULL;
+ return vda.Pass();
}
GpuVideoDecodeAcceleratorHost* decoder_host =
- new GpuVideoDecodeAcceleratorHost(channel_, decoder_route_id, client);
- bool inserted = video_decoder_hosts_.insert(std::make_pair(
- decoder_route_id, base::AsWeakPtr(decoder_host))).second;
- DCHECK(inserted);
-
- channel_->AddRoute(decoder_route_id, base::AsWeakPtr(decoder_host));
-
- return decoder_host;
+ new GpuVideoDecodeAcceleratorHost(channel_, decoder_route_id, client,
+ this);
+ vda.reset(decoder_host);
+ return vda.Pass();
}
gpu::error::Error CommandBufferProxyImpl::GetLastError() {
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.h b/content/common/gpu/client/command_buffer_proxy_impl.h
index 95f3c60..1f37af5 100644
--- a/content/common/gpu/client/command_buffer_proxy_impl.h
+++ b/content/common/gpu/client/command_buffer_proxy_impl.h
@@ -16,12 +16,14 @@
#include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "cc/debug/latency_info.h"
#include "content/common/gpu/gpu_memory_allocation.h"
-#include "content/common/gpu/client/gpu_video_decode_accelerator_host.h"
#include "content/common/gpu/gpu_memory_allocation.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/command_buffer/common/command_buffer_shared.h"
#include "ipc/ipc_listener.h"
+#include "media/video/video_decode_accelerator.h"
struct GPUCommandBufferConsoleMessage;
@@ -43,6 +45,15 @@
public IPC::Listener,
public base::SupportsWeakPtr<CommandBufferProxyImpl> {
public:
+ class DeletionObserver {
+ public:
+ // Called during the destruction of the CommandBufferProxyImpl.
+ virtual void OnWillDeleteImpl() = 0;
+
+ protected:
+ virtual ~DeletionObserver() {}
+ };
+
typedef base::Callback<void(
const std::string& msg, int id)> GpuConsoleMessageCallback;
@@ -50,12 +61,12 @@
virtual ~CommandBufferProxyImpl();
// Sends an IPC message to create a GpuVideoDecodeAccelerator. Creates and
- // returns a pointer to a GpuVideoDecodeAcceleratorHost.
- // Returns NULL on failure to create the GpuVideoDecodeAcceleratorHost.
+ // returns it as an owned pointer to a media::VideoDecodeAccelerator. Returns
+ // NULL on failure to create the GpuVideoDecodeAcceleratorHost.
// Note that the GpuVideoDecodeAccelerator may still fail to be created in
// the GPU process, even if this returns non-NULL. In this case the client is
// notified of an error later.
- GpuVideoDecodeAcceleratorHost* CreateVideoDecoder(
+ scoped_ptr<media::VideoDecodeAccelerator> CreateVideoDecoder(
media::VideoCodecProfile profile,
media::VideoDecodeAccelerator::Client* client);
@@ -93,6 +104,9 @@
const base::Callback<void(const GpuMemoryAllocationForRenderer&)>&
callback);
+ void AddDeletionObserver(DeletionObserver* observer);
+ void RemoveDeletionObserver(DeletionObserver* observer);
+
bool DiscardBackbuffer();
bool EnsureBackbuffer();
@@ -113,6 +127,8 @@
void SetOnConsoleMessageCallback(
const GpuConsoleMessageCallback& callback);
+ void SetLatencyInfo(const cc::LatencyInfo& latency_info);
+
// TODO(apatrick): this is a temporary optimization while skia is calling
// ContentGLContext::MakeCurrent prior to every GL call. It saves returning 6
// ints redundantly when only the error is needed for the
@@ -125,7 +141,6 @@
private:
typedef std::map<int32, gpu::Buffer> TransferBufferMap;
- typedef std::map<int, base::WeakPtr<GpuVideoDecodeAcceleratorHost> > Decoders;
typedef base::hash_map<uint32, base::Closure> SignalTaskMap;
// Send an IPC message over the GPU channel. This is private to fully
@@ -154,9 +169,8 @@
// Local cache of id to transfer buffer mapping.
TransferBufferMap transfer_buffers_;
- // Zero or more (unowned!) video decoder hosts using this proxy, keyed by
- // their decoder_route_id.
- Decoders video_decoder_hosts_;
+ // Unowned list of DeletionObservers.
+ ObserverList<DeletionObserver> deletion_observers_;
// The last cached state received from the service.
State last_state_;
diff --git a/content/common/gpu/client/gl_helper.cc b/content/common/gpu/client/gl_helper.cc
index 0d295f0..09dcd1c 100644
--- a/content/common/gpu/client/gl_helper.cc
+++ b/content/common/gpu/client/gl_helper.cc
@@ -7,14 +7,11 @@
#include <queue>
#include "base/bind.h"
+#include "base/debug/trace_event.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
-#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
-#include "base/synchronization/lock.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_restrictions.h"
+#include "base/time.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
#include "third_party/skia/include/core/SkRegion.h"
@@ -27,24 +24,6 @@
namespace {
-const char kGLHelperThreadName[] = "GLHelperThread";
-
-class GLHelperThread : public base::Thread {
- public:
- GLHelperThread() : base::Thread(kGLHelperThreadName) {
- Start();
- }
- virtual ~GLHelperThread() {
- Stop();
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(GLHelperThread);
-};
-
-base::LazyInstance<GLHelperThread> g_gl_helper_thread =
- LAZY_INSTANCE_INITIALIZER;
-
class ScopedWebGLId {
public:
typedef void (WebGraphicsContext3D::*DeleteFunc)(WebGLId);
@@ -99,15 +78,6 @@
&WebGraphicsContext3D::deleteFramebuffer) {}
};
-class ScopedRenderbuffer : public ScopedWebGLId {
- public:
- ScopedRenderbuffer(WebGraphicsContext3D* context,
- WebGLId id)
- : ScopedWebGLId(context,
- id,
- &WebGraphicsContext3D::deleteRenderbuffer) {}
-};
-
class ScopedProgram : public ScopedWebGLId {
public:
ScopedProgram(WebGraphicsContext3D* context,
@@ -144,19 +114,16 @@
WebGLId id,
BindFunc bind_func)
: context_(context),
- id_(id),
bind_func_(bind_func) {
- (context_->*bind_func_)(target, id_);
+ (context_->*bind_func_)(target, id);
}
virtual ~ScopedBinder() {
- if (id_ != 0)
- (context_->*bind_func_)(target, 0);
+ (context_->*bind_func_)(target, 0);
}
private:
WebGraphicsContext3D* context_;
- WebGLId id_;
BindFunc bind_func_;
DISALLOW_COPY_AND_ASSIGN(ScopedBinder);
@@ -185,17 +152,6 @@
};
template <WebKit::WGC3Denum target>
-class ScopedRenderbufferBinder : ScopedBinder<target> {
- public:
- ScopedRenderbufferBinder(WebGraphicsContext3D* context,
- WebGLId id)
- : ScopedBinder<target>(
- context,
- id,
- &WebGraphicsContext3D::bindRenderbuffer) {}
-};
-
-template <WebKit::WGC3Denum target>
class ScopedTextureBinder : ScopedBinder<target> {
public:
ScopedTextureBinder(WebGraphicsContext3D* context,
@@ -222,27 +178,18 @@
DISALLOW_COPY_AND_ASSIGN(ScopedFlush);
};
-void DeleteContext(WebGraphicsContext3D* context) {
- delete context;
-}
-
-void SignalWaitableEvent(base::WaitableEvent* event) {
- event->Signal();
-}
-
} // namespace
namespace content {
// Implements GLHelper::CropScaleReadbackAndCleanTexture and encapsulates the
// data needed for it.
-class GLHelper::CopyTextureToImpl {
+class GLHelper::CopyTextureToImpl :
+ public base::SupportsWeakPtr<GLHelper::CopyTextureToImpl> {
public:
- CopyTextureToImpl(WebGraphicsContext3D* context,
- WebGraphicsContext3D* context_for_thread,
+ CopyTextureToImpl(WebGraphicsContext3DCommandBufferImpl* context,
GLHelper* helper)
: context_(context),
- context_for_thread_(context_for_thread),
helper_(helper),
flush_(context),
program_(context, context->createProgram()),
@@ -253,7 +200,6 @@
}
~CopyTextureToImpl() {
CancelRequests();
- DeleteContextForThread();
}
void InitBuffer();
@@ -278,40 +224,66 @@
private:
// A single request to CropScaleReadbackAndCleanTexture.
- // Thread-safety notes: the main thread creates instances of this class. The
- // main thread can cancel the request, before it's handled by the helper
+ // The main thread can cancel the request, before it's handled by the helper
// thread, by resetting the texture and pixels fields. Alternatively, the
// thread marks that it handles the request by resetting the pixels field
// (meaning it guarantees that the callback with be called).
// In either case, the callback must be called exactly once, and the texture
// must be deleted by the main thread context.
- struct Request : public base::RefCountedThreadSafe<Request> {
- Request(CopyTextureToImpl* impl,
- WebGLId texture_,
+ struct Request {
+ Request(WebGLId texture_,
const gfx::Size& size_,
unsigned char* pixels_,
const base::Callback<void(bool)>& callback_)
- : copy_texture_impl(impl),
- size(size_),
- callback(callback_),
- lock(),
- texture(texture_),
- pixels(pixels_) {
+ : size(size_),
+ callback(callback_),
+ texture(texture_),
+ pixels(pixels_),
+ buffer(0) {
}
- // These members are only accessed on the main thread.
- GLHelper::CopyTextureToImpl* copy_texture_impl;
gfx::Size size;
base::Callback<void(bool)> callback;
- // Locks access to below members, which can be accessed on any thread.
- base::Lock lock;
WebGLId texture;
unsigned char* pixels;
+ GLuint buffer;
+ };
+
+ class ShaderProgram {
+ public:
+ ShaderProgram(WebGraphicsContext3D* context,
+ GLHelper* helper) :
+ context_(context),
+ helper_(helper),
+ program_(context, context->createProgram()) {
+ }
+
+ void Setup(const WebKit::WGC3Dchar* vertex_shader_text,
+ const WebKit::WGC3Dchar* fragment_shader_text);
+ void UseProgram(const gfx::Size& src_size,
+ const gfx::Rect& src_subrect,
+ const gfx::Size& dst_size);
private:
- friend class base::RefCountedThreadSafe<Request>;
- ~Request() {}
+ WebGraphicsContext3D* context_;
+ GLHelper* helper_;
+
+ // A program for copying a source texture into a destination texture.
+ ScopedProgram program_;
+
+ // The location of the position in the program.
+ WebKit::WGC3Dint position_location_;
+ // The location of the texture coordinate in the program.
+ WebKit::WGC3Dint texcoord_location_;
+ // The location of the source texture in the program.
+ WebKit::WGC3Dint texture_location_;
+ // The location of the texture coordinate of
+ // the sub-rectangle in the program.
+ WebKit::WGC3Dint src_subrect_location_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ShaderProgram);
};
// Copies the block of pixels specified with |src_subrect| from |src_texture|,
@@ -321,16 +293,11 @@
const gfx::Size& src_size,
const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
- bool vertically_flip_texture);
+ bool vertically_flip_texture,
+ bool swizzle);
- // Deletes the context for GLHelperThread.
- void DeleteContextForThread();
- static void ReadBackFramebuffer(scoped_refptr<Request> request,
- WebGraphicsContext3D* context,
- scoped_refptr<base::TaskRunner> reply_loop);
- static void ReadBackFramebufferComplete(scoped_refptr<Request> request,
- bool result);
- void FinishRequest(scoped_refptr<Request> request);
+ void ReadbackDone(Request* request);
+ void FinishRequest(Request* request, bool result);
void CancelRequests();
// Interleaved array of 2-dimentional vertex positions (x, y) and
@@ -343,9 +310,9 @@
// GLHelper::ReadbackTextureSync
static const WebKit::WGC3Dchar kCopyVertexShader[];
static const WebKit::WGC3Dchar kCopyFragmentShader[];
+ static const WebKit::WGC3Dchar kCopyAndSwizzleShader[];
- WebGraphicsContext3D* context_;
- WebGraphicsContext3D* context_for_thread_;
+ WebGraphicsContext3DCommandBufferImpl* context_;
GLHelper* helper_;
// A scoped flush that will ensure all resource deletions are flushed when
@@ -358,15 +325,10 @@
ScopedBuffer vertex_attributes_buffer_;
ScopedBuffer flipped_vertex_attributes_buffer_;
- // The location of the position in the program.
- WebKit::WGC3Dint position_location_;
- // The location of the texture coordinate in the program.
- WebKit::WGC3Dint texcoord_location_;
- // The location of the source texture in the program.
- WebKit::WGC3Dint texture_location_;
- // The location of the texture coordinate of the sub-rectangle in the program.
- WebKit::WGC3Dint src_subrect_location_;
- std::queue<scoped_refptr<Request> > request_queue_;
+ scoped_ptr<ShaderProgram> no_swizzle_program_;
+ scoped_ptr<ShaderProgram> swizzle_program_;
+
+ std::queue<Request*> request_queue_;
};
const WebKit::WGC3Dfloat GLHelper::CopyTextureToImpl::kVertexAttributes[] = {
@@ -394,6 +356,7 @@
" v_texcoord = src_subrect.xy + a_texcoord * src_subrect.zw;"
"}";
+
const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyFragmentShader[] =
"precision mediump float;"
"varying vec2 v_texcoord;"
@@ -402,6 +365,15 @@
" gl_FragColor = texture2D(s_texture, v_texcoord);"
"}";
+const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyAndSwizzleShader[] =
+ "precision mediump float;"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D s_texture;"
+ "void main() {"
+ " gl_FragColor = texture2D(s_texture, v_texcoord).bgra;"
+ "}";
+
+
void GLHelper::CopyTextureToImpl::InitBuffer() {
ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(
context_, vertex_attributes_buffer_);
@@ -418,14 +390,23 @@
}
void GLHelper::CopyTextureToImpl::InitProgram() {
+ no_swizzle_program_.reset(new ShaderProgram(context_, helper_));
+ no_swizzle_program_->Setup(kCopyVertexShader, kCopyFragmentShader);
+ swizzle_program_.reset(new ShaderProgram(context_, helper_));
+ swizzle_program_->Setup(kCopyVertexShader, kCopyAndSwizzleShader);
+}
+
+void GLHelper::CopyTextureToImpl::ShaderProgram::Setup(
+ const WebKit::WGC3Dchar* vertex_shader_text,
+ const WebKit::WGC3Dchar* fragment_shader_text) {
// Shaders to map the source texture to |dst_texture_|.
ScopedShader vertex_shader(context_, helper_->CompileShaderFromSource(
- kCopyVertexShader, GL_VERTEX_SHADER));
- DCHECK_NE(0U, vertex_shader.id());
+ vertex_shader_text, GL_VERTEX_SHADER));
+ DCHECK(vertex_shader.id());
context_->attachShader(program_, vertex_shader);
ScopedShader fragment_shader(context_, helper_->CompileShaderFromSource(
- kCopyFragmentShader, GL_FRAGMENT_SHADER));
- DCHECK_NE(0U, fragment_shader.id());
+ fragment_shader_text, GL_FRAGMENT_SHADER));
+ DCHECK(fragment_shader.id());
context_->attachShader(program_, fragment_shader);
context_->linkProgram(program_);
@@ -442,20 +423,57 @@
src_subrect_location_ = context_->getUniformLocation(program_, "src_subrect");
}
+
+void GLHelper::CopyTextureToImpl::ShaderProgram::UseProgram(
+ const gfx::Size& src_size,
+ const gfx::Rect& src_subrect,
+ const gfx::Size& dst_size) {
+ context_->useProgram(program_);
+
+ WebKit::WGC3Dintptr offset = 0;
+ context_->vertexAttribPointer(position_location_,
+ 2,
+ GL_FLOAT,
+ GL_FALSE,
+ 4 * sizeof(WebKit::WGC3Dfloat),
+ offset);
+ context_->enableVertexAttribArray(position_location_);
+
+ offset += 2 * sizeof(WebKit::WGC3Dfloat);
+ context_->vertexAttribPointer(texcoord_location_,
+ 2,
+ GL_FLOAT,
+ GL_FALSE,
+ 4 * sizeof(WebKit::WGC3Dfloat),
+ offset);
+ context_->enableVertexAttribArray(texcoord_location_);
+
+ context_->uniform1i(texture_location_, 0);
+
+ // Convert |src_subrect| to texture coordinates.
+ GLfloat src_subrect_texcoord[] = {
+ static_cast<float>(src_subrect.x()) / src_size.width(),
+ static_cast<float>(src_subrect.y()) / src_size.height(),
+ static_cast<float>(src_subrect.width()) / src_size.width(),
+ static_cast<float>(src_subrect.height()) / src_size.height(),
+ };
+ context_->uniform4fv(src_subrect_location_, 1, src_subrect_texcoord);
+}
+
WebGLId GLHelper::CopyTextureToImpl::ScaleTexture(
WebGLId src_texture,
const gfx::Size& src_size,
const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
- bool vertically_flip_texture) {
+ bool vertically_flip_texture,
+ bool swizzle) {
WebGLId dst_texture = context_->createTexture();
{
ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer());
- ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(
- context_, dst_framebuffer);
+ ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(context_,
+ dst_framebuffer);
{
- ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(
- context_, dst_texture);
+ ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, dst_texture);
context_->texImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
@@ -475,41 +493,17 @@
ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, src_texture);
WebKit::WebGLId vertex_attributes_buffer = vertically_flip_texture ?
flipped_vertex_attributes_buffer_ : vertex_attributes_buffer_;
- ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(
- context_, vertex_attributes_buffer);
+ ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(context_,
+ vertex_attributes_buffer);
context_->viewport(0, 0, dst_size.width(), dst_size.height());
- context_->useProgram(program_);
-
- WebKit::WGC3Dintptr offset = 0;
- context_->vertexAttribPointer(position_location_,
- 2,
- GL_FLOAT,
- GL_FALSE,
- 4 * sizeof(WebKit::WGC3Dfloat),
- offset);
- context_->enableVertexAttribArray(position_location_);
-
- offset += 2 * sizeof(WebKit::WGC3Dfloat);
- context_->vertexAttribPointer(texcoord_location_,
- 2,
- GL_FLOAT,
- GL_FALSE,
- 4 * sizeof(WebKit::WGC3Dfloat),
- offset);
- context_->enableVertexAttribArray(texcoord_location_);
-
- context_->uniform1i(texture_location_, 0);
-
- // Convert |src_subrect| to texture coordinates.
- GLfloat src_subrect_texcoord[] = {
- static_cast<float>(src_subrect.x()) / src_size.width(),
- static_cast<float>(src_subrect.y()) / src_size.height(),
- static_cast<float>(src_subrect.width()) / src_size.width(),
- static_cast<float>(src_subrect.height()) / src_size.height(),
- };
-
- context_->uniform4fv(src_subrect_location_, 1, src_subrect_texcoord);
+ ShaderProgram* program;
+ if (swizzle) {
+ program = swizzle_program_.get();
+ } else {
+ program = no_swizzle_program_.get();
+ }
+ program->UseProgram(src_size, src_subrect, dst_size);
// Conduct texture mapping by drawing a quad composed of two triangles.
context_->drawArrays(GL_TRIANGLE_STRIP, 0, 4);
@@ -517,17 +511,6 @@
return dst_texture;
}
-void GLHelper::CopyTextureToImpl::DeleteContextForThread() {
- if (!context_for_thread_)
- return;
-
- g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(
- FROM_HERE,
- base::Bind(&DeleteContext,
- context_for_thread_));
- context_for_thread_ = NULL;
-}
-
void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture(
WebGLId src_texture,
const gfx::Size& src_size,
@@ -535,34 +518,56 @@
const gfx::Size& dst_size,
unsigned char* out,
const base::Callback<void(bool)>& callback) {
- if (!context_for_thread_) {
- callback.Run(false);
- return;
- }
-
WebGLId texture = ScaleTexture(src_texture,
src_size,
src_subrect,
dst_size,
- false);
+ true,
+#if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT
+ true
+#else
+ false
+#endif
+ );
context_->flush();
- scoped_refptr<Request> request =
- new Request(this, texture, dst_size, out, callback);
+ Request* request = new Request(texture, dst_size, out, callback);
request_queue_.push(request);
- g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(FROM_HERE,
- base::Bind(&ReadBackFramebuffer,
- request,
- context_for_thread_,
- base::MessageLoopProxy::current()));
+ ScopedFlush flush(context_);
+ ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer());
+ gfx::Size size;
+ size = request->size;
+
+ ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(context_,
+ dst_framebuffer);
+ ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, request->texture);
+ context_->framebufferTexture2D(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D,
+ request->texture,
+ 0);
+ request->buffer = context_->createBuffer();
+ context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
+ request->buffer);
+ context_->bufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
+ 4 * size.GetArea(),
+ NULL,
+ GL_STREAM_READ);
+
+ context_->readPixels(0, 0, size.width(), size.height(),
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
+ context_->GetCommandBufferProxy()->SignalSyncPoint(
+ context_->insertSyncPoint(),
+ base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(), request));
}
void GLHelper::CopyTextureToImpl::ReadbackTextureSync(WebGLId texture,
const gfx::Rect& src_rect,
unsigned char* out) {
ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer());
- ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(
- context_, dst_framebuffer);
+ ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(context_,
+ dst_framebuffer);
ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture);
context_->framebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
@@ -587,139 +592,64 @@
src_size,
gfx::Rect(src_size),
dst_size,
- vertically_flip_texture);
+ vertically_flip_texture,
+ false);
}
-void GLHelper::CopyTextureToImpl::ReadBackFramebuffer(
- scoped_refptr<Request> request,
- WebGraphicsContext3D* context,
- scoped_refptr<base::TaskRunner> reply_loop) {
- DCHECK(context);
- if (!context->makeContextCurrent() || context->isContextLost()) {
- base::AutoLock auto_lock(request->lock);
- if (request->pixels) {
- // Only report failure if the request wasn't canceled (otherwise the
- // failure has already been reported).
- request->pixels = NULL;
- reply_loop->PostTask(
- FROM_HERE, base::Bind(ReadBackFramebufferComplete, request, false));
+void GLHelper::CopyTextureToImpl::ReadbackDone(Request* request) {
+ TRACE_EVENT0("mirror",
+ "GLHelper::CopyTextureToImpl::CheckReadBackFramebufferComplete");
+ DCHECK(request == request_queue_.front());
+
+ bool result = false;
+ if (request->buffer != 0) {
+ context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
+ request->buffer);
+ void* data = context_->mapBufferCHROMIUM(
+ GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY);
+
+ if (data) {
+ result = true;
+ memcpy(request->pixels, data, request->size.GetArea() * 4);
+ context_->unmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM);
}
- return;
+ context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
}
- ScopedFlush flush(context);
- ScopedFramebuffer dst_framebuffer(context, context->createFramebuffer());
- unsigned char* pixels = NULL;
- gfx::Size size;
- {
- // Note: We don't want to keep the lock while doing the readBack (since we
- // don't want to block the UI thread). We rely on the fact that once the
- // texture is bound to a FBO (that isn't current), deleting the texture is
- // delayed until the FBO is deleted. We ensure ordering by flushing while
- // the lock is held. Either the main thread cancelled before we get the
- // lock, and we'll exit early, or we ensure that the texture is bound to the
- // framebuffer before the main thread has a chance to delete it.
- base::AutoLock auto_lock(request->lock);
- if (!request->texture || !request->pixels)
- return;
- pixels = request->pixels;
- request->pixels = NULL;
- size = request->size;
- {
- ScopedFlush flush(context);
- ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(
- context, dst_framebuffer);
- ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(
- context, request->texture);
- context->framebufferTexture2D(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D,
- request->texture,
- 0);
- }
- }
- bool result = context->readBackFramebuffer(
- pixels,
- 4 * size.GetArea(),
- dst_framebuffer.id(),
- size.width(),
- size.height());
- reply_loop->PostTask(
- FROM_HERE, base::Bind(ReadBackFramebufferComplete, request, result));
+
+ FinishRequest(request, result);
}
-void GLHelper::CopyTextureToImpl::ReadBackFramebufferComplete(
- scoped_refptr<Request> request,
- bool result) {
- request->callback.Run(result);
- if (request->copy_texture_impl)
- request->copy_texture_impl->FinishRequest(request);
-}
-
-void GLHelper::CopyTextureToImpl::FinishRequest(
- scoped_refptr<Request> request) {
- CHECK(request_queue_.front() == request);
+void GLHelper::CopyTextureToImpl::FinishRequest(Request* request, bool result) {
+ DCHECK(request_queue_.front() == request);
request_queue_.pop();
- base::AutoLock auto_lock(request->lock);
+ request->callback.Run(result);
+ ScopedFlush flush(context_);
if (request->texture != 0) {
context_->deleteTexture(request->texture);
request->texture = 0;
- context_->flush();
}
+ if (request->buffer != 0) {
+ context_->deleteBuffer(request->buffer);
+ request->buffer = 0;
+ }
+ delete request;
}
void GLHelper::CopyTextureToImpl::CancelRequests() {
while (!request_queue_.empty()) {
- scoped_refptr<Request> request = request_queue_.front();
- request_queue_.pop();
- request->copy_texture_impl = NULL;
- bool cancelled = false;
- {
- base::AutoLock auto_lock(request->lock);
- if (request->texture != 0) {
- context_->deleteTexture(request->texture);
- request->texture = 0;
- }
- if (request->pixels != NULL) {
- request->pixels = NULL;
- cancelled = true;
- }
- }
- if (cancelled)
- request->callback.Run(false);
+ Request* request = request_queue_.front();
+ FinishRequest(request, false);
}
}
-base::subtle::Atomic32 GLHelper::count_ = 0;
-
-GLHelper::GLHelper(WebGraphicsContext3D* context,
- WebGraphicsContext3D* context_for_thread)
- : context_(context),
- context_for_thread_(context_for_thread) {
- base::subtle::NoBarrier_AtomicIncrement(&count_, 1);
+GLHelper::GLHelper(WebGraphicsContext3DCommandBufferImpl* context)
+ : context_(context) {
}
GLHelper::~GLHelper() {
- DCHECK_NE(MessageLoop::current(),
- g_gl_helper_thread.Pointer()->message_loop());
- base::subtle::Atomic32 decremented_count =
- base::subtle::NoBarrier_AtomicIncrement(&count_, -1);
- if (decremented_count == 0) {
- // When this is the last instance, we synchronize with the pending
- // operations on GLHelperThread. Otherwise on shutdown we may kill the GPU
- // process infrastructure (BrowserGpuChannelHostFactory) before they have
- // a chance to complete, likely leading to a crash.
- base::WaitableEvent event(false, false);
- g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(
- FROM_HERE,
- base::Bind(&SignalWaitableEvent,
- &event));
- // http://crbug.com/125415
- base::ThreadRestrictions::ScopedAllowWait allow_wait;
- event.Wait();
- }
}
-WebGraphicsContext3D* GLHelper::context() const {
+WebGraphicsContext3DCommandBufferImpl* GLHelper::context() const {
return context_;
}
@@ -785,10 +715,8 @@
void GLHelper::InitCopyTextToImpl() {
// Lazily initialize |copy_texture_to_impl_|
- if (!copy_texture_to_impl_.get())
- copy_texture_to_impl_.reset(new CopyTextureToImpl(context_,
- context_for_thread_,
- this));
+ if (!copy_texture_to_impl_)
+ copy_texture_to_impl_.reset(new CopyTextureToImpl(context_, this));
}
void GLHelper::CopySubBufferDamage(WebKit::WebGLId texture,
@@ -798,8 +726,8 @@
SkRegion region(old_damage);
if (region.op(new_damage, SkRegion::kDifference_Op)) {
ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer());
- ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(
- context_, dst_framebuffer);
+ ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(context_,
+ dst_framebuffer);
ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture);
context_->framebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
diff --git a/content/common/gpu/client/gl_helper.h b/content/common/gpu/client/gl_helper.h
index 40e25eb..2908f6e 100644
--- a/content/common/gpu/client/gl_helper.h
+++ b/content/common/gpu/client/gl_helper.h
@@ -9,7 +9,7 @@
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
-#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
+#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
namespace gfx {
class Rect;
@@ -24,11 +24,10 @@
// interfaces.
class GLHelper {
public:
- GLHelper(WebKit::WebGraphicsContext3D* context,
- WebKit::WebGraphicsContext3D* context_for_thread);
+ explicit GLHelper(WebGraphicsContext3DCommandBufferImpl* context);
virtual ~GLHelper();
- WebKit::WebGraphicsContext3D* context() const;
+ WebGraphicsContext3DCommandBufferImpl* context() const;
// Copies the block of pixels specified with |src_subrect| from |src_texture|,
// scales it to |dst_size|, and writes it into |out|.
@@ -81,13 +80,9 @@
// Creates |copy_texture_to_impl_| if NULL.
void InitCopyTextToImpl();
- WebKit::WebGraphicsContext3D* context_;
- WebKit::WebGraphicsContext3D* context_for_thread_;
+ WebGraphicsContext3DCommandBufferImpl* context_;
scoped_ptr<CopyTextureToImpl> copy_texture_to_impl_;
- // The number of all GLHelper instances.
- static base::subtle::Atomic32 count_;
-
DISALLOW_COPY_AND_ASSIGN(GLHelper);
};
diff --git a/content/common/gpu/client/gpu_channel_host.cc b/content/common/gpu/client/gpu_channel_host.cc
index d5bb6b3..91ff7a6 100644
--- a/content/common/gpu/client/gpu_channel_host.cc
+++ b/content/common/gpu/client/gpu_channel_host.cc
@@ -8,6 +8,7 @@
#include "base/debug/trace_event.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
+#include "base/posix/eintr_wrapper.h"
#include "base/threading/thread_restrictions.h"
#include "content/common/gpu/client/command_buffer_proxy_impl.h"
#include "content/common/gpu/gpu_messages.h"
@@ -111,12 +112,12 @@
// TODO: Can we just always use sync_filter_ since we setup the channel
// without a main listener?
if (factory_->IsMainThread()) {
- if (channel_.get()) {
+ if (channel_) {
// http://crbug.com/125264
base::ThreadRestrictions::ScopedAllowWait allow_wait;
return channel_->Send(message);
}
- } else if (MessageLoop::current()) {
+ } else if (base::MessageLoop::current()) {
return sync_filter_->Send(message);
}
@@ -140,7 +141,7 @@
AutoLock lock(context_lock_);
// An error occurred. Need to get the host again to reinitialize it.
- if (!channel_.get())
+ if (!channel_)
return NULL;
GPUCreateCommandBufferConfig init_params;
@@ -172,7 +173,7 @@
AutoLock lock(context_lock_);
// An error occurred. Need to get the host again to reinitialize it.
- if (!channel_.get())
+ if (!channel_)
return NULL;
GPUCreateCommandBufferConfig init_params;
@@ -199,7 +200,7 @@
return command_buffer;
}
-GpuVideoDecodeAcceleratorHost* GpuChannelHost::CreateVideoDecoder(
+scoped_ptr<media::VideoDecodeAccelerator> GpuChannelHost::CreateVideoDecoder(
int command_buffer_route_id,
media::VideoCodecProfile profile,
media::VideoDecodeAccelerator::Client* client) {
@@ -207,7 +208,7 @@
ProxyMap::iterator it = proxies_.find(command_buffer_route_id);
DCHECK(it != proxies_.end());
CommandBufferProxyImpl* proxy = it->second;
- return proxy->CreateVideoDecoder(profile, client);
+ return proxy->CreateVideoDecoder(profile, client).Pass();
}
void GpuChannelHost::DestroyCommandBuffer(
@@ -251,28 +252,31 @@
}
base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess(
- base::SharedMemory* shared_memory) {
+ base::SharedMemoryHandle source_handle) {
AutoLock lock(context_lock_);
- if (!channel_.get())
+ if (!channel_)
return base::SharedMemory::NULLHandle();
- base::SharedMemoryHandle handle;
#if defined(OS_WIN)
// Windows needs to explicitly duplicate the handle out to another process.
- if (!BrokerDuplicateHandle(shared_memory->handle(),
+ base::SharedMemoryHandle target_handle;
+ if (!BrokerDuplicateHandle(source_handle,
channel_->peer_pid(),
- &handle,
- FILE_MAP_WRITE,
- 0)) {
+ &target_handle,
+ 0,
+ DUPLICATE_SAME_ACCESS)) {
return base::SharedMemory::NULLHandle();
}
-#else
- if (!shared_memory->ShareToProcess(channel_->peer_pid(), &handle))
- return base::SharedMemory::NULLHandle();
-#endif
- return handle;
+ return target_handle;
+#else
+ int duped_handle = HANDLE_EINTR(dup(source_handle.fd));
+ if (duped_handle < 0)
+ return base::SharedMemory::NULLHandle();
+
+ return base::FileDescriptor(duped_handle, true);
+#endif
}
bool GpuChannelHost::GenerateMailboxNames(unsigned num,
@@ -321,7 +325,7 @@
base::WeakPtr<GpuChannelHost> parent,
GpuChannelHostFactory* factory)
: parent_(parent),
- factory_(factory) {
+ main_thread_loop_(factory->GetMainLoop()->message_loop_proxy()) {
}
GpuChannelHost::MessageFilter::~MessageFilter() {}
@@ -330,7 +334,6 @@
int route_id,
base::WeakPtr<IPC::Listener> listener,
scoped_refptr<MessageLoopProxy> loop) {
- DCHECK(factory_->IsIOThread());
DCHECK(listeners_.find(route_id) == listeners_.end());
GpuListenerInfo info;
info.listener = listener;
@@ -339,7 +342,6 @@
}
void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) {
- DCHECK(factory_->IsIOThread());
ListenerMap::iterator it = listeners_.find(route_id);
if (it != listeners_.end())
listeners_.erase(it);
@@ -347,18 +349,14 @@
bool GpuChannelHost::MessageFilter::OnMessageReceived(
const IPC::Message& message) {
- DCHECK(factory_->IsIOThread());
-
// Never handle sync message replies or we will deadlock here.
if (message.is_reply())
return false;
if (message.routing_id() == MSG_ROUTING_CONTROL) {
- MessageLoop* main_loop = factory_->GetMainLoop();
- main_loop->PostTask(FROM_HERE,
- base::Bind(&GpuChannelHost::OnMessageReceived,
- parent_,
- message));
+ main_thread_loop_->PostTask(
+ FROM_HERE, base::Bind(
+ &GpuChannelHost::OnMessageReceived, parent_, message));
return true;
}
@@ -378,14 +376,12 @@
}
void GpuChannelHost::MessageFilter::OnChannelError() {
- DCHECK(factory_->IsIOThread());
-
// Post the task to signal the GpuChannelHost before the proxies. That way, if
// they themselves post a task to recreate the context, they will not try to
// re-use this channel host before it has a chance to mark itself lost.
- MessageLoop* main_loop = factory_->GetMainLoop();
- main_loop->PostTask(FROM_HERE,
- base::Bind(&GpuChannelHost::OnChannelError, parent_));
+ main_thread_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&GpuChannelHost::OnChannelError, parent_));
// Inform all the proxies that an error has occurred. This will be reported
// via OpenGL as a lost context.
for (ListenerMap::iterator it = listeners_.begin();
diff --git a/content/common/gpu/client/gpu_channel_host.h b/content/common/gpu/client/gpu_channel_host.h
index 9f55d5a..c52505a 100644
--- a/content/common/gpu/client/gpu_channel_host.h
+++ b/content/common/gpu/client/gpu_channel_host.h
@@ -17,23 +17,23 @@
#include "base/process_util.h"
#include "base/synchronization/lock.h"
#include "content/common/content_export.h"
-#include "content/common/gpu/client/gpu_video_decode_accelerator_host.h"
#include "content/common/gpu/gpu_process_launch_causes.h"
#include "content/common/message_router.h"
#include "content/public/common/gpu_info.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_channel_proxy.h"
#include "ipc/ipc_sync_channel.h"
+#include "media/video/video_decode_accelerator.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/size.h"
#include "ui/gl/gpu_preference.h"
class GURL;
-class MessageLoop;
class TransportTextureService;
struct GPUCreateCommandBufferConfig;
namespace base {
+class MessageLoop;
class MessageLoopProxy;
}
@@ -47,6 +47,7 @@
namespace content {
class CommandBufferProxyImpl;
+class GpuChannelHost;
struct GpuRenderingStats;
struct GpuListenerInfo {
@@ -65,7 +66,7 @@
virtual bool IsMainThread() = 0;
virtual bool IsIOThread() = 0;
- virtual MessageLoop* GetMainLoop() = 0;
+ virtual base::MessageLoop* GetMainLoop() = 0;
virtual scoped_refptr<base::MessageLoopProxy> GetIOLoopProxy() = 0;
virtual base::WaitableEvent* GetShutDownEvent() = 0;
virtual scoped_ptr<base::SharedMemory> AllocateSharedMemory(size_t size) = 0;
@@ -137,8 +138,7 @@
gfx::GpuPreference gpu_preference);
// Creates a video decoder in the GPU process.
- // Returned pointer is owned by the CommandBufferProxy for |route_id|.
- GpuVideoDecodeAcceleratorHost* CreateVideoDecoder(
+ scoped_ptr<media::VideoDecodeAccelerator> CreateVideoDecoder(
int command_buffer_route_id,
media::VideoCodecProfile profile,
media::VideoDecodeAccelerator::Client* client);
@@ -157,18 +157,13 @@
GpuChannelHostFactory* factory() const { return factory_; }
int gpu_host_id() const { return gpu_host_id_; }
- // Do not use this function! It does not take the context lock and even
- // if it did the PID might become invalid immediately after releasing it
- // TODO(apatrick): Make all callers use ShareToGpuProcess().
- base::ProcessId gpu_pid() const { return channel_->peer_pid(); }
-
int client_id() const { return client_id_; }
// Returns a handle to the shared memory that can be sent via IPC to the
// GPU process. The caller is responsible for ensuring it is closed. Returns
// an invalid handle on failure.
base::SharedMemoryHandle ShareToGpuProcess(
- base::SharedMemory* shared_memory);
+ base::SharedMemoryHandle source_handle);
// Generates n unique mailbox names that can be used with
// GL_texture_mailbox_CHROMIUM. Unlike genMailboxCHROMIUM, this IPC is
@@ -210,7 +205,7 @@
// MessageFilter lives.
base::WeakPtr<GpuChannelHost> parent_;
- GpuChannelHostFactory* factory_;
+ scoped_refptr<base::MessageLoopProxy> main_thread_loop_;
typedef base::hash_map<int, GpuListenerInfo> ListenerMap;
ListenerMap listeners_;
diff --git a/content/common/gpu/client/gpu_video_decode_accelerator_host.cc b/content/common/gpu/client/gpu_video_decode_accelerator_host.cc
index c5fdb18..7288c69 100644
--- a/content/common/gpu/client/gpu_video_decode_accelerator_host.cc
+++ b/content/common/gpu/client/gpu_video_decode_accelerator_host.cc
@@ -23,18 +23,25 @@
GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost(
GpuChannelHost* channel,
int32 decoder_route_id,
- VideoDecodeAccelerator::Client* client)
+ VideoDecodeAccelerator::Client* client,
+ CommandBufferProxyImpl* impl)
: channel_(channel),
decoder_route_id_(decoder_route_id),
- client_(client) {
+ client_(client),
+ impl_(impl) {
DCHECK(channel_);
DCHECK(client_);
+ channel_->AddRoute(decoder_route_id, base::AsWeakPtr(this));
+ impl_->AddDeletionObserver(this);
}
void GpuVideoDecodeAcceleratorHost::OnChannelError() {
DLOG(ERROR) << "GpuVideoDecodeAcceleratorHost::OnChannelError()";
OnErrorNotification(PLATFORM_FAILURE);
- channel_ = NULL;
+ if (channel_) {
+ channel_->RemoveRoute(decoder_route_id_);
+ channel_ = NULL;
+ }
}
bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) {
@@ -71,19 +78,16 @@
// Can happen if a decode task was posted before an error was delivered.
if (!channel_)
return;
- base::SharedMemoryHandle buffer_handle = bitstream_buffer.handle();
-#if defined(OS_WIN)
- if (!BrokerDuplicateHandle(bitstream_buffer.handle(),
- channel_->gpu_pid(),
- &buffer_handle, 0,
- DUPLICATE_SAME_ACCESS)) {
+
+ base::SharedMemoryHandle handle = channel_->ShareToGpuProcess(
+ bitstream_buffer.handle());
+ if (!base::SharedMemory::IsHandleValid(handle)) {
NOTREACHED() << "Failed to duplicate buffer handler";
return;
}
-#endif // OS_WIN
Send(new AcceleratedVideoDecoderMsg_Decode(
- decoder_route_id_, buffer_handle, bitstream_buffer.id(),
+ decoder_route_id_, handle, bitstream_buffer.id(),
bitstream_buffer.size()));
}
@@ -123,16 +127,26 @@
void GpuVideoDecodeAcceleratorHost::Destroy() {
DCHECK(CalledOnValidThread());
- if (channel_)
- channel_->RemoveRoute(decoder_route_id_);
client_ = NULL;
Send(new AcceleratedVideoDecoderMsg_Destroy(decoder_route_id_));
delete this;
}
+void GpuVideoDecodeAcceleratorHost::OnWillDeleteImpl() {
+ impl_ = NULL;
+
+ // The CommandBufferProxyImpl is going away; error out this VDA.
+ OnChannelError();
+}
+
GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() {
DCHECK(CalledOnValidThread());
DCHECK(!client_) << "destructor called without Destroy being called!";
+
+ if (channel_)
+ channel_->RemoveRoute(decoder_route_id_);
+ if (impl_)
+ impl_->RemoveDeletionObserver(this);
}
void GpuVideoDecodeAcceleratorHost::Send(IPC::Message* message) {
diff --git a/content/common/gpu/client/gpu_video_decode_accelerator_host.h b/content/common/gpu/client/gpu_video_decode_accelerator_host.h
index fc1c040..ed67571 100644
--- a/content/common/gpu/client/gpu_video_decode_accelerator_host.h
+++ b/content/common/gpu/client/gpu_video_decode_accelerator_host.h
@@ -9,6 +9,7 @@
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
+#include "content/common/gpu/client/command_buffer_proxy_impl.h"
#include "ipc/ipc_listener.h"
#include "media/video/video_decode_accelerator.h"
@@ -20,12 +21,14 @@
class GpuVideoDecodeAcceleratorHost
: public IPC::Listener,
public media::VideoDecodeAccelerator,
+ public CommandBufferProxyImpl::DeletionObserver,
public base::NonThreadSafe {
public:
// |channel| is used to send IPC messages to GPU process.
GpuVideoDecodeAcceleratorHost(GpuChannelHost* channel,
int32 decoder_route_id,
- media::VideoDecodeAccelerator::Client* client);
+ media::VideoDecodeAccelerator::Client* client,
+ CommandBufferProxyImpl* impl);
// IPC::Listener implementation.
virtual void OnChannelError() OVERRIDE;
@@ -41,6 +44,9 @@
virtual void Reset() OVERRIDE;
virtual void Destroy() OVERRIDE;
+ // CommandBufferProxyImpl::DeletionObserver implemetnation.
+ virtual void OnWillDeleteImpl() OVERRIDE;
+
private:
// Only Destroy() should be deleting |this|.
virtual ~GpuVideoDecodeAcceleratorHost();
@@ -66,6 +72,9 @@
// Reference to the client that will receive callbacks from the decoder.
media::VideoDecodeAccelerator::Client* client_;
+ // Unowned reference to the CommandBufferProxyImpl that created us.
+ CommandBufferProxyImpl* impl_;
+
DISALLOW_COPY_AND_ASSIGN(GpuVideoDecodeAcceleratorHost);
};
diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
index 8484974..e74a7ee 100644
--- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
+++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
@@ -146,7 +146,7 @@
cached_width_(0),
cached_height_(0),
bound_fbo_(0),
- weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ weak_ptr_factory_(this),
initialized_(false),
parent_(NULL),
parent_texture_id_(0),
@@ -180,16 +180,6 @@
Destroy();
}
-void WebGraphicsContext3DCommandBufferImpl::InitializeWithCommandBuffer(
- CommandBufferProxyImpl* command_buffer,
- const WebGraphicsContext3D::Attributes& attributes,
- bool bind_generates_resources) {
- DCHECK(command_buffer);
- command_buffer_ = command_buffer;
- attributes_ = attributes;
- bind_generates_resources_ = bind_generates_resources;
-}
-
bool WebGraphicsContext3DCommandBufferImpl::Initialize(
const WebGraphicsContext3D::Attributes& attributes,
bool bind_generates_resources,
@@ -230,6 +220,7 @@
allowed_extensions ?
allowed_extensions : preferred_extensions)) {
Destroy();
+ initialize_failed_ = true;
return false;
}
@@ -999,8 +990,8 @@
program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length);
if (max_name_length < 0)
return false;
- scoped_array<GLchar> name(new GLchar[max_name_length]);
- if (!name.get()) {
+ scoped_ptr<GLchar[]> name(new GLchar[max_name_length]);
+ if (!name) {
synthesizeGLError(GL_OUT_OF_MEMORY);
return false;
}
@@ -1025,8 +1016,8 @@
program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length);
if (max_name_length < 0)
return false;
- scoped_array<GLchar> name(new GLchar[max_name_length]);
- if (!name.get()) {
+ scoped_ptr<GLchar[]> name(new GLchar[max_name_length]);
+ if (!name) {
synthesizeGLError(GL_OUT_OF_MEMORY);
return false;
}
@@ -1093,8 +1084,8 @@
gl_->GetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
if (!logLength)
return WebKit::WebString();
- scoped_array<GLchar> log(new GLchar[logLength]);
- if (!log.get())
+ scoped_ptr<GLchar[]> log(new GLchar[logLength]);
+ if (!log)
return WebKit::WebString();
GLsizei returnedLogLength = 0;
gl_->GetProgramInfoLog(
@@ -1116,8 +1107,8 @@
gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
if (!logLength)
return WebKit::WebString();
- scoped_array<GLchar> log(new GLchar[logLength]);
- if (!log.get())
+ scoped_ptr<GLchar[]> log(new GLchar[logLength]);
+ if (!log)
return WebKit::WebString();
GLsizei returnedLogLength = 0;
gl_->GetShaderInfoLog(
@@ -1137,8 +1128,8 @@
gl_->GetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength);
if (!logLength)
return WebKit::WebString();
- scoped_array<GLchar> log(new GLchar[logLength]);
- if (!log.get())
+ scoped_ptr<GLchar[]> log(new GLchar[logLength]);
+ if (!log)
return WebKit::WebString();
GLsizei returnedLogLength = 0;
gl_->GetShaderSource(
@@ -1158,8 +1149,8 @@
shader, GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, &logLength);
if (!logLength)
return WebKit::WebString();
- scoped_array<GLchar> log(new GLchar[logLength]);
- if (!log.get())
+ scoped_ptr<GLchar[]> log(new GLchar[logLength]);
+ if (!log)
return WebKit::WebString();
GLsizei returnedLogLength = 0;
gl_->GetTranslatedShaderSourceANGLE(
@@ -1441,8 +1432,10 @@
typedef WebGraphicsContext3DSwapBuffersClient WGC3DSwapClient;
// This may be called after tear-down of the RenderView.
if (ShouldUseSwapClient()) {
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
- &WGC3DSwapClient::OnViewContextSwapBuffersComplete, swap_client_));
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&WGC3DSwapClient::OnViewContextSwapBuffersComplete,
+ swap_client_));
}
if (swapbuffers_complete_callback_)
@@ -1531,30 +1524,6 @@
// static
WebGraphicsContext3DCommandBufferImpl*
-WebGraphicsContext3DCommandBufferImpl::CreateViewContext(
- GpuChannelHostFactory* factory,
- int32 surface_id,
- const char* allowed_extensions,
- const WebGraphicsContext3D::Attributes& attributes,
- bool bind_generates_resources,
- const GURL& active_url,
- CauseForGpuLaunch cause) {
- WebGraphicsContext3DCommandBufferImpl* context =
- new WebGraphicsContext3DCommandBufferImpl(
- surface_id,
- active_url,
- factory,
- base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>());
- if (!context->Initialize(attributes, bind_generates_resources, cause) ||
- !context->MaybeInitializeGL(allowed_extensions)) {
- delete context;
- return NULL;
- }
- return context;
-}
-
-// static
-WebGraphicsContext3DCommandBufferImpl*
WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
GpuChannelHostFactory* factory,
const WebGraphicsContext3D::Attributes& attributes,
@@ -1602,8 +1571,21 @@
DELEGATE_TO_GL_3(getQueryObjectuivEXT, GetQueryObjectuivEXT,
WebGLId, WGC3Denum, WGC3Duint*)
-DELEGATE_TO_GL_5(copyTextureCHROMIUM, CopyTextureCHROMIUM, WGC3Denum,
- WebGLId, WebGLId, WGC3Dint, WGC3Denum);
+DELEGATE_TO_GL_6(copyTextureCHROMIUM, CopyTextureCHROMIUM, WGC3Denum,
+ WebGLId, WebGLId, WGC3Dint, WGC3Denum, WGC3Denum);
+
+// This copyTextureCHROMIUM(...) has five parameters and delegates the call to
+// CopyTextureCHROMIUM(...) with the sixth parameter set to GL_UNSIGNED_BYTE
+// to bridge the parameter differences.
+// TODO(jun.a.jiang@intel.com): once all clients switch to call
+// the newer copyTextureCHROMIUM(...) with six parameters, this
+// function will be removed.
+void WebGraphicsContext3DCommandBufferImpl::copyTextureCHROMIUM(
+ WGC3Denum target, WebGLId source_id, WebGLId dest_id, WGC3Dint level,
+ WGC3Denum internal_format) {
+ gl_->CopyTextureCHROMIUM(target, source_id, dest_id, level, internal_format,
+ GL_UNSIGNED_BYTE);
+}
DELEGATE_TO_GL_3(bindUniformLocationCHROMIUM, BindUniformLocationCHROMIUM,
WebGLId, WGC3Dint, const WGC3Dchar*)
@@ -1612,6 +1594,22 @@
DELEGATE_TO_GL_1(waitSyncPoint, WaitSyncPointCHROMIUM, GLuint)
+static void SignalSyncPointCallback(
+ scoped_ptr<
+ WebKit::WebGraphicsContext3D::WebGraphicsSyncPointCallback> callback) {
+ callback->onSyncPointReached();
+}
+
+void WebGraphicsContext3DCommandBufferImpl::signalSyncPoint(
+ unsigned sync_point,
+ WebGraphicsSyncPointCallback* callback) {
+ // Take ownership of the callback.
+ scoped_ptr<WebGraphicsSyncPointCallback> own_callback(callback);
+ command_buffer_->SignalSyncPoint(
+ sync_point,
+ base::Bind(&SignalSyncPointCallback, base::Passed(&own_callback)));
+}
+
void WebGraphicsContext3DCommandBufferImpl::genMailboxCHROMIUM(
WGC3Dbyte* name) {
std::vector<gpu::Mailbox> names(1);
diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
index 46d311a..c24a238 100644
--- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
+++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
@@ -79,11 +79,6 @@
virtual ~WebGraphicsContext3DCommandBufferImpl();
- void InitializeWithCommandBuffer(
- CommandBufferProxyImpl* command_buffer,
- const Attributes& attributes,
- bool bind_generates_resources);
-
bool Initialize(const Attributes& attributes,
bool bind_generates_resources,
CauseForGpuLaunch cause);
@@ -106,28 +101,6 @@
// problem communicating with the GPU process.
bool IsCommandBufferContextLost();
- // Create a WebGraphicsContext3DCommandBufferImpl that renders directly to a
- // view. The view and the associated window must not be destroyed until
- // the returned ContentGLContext has been destroyed, otherwise the GPU process
- // might attempt to render to an invalid window handle.
- //
- // NOTE: on Mac OS X, this entry point is only used to set up the
- // accelerated compositor's output. On this platform, we actually pass
- // a gfx::PluginWindowHandle in place of the gfx::NativeViewId,
- // because the facility to allocate a fake PluginWindowHandle is
- // already in place. We could add more entry points and messages to
- // allocate both fake PluginWindowHandles and NativeViewIds and map
- // from fake NativeViewIds to PluginWindowHandles, but this seems like
- // unnecessary complexity at the moment.
- static WebGraphicsContext3DCommandBufferImpl* CreateViewContext(
- GpuChannelHostFactory* factory,
- int32 surface_id,
- const char* allowed_extensions,
- const WebGraphicsContext3D::Attributes& attributes,
- bool bind_generates_resources,
- const GURL& active_url,
- CauseForGpuLaunch cause);
-
// Create & initialize a WebGraphicsContext3DCommandBufferImpl. Return NULL
// on any failure.
static WebGraphicsContext3DCommandBufferImpl* CreateOffscreenContext(
@@ -151,7 +124,9 @@
virtual bool setParentContext(WebGraphicsContext3D* parent_context);
virtual unsigned int insertSyncPoint();
- virtual void waitSyncPoint(unsigned int);
+ virtual void waitSyncPoint(unsigned int sync_point);
+ virtual void signalSyncPoint(unsigned sync_point,
+ WebGraphicsSyncPointCallback* callback);
virtual void reshape(int width, int height);
@@ -574,6 +549,11 @@
WebGLId dest_id, WGC3Dint level,
WGC3Denum internal_format);
+ virtual void copyTextureCHROMIUM(WGC3Denum target, WebGLId source_id,
+ WebGLId dest_id, WGC3Dint level,
+ WGC3Denum internal_format,
+ WGC3Denum dest_type);
+
virtual void bindUniformLocationCHROMIUM(WebGLId program, WGC3Dint location,
const WGC3Dchar* uniform);
diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc
index b7231b4..d116d84 100644
--- a/content/common/gpu/gpu_channel.cc
+++ b/content/common/gpu/gpu_channel.cc
@@ -126,7 +126,7 @@
// All other messages get processed by the GpuChannel.
if (!handled) {
messages_forwarded_to_channel_++;
- if (preempting_flag_.get())
+ if (preempting_flag_)
pending_messages_.push(PendingMessage(messages_forwarded_to_channel_));
UpdatePreemptionState();
}
@@ -448,7 +448,7 @@
handle_messages_scheduled_(false),
processed_get_state_fast_(false),
currently_processing_message_(NULL),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ weak_factory_(this),
num_stubs_descheduled_(0) {
DCHECK(gpu_channel_manager);
DCHECK(client_id);
@@ -497,7 +497,7 @@
#if defined(OS_POSIX)
int GpuChannel::TakeRendererFileDescriptor() {
- if (!channel_.get()) {
+ if (!channel_) {
NOTREACHED();
return -1;
}
@@ -561,7 +561,7 @@
<< " with type " << message->type();
}
- if (!channel_.get()) {
+ if (!channel_) {
delete message;
return false;
}
@@ -585,7 +585,7 @@
// defer newly received messages until the ones in the queue have all been
// handled by HandleMessage. HandleMessage is invoked as a
// task to prevent reentrancy.
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&GpuChannel::HandleMessage, weak_factory_.GetWeakPtr()));
handle_messages_scheduled_ = true;
@@ -603,7 +603,7 @@
bool a_stub_is_descheduled = num_stubs_descheduled_ > 0;
if (a_stub_is_descheduled != a_stub_was_descheduled) {
- if (preempting_flag_.get()) {
+ if (preempting_flag_) {
io_message_loop_->PostTask(
FROM_HERE,
base::Bind(&GpuChannelMessageFilter::UpdateStubSchedulingState,
@@ -628,6 +628,14 @@
GpuCommandBufferStub* share_group = stubs_.Lookup(init_params.share_group_id);
+ // Virtualize compositor contexts on OS X to prevent performance regressions
+ // when enabling FCM.
+ // http://crbug.com/180463
+ bool use_virtualized_gl_context = false;
+#if defined(OS_MACOSX)
+ use_virtualized_gl_context = true;
+#endif
+
*route_id = GenerateRouteID();
scoped_ptr<GpuCommandBufferStub> stub(new GpuCommandBufferStub(
this,
@@ -640,12 +648,13 @@
init_params.allowed_extensions,
init_params.attribs,
init_params.gpu_preference,
+ use_virtualized_gl_context,
*route_id,
surface_id,
watchdog_,
software_,
init_params.active_url));
- if (preempted_flag_.get())
+ if (preempted_flag_)
stub->SetPreemptByFlag(preempted_flag_);
router_.AddRoute(*route_id, stub.get());
stubs_.AddWithID(stub.release(), *route_id);
@@ -694,7 +703,7 @@
}
void GpuChannel::DestroySoon() {
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE, base::Bind(&GpuChannel::OnDestroy, this));
}
@@ -712,7 +721,7 @@
}
gpu::PreemptionFlag* GpuChannel::GetPreemptionFlag() {
- if (!preempting_flag_.get()) {
+ if (!preempting_flag_) {
preempting_flag_ = new gpu::PreemptionFlag;
io_message_loop_->PostTask(
FROM_HERE, base::Bind(
@@ -733,7 +742,7 @@
}
GpuChannel::~GpuChannel() {
- if (preempting_flag_.get())
+ if (preempting_flag_)
preempting_flag_->Reset();
}
@@ -857,11 +866,13 @@
init_params.allowed_extensions,
init_params.attribs,
init_params.gpu_preference,
+ false,
*route_id,
- 0, watchdog_,
+ 0,
+ watchdog_,
software_,
init_params.active_url));
- if (preempted_flag_.get())
+ if (preempted_flag_)
stub->SetPreemptByFlag(preempted_flag_);
router_.AddRoute(*route_id, stub.get());
stubs_.AddWithID(stub.release(), *route_id);
@@ -873,18 +884,17 @@
TRACE_EVENT1("gpu", "GpuChannel::OnDestroyCommandBuffer",
"route_id", route_id);
- if (router_.ResolveRoute(route_id)) {
- GpuCommandBufferStub* stub = stubs_.Lookup(route_id);
- bool need_reschedule = (stub && !stub->IsScheduled());
- router_.RemoveRoute(route_id);
- stubs_.Remove(route_id);
- // In case the renderer is currently blocked waiting for a sync reply from
- // the stub, we need to make sure to reschedule the GpuChannel here.
- if (need_reschedule) {
- // This stub won't get a chance to reschedule, so update the count
- // now.
- StubSchedulingChanged(true);
- }
+ GpuCommandBufferStub* stub = stubs_.Lookup(route_id);
+ if (!stub)
+ return;
+ bool need_reschedule = (stub && !stub->IsScheduled());
+ router_.RemoveRoute(route_id);
+ stubs_.Remove(route_id);
+ // In case the renderer is currently blocked waiting for a sync reply from the
+ // stub, we need to make sure to reschedule the GpuChannel here.
+ if (need_reschedule) {
+ // This stub won't get a chance to reschedule, so update the count now.
+ StubSchedulingChanged(true);
}
}
@@ -931,7 +941,7 @@
void GpuChannel::MessageProcessed() {
messages_processed_++;
- if (preempting_flag_.get()) {
+ if (preempting_flag_) {
io_message_loop_->PostTask(
FROM_HERE,
base::Bind(&GpuChannelMessageFilter::MessageProcessed,
diff --git a/content/common/gpu/gpu_channel_manager.cc b/content/common/gpu/gpu_channel_manager.cc
index fc48010..d695ff5 100644
--- a/content/common/gpu/gpu_channel_manager.cc
+++ b/content/common/gpu/gpu_channel_manager.cc
@@ -33,13 +33,12 @@
GpuWatchdog* watchdog,
base::MessageLoopProxy* io_message_loop,
base::WaitableEvent* shutdown_event)
- : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+ : weak_factory_(this),
io_message_loop_(io_message_loop),
shutdown_event_(shutdown_event),
gpu_child_thread_(gpu_child_thread),
- ALLOW_THIS_IN_INITIALIZER_LIST(gpu_memory_manager_(
- this,
- GpuMemoryManager::kDefaultMaxSurfacesWithFrontbufferSoftLimit)),
+ gpu_memory_manager_(
+ this, GpuMemoryManager::kDefaultMaxSurfacesWithFrontbufferSoftLimit),
watchdog_(watchdog),
sync_point_manager_(new SyncPointManager),
program_cache_(NULL) {
@@ -50,7 +49,7 @@
GpuChannelManager::~GpuChannelManager() {
gpu_channels_.clear();
- if (default_offscreen_surface_.get()) {
+ if (default_offscreen_surface_) {
default_offscreen_surface_->Destroy();
default_offscreen_surface_ = NULL;
}
@@ -279,7 +278,7 @@
}
void GpuChannelManager::LoseAllContexts() {
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&GpuChannelManager::OnLoseAllContexts,
weak_factory_.GetWeakPtr()));
@@ -290,7 +289,7 @@
}
gfx::GLSurface* GpuChannelManager::GetDefaultOffscreenSurface() {
- if (!default_offscreen_surface_.get()) {
+ if (!default_offscreen_surface_) {
default_offscreen_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(
false, gfx::Size(1, 1));
}
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index 04e55bc..4934df5 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -25,6 +25,7 @@
#include "gpu/command_buffer/common/constants.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/gl_context_virtual.h"
+#include "gpu/command_buffer/service/logger.h"
#include "gpu/command_buffer/service/memory_tracking.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_switches.h"
@@ -107,6 +108,7 @@
const std::string& allowed_extensions,
const std::vector<int32>& attribs,
gfx::GpuPreference gpu_preference,
+ bool use_virtualized_gl_context,
int32 route_id,
int32 surface_id,
GpuWatchdog* watchdog,
@@ -119,6 +121,7 @@
allowed_extensions_(allowed_extensions),
requested_attribs_(attribs),
gpu_preference_(gpu_preference),
+ use_virtualized_gl_context_(use_virtualized_gl_context),
route_id_(route_id),
surface_id_(surface_id),
software_(software),
@@ -165,7 +168,8 @@
// Echo, RetireSyncPoint, or WaitSyncPoint).
if (decoder_.get() &&
message.type() != GpuCommandBufferMsg_Echo::ID &&
- message.type() != GpuCommandBufferMsg_RetireSyncPoint::ID) {
+ message.type() != GpuCommandBufferMsg_RetireSyncPoint::ID &&
+ message.type() != GpuCommandBufferMsg_SetLatencyInfo::ID) {
if (!MakeCurrent())
return false;
}
@@ -185,6 +189,7 @@
IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetStateFast,
OnGetStateFast);
IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush);
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetLatencyInfo, OnSetLatencyInfo);
IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Rescheduled, OnRescheduled);
IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RegisterTransferBuffer,
OnRegisterTransferBuffer);
@@ -194,8 +199,6 @@
OnGetTransferBuffer);
IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateVideoDecoder,
OnCreateVideoDecoder)
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyVideoDecoder,
- OnDestroyVideoDecoder)
IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetSurfaceVisible,
OnSetSurfaceVisible)
IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DiscardBackbuffer,
@@ -240,7 +243,7 @@
if (decoder_.get() && !MakeCurrent())
return;
- if (scheduler_.get()) {
+ if (scheduler_) {
bool fences_complete = scheduler_->PollUnscheduleFences();
// Perform idle work if all fences are complete.
if (fences_complete) {
@@ -271,7 +274,7 @@
}
bool GpuCommandBufferStub::HasUnprocessedCommands() {
- if (command_buffer_.get()) {
+ if (command_buffer_) {
gpu::CommandBuffer::State state = command_buffer_->GetLastState();
return state.put_offset != state.get_offset &&
!gpu::error::IsError(state.error);
@@ -308,10 +311,9 @@
delay = 0;
}
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
- base::Bind(&GpuCommandBufferStub::PollWork,
- AsWeakPtr()),
+ base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()),
base::TimeDelta::FromMilliseconds(delay));
}
@@ -343,7 +345,7 @@
while (!sync_points_.empty())
OnRetireSyncPoint(sync_points_.front());
- if (decoder_.get())
+ if (decoder_)
decoder_->set_engine(NULL);
// The scheduler has raw references to the decoder and the command buffer so
@@ -351,14 +353,14 @@
scheduler_.reset();
bool have_context = false;
- if (decoder_.get())
+ if (decoder_)
have_context = decoder_->MakeCurrent();
FOR_EACH_OBSERVER(DestructionObserver,
destruction_observers_,
- OnWillDestroyStub(this));
+ OnWillDestroyStub());
scoped_refptr<gfx::GLContext> context;
- if (decoder_.get()) {
+ if (decoder_) {
context = decoder_->GetGLContext();
decoder_->Destroy(have_context);
decoder_.reset();
@@ -405,7 +407,7 @@
scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(),
decoder_.get(),
decoder_.get()));
- if (preemption_flag_.get())
+ if (preemption_flag_)
scheduler_->SetPreemptByFlag(preemption_flag_);
decoder_->set_engine(scheduler_.get());
@@ -428,18 +430,16 @@
surface_ = manager->GetDefaultOffscreenSurface();
}
- if (!surface_.get()) {
- // Ensure the decoder is not destroyed if it is not initialized.
- decoder_.reset();
-
+ if (!surface_) {
DLOG(ERROR) << "Failed to create surface.\n";
OnInitializeFailed(reply_message);
return;
}
scoped_refptr<gfx::GLContext> context;
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableVirtualGLContexts) && channel_->share_group()) {
+ if ((CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableVirtualGLContexts) || use_virtualized_gl_context_) &&
+ channel_->share_group()) {
context = channel_->share_group()->GetSharedContext();
if (!context) {
context = gfx::GLContext::CreateGLContext(
@@ -460,9 +460,6 @@
// with a config that is compatible with onscreen and offscreen surfaces.
context = NULL;
- // Ensure the decoder is not destroyed if it is not initialized.
- decoder_.reset();
-
DLOG(ERROR) << "Failed to initialize virtual GL context.";
OnInitializeFailed(reply_message);
return;
@@ -477,17 +474,12 @@
gpu_preference_);
}
if (!context) {
- // Ensure the decoder is not destroyed if it is not initialized.
- decoder_.reset();
-
DLOG(ERROR) << "Failed to create context.\n";
OnInitializeFailed(reply_message);
return;
}
- if (!context->MakeCurrent(surface_.get())) {
- // Ensure the decoder is not destroyed if it is not initialized.
- decoder_.reset();
+ if (!context->MakeCurrent(surface_)) {
LOG(ERROR) << "Failed to make context current.";
OnInitializeFailed(reply_message);
return;
@@ -519,7 +511,7 @@
decoder_->set_log_commands(true);
}
- decoder_->SetMsgCallback(
+ decoder_->GetLogger()->SetMsgCallback(
base::Bind(&GpuCommandBufferStub::SendConsoleMessage,
base::Unretained(this)));
decoder_->SetShaderCacheCallback(
@@ -573,10 +565,21 @@
}
}
+void GpuCommandBufferStub::OnSetLatencyInfo(
+ const cc::LatencyInfo& latency_info) {
+ if (!latency_info_callback_.is_null())
+ latency_info_callback_.Run(latency_info);
+}
+
+void GpuCommandBufferStub::SetLatencyInfoCallback(
+ const LatencyInfoCallback& callback) {
+ latency_info_callback_ = callback;
+}
+
void GpuCommandBufferStub::OnSetGetBuffer(int32 shm_id,
IPC::Message* reply_message) {
TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetGetBuffer");
- if (command_buffer_.get())
+ if (command_buffer_)
command_buffer_->SetGetBuffer(shm_id);
Send(reply_message);
}
@@ -591,7 +594,7 @@
}
bool result = true;
- if (scheduler_.get()) {
+ if (scheduler_) {
gpu::gles2::GLES2Decoder* parent_decoder =
parent_stub ? parent_stub->decoder_.get() : NULL;
result = decoder_->SetParent(parent_decoder, parent_texture_id);
@@ -609,7 +612,7 @@
void GpuCommandBufferStub::OnGetState(IPC::Message* reply_message) {
TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetState");
- if (command_buffer_.get()) {
+ if (command_buffer_) {
gpu::CommandBuffer::State state = command_buffer_->GetState();
if (state.error == gpu::error::kLostContext &&
gfx::GLContext::LosesAllContextsOnContextLost())
@@ -685,14 +688,14 @@
TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnRegisterTransferBuffer");
base::SharedMemory shared_memory(transfer_buffer, false);
- if (command_buffer_.get())
+ if (command_buffer_)
command_buffer_->RegisterTransferBuffer(id, &shared_memory, size);
}
void GpuCommandBufferStub::OnDestroyTransferBuffer(int32 id) {
TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyTransferBuffer");
- if (command_buffer_.get())
+ if (command_buffer_)
command_buffer_->DestroyTransferBuffer(id);
}
@@ -700,7 +703,7 @@
int32 id,
IPC::Message* reply_message) {
TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetTransferBuffer");
- if (command_buffer_.get()) {
+ if (command_buffer_) {
base::SharedMemoryHandle transfer_buffer = base::SharedMemoryHandle();
uint32 size = 0;
@@ -755,18 +758,14 @@
int decoder_route_id = channel_->GenerateRouteID();
GpuVideoDecodeAccelerator* decoder =
new GpuVideoDecodeAccelerator(decoder_route_id, this);
- video_decoders_.AddWithID(decoder, decoder_route_id);
decoder->Initialize(profile, reply_message);
-}
-
-void GpuCommandBufferStub::OnDestroyVideoDecoder(int decoder_route_id) {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyVideoDecoder");
- video_decoders_.Remove(decoder_route_id);
+ // decoder is registered as a DestructionObserver of this stub and will
+ // self-delete during destruction of this stub.
}
void GpuCommandBufferStub::OnSetSurfaceVisible(bool visible) {
TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetSurfaceVisible");
- if (memory_manager_client_state_.get())
+ if (memory_manager_client_state_)
memory_manager_client_state_->SetVisible(visible);
}
@@ -849,7 +848,7 @@
TRACE_EVENT0(
"gpu",
"GpuCommandBufferStub::OnReceivedClientManagedMemoryStats");
- if (memory_manager_client_state_.get())
+ if (memory_manager_client_state_)
memory_manager_client_state_->SetManagedMemoryStats(stats);
}
@@ -859,7 +858,7 @@
"gpu",
"GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback");
if (has_callback) {
- if (!memory_manager_client_state_.get()) {
+ if (!memory_manager_client_state_) {
memory_manager_client_state_.reset(GetMemoryManager()->CreateClientState(
this, surface_id_ != 0, true));
}
@@ -898,7 +897,7 @@
void GpuCommandBufferStub::SetPreemptByFlag(
scoped_refptr<gpu::PreemptionFlag> flag) {
preemption_flag_ = flag;
- if (scheduler_.get())
+ if (scheduler_)
scheduler_->SetPreemptByFlag(preemption_flag_);
}
diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h
index 512012d..c7f8195 100644
--- a/content/common/gpu/gpu_command_buffer_stub.h
+++ b/content/common/gpu/gpu_command_buffer_stub.h
@@ -9,9 +9,10 @@
#include <string>
#include <vector>
-#include "base/id_map.h"
+#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
+#include "cc/debug/latency_info.h"
#include "content/common/content_export.h"
#include "content/common/gpu/gpu_memory_allocation.h"
#include "content/common/gpu/gpu_memory_manager.h"
@@ -52,12 +53,15 @@
class DestructionObserver {
public:
// Called in Destroy(), before the context/surface are released.
- virtual void OnWillDestroyStub(GpuCommandBufferStub* stub) = 0;
+ virtual void OnWillDestroyStub() = 0;
protected:
virtual ~DestructionObserver() {}
};
+ typedef base::Callback<void(const cc::LatencyInfo&)>
+ LatencyInfoCallback;
+
GpuCommandBufferStub(
GpuChannel* channel,
GpuCommandBufferStub* share_group,
@@ -69,6 +73,7 @@
const std::string& allowed_extensions,
const std::vector<int32>& attribs,
gfx::GpuPreference gpu_preference,
+ bool use_virtualized_gl_context,
int32 route_id,
int32 surface_id,
GpuWatchdog* watchdog,
@@ -130,6 +135,8 @@
void SetPreemptByFlag(scoped_refptr<gpu::PreemptionFlag> flag);
+ void SetLatencyInfoCallback(const LatencyInfoCallback& callback);
+
private:
GpuMemoryManager* GetMemoryManager();
bool MakeCurrent();
@@ -159,7 +166,6 @@
void OnCreateVideoDecoder(
media::VideoCodecProfile profile,
IPC::Message* reply_message);
- void OnDestroyVideoDecoder(int32 decoder_route_id);
void OnSetSurfaceVisible(bool visible);
@@ -177,6 +183,7 @@
void OnCommandProcessed();
void OnParseError();
+ void OnSetLatencyInfo(const cc::LatencyInfo& latency_info);
void ReportState();
@@ -205,6 +212,7 @@
std::string allowed_extensions_;
std::vector<int32> requested_attribs_;
gfx::GpuPreference gpu_preference_;
+ bool use_virtualized_gl_context_;
int32 route_id_;
int32 surface_id_;
bool software_;
@@ -228,10 +236,6 @@
GpuWatchdog* watchdog_;
- // Zero or more video decoders owned by this stub, keyed by their
- // decoder_route_id.
- IDMap<GpuVideoDecodeAccelerator, IDMapOwnPointer> video_decoders_;
-
ObserverList<DestructionObserver> destruction_observers_;
// A queue of sync points associated with this stub.
@@ -244,6 +248,8 @@
scoped_refptr<gpu::PreemptionFlag> preemption_flag_;
+ LatencyInfoCallback latency_info_callback_;
+
GURL active_url_;
size_t active_url_hash_;
diff --git a/content/common/gpu/gpu_memory_manager.cc b/content/common/gpu/gpu_memory_manager.cc
index 9a1402c..4794b9f 100644
--- a/content/common/gpu/gpu_memory_manager.cc
+++ b/content/common/gpu/gpu_memory_manager.cc
@@ -75,6 +75,14 @@
bytes_minimum_per_client_ = 64 * 1024 * 1024;
#endif
+ // On Android, always discard everything that is nonvisible.
+ // On Mac, use as little memory as possible to avoid stability issues.
+#if defined(OS_ANDROID) || defined(OS_MACOSX)
+ allow_nonvisible_memory_ = false;
+#else
+ allow_nonvisible_memory_ = true;
+#endif
+
if (command_line->HasSwitch(switches::kForceGpuMemAvailableMb)) {
base::StringToUint64(
command_line->GetSwitchValueASCII(switches::kForceGpuMemAvailableMb),
@@ -207,9 +215,8 @@
if (manage_immediate_scheduled_)
return;
if (schedule_manage_time == kScheduleManageNow) {
- MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&GpuMemoryManager::Manage, AsWeakPtr()));
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(&GpuMemoryManager::Manage, AsWeakPtr()));
manage_immediate_scheduled_ = true;
if (!delayed_manage_callback_.IsCancelled())
delayed_manage_callback_.Cancel();
@@ -218,10 +225,10 @@
return;
delayed_manage_callback_.Reset(base::Bind(&GpuMemoryManager::Manage,
AsWeakPtr()));
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- delayed_manage_callback_.callback(),
- base::TimeDelta::FromMilliseconds(kDelayedScheduleManageTimeoutMs));
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ delayed_manage_callback_.callback(),
+ base::TimeDelta::FromMilliseconds(kDelayedScheduleManageTimeoutMs));
}
}
@@ -634,10 +641,9 @@
bytes_available_total - bytes_allocated_visible);
}
- // On Android, always discard everything that is nonvisible.
-#if defined(OS_ANDROID)
- bytes_available_nonvisible = 0;
-#endif
+ // Clamp the amount of memory available to non-visible clients.
+ if (!allow_nonvisible_memory_)
+ bytes_available_nonvisible = 0;
// Determine which now-visible clients should keep their contents when
// they are made nonvisible.
@@ -765,6 +771,9 @@
allocation.renderer_allocation.bytes_limit_when_visible =
client_state->bytes_allocation_when_visible_;
+ // Use a more conservative memory allocation policy on Mac because the
+ // platform is unstable when under memory pressure.
+ // http://crbug.com/141377
allocation.renderer_allocation.priority_cutoff_when_visible =
#if defined(OS_MACOSX)
GpuMemoryAllocationForRenderer::kPriorityCutoffAllowNiceToHave;
diff --git a/content/common/gpu/gpu_memory_manager.h b/content/common/gpu/gpu_memory_manager.h
index 2315c84..57c2c16 100644
--- a/content/common/gpu/gpu_memory_manager.h
+++ b/content/common/gpu/gpu_memory_manager.h
@@ -230,6 +230,9 @@
uint64 bytes_available_gpu_memory_;
bool bytes_available_gpu_memory_overridden_;
+ // Whether or not clients can be allocated memory when nonvisible.
+ bool allow_nonvisible_memory_;
+
// The minimum and default allocations for a single client.
uint64 bytes_minimum_per_client_;
uint64 bytes_default_per_client_;
diff --git a/content/common/gpu/gpu_memory_manager_unittest.cc b/content/common/gpu/gpu_memory_manager_unittest.cc
index 9cbb4b3..d877ef6 100644
--- a/content/common/gpu/gpu_memory_manager_unittest.cc
+++ b/content/common/gpu/gpu_memory_manager_unittest.cc
@@ -716,9 +716,8 @@
memmgr_.TestingSetMinimumClientAllocation(8);
uint64 bytes_when_not_visible_expected = 6u;
-#if defined (OS_ANDROID)
- bytes_when_not_visible_expected = 0;
-#endif
+ if (!memmgr_.allow_nonvisible_memory_)
+ bytes_when_not_visible_expected = 0;
FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true);
FakeClient stub2(&memmgr_, GenerateUniqueSurfaceId(), true);
@@ -772,9 +771,8 @@
memmgr_.TestingSetMinimumClientAllocation(8);
uint64 bytes_when_not_visible_expected = 10ul;
-#if defined (OS_ANDROID)
- bytes_when_not_visible_expected = 0;
-#endif
+ if (!memmgr_.allow_nonvisible_memory_)
+ bytes_when_not_visible_expected = 0;
FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true);
FakeClient stub2(&memmgr_, GenerateUniqueSurfaceId(), true);
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h
index de5d1e2..f8b8549 100644
--- a/content/common/gpu/gpu_messages.h
+++ b/content/common/gpu/gpu_messages.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/shared_memory.h"
+#include "cc/debug/latency_info.h"
#include "content/common/content_export.h"
#include "content/common/gpu/gpu_memory_allocation.h"
#include "content/common/gpu/gpu_memory_uma_stats.h"
@@ -50,6 +51,7 @@
IPC_STRUCT_MEMBER(int32, route_id)
IPC_STRUCT_MEMBER(std::string, mailbox_name)
IPC_STRUCT_MEMBER(gfx::Size, size)
+ IPC_STRUCT_MEMBER(cc::LatencyInfo, latency_info)
IPC_STRUCT_END()
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT
@@ -64,6 +66,7 @@
IPC_STRUCT_MEMBER(int, height)
IPC_STRUCT_MEMBER(std::string, mailbox_name)
IPC_STRUCT_MEMBER(gfx::Size, surface_size)
+ IPC_STRUCT_MEMBER(cc::LatencyInfo, latency_info)
IPC_STRUCT_END()
IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceRelease_Params)
@@ -361,6 +364,11 @@
int32 /* route_id */,
gfx::Size /* size */)
+// Tells the browser that a frame with the specific latency info was drawn to
+// the screen
+IPC_MESSAGE_CONTROL1(GpuHostMsg_FrameDrawn,
+ cc::LatencyInfo /* latency_info */)
+
// Same as above with a rect of the part of the surface that changed.
IPC_MESSAGE_CONTROL1(GpuHostMsg_AcceleratedSurfaceBuffersSwapped,
GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params)
@@ -502,6 +510,11 @@
int32 /* put_offset */,
uint32 /* flush_count */)
+// Sends information about the latency of the current frame to the GPU
+// process.
+IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_SetLatencyInfo,
+ cc::LatencyInfo /* latency_info */)
+
// Asynchronously process any commands known to the GPU process. This is only
// used in the event that a channel is unscheduled and needs to be flushed
// again to process any commands issued subsequent to unscheduling. The GPU
@@ -531,14 +544,12 @@
uint32 /* size */)
// Create and initialize a hardware video decoder, returning its new route_id.
+// Created decoders should be freed with AcceleratedVideoDecoderMsg_Destroy when
+// no longer needed.
IPC_SYNC_MESSAGE_ROUTED1_1(GpuCommandBufferMsg_CreateVideoDecoder,
media::VideoCodecProfile /* profile */,
int /* route_id */)
-// Release all resources held by the named hardware video decoder.
-IPC_SYNC_MESSAGE_ROUTED1_0(GpuCommandBufferMsg_DestroyVideoDecoder,
- int /* route_id */)
-
// Tells the proxy that there was an error and the command buffer had to be
// destroyed for some reason.
IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_Destroyed,
@@ -625,7 +636,7 @@
IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderMsg_Reset)
// Send destroy request to the decoder.
-IPC_SYNC_MESSAGE_ROUTED0_0(AcceleratedVideoDecoderMsg_Destroy)
+IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderMsg_Destroy)
//------------------------------------------------------------------------------
// Accelerated Video Decoder Host Messages
diff --git a/content/common/gpu/image_transport_surface.cc b/content/common/gpu/image_transport_surface.cc
index 445f184..f8f0742 100644
--- a/content/common/gpu/image_transport_surface.cc
+++ b/content/common/gpu/image_transport_surface.cc
@@ -12,6 +12,7 @@
#include "content/common/gpu/gpu_channel_manager.h"
#include "content/common/gpu/gpu_command_buffer_stub.h"
#include "content/common/gpu/gpu_messages.h"
+#include "content/common/gpu/texture_image_transport_surface.h"
#include "gpu/command_buffer/service/gpu_scheduler.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_switches.h"
@@ -23,6 +24,21 @@
ImageTransportSurface::~ImageTransportSurface() {}
+scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface(
+ GpuChannelManager* manager,
+ GpuCommandBufferStub* stub,
+ const gfx::GLSurfaceHandle& handle) {
+ scoped_refptr<gfx::GLSurface> surface;
+ if (handle.transport_type == gfx::TEXTURE_TRANSPORT)
+ surface = new TextureImageTransportSurface(manager, stub, handle);
+ else
+ surface = CreateNativeSurface(manager, stub, handle);
+
+ if (!surface || !surface->Initialize())
+ return NULL;
+ return surface;
+}
+
ImageTransportHelper::ImageTransportHelper(ImageTransportSurface* surface,
GpuChannelManager* manager,
GpuCommandBufferStub* stub,
@@ -36,6 +52,10 @@
}
ImageTransportHelper::~ImageTransportHelper() {
+ if (stub_) {
+ stub_->SetLatencyInfoCallback(
+ base::Callback<void(const cc::LatencyInfo&)>());
+ }
manager_->RemoveRoute(route_id_);
}
@@ -48,6 +68,10 @@
decoder->SetResizeCallback(
base::Bind(&ImageTransportHelper::Resize, base::Unretained(this)));
+ stub_->SetLatencyInfoCallback(
+ base::Bind(&ImageTransportHelper::SetLatencyInfo,
+ base::Unretained(this)));
+
return true;
}
@@ -68,6 +92,7 @@
GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params) {
// TRACE_EVENT for gpu tests:
TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffers",
+ TRACE_EVENT_SCOPE_THREAD,
"GLImpl", static_cast<int>(gfx::GetGLImplementation()),
"width", params.size.width());
params.surface_id = stub_->surface_id();
@@ -102,6 +127,11 @@
interval));
}
+void ImageTransportHelper::SendLatencyInfo(
+ const cc::LatencyInfo& latency_info) {
+ manager_->Send(new GpuHostMsg_FrameDrawn(latency_info));
+}
+
void ImageTransportHelper::SetScheduled(bool is_scheduled) {
gpu::GpuScheduler* scheduler = Scheduler();
if (!scheduler)
@@ -141,13 +171,13 @@
}
gpu::GpuScheduler* ImageTransportHelper::Scheduler() {
- if (!stub_.get())
+ if (!stub_)
return NULL;
return stub_->scheduler();
}
gpu::gles2::GLES2Decoder* ImageTransportHelper::Decoder() {
- if (!stub_.get())
+ if (!stub_)
return NULL;
return stub_->decoder();
}
@@ -170,6 +200,11 @@
#endif
}
+void ImageTransportHelper::SetLatencyInfo(
+ const cc::LatencyInfo& latency_info) {
+ surface_->SetLatencyInfo(latency_info);
+}
+
PassThroughImageTransportSurface::PassThroughImageTransportSurface(
GpuChannelManager* manager,
GpuCommandBufferStub* stub,
@@ -206,9 +241,17 @@
return false;
}
+void PassThroughImageTransportSurface::SetLatencyInfo(
+ const cc::LatencyInfo& latency_info) {
+ latency_info_ = latency_info;
+}
+
bool PassThroughImageTransportSurface::SwapBuffers() {
- bool result = gfx::GLSurfaceAdapter::SwapBuffers();
+ // GetVsyncValues before SwapBuffers to work around Mali driver bug:
+ // crbug.com/223558.
SendVSyncUpdateIfAvailable();
+ bool result = gfx::GLSurfaceAdapter::SwapBuffers();
+ latency_info_.swap_timestamp = base::TimeTicks::HighResNow();
if (transport_) {
DCHECK(!is_swap_buffers_pending_);
@@ -218,16 +261,20 @@
// SwapBuffers message.
GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
params.surface_handle = 0;
+ params.latency_info = latency_info_;
params.size = surface()->GetSize();
helper_->SendAcceleratedSurfaceBuffersSwapped(params);
+ } else {
+ helper_->SendLatencyInfo(latency_info_);
}
return result;
}
bool PassThroughImageTransportSurface::PostSubBuffer(
int x, int y, int width, int height) {
- bool result = gfx::GLSurfaceAdapter::PostSubBuffer(x, y, width, height);
SendVSyncUpdateIfAvailable();
+ bool result = gfx::GLSurfaceAdapter::PostSubBuffer(x, y, width, height);
+ latency_info_.swap_timestamp = base::TimeTicks::HighResNow();
if (transport_) {
DCHECK(!is_swap_buffers_pending_);
@@ -237,6 +284,7 @@
// PostSubBuffer message.
GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params;
params.surface_handle = 0;
+ params.latency_info = latency_info_;
params.surface_size = surface()->GetSize();
params.x = x;
params.y = y;
@@ -245,6 +293,8 @@
helper_->SendAcceleratedSurfacePostSubBuffer(params);
helper_->SetScheduled(false);
+ } else {
+ helper_->SendLatencyInfo(latency_info_);
}
return result;
}
@@ -272,6 +322,7 @@
DCHECK(transport_);
Resize(new_size_);
+ TRACE_EVENT_ASYNC_END0("gpu", "OnResize", this);
helper_->SetScheduled(true);
}
@@ -281,6 +332,8 @@
if (transport_) {
helper_->SendResizeView(size);
helper_->SetScheduled(false);
+ TRACE_EVENT_ASYNC_BEGIN2("gpu", "OnResize", this,
+ "width", size.width(), "height", size.height());
} else {
Resize(new_size_);
}
diff --git a/content/common/gpu/image_transport_surface.h b/content/common/gpu/image_transport_surface.h
index b4b7a49..503a411 100644
--- a/content/common/gpu/image_transport_surface.h
+++ b/content/common/gpu/image_transport_surface.h
@@ -12,6 +12,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "cc/debug/latency_info.h"
#include "content/common/content_export.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_message.h"
@@ -63,12 +64,15 @@
const AcceleratedSurfaceMsg_BufferPresented_Params& params) = 0;
virtual void OnResizeViewACK() = 0;
virtual void OnResize(gfx::Size size) = 0;
+ virtual void SetLatencyInfo(
+ const cc::LatencyInfo& latency_info) = 0;
- // Creates the appropriate surface depending on the GL implementation.
- static scoped_refptr<gfx::GLSurface>
- CreateSurface(GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- const gfx::GLSurfaceHandle& handle);
+ // Creates a surface with the given attributes.
+ static scoped_refptr<gfx::GLSurface> CreateSurface(
+ GpuChannelManager* manager,
+ GpuCommandBufferStub* stub,
+ const gfx::GLSurfaceHandle& handle);
+
#if defined(OS_MACOSX)
CONTENT_EXPORT static void SetAllowOSMesaForTesting(bool allow);
#endif
@@ -79,6 +83,18 @@
virtual ~ImageTransportSurface();
private:
+ // Creates the appropriate native surface depending on the GL implementation.
+ // This will be implemented separately by each platform.
+ //
+ // This will not be called for texture transport surfaces which are
+ // cross-platform. The platform implementation should only create the
+ // surface and should not initialize it. On failure, a null scoped_refptr
+ // should be returned.
+ static scoped_refptr<gfx::GLSurface> CreateNativeSurface(
+ GpuChannelManager* manager,
+ GpuCommandBufferStub* stub,
+ const gfx::GLSurfaceHandle& handle);
+
DISALLOW_COPY_AND_ASSIGN(ImageTransportSurface);
};
@@ -111,6 +127,8 @@
void SendUpdateVSyncParameters(
base::TimeTicks timebase, base::TimeDelta interval);
+ void SendLatencyInfo(const cc::LatencyInfo& latency_info);
+
// Whether or not we should execute more commands.
void SetScheduled(bool is_scheduled);
@@ -142,6 +160,8 @@
// Backbuffer resize callback.
void Resize(gfx::Size size);
+ void SetLatencyInfo(const cc::LatencyInfo& latency_info);
+
// Weak pointers that point to objects that outlive this helper.
ImageTransportSurface* surface_;
GpuChannelManager* manager_;
@@ -178,6 +198,8 @@
virtual void OnResizeViewACK() OVERRIDE;
virtual void OnResize(gfx::Size size) OVERRIDE;
virtual gfx::Size GetSize() OVERRIDE;
+ virtual void SetLatencyInfo(
+ const cc::LatencyInfo& latency_info) OVERRIDE;
protected:
virtual ~PassThroughImageTransportSurface();
@@ -193,6 +215,7 @@
bool did_set_swap_interval_;
bool did_unschedule_;
bool is_swap_buffers_pending_;
+ cc::LatencyInfo latency_info_;
DISALLOW_COPY_AND_ASSIGN(PassThroughImageTransportSurface);
};
diff --git a/content/common/gpu/image_transport_surface_android.cc b/content/common/gpu/image_transport_surface_android.cc
index a497559..2d8ee43 100644
--- a/content/common/gpu/image_transport_surface_android.cc
+++ b/content/common/gpu/image_transport_surface_android.cc
@@ -5,45 +5,32 @@
#include "content/common/gpu/image_transport_surface.h"
#include "base/logging.h"
+#include "content/common/gpu/gpu_command_buffer_stub.h"
#include "content/common/gpu/gpu_surface_lookup.h"
-#include "content/common/gpu/texture_image_transport_surface.h"
#include "ui/gl/gl_surface_egl.h"
namespace content {
// static
-scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface(
+scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface(
GpuChannelManager* manager,
GpuCommandBufferStub* stub,
const gfx::GLSurfaceHandle& handle) {
- scoped_refptr<gfx::GLSurface> surface;
- if (handle.transport_type == gfx::TEXTURE_TRANSPORT) {
- surface = new TextureImageTransportSurface(manager, stub, handle);
- } else if (handle.transport_type == gfx::NATIVE_DIRECT) {
- DCHECK(GpuSurfaceLookup::GetInstance());
- ANativeWindow* window =
- GpuSurfaceLookup::GetInstance()->AcquireNativeWidget(
- stub->surface_id());
- surface = new gfx::NativeViewGLSurfaceEGL(false, window);
- bool initialize_success = surface->Initialize();
- if (window)
- ANativeWindow_release(window);
- if (!initialize_success)
- return NULL;
+ DCHECK(GpuSurfaceLookup::GetInstance());
+ DCHECK_EQ(handle.transport_type, gfx::NATIVE_DIRECT);
+ ANativeWindow* window =
+ GpuSurfaceLookup::GetInstance()->AcquireNativeWidget(
+ stub->surface_id());
+ scoped_refptr<gfx::GLSurface> surface =
+ new gfx::NativeViewGLSurfaceEGL(false, window);
+ bool initialize_success = surface->Initialize();
+ if (window)
+ ANativeWindow_release(window);
+ if (!initialize_success)
+ return scoped_refptr<gfx::GLSurface>();
- surface = new PassThroughImageTransportSurface(
- manager, stub, surface.get(), false);
- } else {
- NOTIMPLEMENTED();
- return NULL;
- }
-
- if (surface->Initialize()) {
- return surface;
- } else {
- LOG(ERROR) << "Failed to initialize ImageTransportSurface";
- return NULL;
- }
+ return scoped_refptr<gfx::GLSurface>(new PassThroughImageTransportSurface(
+ manager, stub, surface.get(), false));
}
} // namespace content
diff --git a/content/common/gpu/image_transport_surface_linux.cc b/content/common/gpu/image_transport_surface_linux.cc
deleted file mode 100644
index b9a97db..0000000
--- a/content/common/gpu/image_transport_surface_linux.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/common/gpu/image_transport_surface.h"
-
-#include "content/common/gpu/texture_image_transport_surface.h"
-
-namespace content {
-
-// static
-scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface(
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- const gfx::GLSurfaceHandle& handle) {
- scoped_refptr<gfx::GLSurface> surface;
- if (handle.transport_type == gfx::TEXTURE_TRANSPORT) {
- DCHECK(!handle.handle);
- surface = new TextureImageTransportSurface(manager, stub, handle);
- } else {
- DCHECK(handle.handle);
- DCHECK(handle.transport_type == gfx::NATIVE_DIRECT ||
- handle.transport_type == gfx::NATIVE_TRANSPORT);
- surface = gfx::GLSurface::CreateViewGLSurface(false, handle.handle);
- if (!surface.get())
- return NULL;
- surface = new PassThroughImageTransportSurface(manager,
- stub,
- surface.get(),
- handle.is_transport());
- }
-
- if (surface->Initialize())
- return surface;
- else
- return NULL;
-}
-
-} // namespace content
diff --git a/content/common/gpu/image_transport_surface_mac.cc b/content/common/gpu/image_transport_surface_mac.cc
index 22a7460..62c3265 100644
--- a/content/common/gpu/image_transport_surface_mac.cc
+++ b/content/common/gpu/image_transport_surface_mac.cc
@@ -7,7 +7,6 @@
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/gpu/gpu_messages.h"
-#include "content/common/gpu/texture_image_transport_surface.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
@@ -61,6 +60,7 @@
const AcceleratedSurfaceMsg_BufferPresented_Params& params) OVERRIDE;
virtual void OnResizeViewACK() OVERRIDE;
virtual void OnResize(gfx::Size size) OVERRIDE;
+ virtual void SetLatencyInfo(const cc::LatencyInfo&) OVERRIDE;
private:
virtual ~IOSurfaceImageTransportSurface() OVERRIDE;
@@ -96,6 +96,8 @@
// Whether we unscheduled command buffer because of pending SwapBuffers.
bool did_unschedule_;
+ cc::LatencyInfo latency_info_;
+
scoped_ptr<ImageTransportHelper> helper_;
DISALLOW_COPY_AND_ASSIGN(IOSurfaceImageTransportSurface);
@@ -215,7 +217,7 @@
io_surface_.get()) {
UnrefIOSurface();
helper_->Suspend();
- } else if (backbuffer_suggested_allocation_ && !io_surface_.get()) {
+ } else if (backbuffer_suggested_allocation_ && !io_surface_) {
CreateIOSurface();
}
}
@@ -229,6 +231,7 @@
GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
params.surface_handle = io_surface_handle_;
params.size = GetSize();
+ params.latency_info = latency_info_;
helper_->SendAcceleratedSurfaceBuffersSwapped(params);
DCHECK(!is_swap_buffers_pending_);
@@ -250,6 +253,7 @@
params.width = width;
params.height = height;
params.surface_size = GetSize();
+ params.latency_info = latency_info_;
helper_->SendAcceleratedSurfacePostSubBuffer(params);
DCHECK(!is_swap_buffers_pending_);
@@ -298,6 +302,11 @@
CreateIOSurface();
}
+void IOSurfaceImageTransportSurface::SetLatencyInfo(
+ const cc::LatencyInfo& latency_info) {
+ latency_info_ = latency_info;
+}
+
void IOSurfaceImageTransportSurface::UnrefIOSurface() {
// If we have resources to destroy, then make sure that we have a current
// context which we can use to delete the resources.
@@ -437,49 +446,37 @@
} // namespace
// static
-scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface(
+scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface(
GpuChannelManager* manager,
GpuCommandBufferStub* stub,
const gfx::GLSurfaceHandle& surface_handle) {
- scoped_refptr<gfx::GLSurface> surface;
- if (surface_handle.transport_type == gfx::TEXTURE_TRANSPORT) {
- surface = new TextureImageTransportSurface(manager, stub, surface_handle);
- } else {
- DCHECK(surface_handle.transport_type == gfx::NATIVE_TRANSPORT);
- IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
+ DCHECK(surface_handle.transport_type == gfx::NATIVE_TRANSPORT);
+ IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
- switch (gfx::GetGLImplementation()) {
- case gfx::kGLImplementationDesktopGL:
- case gfx::kGLImplementationAppleGL:
- if (!io_surface_support) {
- DLOG(WARNING) << "No IOSurface support";
- return NULL;
- } else {
- surface = new IOSurfaceImageTransportSurface(
- manager, stub, surface_handle.handle);
- }
- break;
- default:
- // Content shell in DRT mode spins up a gpu process which needs an
- // image transport surface, but that surface isn't used to read pixel
- // baselines. So this is mostly a dummy surface.
- if (g_allow_os_mesa) {
- surface = new DRTSurfaceOSMesa();
- if (!surface || !surface->Initialize())
- return NULL;
+ switch (gfx::GetGLImplementation()) {
+ case gfx::kGLImplementationDesktopGL:
+ case gfx::kGLImplementationAppleGL:
+ if (!io_surface_support) {
+ DLOG(WARNING) << "No IOSurface support";
+ return scoped_refptr<gfx::GLSurface>();
+ }
+ return scoped_refptr<gfx::GLSurface>(new IOSurfaceImageTransportSurface(
+ manager, stub, surface_handle.handle));
- surface = new PassThroughImageTransportSurface(
- manager, stub, surface.get(), /*is_transport=*/false);
- } else {
- NOTREACHED();
- return NULL;
- }
- }
+ default:
+ // Content shell in DRT mode spins up a gpu process which needs an
+ // image transport surface, but that surface isn't used to read pixel
+ // baselines. So this is mostly a dummy surface.
+ if (!g_allow_os_mesa) {
+ NOTREACHED();
+ return scoped_refptr<gfx::GLSurface>();
+ }
+ scoped_refptr<gfx::GLSurface> surface(new DRTSurfaceOSMesa());
+ if (!surface || !surface->Initialize())
+ return surface;
+ return scoped_refptr<gfx::GLSurface>(new PassThroughImageTransportSurface(
+ manager, stub, surface.get(), false));
}
- if (surface->Initialize())
- return surface;
- else
- return NULL;
}
// static
diff --git a/content/common/gpu/image_transport_surface_win.cc b/content/common/gpu/image_transport_surface_win.cc
index 479eeb4..5e27ba0 100644
--- a/content/common/gpu/image_transport_surface_win.cc
+++ b/content/common/gpu/image_transport_surface_win.cc
@@ -12,7 +12,6 @@
#include "base/win/windows_version.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/public/common/content_switches.h"
-#include "content/common/gpu/texture_image_transport_surface.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
@@ -49,6 +48,7 @@
const AcceleratedSurfaceMsg_BufferPresented_Params& params) OVERRIDE;
virtual void OnResizeViewACK() OVERRIDE;
virtual void OnResize(gfx::Size size) OVERRIDE;
+ virtual void SetLatencyInfo(const cc::LatencyInfo&) OVERRIDE;
virtual gfx::Size GetSize() OVERRIDE;
private:
@@ -69,6 +69,8 @@
// Size to resize to when the surface becomes visible.
gfx::Size visible_size_;
+ cc::LatencyInfo latency_info_;
+
scoped_ptr<ImageTransportHelper> helper_;
DISALLOW_COPY_AND_ASSIGN(PbufferImageTransportSurface);
@@ -196,6 +198,7 @@
params.surface_handle = reinterpret_cast<int64>(GetShareHandle());
CHECK(params.surface_handle);
params.size = GetSize();
+ params.latency_info = latency_info_;
helper_->SendAcceleratedSurfaceBuffersSwapped(params);
@@ -226,6 +229,11 @@
visible_size_ = size;
}
+void PbufferImageTransportSurface::SetLatencyInfo(
+ const cc::LatencyInfo& latency_info) {
+ latency_info_ = latency_info;
+}
+
gfx::Size PbufferImageTransportSurface::GetSize() {
return GLSurfaceAdapter::GetSize();
}
@@ -233,57 +241,39 @@
} // namespace anonymous
// static
-scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface(
+scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface(
GpuChannelManager* manager,
GpuCommandBufferStub* stub,
const gfx::GLSurfaceHandle& handle) {
- scoped_refptr<gfx::GLSurface> surface;
-
- if (handle.transport_type == gfx::TEXTURE_TRANSPORT) {
- // If we don't have a valid handle with the transport flag set, then we're
- // coming from a renderer and we want to render the webpage contents to a
- // texture.
- DCHECK(!handle.handle);
- surface = new TextureImageTransportSurface(manager, stub, handle);
- } else {
- DCHECK(handle.handle);
- DCHECK(handle.transport_type == gfx::NATIVE_DIRECT ||
- handle.transport_type == gfx::NATIVE_TRANSPORT);
- if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
- !CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableImageTransportSurface)) {
- // This path handles two different cases.
- //
- // For post-Vista regular Windows, this surface will be used for
- // renderer compositors.
- //
- // For Aura Windows, this will be the surface for the browser compositor
- // (and the renderer compositors surface's will be
- // TextureImageTransportSurface above).
- const char* extensions = eglQueryString(
- eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_EXTENSIONS);
- if (strstr(extensions, "EGL_ANGLE_query_surface_pointer") &&
- strstr(extensions, "EGL_ANGLE_surface_d3d_texture_2d_share_handle")) {
- surface = new PbufferImageTransportSurface(manager, stub);
- }
- }
-
- if (!surface.get()) {
- surface = gfx::GLSurface::CreateViewGLSurface(false, handle.handle);
- if (!surface.get())
- return NULL;
-
- surface = new PassThroughImageTransportSurface(manager,
- stub,
- surface.get(),
- handle.is_transport());
+ DCHECK(handle.handle);
+ DCHECK(handle.transport_type == gfx::NATIVE_DIRECT ||
+ handle.transport_type == gfx::NATIVE_TRANSPORT);
+ if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
+ !CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableImageTransportSurface)) {
+ // This path handles two different cases.
+ //
+ // For post-Vista regular Windows, this surface will be used for
+ // renderer compositors.
+ //
+ // For Aura Windows, this will be the surface for the browser compositor
+ // (and the renderer compositors surface's will be
+ // TextureImageTransportSurface above).
+ const char* extensions = eglQueryString(
+ eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_EXTENSIONS);
+ if (strstr(extensions, "EGL_ANGLE_query_surface_pointer") &&
+ strstr(extensions, "EGL_ANGLE_surface_d3d_texture_2d_share_handle")) {
+ return scoped_refptr<gfx::GLSurface>(
+ new PbufferImageTransportSurface(manager, stub));
}
}
- if (surface->Initialize())
+ scoped_refptr<gfx::GLSurface> surface =
+ gfx::GLSurface::CreateViewGLSurface(false, handle.handle);
+ if (!surface)
return surface;
- else
- return NULL;
+ return scoped_refptr<gfx::GLSurface>(new PassThroughImageTransportSurface(
+ manager, stub, surface.get(), handle.is_transport()));
}
} // namespace content
diff --git a/content/common/gpu/image_transport_surface_x11.cc b/content/common/gpu/image_transport_surface_x11.cc
new file mode 100644
index 0000000..b6aca42
--- /dev/null
+++ b/content/common/gpu/image_transport_surface_x11.cc
@@ -0,0 +1,25 @@
+// 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/common/gpu/image_transport_surface.h"
+
+namespace content {
+
+// static
+scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface(
+ GpuChannelManager* manager,
+ GpuCommandBufferStub* stub,
+ const gfx::GLSurfaceHandle& handle) {
+ DCHECK(handle.handle);
+ DCHECK(handle.transport_type == gfx::NATIVE_DIRECT ||
+ handle.transport_type == gfx::NATIVE_TRANSPORT);
+ scoped_refptr<gfx::GLSurface> surface =
+ gfx::GLSurface::CreateViewGLSurface(false, handle.handle);
+ if (!surface)
+ return surface;
+ return scoped_refptr<gfx::GLSurface>(new PassThroughImageTransportSurface(
+ manager, stub, surface.get(), handle.is_transport()));
+}
+
+} // namespace content
diff --git a/content/common/gpu/media/android_video_decode_accelerator.cc b/content/common/gpu/media/android_video_decode_accelerator.cc
index 3e4dacd..4d65c61 100644
--- a/content/common/gpu/media/android_video_decode_accelerator.cc
+++ b/content/common/gpu/media/android_video_decode_accelerator.cc
@@ -7,28 +7,28 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop.h"
-#include "content/common/android/scoped_java_surface.h"
#include "content/common/gpu/gpu_channel.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "media/base/bitstream_buffer.h"
#include "media/base/limits.h"
#include "media/video/picture.h"
+#include "ui/gl/android/scoped_java_surface.h"
#include "ui/gl/gl_bindings.h"
namespace content {
// Helper macros for dealing with failure. If |result| evaluates false, emit
// |log| to ERROR, register |error| with the decoder, and return.
-#define RETURN_ON_FAILURE(result, log, error) \
- do { \
- if (!(result)) { \
- DLOG(ERROR) << log; \
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind( \
- &AndroidVideoDecodeAccelerator::NotifyError, \
- base::AsWeakPtr(this), error)); \
- state_ = ERROR; \
- return; \
- } \
+#define RETURN_ON_FAILURE(result, log, error) \
+ do { \
+ if (!(result)) { \
+ DLOG(ERROR) << log; \
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( \
+ &AndroidVideoDecodeAccelerator::NotifyError, \
+ base::AsWeakPtr(this), error)); \
+ state_ = ERROR; \
+ return; \
+ } \
} while (0)
// TODO(dwkang): We only need kMaxVideoFrames to pass media stack's prerolling
@@ -50,7 +50,7 @@
const base::Callback<bool(void)>& make_context_current)
: client_(client),
make_context_current_(make_context_current),
- codec_(media::MediaCodecBridge::VIDEO_H264),
+ codec_(media::kCodecH264),
state_(NO_ERROR),
surface_texture_id_(0),
picturebuffers_requested_(false),
@@ -73,7 +73,7 @@
return false;
if (profile == media::VP8PROFILE_MAIN) {
- codec_ = media::MediaCodecBridge::VIDEO_VP8;
+ codec_ = media::kCodecVP8;
} else {
// TODO(dwkang): enable H264 once b/8125974 is fixed.
LOG(ERROR) << "Unsupported profile: " << profile;
@@ -85,7 +85,7 @@
return false;
}
- if (!gl_decoder_.get()) {
+ if (!gl_decoder_) {
LOG(ERROR) << "Failed to get gles2 decoder instance.";
return false;
}
@@ -102,11 +102,11 @@
gl_decoder_->RestoreTextureUnitBindings(0);
gl_decoder_->RestoreActiveTexture();
- surface_texture_ = new SurfaceTextureBridge(surface_texture_id_);
+ surface_texture_ = new gfx::SurfaceTextureBridge(surface_texture_id_);
ConfigureMediaCodec();
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&AndroidVideoDecodeAccelerator::NotifyInitializeDone,
base::AsWeakPtr(this)));
return true;
@@ -126,7 +126,7 @@
io_task_is_posted_ = true;
// TODO(dwkang): PostDelayedTask() does not guarantee the task will awake
// at the exact time. Need a better way for polling.
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(
&AndroidVideoDecodeAccelerator::DoIOTask, base::AsWeakPtr(this)),
@@ -187,7 +187,7 @@
// keep getting more bitstreams from the client, and throttle them by using
// |bitstreams_notified_in_advance_|.
// TODO(dwkang): check if there is a way to remove this workaround.
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
base::AsWeakPtr(this), bitstream_buffer.id()));
bitstreams_notified_in_advance_.push_back(bitstream_buffer.id());
@@ -223,7 +223,7 @@
if (!picturebuffers_requested_) {
picturebuffers_requested_ = true;
size_ = gfx::Size(width, height);
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&AndroidVideoDecodeAccelerator::RequestPictureBuffers,
base::AsWeakPtr(this)));
} else {
@@ -248,7 +248,7 @@
media_codec_->ReleaseOutputBuffer(buf_index, true);
if (eos) {
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&AndroidVideoDecodeAccelerator::NotifyFlushDone,
base::AsWeakPtr(this)));
decoder_met_eos_ = true;
@@ -319,7 +319,7 @@
picture_buffer_texture_id, 0, size_.width(),
size_.height(), false, false, false);
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&AndroidVideoDecodeAccelerator::NotifyPictureReady,
base::AsWeakPtr(this), media::Picture(picture_buffer_id, bitstream_id)));
}
@@ -328,7 +328,7 @@
const media::BitstreamBuffer& bitstream_buffer) {
DCHECK(thread_checker_.CalledOnValidThread());
if (bitstream_buffer.id() != -1 && bitstream_buffer.size() == 0) {
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
base::AsWeakPtr(this), bitstream_buffer.id()));
return;
@@ -379,13 +379,13 @@
void AndroidVideoDecodeAccelerator::ConfigureMediaCodec() {
DCHECK(surface_texture_.get());
- media_codec_.reset(new media::MediaCodecBridge(codec_));
+ media_codec_.reset(new media::VideoCodecBridge(codec_));
- ScopedJavaSurface surface(surface_texture_.get());
+ gfx::ScopedJavaSurface surface(surface_texture_.get());
// VDA does not pass the container indicated resolution in the initialization
// phase. Here, we set 720p by default.
// TODO(dwkang): find out a way to remove the following hard-coded value.
- media_codec_->StartVideo(
+ media_codec_->Start(
codec_, gfx::Size(1280, 720), surface.j_surface().obj());
media_codec_->GetOutputBuffers();
}
@@ -399,7 +399,7 @@
pending_bitstream_buffers_.pop();
if (bitstream_buffer.id() != -1) {
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
base::AsWeakPtr(this), bitstream_buffer.id()));
}
@@ -418,7 +418,7 @@
num_bytes_used_in_the_pending_buffer_ = 0;
state_ = NO_ERROR;
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&AndroidVideoDecodeAccelerator::NotifyResetDone, base::AsWeakPtr(this)));
}
diff --git a/content/common/gpu/media/android_video_decode_accelerator.h b/content/common/gpu/media/android_video_decode_accelerator.h
index 6ddd7f0..e892999 100644
--- a/content/common/gpu/media/android_video_decode_accelerator.h
+++ b/content/common/gpu/media/android_video_decode_accelerator.h
@@ -20,9 +20,11 @@
#include "media/base/android/media_codec_bridge.h"
#include "media/video/video_decode_accelerator.h"
-namespace content {
-
+namespace gfx {
class SurfaceTextureBridge;
+}
+
+namespace content {
// A VideoDecodeAccelerator implementation for Android.
// This class decodes the input encoded stream by using Android's MediaCodec
@@ -107,7 +109,7 @@
base::Callback<bool(void)> make_context_current_;
// Codec type. Used when we configure media codec.
- media::MediaCodecBridge::Codec codec_;
+ media::VideoCodec codec_;
// The current state of this class. For now, this is used only for setting
// error state.
@@ -123,10 +125,10 @@
std::queue<int32> free_picture_ids_;
// The low-level decoder which Android SDK provides.
- scoped_ptr<media::MediaCodecBridge> media_codec_;
+ scoped_ptr<media::VideoCodecBridge> media_codec_;
// A container of texture. Used to set a texture to |media_codec_|.
- scoped_refptr<SurfaceTextureBridge> surface_texture_;
+ scoped_refptr<gfx::SurfaceTextureBridge> surface_texture_;
// The texture id which is set to |surface_texture_|.
uint32 surface_texture_id_;
diff --git a/content/common/gpu/media/avc_config_record_builder.cc b/content/common/gpu/media/avc_config_record_builder.cc
deleted file mode 100644
index df0abe7..0000000
--- a/content/common/gpu/media/avc_config_record_builder.cc
+++ /dev/null
@@ -1,155 +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/common/gpu/media/avc_config_record_builder.h"
-
-#include <limits>
-
-#include "base/logging.h"
-#include "content/common/gpu/media/h264_parser.h"
-
-namespace content {
-
-AVCConfigRecordBuilder::AVCConfigRecordBuilder()
- : sps_profile_idc_(0),
- sps_constraint_setx_flag_(0),
- sps_level_idc_(0),
- coded_width_(0),
- coded_height_(0) {
-}
-
-AVCConfigRecordBuilder::~AVCConfigRecordBuilder() {
-}
-
-bool AVCConfigRecordBuilder::ProcessNALU(
- H264Parser* parser,
- const H264NALU& nalu,
- std::vector<uint8>* config_record) {
- if (nalu.nal_unit_type == H264NALU::kSPS) {
- return ProcessSPS(parser, nalu);
- } else if (nalu.nal_unit_type == H264NALU::kPPS) {
- return ProcessPPS(parser, nalu);
- } else if (nalu.nal_unit_type >= 1 && nalu.nal_unit_type <= 5) {
- // Ready to build the AVC decoder configuration record once the first slice
- // type is encountered.
- return BuildConfigRecord(config_record);
- }
- // Effectively skip this NALU by returning success.
- return true;
-}
-
-bool AVCConfigRecordBuilder::BuildConfigRecord(
- std::vector<uint8>* config_record) {
- // 5 bytes for AVC record header. 1 byte for the number of SPS units.
- // 1 byte for the number of PPS units.
- size_t record_size = 7;
- for (NALUVector::const_iterator it = sps_nalus_.begin();
- it != sps_nalus_.end(); ++it) {
- // Plus 2 bytes to store the SPS size.
- size_t size = (*it)->size() + 2;
- if (std::numeric_limits<size_t>::max() - size <= record_size)
- return false;
- record_size += size;
- }
- for (NALUVector::const_iterator it = pps_nalus_.begin();
- it != pps_nalus_.end(); ++it) {
- // Plus 2 bytes to store the PPS size.
- size_t size = (*it)->size() + 2;
- if (std::numeric_limits<size_t>::max() - size <= record_size)
- return false;
- record_size += size;
- }
- std::vector<uint8> extra_data(record_size);
-
- // AVC decoder configuration record version.
- extra_data[0] = 0x01;
- // Profile.
- extra_data[1] = sps_profile_idc_ & 0xff;
- // Profile compatibility, must match the byte between profile IDC
- // and level IDC in the SPS.
- extra_data[2] = sps_constraint_setx_flag_;
- // AVC level.
- extra_data[3] = sps_level_idc_ & 0xff;
-
- // TODO(sail): There's no way to get the NALU length field size from the
- // SPS and PPS data. Just assume 4 for now.
- const size_t kNALULengthFieldSize = 4;
-
- // The first 6 bits are reserved and must be 1. Last two bits are the
- // NALU field size minus 1.
- extra_data[4] = 0xfc | ((kNALULengthFieldSize - 1) & 0x03);
-
- // The first 3 bits are reserved and must be 1. Last 5 bits are the
- // number of SPS units.
- extra_data[5] = 0xe0 | (sps_nalus_.size() & 0x1f);
- size_t index = 6;
- if (!sps_nalus_.empty())
- index += CopyNALUsToConfigRecord(sps_nalus_, &extra_data[index]);
-
- // The number of PPS units.
- extra_data[index++] = pps_nalus_.size() & 0xff;
- if (!pps_nalus_.empty())
- CopyNALUsToConfigRecord(pps_nalus_, &extra_data[index]);
-
- *config_record = extra_data;
- return true;
-}
-
-size_t AVCConfigRecordBuilder::CopyNALUsToConfigRecord(const NALUVector& nalus,
- uint8* record_buffer) {
- size_t index = 0;
- for (NALUVector::const_iterator it = nalus.begin();
- it != nalus.end(); ++it) {
- // High byte of the NALU size.
- record_buffer[index++] = ((*it)->size() >> 8) & 0xff;
- // Low byte of the NALU size.
- record_buffer[index++] = (*it)->size() & 0xff;
- // The NALU data.
- memcpy(record_buffer + index, (*it)->front(), (*it)->size());
- index += (*it)->size();
- }
- return index;
-}
-
-bool AVCConfigRecordBuilder::ProcessSPS(H264Parser* parser,
- const H264NALU& nalu) {
- int sps_id = 0;
- H264Parser::Result result = parser->ParseSPS(&sps_id);
- if (result != H264Parser::kOk)
- return false;
-
- std::vector<uint8> bytes(nalu.data, nalu.data + nalu.size);
- sps_nalus_.push_back(base::RefCountedBytes::TakeVector(&bytes));
-
- const H264SPS* sps = parser->GetSPS(sps_id);
-
- // Use the last width and height that are encountered.
- coded_width_ = (sps->pic_width_in_mbs_minus1 + 1) * 16;
- if (sps->frame_mbs_only_flag)
- coded_height_ = (sps->pic_height_in_map_units_minus1 + 1) * 16;
- else
- coded_height_ = (sps->pic_height_in_map_units_minus1 + 1) * 32;
-
- // Use the last video profile and flags that are encountered.
- sps_profile_idc_ = sps->profile_idc;
- sps_constraint_setx_flag_ = sps->constraint_setx_flag;
- // Use the largest AVC level that's encountered.
- sps_level_idc_ = std::max(sps_level_idc_, sps->level_idc);
-
- return true;
-}
-
-bool AVCConfigRecordBuilder::ProcessPPS(H264Parser* parser,
- const H264NALU& nalu) {
- int pps_id = 0;
- H264Parser::Result result = parser->ParsePPS(&pps_id);
- if (result != H264Parser::kOk)
- return false;
-
- std::vector<uint8> bytes(nalu.data, nalu.data + nalu.size);
- pps_nalus_.push_back(base::RefCountedBytes::TakeVector(&bytes));
- return true;
-}
-
-} // namespace content
diff --git a/content/common/gpu/media/avc_config_record_builder.h b/content/common/gpu/media/avc_config_record_builder.h
deleted file mode 100644
index 3214244..0000000
--- a/content/common/gpu/media/avc_config_record_builder.h
+++ /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.
-
-#ifndef CONTENT_COMMON_GPU_MEDIA_AVC_CONFIG_RECORD_BUILDER_H_
-#define CONTENT_COMMON_GPU_MEDIA_AVC_CONFIG_RECORD_BUILDER_H_
-
-#include <vector>
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/ref_counted_memory.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-struct H264NALU;
-class H264Parser;
-
-// Utility class to build an AVC configuration record given a stream of NALUs
-// containing SPS and PPS data.
-class CONTENT_EXPORT AVCConfigRecordBuilder {
- public:
- AVCConfigRecordBuilder();
- ~AVCConfigRecordBuilder();
-
- // Processes the given NALU. If the final AVC decoder configuration record
- // can be built then the NALU is not consumed and the record is returned
- // in |config_record|. Otherwise the NALU is consumed and |config_record|
- // is not modified. Returns true on success, false on failure.
- bool ProcessNALU(H264Parser* parser,
- const H264NALU& nalu,
- std::vector<uint8>* config_record);
-
- int coded_width() const { return coded_width_; }
- int coded_height() const { return coded_height_; }
-
- private:
- typedef std::vector<scoped_refptr<base::RefCountedBytes> > NALUVector;
-
- bool ProcessSPS(H264Parser* parser, const H264NALU& nalu);
- bool ProcessPPS(H264Parser* parser, const H264NALU& nalu);
- bool BuildConfigRecord(std::vector<uint8>* config_record);
-
- // Copies data from |nalus| into |record_buffer|. Returns the number of bytes
- // that were written.
- size_t CopyNALUsToConfigRecord(const NALUVector& nalus, uint8* record_buffer);
-
- // Data for each SPS.
- NALUVector sps_nalus_;
- // Data for each PPS.
- NALUVector pps_nalus_;
- // The video codec profile stored in the SPS.
- int sps_profile_idc_;
- // The constraint setx flags stored in the SPS.
- int sps_constraint_setx_flag_;
- // The avc level stored in the SPS.
- int sps_level_idc_;
- // The width of the video as enocded in the SPS.
- uint32 coded_width_;
- // The height of the video as enocded in the SPS.
- uint32 coded_height_;
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_MEDIA_AVC_CONFIG_RECORD_BUILDER_H_
diff --git a/content/common/gpu/media/avc_config_record_builder_unittest.cc b/content/common/gpu/media/avc_config_record_builder_unittest.cc
deleted file mode 100644
index 150adca..0000000
--- a/content/common/gpu/media/avc_config_record_builder_unittest.cc
+++ /dev/null
@@ -1,92 +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/common/gpu/media/avc_config_record_builder.h"
-
-#include "content/common/gpu/media/h264_parser.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-const uint8 kSPSData[] = {
- 0x67, 0x64, 0x00, 0x1f, 0xac, 0x34, 0xec, 0x05,
- 0x00, 0x5b, 0xa1, 0x00, 0x00, 0x03, 0x00, 0x01,
- 0x00, 0x00, 0x03, 0x00, 0x32, 0x0f, 0x18, 0x31,
- 0x38,
-};
-
-const uint8 kPPSData[] = {
- 0x68, 0xef, 0xb2, 0xc8, 0xb0,
-};
-
-const uint8 kNALUHeader[] = {
- 0x00, 0x00, 0x00, 0x01
-};
-
-} // namespace
-
-TEST(AVCConfigRecordBuilderTest, BuildConfig) {
- std::vector<uint8> stream;
- stream.insert(stream.end(), kNALUHeader,
- kNALUHeader + arraysize(kNALUHeader));
- stream.insert(stream.end(), kSPSData, kSPSData + arraysize(kSPSData));
- stream.insert(stream.end(), kNALUHeader,
- kNALUHeader + arraysize(kNALUHeader));
- stream.insert(stream.end(), kPPSData, kPPSData + arraysize(kPPSData));
-
- content::H264Parser parser;
- parser.SetStream(&stream[0], stream.size());
- content::H264NALU nalu;
- ASSERT_EQ(parser.AdvanceToNextNALU(&nalu), content::H264Parser::kOk);
-
- content::AVCConfigRecordBuilder config;
- std::vector<uint8> config_data;
- EXPECT_TRUE(config.ProcessNALU(&parser, nalu, &config_data));
- EXPECT_TRUE(config_data.empty());
-
- ASSERT_EQ(parser.AdvanceToNextNALU(&nalu), content::H264Parser::kOk);
-
- EXPECT_TRUE(config.ProcessNALU(&parser, nalu, &config_data));
- EXPECT_TRUE(config_data.empty());
-
- nalu.nal_unit_type = content::H264NALU::kIDRSlice;
- EXPECT_TRUE(config.ProcessNALU(&parser, nalu, &config_data));
- EXPECT_FALSE(config_data.empty());
- EXPECT_EQ(config.coded_width(), 1280);
- EXPECT_EQ(config.coded_height(), 720);
-
- const uint8 kExpectedData[] = {
- 0x01, 0x64, 0x00, 0x1f, 0xff, 0xe1, 0x00, 0x19,
- 0x67, 0x64, 0x00, 0x1f, 0xac, 0x34, 0xec, 0x05,
- 0x00, 0x5b, 0xa1, 0x00, 0x00, 0x03, 0x00, 0x01,
- 0x00, 0x00, 0x03, 0x00, 0x32, 0x0f, 0x18, 0x31,
- 0x38, 0x01, 0x00, 0x05, 0x68, 0xef, 0xb2, 0xc8,
- 0xb0,
- };
- std::vector<uint8> expected_config_data(
- kExpectedData, kExpectedData + arraysize(kExpectedData));
- EXPECT_EQ(config_data, expected_config_data);
-}
-
-// Test building a config record with zero SPS and PPS data.
-TEST(AVCConfigRecordBuilderTest, EmptyConfig) {
- content::AVCConfigRecordBuilder config;
- content::H264Parser parser;
- std::vector<uint8> config_data;
-
- // Feed the builder a slice right away.
- content::H264NALU nalu;
- nalu.nal_unit_type = content::H264NALU::kIDRSlice;
- EXPECT_TRUE(config.ProcessNALU(&parser, nalu, &config_data));
- EXPECT_FALSE(config_data.empty());
- EXPECT_EQ(config.coded_width(), 0);
- EXPECT_EQ(config.coded_height(), 0);
-
- const uint8 kExpectedData[] = {
- 0x01, 0x0, 0x00, 0x0, 0xff, 0xe0, 0x00,
- };
- std::vector<uint8> expected_config_data(
- kExpectedData, kExpectedData + arraysize(kExpectedData));
- EXPECT_EQ(config_data, expected_config_data);
-}
diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.cc b/content/common/gpu/media/dxva_video_decode_accelerator.cc
index ad79c51..1d14852 100644
--- a/content/common/gpu/media/dxva_video_decode_accelerator.cc
+++ b/content/common/gpu/media/dxva_video_decode_accelerator.cc
@@ -498,7 +498,7 @@
PLATFORM_FAILURE, false);
state_ = kNormal;
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&DXVAVideoDecodeAccelerator::NotifyInitializeDone,
base::AsWeakPtr(this)));
return true;
@@ -531,6 +531,9 @@
RETURN_AND_NOTIFY_ON_FAILURE((state_ != kUninitialized),
"Invalid state: " << state_, ILLEGAL_STATE,);
+ RETURN_AND_NOTIFY_ON_FAILURE((kNumPictureBuffers == buffers.size()),
+ "Failed to provide requested picture buffers. (Got " << buffers.size() <<
+ ", requested " << kNumPictureBuffers << ")", INVALID_ARGUMENT,);
// Copy the picture buffers provided by the client to the available list,
// and mark these buffers as available for use.
@@ -604,7 +607,7 @@
RETURN_AND_NOTIFY_ON_FAILURE(SendMFTMessage(MFT_MESSAGE_COMMAND_FLUSH, 0),
"Reset: Failed to send message.", PLATFORM_FAILURE,);
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&DXVAVideoDecodeAccelerator::NotifyResetDone, base::AsWeakPtr(this)));
state_ = DXVAVideoDecodeAccelerator::kNormal;
@@ -875,7 +878,7 @@
RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false);
// Go ahead and request picture buffers.
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&DXVAVideoDecodeAccelerator::RequestPictureBuffers,
base::AsWeakPtr(this), surface_desc.Width, surface_desc.Height));
@@ -916,7 +919,7 @@
media::Picture output_picture(index->second->id(),
sample_info.input_buffer_id);
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&DXVAVideoDecodeAccelerator::NotifyPictureReady,
base::AsWeakPtr(this), output_picture));
@@ -926,7 +929,7 @@
}
if (!pending_input_buffers_.empty() && pending_output_samples_.empty()) {
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers,
base::AsWeakPtr(this)));
}
@@ -1037,7 +1040,7 @@
return;
}
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&DXVAVideoDecodeAccelerator::NotifyFlushDone, base::AsWeakPtr(this)));
state_ = kNormal;
@@ -1109,7 +1112,7 @@
// decoder to emit an output packet for every input packet.
// http://code.google.com/p/chromium/issues/detail?id=108121
// http://code.google.com/p/chromium/issues/detail?id=150925
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&DXVAVideoDecodeAccelerator::NotifyInputBufferRead,
base::AsWeakPtr(this), input_buffer_id));
}
diff --git a/content/common/gpu/media/exynos_video_decode_accelerator.cc b/content/common/gpu/media/exynos_video_decode_accelerator.cc
index 43089b9..697ddd6 100644
--- a/content/common/gpu/media/exynos_video_decode_accelerator.cc
+++ b/content/common/gpu/media/exynos_video_decode_accelerator.cc
@@ -220,6 +220,7 @@
mfc_output_streamon_(false),
mfc_output_buffer_queued_count_(0),
mfc_output_buffer_pixelformat_(0),
+ mfc_output_dpb_size_(0),
gsc_fd_(-1),
gsc_input_streamon_(false),
gsc_input_buffer_queued_count_(0),
@@ -427,7 +428,9 @@
DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
if (buffers.size() != gsc_output_buffer_map_.size()) {
- DLOG(ERROR) << "AssignPictureBuffers(): invalid buffer count";
+ DLOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture"
+ " buffers. (Got " << buffers.size() << ", requested " <<
+ gsc_output_buffer_map_.size() << ")";
NOTIFY_ERROR(INVALID_ARGUMENT);
return;
}
@@ -597,7 +600,7 @@
void ExynosVideoDecodeAccelerator::DecodeTask(
scoped_ptr<BitstreamBufferRef> bitstream_record) {
DVLOG(3) << "DecodeTask(): input_id=" << bitstream_record->input_id;
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DCHECK_NE(decoder_state_, kUninitialized);
TRACE_EVENT1("Video Decoder", "EVDA::DecodeTask", "input_id",
bitstream_record->input_id);
@@ -623,7 +626,7 @@
void ExynosVideoDecodeAccelerator::DecodeBufferTask() {
DVLOG(3) << "DecodeBufferTask()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DCHECK_NE(decoder_state_, kUninitialized);
TRACE_EVENT0("Video Decoder", "EVDA::DecodeBufferTask");
@@ -820,7 +823,7 @@
}
void ExynosVideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() {
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
// If we're behind on tasks, schedule another one.
int buffers_to_decode = decoder_input_queue_.size();
@@ -837,7 +840,7 @@
bool ExynosVideoDecodeAccelerator::DecodeBufferInitial(
const void* data, size_t size, size_t* endpos) {
DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size;
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DCHECK_NE(decoder_state_, kUninitialized);
DCHECK_NE(decoder_state_, kDecoding);
DCHECK(!device_poll_thread_.IsRunning());
@@ -912,7 +915,7 @@
bool ExynosVideoDecodeAccelerator::DecodeBufferContinue(
const void* data, size_t size) {
DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size;
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DCHECK_EQ(decoder_state_, kDecoding);
// Both of these calls will set kError state if they fail.
@@ -924,7 +927,7 @@
bool ExynosVideoDecodeAccelerator::AppendToInputFrame(
const void* data, size_t size) {
DVLOG(3) << "AppendToInputFrame()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DCHECK_NE(decoder_state_, kUninitialized);
DCHECK_NE(decoder_state_, kResetting);
DCHECK_NE(decoder_state_, kError);
@@ -990,7 +993,7 @@
bool ExynosVideoDecodeAccelerator::FlushInputFrame() {
DVLOG(3) << "FlushInputFrame()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DCHECK_NE(decoder_state_, kUninitialized);
DCHECK_NE(decoder_state_, kResetting);
DCHECK_NE(decoder_state_, kError);
@@ -1029,7 +1032,7 @@
void ExynosVideoDecodeAccelerator::AssignPictureBuffersTask(
scoped_ptr<PictureBufferArrayRef> pic_buffers) {
DVLOG(3) << "AssignPictureBuffersTask()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DCHECK_NE(decoder_state_, kUninitialized);
TRACE_EVENT0("Video Decoder", "EVDA::AssignPictureBuffersTask");
@@ -1066,7 +1069,7 @@
void ExynosVideoDecodeAccelerator::ServiceDeviceTask() {
DVLOG(3) << "ServiceDeviceTask()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DCHECK_NE(decoder_state_, kUninitialized);
DCHECK_NE(decoder_state_, kInitialized);
DCHECK_NE(decoder_state_, kAfterReset);
@@ -1135,7 +1138,7 @@
void ExynosVideoDecodeAccelerator::EnqueueMfc() {
DVLOG(3) << "EnqueueMfc()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DCHECK_NE(decoder_state_, kUninitialized);
TRACE_EVENT0("Video Decoder", "EVDA::EnqueueMfc");
@@ -1180,7 +1183,7 @@
void ExynosVideoDecodeAccelerator::DequeueMfc() {
DVLOG(3) << "DequeueMfc()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DCHECK_NE(decoder_state_, kUninitialized);
TRACE_EVENT0("Video Decoder", "EVDA::DequeueMfc");
@@ -1259,7 +1262,7 @@
void ExynosVideoDecodeAccelerator::EnqueueGsc() {
DVLOG(3) << "EnqueueGsc()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DCHECK_NE(decoder_state_, kUninitialized);
DCHECK_NE(decoder_state_, kInitialized);
TRACE_EVENT0("Video Decoder", "EVDA::EnqueueGsc");
@@ -1285,9 +1288,13 @@
}
// Enqueue a GSC output, only if we need one
+ // TODO(ihf): Revert to size > 0 once issue 225563 is fixed.
+ COMPILE_ASSERT(
+ kDpbOutputBufferExtraCount >= kGscOutputBufferExtraForSyncCount,
+ gsc_output_buffer_extra_for_sync_count_too_large);
if (gsc_input_buffer_queued_count_ != 0 &&
gsc_output_buffer_queued_count_ == 0 &&
- !gsc_free_output_buffers_.empty()) {
+ gsc_free_output_buffers_.size() > kGscOutputBufferExtraForSyncCount) {
const int old_gsc_outputs_queued = gsc_output_buffer_queued_count_;
if (!EnqueueGscOutputRecord())
return;
@@ -1311,7 +1318,7 @@
void ExynosVideoDecodeAccelerator::DequeueGsc() {
DVLOG(3) << "DequeueGsc()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DCHECK_NE(decoder_state_, kUninitialized);
DCHECK_NE(decoder_state_, kInitialized);
DCHECK_NE(decoder_state_, kAfterReset);
@@ -1518,7 +1525,7 @@
int32 picture_buffer_id, scoped_ptr<EGLSyncKHRRef> egl_sync_ref) {
DVLOG(3) << "ReusePictureBufferTask(): picture_buffer_id="
<< picture_buffer_id;
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
TRACE_EVENT0("Video Decoder", "EVDA::ReusePictureBufferTask");
// We run ReusePictureBufferTask even if we're in kResetting.
@@ -1558,7 +1565,7 @@
void ExynosVideoDecodeAccelerator::FlushTask() {
DVLOG(3) << "FlushTask()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
TRACE_EVENT0("Video Decoder", "EVDA::FlushTask");
// Flush outstanding buffers.
@@ -1620,7 +1627,7 @@
void ExynosVideoDecodeAccelerator::ResetTask() {
DVLOG(3) << "ResetTask()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
TRACE_EVENT0("Video Decoder", "EVDA::ResetTask");
if (decoder_state_ == kError) {
@@ -1650,7 +1657,7 @@
void ExynosVideoDecodeAccelerator::ResetDoneTask() {
DVLOG(3) << "ResetDoneTask()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
TRACE_EVENT0("Video Decoder", "EVDA::ResetDoneTask");
if (decoder_state_ == kError) {
@@ -1698,7 +1705,7 @@
bool ExynosVideoDecodeAccelerator::StartDevicePoll() {
DVLOG(3) << "StartDevicePoll()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DCHECK(!device_poll_thread_.IsRunning());
// Start up the device poll thread and schedule its first DevicePollTask().
@@ -1717,7 +1724,7 @@
bool ExynosVideoDecodeAccelerator::StopDevicePoll() {
DVLOG(3) << "StopDevicePoll()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
// Signal the DevicePollTask() to stop, and stop the device poll thread.
if (!SetDevicePollInterrupt())
@@ -1790,7 +1797,7 @@
bool ExynosVideoDecodeAccelerator::SetDevicePollInterrupt() {
DVLOG(3) << "SetDevicePollInterrupt()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
const uint64 buf = 1;
if (HANDLE_EINTR(write(device_poll_interrupt_fd_, &buf, sizeof(buf))) == -1) {
@@ -1803,7 +1810,7 @@
bool ExynosVideoDecodeAccelerator::ClearDevicePollInterrupt() {
DVLOG(3) << "ClearDevicePollInterrupt()";
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
uint64 buf;
if (HANDLE_EINTR(read(device_poll_interrupt_fd_, &buf, sizeof(buf))) == -1) {
@@ -1821,7 +1828,7 @@
void ExynosVideoDecodeAccelerator::DevicePollTask(unsigned int poll_fds) {
DVLOG(3) << "DevicePollTask()";
- DCHECK_EQ(device_poll_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current());
TRACE_EVENT0("Video Decoder", "EVDA::DevicePollTask");
// This routine just polls the set of device fds, and schedules a
@@ -1886,7 +1893,7 @@
// We can touch decoder_state_ only if this is the decoder thread or the
// decoder thread isn't running.
if (decoder_thread_.message_loop() != NULL &&
- decoder_thread_.message_loop() != MessageLoop::current()) {
+ decoder_thread_.message_loop() != base::MessageLoop::current()) {
decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
&ExynosVideoDecodeAccelerator::SetDecoderState,
base::Unretained(this), state));
@@ -1967,13 +1974,14 @@
memset(&ctrl, 0, sizeof(ctrl));
ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_G_CTRL, &ctrl);
+ mfc_output_dpb_size_ = ctrl.value;
// Output format setup in Initialize().
// Allocate the output buffers.
struct v4l2_requestbuffers reqbufs;
memset(&reqbufs, 0, sizeof(reqbufs));
- reqbufs.count = ctrl.value + kMfcOutputBufferExtraCount;
+ reqbufs.count = mfc_output_dpb_size_ + kDpbOutputBufferExtraCount;
reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
reqbufs.memory = V4L2_MEMORY_MMAP;
IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_REQBUFS, &reqbufs);
@@ -2092,7 +2100,7 @@
struct v4l2_requestbuffers reqbufs;
memset(&reqbufs, 0, sizeof(reqbufs));
- reqbufs.count = kGscOutputBufferCount;
+ reqbufs.count = mfc_output_dpb_size_ + kDpbOutputBufferExtraCount;
reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
reqbufs.memory = V4L2_MEMORY_DMABUF;
IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_REQBUFS, &reqbufs);
diff --git a/content/common/gpu/media/exynos_video_decode_accelerator.h b/content/common/gpu/media/exynos_video_decode_accelerator.h
index 920af68..0eb3299 100644
--- a/content/common/gpu/media/exynos_video_decode_accelerator.h
+++ b/content/common/gpu/media/exynos_video_decode_accelerator.h
@@ -86,10 +86,17 @@
// These are rather subjectively tuned.
enum {
kMfcInputBufferCount = 8,
- kMfcOutputBufferExtraCount = 5, // number of buffers above request by V4L2.
kMfcInputBufferMaxSize = 512 * 1024,
- kGscInputBufferCount = 6,
- kGscOutputBufferCount = 6,
+ kGscInputBufferCount = 4,
+ // Number of output buffers to use for each VDA stage above what's required
+ // by the decoder (e.g. DPB size, in H264).
+ kDpbOutputBufferExtraCount = 3,
+ // We're continuing to have issues with synchronization between Mali 3D and
+ // Exynos video decode, so we buffer this many extra GSC output buffers in
+ // the GSC free output buffers queue, to add a safety margin.
+ // Must be lesser than or equal to kDpbOutputBufferExtraCount.
+ // TODO(sheu): remove this hack (http://crbug.com/225563).
+ kGscOutputBufferExtraForSyncCount = 2,
};
// Internal state of the decoder.
@@ -367,6 +374,8 @@
// Required size of MFC output buffers. Two sizes for two planes.
size_t mfc_output_buffer_size_[2];
uint32 mfc_output_buffer_pixelformat_;
+ // Required size of DPB for decoding.
+ int mfc_output_dpb_size_;
// Completed MFC outputs, waiting for GSC.
std::list<int> mfc_output_gsc_input_queue_;
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc
index 7e51777..251e202 100644
--- a/content/common/gpu/media/gpu_video_decode_accelerator.cc
+++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc
@@ -29,9 +29,6 @@
#elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11)
#include "ui/gl/gl_context_glx.h"
#include "content/common/gpu/media/vaapi_video_decode_accelerator.h"
-#elif defined(OS_MACOSX)
-#include "gpu/command_buffer/service/texture_manager.h"
-#include "content/common/gpu/media/mac_video_decode_accelerator.h"
#elif defined(OS_ANDROID)
#include "content/common/gpu/media/android_video_decode_accelerator.h"
#endif
@@ -63,28 +60,28 @@
GpuCommandBufferStub* stub)
: init_done_msg_(NULL),
host_route_id_(host_route_id),
- stub_(stub->AsWeakPtr()),
+ stub_(stub),
video_decode_accelerator_(NULL),
texture_target_(0) {
- if (!stub_)
- return;
+ DCHECK(stub_);
stub_->AddDestructionObserver(this);
+ stub_->channel()->AddRoute(host_route_id_, this);
make_context_current_ =
base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr());
}
GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() {
- if (stub_) {
- stub_->channel()->RemoveRoute(host_route_id_);
- stub_->RemoveDestructionObserver(this);
- }
-
- if (video_decode_accelerator_.get())
+ DCHECK(stub_);
+ if (video_decode_accelerator_)
video_decode_accelerator_.release()->Destroy();
+
+ stub_->channel()->RemoveRoute(host_route_id_);
+ stub_->RemoveDestructionObserver(this);
}
bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) {
- if (!stub_ || !video_decode_accelerator_.get())
+ DCHECK(stub_);
+ if (!video_decode_accelerator_)
return false;
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg)
@@ -156,14 +153,11 @@
void GpuVideoDecodeAccelerator::Initialize(
const media::VideoCodecProfile profile,
IPC::Message* init_done_msg) {
+ DCHECK(stub_);
DCHECK(!video_decode_accelerator_.get());
DCHECK(!init_done_msg_);
DCHECK(init_done_msg);
init_done_msg_ = init_done_msg;
- if (!stub_)
- return;
-
- stub_->channel()->AddRoute(host_route_id_, this);
#if !defined(OS_WIN)
// Ensure we will be able to get a GL context at all before initializing
@@ -205,11 +199,6 @@
video_decode_accelerator_.reset(new VaapiVideoDecodeAccelerator(
glx_context->display(), glx_context_handle, this,
make_context_current_));
-#elif defined(OS_MACOSX)
- video_decode_accelerator_.reset(new MacVideoDecodeAccelerator(
- static_cast<CGLContextObj>(
- stub_->decoder()->GetGLContext()->GetHandle()),
- this));
#elif defined(OS_ANDROID)
video_decode_accelerator_.reset(new AndroidVideoDecodeAccelerator(
this,
@@ -240,6 +229,7 @@
const std::vector<int32>& buffer_ids,
const std::vector<uint32>& texture_ids,
const std::vector<gfx::Size>& sizes) {
+ DCHECK(stub_);
if (buffer_ids.size() != texture_ids.size() ||
buffer_ids.size() != sizes.size()) {
NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
@@ -316,7 +306,7 @@
void GpuVideoDecodeAccelerator::OnDestroy() {
DCHECK(video_decode_accelerator_.get());
- video_decode_accelerator_.release()->Destroy();
+ delete this;
}
void GpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
@@ -347,14 +337,8 @@
DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ResetDone) failed";
}
-void GpuVideoDecodeAccelerator::OnWillDestroyStub(GpuCommandBufferStub* stub) {
- DCHECK_EQ(stub, stub_.get());
- if (video_decode_accelerator_.get())
- video_decode_accelerator_.release()->Destroy();
- if (stub_) {
- stub_->RemoveDestructionObserver(this);
- stub_.reset();
- }
+void GpuVideoDecodeAccelerator::OnWillDestroyStub() {
+ delete this;
}
bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) {
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.h b/content/common/gpu/media/gpu_video_decode_accelerator.h
index 52d0417..91f1b7c 100644
--- a/content/common/gpu/media/gpu_video_decode_accelerator.h
+++ b/content/common/gpu/media/gpu_video_decode_accelerator.h
@@ -45,7 +45,7 @@
virtual void NotifyResetDone() OVERRIDE;
// GpuCommandBufferStub::DestructionObserver implementation.
- virtual void OnWillDestroyStub(GpuCommandBufferStub* stub) OVERRIDE;
+ virtual void OnWillDestroyStub() OVERRIDE;
// Function to delegate sending to actual sender.
virtual bool Send(IPC::Message* message) OVERRIDE;
@@ -79,7 +79,7 @@
int32 host_route_id_;
// Unowned pointer to the underlying GpuCommandBufferStub.
- base::WeakPtr<GpuCommandBufferStub> stub_;
+ GpuCommandBufferStub* stub_;
// The underlying VideoDecodeAccelerator.
scoped_ptr<media::VideoDecodeAccelerator> video_decode_accelerator_;
diff --git a/content/common/gpu/media/mac_video_decode_accelerator.h b/content/common/gpu/media/mac_video_decode_accelerator.h
deleted file mode 100644
index 3582f10..0000000
--- a/content/common/gpu/media/mac_video_decode_accelerator.h
+++ /dev/null
@@ -1,137 +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_COMMON_GPU_MEDIA_MAC_VIDEO_DECODE_ACCELERATOR_H_
-#define CONTENT_COMMON_GPU_MEDIA_MAC_VIDEO_DECODE_ACCELERATOR_H_
-
-#include <CoreVideo/CoreVideo.h>
-#include <map>
-#include <list>
-
-#include "base/mac/scoped_cftyperef.h"
-#include "base/memory/ref_counted.h"
-#include "base/threading/non_thread_safe.h"
-#include "content/common/content_export.h"
-#include "content/common/gpu/media/avc_config_record_builder.h"
-#include "content/common/gpu/media/h264_parser.h"
-#include "media/video/video_decode_accelerator.h"
-
-namespace base {
-class RefCountedBytes;
-}
-namespace gfx {
-class GLContext;
-class VideoDecodeAccelerationSupport;
-}
-
-namespace content {
-
-class GpuCommandBufferStub;
-
-class CONTENT_EXPORT MacVideoDecodeAccelerator
- : public media::VideoDecodeAccelerator,
- public base::NonThreadSafe {
- public:
- // Does not take ownership of |client| which must outlive |*this|.
- MacVideoDecodeAccelerator(CGLContextObj cgl_context,
- media::VideoDecodeAccelerator::Client* client);
- virtual ~MacVideoDecodeAccelerator();
-
- // media::VideoDecodeAccelerator implementation.
- virtual bool Initialize(media::VideoCodecProfile profile) OVERRIDE;
- virtual void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE;
- virtual void AssignPictureBuffers(
- const std::vector<media::PictureBuffer>& buffers) OVERRIDE;
- virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE;
- virtual void Flush() OVERRIDE;
- virtual void Reset() OVERRIDE;
- virtual void Destroy() OVERRIDE;
-
- private:
-
- // Callback for a completed frame.
- void OnFrameReady(int32 bitstream_buffer_id,
- scoped_refptr<base::RefCountedBytes> bytes,
- CVImageBufferRef image,
- int status);
-
- // Sends available decoded frames to the client.
- void SendImages();
-
- // Stop the component when any error is detected.
- void StopOnError(media::VideoDecodeAccelerator::Error error);
-
- // Create the decoder.
- bool CreateDecoder(const std::vector<uint8_t>& extra_data);
-
- // Send the given NALU to the decoder.
- void DecodeNALU(const H264NALU& nalu, int32 bitstream_buffer_id);
-
- // Calls the client's initialize completed callback.
- void NotifyInitializeDone();
-
- // Requests pictures from the client.
- void RequestPictures();
-
- // Calls the client's flush completed callback.
- void NotifyFlushDone();
-
- // Calls the client's reset completed callback.
- void NotifyResetDone();
-
- // Notifies the client that the input buffer identifed by |input_buffer_id|
- // has been processed.
- void NotifyInputBufferRead(int input_buffer_id);
-
- // Helper for Destroy(), doing all the actual work except for deleting self.
- void Cleanup();
-
- // To expose client callbacks from VideoDecodeAccelerator.
- Client* client_;
- // C++ wrapper around the Mac VDA API.
- scoped_refptr<gfx::VideoDecodeAccelerationSupport> vda_support_;
- // Picture buffers that are available for use by the decoder to draw decoded
- // video frames on.
- std::list<media::PictureBuffer> available_pictures_;
-
- // Maps ids to picture buffers that are in use by the client.
- struct UsedPictureInfo {
- UsedPictureInfo(const media::PictureBuffer& pic,
- const base::mac::ScopedCFTypeRef<CVImageBufferRef>& image);
- ~UsedPictureInfo();
- const media::PictureBuffer picture_buffer;
- const base::mac::ScopedCFTypeRef<CVImageBufferRef> image;
- };
- std::map<int32, UsedPictureInfo> used_pictures_;
-
- // List of decoded images waiting to be sent to the client.
- struct DecodedImageInfo {
- DecodedImageInfo();
- ~DecodedImageInfo();
- base::mac::ScopedCFTypeRef<CVImageBufferRef> image;
- int32 bitstream_buffer_id;
- };
- std::list<DecodedImageInfo> decoded_images_;
-
- // The context to use to perform OpenGL operations.
- CGLContextObj cgl_context_;
-
- // Flag to check if AVC decoder configuration record has been built.
- bool did_build_config_record_;
-
- // Parser for the H264 stream.
- H264Parser h264_parser_;
-
- // Utility to build the AVC configuration record.
- AVCConfigRecordBuilder config_record_builder_;
-
- // Maps a bitstream ID to the number of NALUs that are being decoded for
- // that bitstream. This is used to ensure that NotifyEndOfBitstreamBuffer()
- // is called after all NALUs contained in a bitstream have been decoded.
- std::map<int32, int> bitstream_nalu_count_;
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_GPU_MEDIA_VIDEO_DECODE_ACCELERATOR_MAC_H_
diff --git a/content/common/gpu/media/mac_video_decode_accelerator.mm b/content/common/gpu/media/mac_video_decode_accelerator.mm
deleted file mode 100644
index cfc3077..0000000
--- a/content/common/gpu/media/mac_video_decode_accelerator.mm
+++ /dev/null
@@ -1,390 +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/common/gpu/media/mac_video_decode_accelerator.h"
-
-#include "base/bind.h"
-#include "base/files/file_path.h"
-#include "base/location.h"
-#import "base/mac/foundation_util.h"
-#import "base/memory/ref_counted_memory.h"
-#import "base/message_loop.h"
-#include "base/native_library.h"
-#include "ui/gfx/video_decode_acceleration_support_mac.h"
-#include "ui/surface/io_surface_support_mac.h"
-
-namespace content {
-
-// Helper macros for dealing with failure. If |result| evaluates false, emit
-// |log| to ERROR, register |error| with the decoder, and return |ret_val|
-// (which may be omitted for functions that return void).
-#define RETURN_ON_FAILURE(result, log, error, ret_val) \
- do { \
- if (!(result)) { \
- DLOG(ERROR) << log; \
- StopOnError(error); \
- return ret_val; \
- } \
- } while (0)
-
-namespace {
-
-enum { kNumPictureBuffers = 4 };
-
-class ScopedContextSetter {
- public:
- ScopedContextSetter(CGLContextObj context)
- : old_context_(NULL),
- did_succeed_(false) {
- old_context_ = CGLGetCurrentContext();
- did_succeed_ = CGLSetCurrentContext(context) == kCGLNoError;
- }
-
- ~ScopedContextSetter() {
- if (did_succeed_)
- CGLSetCurrentContext(old_context_);
- }
-
- bool did_succeed() const {
- return did_succeed_;
- }
-
- private:
- CGLContextObj old_context_;
- bool did_succeed_;
-};
-
-} // namespace
-
-static bool BindImageToTexture(CGLContextObj context,
- CVImageBufferRef image,
- uint32 texture_id) {
- ScopedContextSetter scoped_context_setter(context);
- if (!scoped_context_setter.did_succeed()) {
- DVLOG(1) << "Unable to set OpenGL context.";
- return false;
- }
-
- IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
- DCHECK(io_surface_support);
-
- CFTypeRef io_surface =
- io_surface_support->CVPixelBufferGetIOSurface(image);
- if (!io_surface) {
- DVLOG(1) << "Unable to get IOSurface for CVPixelBuffer.";
- return false;
- }
-
- glEnable(GL_TEXTURE_RECTANGLE_ARB);
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_id);
- if (io_surface_support->CGLTexImageIOSurface2D(
- context,
- GL_TEXTURE_RECTANGLE_ARB,
- GL_RGB,
- io_surface_support->IOSurfaceGetWidth(io_surface),
- io_surface_support->IOSurfaceGetHeight(io_surface),
- GL_YCBCR_422_APPLE,
- GL_UNSIGNED_SHORT_8_8_APPLE,
- io_surface,
- 0) != kCGLNoError) {
- DVLOG(1) << "Failed to bind image to texture.";
- return false;
- }
- return glGetError() == GL_NO_ERROR;
-}
-
-MacVideoDecodeAccelerator::MacVideoDecodeAccelerator(
- CGLContextObj cgl_context, media::VideoDecodeAccelerator::Client* client)
- : client_(client),
- cgl_context_(cgl_context),
- did_build_config_record_(false) {
-}
-
-bool MacVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile) {
- DCHECK(CalledOnValidThread());
-
- // MacVDA still fails on too many videos to be useful, even to users who
- // ignore the GPU blacklist. Fail unconditionally here until enough of
- // crbug.com/133828's blockers are resolved.
- if (true)
- return false;
-
- if (profile < media::H264PROFILE_MIN || profile > media::H264PROFILE_MAX)
- return false;
-
- IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
- if (!io_surface_support)
- return false;
-
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
- &MacVideoDecodeAccelerator::NotifyInitializeDone, base::AsWeakPtr(this)));
- return true;
-}
-
-void MacVideoDecodeAccelerator::Decode(
- const media::BitstreamBuffer& bitstream_buffer) {
- DCHECK(CalledOnValidThread());
- RETURN_ON_FAILURE(client_,
- "Call to Decode() during invalid state.", ILLEGAL_STATE,);
-
- base::SharedMemory memory(bitstream_buffer.handle(), true);
- RETURN_ON_FAILURE(memory.Map(bitstream_buffer.size()),
- "Failed to SharedMemory::Map().", UNREADABLE_INPUT,);
-
- h264_parser_.SetStream(static_cast<const uint8_t*>(memory.memory()),
- bitstream_buffer.size());
- while (true) {
- H264NALU nalu;
- H264Parser::Result result = h264_parser_.AdvanceToNextNALU(&nalu);
- if (result == H264Parser::kEOStream) {
- if (bitstream_nalu_count_.count(bitstream_buffer.id()) == 0) {
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
- &MacVideoDecodeAccelerator::NotifyInputBufferRead,
- base::AsWeakPtr(this), bitstream_buffer.id()));
- }
- return;
- }
- RETURN_ON_FAILURE(result == H264Parser::kOk,
- "Unable to parse bitstream.", UNREADABLE_INPUT,);
- if (!did_build_config_record_) {
- std::vector<uint8_t> config_record;
- RETURN_ON_FAILURE(config_record_builder_.ProcessNALU(&h264_parser_, nalu,
- &config_record),
- "Unable to build AVC configuraiton record.",
- UNREADABLE_INPUT,);
- if (!config_record.empty()) {
- did_build_config_record_ = true;
- if (!CreateDecoder(config_record))
- return;
- }
- }
- // If the decoder has been created and this is a slice type then pass it
- // to the decoder.
- if (vda_support_.get() && nalu.nal_unit_type >= 1 &&
- nalu.nal_unit_type <= 5) {
- bitstream_nalu_count_[bitstream_buffer.id()]++;
- DecodeNALU(nalu, bitstream_buffer.id());
- }
- }
-}
-
-void MacVideoDecodeAccelerator::AssignPictureBuffers(
- const std::vector<media::PictureBuffer>& buffers) {
- DCHECK(CalledOnValidThread());
- RETURN_ON_FAILURE(client_,
- "Call to AssignPictureBuffers() during invalid state.",
- ILLEGAL_STATE,);
- available_pictures_.insert(
- available_pictures_.end(), buffers.begin(), buffers.end());
- SendImages();
-}
-
-void MacVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) {
- DCHECK(CalledOnValidThread());
- RETURN_ON_FAILURE(client_,
- "Call to ReusePictureBuffe() during invalid state.",
- ILLEGAL_STATE,);
-
- std::map<int32, UsedPictureInfo>::iterator it =
- used_pictures_.find(picture_buffer_id);
- RETURN_ON_FAILURE(it != used_pictures_.end(),
- "Missing picture buffer id: " << picture_buffer_id,
- INVALID_ARGUMENT,);
- UsedPictureInfo info = it->second;
- used_pictures_.erase(it);
- available_pictures_.push_back(info.picture_buffer);
- SendImages();
-}
-
-void MacVideoDecodeAccelerator::Flush() {
- DCHECK(CalledOnValidThread());
- RETURN_ON_FAILURE(vda_support_,
- "Call to Flush() during invalid state.", ILLEGAL_STATE,);
- vda_support_->Flush(true);
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
- &MacVideoDecodeAccelerator::NotifyFlushDone, base::AsWeakPtr(this)));
-}
-
-void MacVideoDecodeAccelerator::Reset() {
- DCHECK(CalledOnValidThread());
- RETURN_ON_FAILURE(vda_support_,
- "Call to Reset() during invalid state.", ILLEGAL_STATE,);
- vda_support_->Flush(false);
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
- &MacVideoDecodeAccelerator::NotifyResetDone, base::AsWeakPtr(this)));
-}
-
-void MacVideoDecodeAccelerator::Cleanup() {
- DCHECK(CalledOnValidThread());
- if (vda_support_) {
- vda_support_->Destroy();
- vda_support_ = NULL;
- }
- client_ = NULL;
- decoded_images_.clear();
-}
-
-void MacVideoDecodeAccelerator::Destroy() {
- DCHECK(CalledOnValidThread());
- Cleanup();
- delete this;
-}
-
-MacVideoDecodeAccelerator::~MacVideoDecodeAccelerator() {
- DCHECK(CalledOnValidThread());
- DCHECK(!vda_support_);
- DCHECK(!client_);
- DCHECK(decoded_images_.empty());
-}
-
-void MacVideoDecodeAccelerator::OnFrameReady(
- int32 bitstream_buffer_id,
- scoped_refptr<base::RefCountedBytes> bytes,
- CVImageBufferRef image,
- int status) {
- DCHECK(CalledOnValidThread());
- RETURN_ON_FAILURE(status == noErr,
- "Decoding image failed with error code: " << status,
- PLATFORM_FAILURE,);
- if (!client_)
- return;
- if (image) {
- DecodedImageInfo info;
- info.image.reset(image, base::scoped_policy::RETAIN);
- info.bitstream_buffer_id = bitstream_buffer_id;
- decoded_images_.push_back(info);
- SendImages();
- }
- std::map<int32, int>::iterator bitstream_count_it =
- bitstream_nalu_count_.find(bitstream_buffer_id);
- if (--bitstream_count_it->second == 0) {
- bitstream_nalu_count_.erase(bitstream_count_it);
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
- &MacVideoDecodeAccelerator::NotifyInputBufferRead,
- base::AsWeakPtr(this), bitstream_buffer_id));
- }
-}
-
-void MacVideoDecodeAccelerator::SendImages() {
- if (!client_) {
- DCHECK(decoded_images_.empty());
- return;
- }
-
- while (available_pictures_.size() && decoded_images_.size()) {
- DecodedImageInfo info = decoded_images_.front();
- decoded_images_.pop_front();
- media::PictureBuffer picture_buffer = available_pictures_.front();
- available_pictures_.pop_front();
-
- RETURN_ON_FAILURE(BindImageToTexture(
- cgl_context_, info.image, picture_buffer.texture_id()),
- "Error binding image to texture.", PLATFORM_FAILURE,);
-
- used_pictures_.insert(std::make_pair(
- picture_buffer.id(), UsedPictureInfo(picture_buffer, info.image)));
- client_->PictureReady(
- media::Picture(picture_buffer.id(), info.bitstream_buffer_id));
- }
-}
-
-void MacVideoDecodeAccelerator::StopOnError(
- media::VideoDecodeAccelerator::Error error) {
- if (client_)
- client_->NotifyError(error);
- Cleanup();
-}
-
-bool MacVideoDecodeAccelerator::CreateDecoder(
- const std::vector<uint8_t>& extra_data) {
- DCHECK(client_);
- DCHECK(!vda_support_.get());
-
- vda_support_ = new gfx::VideoDecodeAccelerationSupport();
- gfx::VideoDecodeAccelerationSupport::Status status = vda_support_->Create(
- config_record_builder_.coded_width(),
- config_record_builder_.coded_height(),
- kCVPixelFormatType_422YpCbCr8,
- &extra_data[0], extra_data.size());
- RETURN_ON_FAILURE(status == gfx::VideoDecodeAccelerationSupport::SUCCESS,
- "Creating video decoder failed with error: " << status,
- PLATFORM_FAILURE, false);
-
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
- &MacVideoDecodeAccelerator::RequestPictures, base::AsWeakPtr(this)));
- return true;
-}
-
-void MacVideoDecodeAccelerator::DecodeNALU(const H264NALU& nalu,
- int32 bitstream_buffer_id) {
- // Assume the NALU length field size is 4 bytes.
- const int kNALULengthFieldSize = 4;
- std::vector<uint8_t> data(kNALULengthFieldSize + nalu.size);
-
- // Store the buffer size at the beginning of the buffer as the decoder
- // expects.
- for (size_t i = 0; i < kNALULengthFieldSize; ++i) {
- size_t shift = kNALULengthFieldSize * 8 - (i + 1) * 8;
- data[i] = (nalu.size >> shift) & 0xff;
- }
-
- // Copy the NALU data.
- memcpy(&data[kNALULengthFieldSize], nalu.data, nalu.size);
-
- // Keep a ref counted copy of the buffer.
- scoped_refptr<base::RefCountedBytes> bytes(
- base::RefCountedBytes::TakeVector(&data));
- vda_support_->Decode(bytes->front(), bytes->size(), base::Bind(
- &MacVideoDecodeAccelerator::OnFrameReady,
- base::AsWeakPtr(this), bitstream_buffer_id, bytes));
-}
-
-void MacVideoDecodeAccelerator::NotifyInitializeDone() {
- if (client_)
- client_->NotifyInitializeDone();
-}
-
-void MacVideoDecodeAccelerator::RequestPictures() {
- if (client_) {
- client_->ProvidePictureBuffers(
- kNumPictureBuffers,
- gfx::Size(config_record_builder_.coded_width(),
- config_record_builder_.coded_height()),
- GL_TEXTURE_RECTANGLE_ARB);
- }
-}
-
-void MacVideoDecodeAccelerator::NotifyFlushDone() {
- if (client_)
- client_->NotifyFlushDone();
-}
-
-void MacVideoDecodeAccelerator::NotifyResetDone() {
- decoded_images_.clear();
- if (client_)
- client_->NotifyResetDone();
-}
-
-void MacVideoDecodeAccelerator::NotifyInputBufferRead(int input_buffer_id) {
- if (client_)
- client_->NotifyEndOfBitstreamBuffer(input_buffer_id);
-}
-
-MacVideoDecodeAccelerator::UsedPictureInfo::UsedPictureInfo(
- const media::PictureBuffer& pic,
- const base::mac::ScopedCFTypeRef<CVImageBufferRef>& image)
- : picture_buffer(pic),
- image(image, base::scoped_policy::RETAIN) {
-}
-
-MacVideoDecodeAccelerator::UsedPictureInfo::~UsedPictureInfo() {
-}
-
-MacVideoDecodeAccelerator::DecodedImageInfo::DecodedImageInfo() {
-}
-
-MacVideoDecodeAccelerator::DecodedImageInfo::~DecodedImageInfo() {
-}
-
-} // namespace content
diff --git a/content/common/gpu/media/omx_video_decode_accelerator.cc b/content/common/gpu/media/omx_video_decode_accelerator.cc
index 06897a8..929b711 100644
--- a/content/common/gpu/media/omx_video_decode_accelerator.cc
+++ b/content/common/gpu/media/omx_video_decode_accelerator.cc
@@ -135,7 +135,7 @@
EGLDisplay egl_display, EGLContext egl_context,
media::VideoDecodeAccelerator::Client* client,
const base::Callback<bool(void)>& make_context_current)
- : message_loop_(MessageLoop::current()),
+ : message_loop_(base::MessageLoop::current()),
component_handle_(NULL),
weak_this_(base::AsWeakPtr(this)),
init_begun_(false),
@@ -150,7 +150,8 @@
egl_display_(egl_display),
egl_context_(egl_context),
make_context_current_(make_context_current),
- client_(client),
+ client_ptr_factory_(client),
+ client_(client_ptr_factory_.GetWeakPtr()),
codec_(UNKNOWN),
h264_profile_(OMX_VIDEO_AVCProfileMax),
component_name_is_nvidia_(false) {
@@ -162,7 +163,7 @@
}
OmxVideoDecodeAccelerator::~OmxVideoDecodeAccelerator() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
DCHECK(free_input_buffers_.empty());
DCHECK_EQ(0, input_buffers_at_component_);
DCHECK_EQ(0, output_buffers_at_component_);
@@ -178,7 +179,7 @@
}
bool OmxVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
if (profile >= media::H264PROFILE_MIN && profile <= media::H264PROFILE_MAX) {
codec_ = H264;
@@ -219,7 +220,7 @@
}
bool OmxVideoDecodeAccelerator::CreateComponent() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
OMX_CALLBACKTYPE omx_accelerator_callbacks = {
&OmxVideoDecodeAccelerator::EventHandler,
&OmxVideoDecodeAccelerator::EmptyBufferCallback,
@@ -332,7 +333,7 @@
const media::BitstreamBuffer& bitstream_buffer) {
TRACE_EVENT1("Video Decoder", "OVDA::Decode",
"Buffer id", bitstream_buffer.id());
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
if (current_state_change_ == RESETTING ||
!queued_bitstream_buffers_.empty() ||
@@ -395,7 +396,7 @@
void OmxVideoDecodeAccelerator::AssignPictureBuffers(
const std::vector<media::PictureBuffer>& buffers) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
// If we are resetting/destroying/erroring, don't bother, as
// OMX_FillThisBuffer will fail anyway. In case we're in the middle of
@@ -408,6 +409,9 @@
return;
RETURN_ON_FAILURE(CanFillBuffer(), "Can't fill buffer", ILLEGAL_STATE,);
+ RETURN_ON_FAILURE((kNumPictureBuffers == buffers.size()),
+ "Failed to provide requested picture buffers. (Got " << buffers.size() <<
+ ", requested " << kNumPictureBuffers << ")", INVALID_ARGUMENT,);
DCHECK_EQ(output_buffers_at_component_, 0);
DCHECK_EQ(fake_output_buffers_.size(), 0U);
@@ -426,10 +430,6 @@
buffers[i].id(), OutputPicture(buffers[i], NULL, egl_image))).second);
}
- if (pictures_.size() < kNumPictureBuffers)
- return; // get all the buffers first.
- DCHECK_EQ(pictures_.size(), kNumPictureBuffers);
-
// These do their own RETURN_ON_FAILURE dances.
if (!AllocateOutputBuffers())
return;
@@ -438,7 +438,7 @@
}
void OmxVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
TRACE_EVENT1("Video Decoder", "OVDA::ReusePictureBuffer",
"Picture id", picture_buffer_id);
scoped_ptr<PictureSyncObject> egl_sync_obj(
@@ -451,14 +451,14 @@
void OmxVideoDecodeAccelerator::CheckPictureStatus(
int32 picture_buffer_id,
scoped_ptr<PictureSyncObject> egl_sync_obj) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
// It's possible for this task to never run if the message loop is
// stopped. In that case we may never call QueuePictureBuffer().
// This is fine though, because all pictures, irrespective of their state,
// are in pictures_ map and that's what will be used to do the clean up.
if (!egl_sync_obj->IsSynced()) {
- MessageLoop::current()->PostDelayedTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostDelayedTask(FROM_HERE, base::Bind(
&OmxVideoDecodeAccelerator::CheckPictureStatus, weak_this_,
picture_buffer_id, base::Passed(&egl_sync_obj)),
base::TimeDelta::FromMilliseconds(kSyncPollDelayMs));
@@ -470,7 +470,7 @@
}
void OmxVideoDecodeAccelerator::QueuePictureBuffer(int32 picture_buffer_id) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
// During port-flushing, do not call OMX FillThisBuffer.
if (current_state_change_ == RESETTING) {
@@ -498,7 +498,7 @@
}
void OmxVideoDecodeAccelerator::Flush() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
DCHECK_EQ(current_state_change_, NO_TRANSITION);
DCHECK_EQ(client_state_, OMX_StateExecuting);
current_state_change_ = FLUSHING;
@@ -507,7 +507,7 @@
}
void OmxVideoDecodeAccelerator::OnReachedEOSInFlushing() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
DCHECK_EQ(client_state_, OMX_StateExecuting);
current_state_change_ = NO_TRANSITION;
if (client_)
@@ -515,7 +515,7 @@
}
void OmxVideoDecodeAccelerator::FlushIOPorts() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
// Flush input port first.
if (!SendCommandToPort(OMX_CommandFlush, input_port_))
@@ -523,20 +523,20 @@
}
void OmxVideoDecodeAccelerator::InputPortFlushDone() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
DCHECK_EQ(input_buffers_at_component_, 0);
if (!SendCommandToPort(OMX_CommandFlush, output_port_))
return;
}
void OmxVideoDecodeAccelerator::OutputPortFlushDone() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
DCHECK_EQ(output_buffers_at_component_, 0);
BeginTransitionToState(OMX_StateExecuting);
}
void OmxVideoDecodeAccelerator::Reset() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
DCHECK_EQ(current_state_change_, NO_TRANSITION);
DCHECK_EQ(client_state_, OMX_StateExecuting);
current_state_change_ = RESETTING;
@@ -544,9 +544,10 @@
}
void OmxVideoDecodeAccelerator::Destroy() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
scoped_ptr<OmxVideoDecodeAccelerator> deleter(this);
+ client_ptr_factory_.InvalidateWeakPtrs();
if (current_state_change_ == ERRORING ||
current_state_change_ == DESTROYING) {
@@ -569,14 +570,13 @@
client_state_ == OMX_StateIdle ||
client_state_ == OMX_StatePause);
current_state_change_ = DESTROYING;
- client_ = NULL;
BeginTransitionToState(OMX_StateIdle);
BusyLoopInDestroying(deleter.Pass());
}
void OmxVideoDecodeAccelerator::BeginTransitionToState(
OMX_STATETYPE new_state) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
if (new_state != OMX_StateInvalid)
DCHECK_NE(current_state_change_, NO_TRANSITION);
if (current_state_change_ == ERRORING)
@@ -696,7 +696,7 @@
// Can't use PostDelayedTask here because MessageLoop doesn't drain delayed
// tasks. Instead we sleep for 5ms. Really.
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(5));
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&OmxVideoDecodeAccelerator::BusyLoopInDestroying,
base::Unretained(this), base::Passed(&self)));
}
@@ -741,14 +741,14 @@
void OmxVideoDecodeAccelerator::StopOnError(
media::VideoDecodeAccelerator::Error error) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
if (current_state_change_ == ERRORING)
return;
if (client_ && init_begun_)
client_->NotifyError(error);
- client_ = NULL;
+ client_ptr_factory_.InvalidateWeakPtrs();
if (client_state_ == OMX_StateInvalid || client_state_ == OMX_StateMax)
return;
@@ -758,7 +758,7 @@
}
bool OmxVideoDecodeAccelerator::AllocateInputBuffers() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
for (int i = 0; i < input_buffer_count_; ++i) {
OMX_BUFFERHEADERTYPE* buffer;
// While registering the buffer header we use fake buffer information
@@ -798,7 +798,7 @@
}
bool OmxVideoDecodeAccelerator::AllocateOutputBuffers() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
DCHECK(!pictures_.empty());
for (OutputPictureById::iterator it = pictures_.begin();
@@ -820,7 +820,7 @@
}
void OmxVideoDecodeAccelerator::FreeOMXBuffers() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
bool failure_seen = false;
while (!free_input_buffers_.empty()) {
OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front();
@@ -865,15 +865,17 @@
fake_output_buffers_.clear();
// Dequeue pending queued_picture_buffer_ids_
- for (size_t i = 0; i < queued_picture_buffer_ids_.size(); ++i)
- client_->DismissPictureBuffer(queued_picture_buffer_ids_[i]);
+ if (client_) {
+ for (size_t i = 0; i < queued_picture_buffer_ids_.size(); ++i)
+ client_->DismissPictureBuffer(queued_picture_buffer_ids_[i]);
+ }
queued_picture_buffer_ids_.clear();
RETURN_ON_FAILURE(!failure_seen, "OMX_FreeBuffer", PLATFORM_FAILURE,);
}
void OmxVideoDecodeAccelerator::OnOutputPortDisabled() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
OMX_PARAM_PORTDEFINITIONTYPE port_format;
InitParam(*this, &port_format);
port_format.nPortIndex = output_port_;
@@ -901,7 +903,7 @@
}
void OmxVideoDecodeAccelerator::OnOutputPortEnabled() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
if (current_state_change_ == RESETTING) {
for (OutputPictureById::iterator it = pictures_.begin();
@@ -940,7 +942,7 @@
TRACE_EVENT2("Video Decoder", "OVDA::FillBufferDoneTask",
"Buffer id", buffer->nTimeStamp,
"Picture id", picture_buffer_id);
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
DCHECK_GT(output_buffers_at_component_, 0);
--output_buffers_at_component_;
@@ -989,7 +991,7 @@
OMX_BUFFERHEADERTYPE* buffer) {
TRACE_EVENT1("Video Decoder", "OVDA::EmptyBufferDoneTask",
"Buffer id", buffer->nTimeStamp);
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
DCHECK_GT(input_buffers_at_component_, 0);
free_input_buffers_.push(buffer);
input_buffers_at_component_--;
@@ -1010,7 +1012,7 @@
}
void OmxVideoDecodeAccelerator::DispatchStateReached(OMX_STATETYPE reached) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
switch (current_state_change_) {
case INITIALIZING:
switch (reached) {
@@ -1074,7 +1076,7 @@
void OmxVideoDecodeAccelerator::EventHandlerCompleteTask(OMX_EVENTTYPE event,
OMX_U32 data1,
OMX_U32 data2) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
switch (event) {
case OMX_EventCmdComplete:
switch (data1) {
@@ -1237,7 +1239,7 @@
}
bool OmxVideoDecodeAccelerator::CanFillBuffer() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
const CurrentStateChange csc = current_state_change_;
const OMX_STATETYPE cs = client_state_;
return (csc != DESTROYING && csc != ERRORING && csc != RESETTING) &&
@@ -1246,7 +1248,7 @@
bool OmxVideoDecodeAccelerator::SendCommandToPort(
OMX_COMMANDTYPE cmd, int port_index) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
OMX_ERRORTYPE result = OMX_SendCommand(component_handle_,
cmd, port_index, 0);
RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd,
diff --git a/content/common/gpu/media/omx_video_decode_accelerator.h b/content/common/gpu/media/omx_video_decode_accelerator.h
index 8855809..d57d3b1 100644
--- a/content/common/gpu/media/omx_video_decode_accelerator.h
+++ b/content/common/gpu/media/omx_video_decode_accelerator.h
@@ -94,7 +94,7 @@
};
typedef std::map<int32, OutputPicture> OutputPictureById;
- MessageLoop* message_loop_;
+ base::MessageLoop* message_loop_;
OMX_HANDLETYPE component_handle_;
// Create the Component for OMX. Handles all OMX initialization.
@@ -206,8 +206,10 @@
std::vector<int> queued_picture_buffer_ids_;
// To expose client callbacks from VideoDecodeAccelerator.
- // NOTE: all calls to this object *MUST* be executed in message_loop_.
- Client* client_;
+ // NOTE: all calls to these objects *MUST* be executed on
+ // message_loop_.
+ base::WeakPtrFactory<Client> client_ptr_factory_;
+ base::WeakPtr<Client> client_;
scoped_ptr<Gles2TextureToEglImageTranslator> texture_to_egl_image_translator_;
diff --git a/content/common/gpu/media/rendering_helper_gl.cc b/content/common/gpu/media/rendering_helper_gl.cc
index fc58a7e..dd32163 100644
--- a/content/common/gpu/media/rendering_helper_gl.cc
+++ b/content/common/gpu/media/rendering_helper_gl.cc
@@ -119,7 +119,7 @@
void MakeCurrent(int window_id);
- MessageLoop* message_loop_;
+ base::MessageLoop* message_loop_;
std::vector<gfx::Size> dimensions_;
bool suppress_swap_to_display_;
@@ -210,7 +210,7 @@
CHECK_GT(dimensions.size(), 0U);
dimensions_ = dimensions;
- message_loop_ = MessageLoop::current();
+ message_loop_ = base::MessageLoop::current();
CHECK_GT(num_windows, 0);
#if GL_VARIANT_GLX
@@ -398,7 +398,7 @@
}
void RenderingHelperGL::UnInitialize(base::WaitableEvent* done) {
- CHECK_EQ(MessageLoop::current(), message_loop_);
+ CHECK_EQ(base::MessageLoop::current(), message_loop_);
#if GL_VARIANT_GLX
glXDestroyContext(x_display_, gl_context_);
@@ -417,7 +417,7 @@
uint32 texture_target,
uint32* texture_id,
base::WaitableEvent* done) {
- if (MessageLoop::current() != message_loop_) {
+ if (base::MessageLoop::current() != message_loop_) {
message_loop_->PostTask(
FROM_HERE,
base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this),
@@ -444,7 +444,7 @@
}
void RenderingHelperGL::RenderTexture(uint32 texture_id) {
- CHECK_EQ(MessageLoop::current(), message_loop_);
+ CHECK_EQ(base::MessageLoop::current(), message_loop_);
size_t window_id = texture_id_to_surface_index_[texture_id];
MakeCurrent(window_id);
int dimensions_id = window_id % dimensions_.size();
diff --git a/content/common/gpu/media/rendering_helper_mac.mm b/content/common/gpu/media/rendering_helper_mac.mm
deleted file mode 100644
index a315791..0000000
--- a/content/common/gpu/media/rendering_helper_mac.mm
+++ /dev/null
@@ -1,222 +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/common/gpu/media/rendering_helper.h"
-
-#import <Cocoa/Cocoa.h>
-#import <OpenGL/CGLMacro.h>
-
-#include "base/mac/scoped_nsautorelease_pool.h"
-#include "base/memory/scoped_nsobject.h"
-#include "base/message_loop.h"
-#include "base/synchronization/waitable_event.h"
-
-// Gets the pixel format to be used by the OpenGL view.
-static scoped_nsobject<NSOpenGLPixelFormat> GetPixelFormat() {
- NSOpenGLPixelFormatAttribute attributes[] = {
- NSOpenGLPFAWindow,
- NSOpenGLPFADoubleBuffer,
- NSOpenGLPFAAccelerated,
- NSOpenGLPFANoRecovery,
- NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)32,
- NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)8,
- NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)24,
- (NSOpenGLPixelFormatAttribute)0
- };
- return scoped_nsobject<NSOpenGLPixelFormat>(
- [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]);
-}
-
-// Gets the CGLContext from the given OpenGL view.
-static CGLContextObj GetCGLContext(NSOpenGLView* gl_view) {
- return static_cast<CGLContextObj>([[gl_view openGLContext] CGLContextObj]);
-}
-
-// Sets up a view port for the OpenGL view.
-static void SetupGLViewPort(NSOpenGLView* gl_view, int width, int height) {
- CGLContextObj cgl_ctx = GetCGLContext(gl_view);
- glViewport(0, 0, width, height);
- glClearColor(1.0, 0.0, 0.0, 0.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- [[gl_view openGLContext] flushBuffer];
- CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
-}
-
-// Draw the given texture to the OpenGL view.
-static void DrawTexture(NSOpenGLView* gl_view,
- GLuint texture_id,
- bool suppress_swap_to_display) {
- CGLContextObj cgl_ctx = GetCGLContext(gl_view);
- [gl_view lockFocus];
-
- GLfloat width = [gl_view bounds].size.width;
- GLfloat height = [gl_view bounds].size.height;
-
- glEnable(GL_TEXTURE_RECTANGLE_ARB);
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_id);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0.0, height);
- glVertex3f(-1.0, -1.0, 0.0);
- glTexCoord2f(width, height);
- glVertex3f(1.0, -1.0, 0.0);
- glTexCoord2f(width, 0.0);
- glVertex3f(1.0, 1.0, 0.0);
- glTexCoord2f(0.0, 0.0);
- glVertex3f(-1.0, 1.0, 0.0);
- glEnd();
-
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
- glDisable(GL_TEXTURE_RECTANGLE_ARB);
-
- if (!suppress_swap_to_display)
- [[gl_view openGLContext] flushBuffer];
- [gl_view unlockFocus];
- CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
-}
-
-namespace content {
-
-class RenderingHelperMac : public RenderingHelper {
- public:
- RenderingHelperMac();
- virtual ~RenderingHelperMac();
-
- // Implement RenderingHelper.
- virtual void Initialize(bool suppress_swap_to_display,
- int num_windows,
- const std::vector<gfx::Size>& dimensions,
- base::WaitableEvent* done) OVERRIDE;
- virtual void UnInitialize(base::WaitableEvent* done) OVERRIDE;
- virtual void CreateTexture(int window_id,
- uint32 texture_target,
- GLuint* texture_id,
- base::WaitableEvent* done) OVERRIDE;
- virtual void RenderTexture(GLuint texture_id) OVERRIDE;
- virtual void DeleteTexture(GLuint texture_id) OVERRIDE;
- virtual void* GetGLContext() OVERRIDE;
- virtual void* GetGLDisplay() OVERRIDE;
-
- private:
- MessageLoop* message_loop_;
- int width_;
- int height_;
- bool suppress_swap_to_display_;
- scoped_nsobject<NSWindow> window_;
- scoped_nsobject<NSOpenGLView> gl_view_;
- base::mac::ScopedNSAutoreleasePool pool_;
-};
-
-// static
-RenderingHelper* RenderingHelper::Create() {
- return new RenderingHelperMac;
-}
-
-// static
-void RenderingHelper::InitializePlatform() {
- // Initialize the Cocoa framework.
- base::mac::ScopedNSAutoreleasePool pool_;
- [NSApplication sharedApplication];
-}
-
-RenderingHelperMac::RenderingHelperMac()
- : message_loop_(NULL),
- width_(0),
- height_(0),
- suppress_swap_to_display_(false) {
-}
-
-RenderingHelperMac::~RenderingHelperMac() {
- CHECK_EQ(width_, 0) << "Must call UnInitialize before dtor.";
-}
-
-void RenderingHelperMac::Initialize(
- bool suppress_swap_to_display,
- int num_windows,
- const std::vector<gfx::Size>& dimensions,
- base::WaitableEvent* done) {
- // Use width_ != 0 as a proxy for the class having already been
- // Initialize()'d, and UnInitialize() before continuing.
- if (width_) {
- base::WaitableEvent done2(false, false);
- UnInitialize(&done2);
- done2.Wait();
- }
-
- // A separate window is created for each decoder. Since the Mac API
- // only supports a single instance only one window should be created.
- CHECK_EQ(num_windows, 1);
-
- // There should be only one window dimension as only one window is created.
- CHECK_EQ(dimensions.size(), 1U);
- width_ = dimensions[0].width();
- height_ = dimensions[0].height();
- suppress_swap_to_display_ = suppress_swap_to_display;
- message_loop_ = MessageLoop::current();
-
- // Create a window to host the OpenGL contents.
- NSRect rect = NSMakeRect(0, 0, width_, height_);
- window_.reset([[NSWindow alloc]
- initWithContentRect:rect
- styleMask:NSTitledWindowMask
- backing:NSBackingStoreBuffered
- defer:NO]);
- [window_ center];
- [window_ makeKeyAndOrderFront:nil];
-
- // Create an OpenGL view.
- scoped_nsobject<NSOpenGLPixelFormat> pixel_format(GetPixelFormat());
- gl_view_.reset([[NSOpenGLView alloc] initWithFrame:rect
- pixelFormat:pixel_format]);
- [[window_ contentView] addSubview:gl_view_];
- SetupGLViewPort(gl_view_, width_, height_);
-
- done->Signal();
-}
-
-void RenderingHelperMac::UnInitialize(base::WaitableEvent* done) {
- CHECK_EQ(MessageLoop::current(), message_loop_);
- width_ = 0;
- height_ = 0;
- message_loop_ = NULL;
- [window_ close];
- window_.reset();
- gl_view_.reset();
- done->Signal();
-}
-
-void RenderingHelperMac::CreateTexture(int window_id,
- uint32 texture_target,
- GLuint* texture_id,
- base::WaitableEvent* done) {
- CHECK_EQ(MessageLoop::current(), message_loop_);
- CHECK_EQ(static_cast<uint32>(GL_TEXTURE_RECTANGLE_ARB), texture_target);
- CGLContextObj cgl_ctx = GetCGLContext(gl_view_);
- glGenTextures(1, texture_id);
- CHECK_EQ(GL_NO_ERROR, static_cast<int>(glGetError()));
- done->Signal();
-}
-
-void RenderingHelperMac::RenderTexture(GLuint texture_id) {
- CHECK_EQ(MessageLoop::current(), message_loop_);
- DrawTexture(gl_view_, texture_id, suppress_swap_to_display_);
-}
-
-void RenderingHelperMac::DeleteTexture(GLuint texture_id) {
- CHECK_EQ(MessageLoop::current(), message_loop_);
- CGLContextObj cgl_ctx = GetCGLContext(gl_view_);
- glDeleteTextures(1, &texture_id);
- CHECK_EQ(GL_NO_ERROR, static_cast<int>(glGetError()));
-}
-
-void* RenderingHelperMac::GetGLContext() {
- return GetCGLContext(gl_view_);
-}
-
-void* RenderingHelperMac::GetGLDisplay() {
- return NULL;
-}
-
-} // namespace content
diff --git a/content/common/gpu/media/vaapi_h264_decoder.cc b/content/common/gpu/media/vaapi_h264_decoder.cc
index 65fd5cd..03cfc4f 100644
--- a/content/common/gpu/media/vaapi_h264_decoder.cc
+++ b/content/common/gpu/media/vaapi_h264_decoder.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/metrics/histogram.h"
#include "base/stl_util.h"
#include "content/common/gpu/gl_scoped_binders.h"
#include "content/common/gpu/media/vaapi_h264_decoder.h"
@@ -16,19 +17,43 @@
#include "third_party/libva/va/va_x11.h"
#include "ui/gl/gl_bindings.h"
+namespace {
+
+enum VAVDAH264DecoderFailure {
+ FRAME_MBS_ONLY_FLAG_NOT_ONE = 0,
+ GAPS_IN_FRAME_NUM = 1,
+ MID_STREAM_RESOLUTION_CHANGE = 2,
+ INTERLACED_STREAM = 3,
+ VAAPI_ERROR = 4,
+ VAVDA_H264_DECODER_FAILURES_MAX,
+};
+
+static void ReportToUMA(VAVDAH264DecoderFailure failure) {
+ UMA_HISTOGRAM_ENUMERATION("Media.VAVDAH264.DecoderFailure",
+ failure,
+ VAVDA_H264_DECODER_FAILURES_MAX);
+}
+
+} // namespace
+
+#define LOG_VA_ERROR_AND_RECORD_UMA(va_res, err_msg) \
+ do { \
+ DVLOG(1) << err_msg \
+ << " VA error: " << VAAPI_ErrorStr(va_res); \
+ ReportToUMA(VAAPI_ERROR); \
+ } while (0)
+
#define VA_LOG_ON_ERROR(va_res, err_msg) \
do { \
if ((va_res) != VA_STATUS_SUCCESS) { \
- DVLOG(1) << err_msg \
- << " VA error: " << VAAPI_ErrorStr(va_res); \
+ LOG_VA_ERROR_AND_RECORD_UMA(va_res, err_msg); \
} \
} while (0)
#define VA_SUCCESS_OR_RETURN(va_res, err_msg, ret) \
do { \
if ((va_res) != VA_STATUS_SUCCESS) { \
- DVLOG(1) << err_msg \
- << " VA error: " << VAAPI_ErrorStr(va_res); \
+ LOG_VA_ERROR_AND_RECORD_UMA(va_res, err_msg); \
return (ret); \
} \
} while (0)
@@ -479,7 +504,7 @@
scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> glx_fb_configs(
glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr,
&num_fbconfigs));
- if (!glx_fb_configs.get())
+ if (!glx_fb_configs)
return false;
if (!num_fbconfigs)
return false;
@@ -1940,6 +1965,7 @@
} else {
// Shouldn't get here.
DVLOG(1) << "Interlaced video not supported.";
+ ReportToUMA(INTERLACED_STREAM);
}
} else {
// Stream has instructions how to discard pictures from DPB and how
@@ -1950,6 +1976,7 @@
} else {
// Shouldn't get here.
DVLOG(1) << "Interlaced video not supported.";
+ ReportToUMA(INTERLACED_STREAM);
}
}
}
@@ -2018,7 +2045,7 @@
if (!(*output_candidate)->ref) {
// Current picture hasn't been inserted into DPB yet, so don't remove it
// if we managed to output it immediately.
- if (*output_candidate != pic.get())
+ if (*output_candidate != pic)
dpb_.RemoveByPOC((*output_candidate)->pic_order_cnt);
// Mark as unused.
UnassignSurfaceFromPoC((*output_candidate)->pic_order_cnt);
@@ -2070,8 +2097,15 @@
const H264SPS* sps = parser_.GetSPS(sps_id);
DCHECK(sps);
+ if (sps->frame_mbs_only_flag == 0) {
+ DVLOG(1) << "frame_mbs_only_flag != 1 not supported";
+ ReportToUMA(FRAME_MBS_ONLY_FLAG_NOT_ONE);
+ return false;
+ }
+
if (sps->gaps_in_frame_num_value_allowed_flag) {
DVLOG(1) << "Gaps in frame numbers not supported";
+ ReportToUMA(GAPS_IN_FRAME_NUM);
return false;
}
@@ -2095,6 +2129,7 @@
if ((pic_width_ != -1 || pic_height_ != -1) &&
(width != pic_width_ || height != pic_height_)) {
DVLOG(1) << "Picture size changed mid-stream";
+ ReportToUMA(MID_STREAM_RESOLUTION_CHANGE);
return false;
}
@@ -2144,6 +2179,7 @@
if (prev_frame_num_ > 0 && prev_frame_num_ < frame_num_ - 1) {
DVLOG(1) << "Gap in frame_num!";
+ ReportToUMA(GAPS_IN_FRAME_NUM);
return false;
}
diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/content/common/gpu/media/vaapi_video_decode_accelerator.cc
index 679162c..a401ef6 100644
--- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc
+++ b/content/common/gpu/media/vaapi_video_decode_accelerator.cc
@@ -36,8 +36,8 @@
}
void VaapiVideoDecodeAccelerator::NotifyError(Error error) {
- if (message_loop_ != MessageLoop::current()) {
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ if (message_loop_ != base::MessageLoop::current()) {
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
message_loop_->PostTask(FROM_HERE, base::Bind(
&VaapiVideoDecodeAccelerator::NotifyError, weak_this_, error));
return;
@@ -64,7 +64,7 @@
state_(kUninitialized),
input_ready_(&lock_),
output_ready_(&lock_),
- message_loop_(MessageLoop::current()),
+ message_loop_(base::MessageLoop::current()),
weak_this_(base::AsWeakPtr(this)),
client_ptr_factory_(client),
client_(client_ptr_factory_.GetWeakPtr()),
@@ -79,12 +79,12 @@
}
VaapiVideoDecodeAccelerator::~VaapiVideoDecodeAccelerator() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
}
bool VaapiVideoDecodeAccelerator::Initialize(
media::VideoCodecProfile profile) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
base::AutoLock auto_lock(lock_);
DCHECK_EQ(state_, kUninitialized);
@@ -114,7 +114,8 @@
int32 output_id,
scoped_ptr<std::queue<VABufferID> > va_bufs,
scoped_ptr<std::queue<VABufferID> > slice_bufs) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
+ base::AutoLock auto_lock(lock_);
TRACE_EVENT1("Video Decoder", "VAVDA::Decode", "output_id", output_id);
@@ -130,7 +131,7 @@
void VaapiVideoDecodeAccelerator::NotifyPictureReady(int32 input_id,
int32 output_id) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
TRACE_EVENT2("Video Decoder", "VAVDA::NotifyPictureReady",
"input_id", input_id, "output_id", output_id);
@@ -160,7 +161,7 @@
void VaapiVideoDecodeAccelerator::MapAndQueueNewInputBuffer(
const media::BitstreamBuffer& bitstream_buffer) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
TRACE_EVENT1("Video Decoder", "MapAndQueueNewInputBuffer", "input_id",
bitstream_buffer.id());
@@ -189,7 +190,7 @@
}
void VaapiVideoDecodeAccelerator::InitialDecodeTask() {
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
base::AutoLock auto_lock(lock_);
// Try to initialize or resume playback after reset.
@@ -209,7 +210,7 @@
case VaapiH264Decoder::kReadyToDecode:
if (state_ == kInitialized) {
state_ = kPicturesRequested;
- int num_pics = decoder_.GetRequiredNumOfPictures();
+ size_t num_pics = decoder_.GetRequiredNumOfPictures();
gfx::Size size(decoder_.pic_width(), decoder_.pic_height());
DVLOG(1) << "Requesting " << num_pics << " pictures of size: "
<< size.width() << "x" << size.height();
@@ -250,7 +251,7 @@
}
bool VaapiVideoDecodeAccelerator::GetInputBuffer_Locked() {
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
lock_.AssertAcquired();
if (curr_input_buffer_.get())
@@ -298,7 +299,7 @@
void VaapiVideoDecodeAccelerator::ReturnCurrInputBuffer_Locked() {
lock_.AssertAcquired();
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DCHECK(curr_input_buffer_.get());
int32 id = curr_input_buffer_->id;
@@ -314,7 +315,7 @@
bool VaapiVideoDecodeAccelerator::GetOutputBuffers_Locked() {
lock_.AssertAcquired();
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
while (output_buffers_.empty() &&
(state_ == kDecoding || state_ == kFlushing || state_ == kIdle)) {
@@ -333,7 +334,7 @@
}
void VaapiVideoDecodeAccelerator::DecodeTask() {
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
TRACE_EVENT0("Video Decoder", "VAVDA::DecodeTask");
base::AutoLock auto_lock(lock_);
@@ -346,10 +347,7 @@
DCHECK(curr_input_buffer_.get());
VaapiH264Decoder::DecResult res;
- {
- base::AutoUnlock auto_unlock(lock_);
- res = decoder_.DecodeOneFrame(curr_input_buffer_->id);
- }
+ res = decoder_.DecodeOneFrame(curr_input_buffer_->id);
switch (res) {
case VaapiH264Decoder::kNeedMoreStreamData:
@@ -383,7 +381,7 @@
void VaapiVideoDecodeAccelerator::Decode(
const media::BitstreamBuffer& bitstream_buffer) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
TRACE_EVENT1("Video Decoder", "VAVDA::Decode", "Buffer id",
bitstream_buffer.id());
@@ -427,10 +425,14 @@
void VaapiVideoDecodeAccelerator::AssignPictureBuffers(
const std::vector<media::PictureBuffer>& buffers) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
base::AutoLock auto_lock(lock_);
DCHECK_EQ(state_, kPicturesRequested);
+ size_t num_pics = decoder_.GetRequiredNumOfPictures();
+ RETURN_AND_NOTIFY_ON_FAILURE((num_pics == buffers.size()),
+ "Failed to provide requested picture buffers. (Got " << buffers.size() <<
+ ", requested " << num_pics << ")", INVALID_ARGUMENT,);
for (size_t i = 0; i < buffers.size(); ++i) {
DVLOG(2) << "Assigning picture id " << buffers[i].id()
@@ -449,7 +451,7 @@
}
void VaapiVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
TRACE_EVENT1("Video Decoder", "VAVDA::ReusePictureBuffer", "Picture id",
picture_buffer_id);
@@ -462,9 +464,11 @@
}
void VaapiVideoDecodeAccelerator::FlushTask() {
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
DVLOG(1) << "Flush task";
+ base::AutoLock auto_lock(lock_);
+
// First flush all the pictures that haven't been outputted, notifying the
// client to output them.
bool res = decoder_.Flush();
@@ -479,7 +483,7 @@
}
void VaapiVideoDecodeAccelerator::Flush() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
DVLOG(1) << "Got flush request";
base::AutoLock auto_lock(lock_);
@@ -493,7 +497,7 @@
}
void VaapiVideoDecodeAccelerator::FinishFlush() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
base::AutoLock auto_lock(lock_);
if (state_ != kFlushing) {
@@ -510,15 +514,15 @@
}
void VaapiVideoDecodeAccelerator::ResetTask() {
- DCHECK_EQ(decoder_thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
+
+ base::AutoLock auto_lock(lock_);
// All the decoding tasks from before the reset request from client are done
// by now, as this task was scheduled after them and client is expected not
// to call Decode() after Reset() and before NotifyResetDone.
decoder_.Reset();
- base::AutoLock auto_lock(lock_);
-
// Return current input buffer, if present.
if (curr_input_buffer_.get())
ReturnCurrInputBuffer_Locked();
@@ -529,7 +533,7 @@
}
void VaapiVideoDecodeAccelerator::Reset() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
DVLOG(1) << "Got reset request";
// This will make any new decode tasks exit early.
@@ -552,7 +556,7 @@
}
void VaapiVideoDecodeAccelerator::FinishReset() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
base::AutoLock auto_lock(lock_);
if (state_ != kResetting) {
@@ -580,7 +584,7 @@
}
void VaapiVideoDecodeAccelerator::Cleanup() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
if (state_ == kUninitialized || state_ == kDestroying)
return;
@@ -608,7 +612,7 @@
}
void VaapiVideoDecodeAccelerator::Destroy() {
- DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(message_loop_, base::MessageLoop::current());
Cleanup();
delete this;
}
diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.h b/content/common/gpu/media/vaapi_video_decode_accelerator.h
index f1cd07a..8c6b71b 100644
--- a/content/common/gpu/media/vaapi_video_decode_accelerator.h
+++ b/content/common/gpu/media/vaapi_video_decode_accelerator.h
@@ -184,7 +184,7 @@
base::ConditionVariable output_ready_;
// ChildThread's message loop
- MessageLoop* message_loop_;
+ base::MessageLoop* message_loop_;
// WeakPtr<> pointing to |this| for use in posting tasks from the decoder
// thread back to the ChildThread. Because the decoder thread is a member of
diff --git a/content/common/gpu/media/video_decode_accelerator_unittest.cc b/content/common/gpu/media/video_decode_accelerator_unittest.cc
index 6b01a9a..764689f 100644
--- a/content/common/gpu/media/video_decode_accelerator_unittest.cc
+++ b/content/common/gpu/media/video_decode_accelerator_unittest.cc
@@ -44,12 +44,9 @@
#if defined(OS_WIN)
#include "content/common/gpu/media/dxva_video_decode_accelerator.h"
-#elif defined(OS_MACOSX)
-#include "content/common/gpu/media/mac_video_decode_accelerator.h"
#elif defined(OS_CHROMEOS)
#if defined(ARCH_CPU_ARMEL)
#include "content/common/gpu/media/exynos_video_decode_accelerator.h"
-#include "content/common/gpu/media/omx_video_decode_accelerator.h"
#elif defined(ARCH_CPU_X86_FAMILY)
#include "content/common/gpu/media/vaapi_video_decode_accelerator.h"
#endif // ARCH_CPU_ARMEL
@@ -79,14 +76,18 @@
// (the latter tests just decode speed).
// - |profile| is the media::VideoCodecProfile set during Initialization.
// An empty value for a numeric field means "ignore".
-#if defined(OS_MACOSX)
-const base::FilePath::CharType* test_video_data =
- FILE_PATH_LITERAL("test-25fps_high.h264:1280:720:250:252:50:100:4");
-#else
const base::FilePath::CharType* test_video_data =
// FILE_PATH_LITERAL("test-25fps.vp8:320:240:250:250:50:175:11");
FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1");
-#endif
+
+// Magic constants for differentiating the reasons for NotifyResetDone being
+// called.
+enum ResetPoint {
+ MID_STREAM_RESET = -2,
+ END_OF_STREAM_RESET = -1
+};
+
+const int kMaxResetAfterFrameNum = 100;
struct TestVideoFile {
explicit TestVideoFile(base::FilePath::StringType file_name)
@@ -97,7 +98,8 @@
num_fragments(-1),
min_fps_render(-1),
min_fps_no_render(-1),
- profile(-1) {
+ profile(-1),
+ reset_after_frame_num(END_OF_STREAM_RESET) {
}
base::FilePath::StringType file_name;
@@ -108,6 +110,7 @@
int min_fps_render;
int min_fps_no_render;
int profile;
+ int reset_after_frame_num;
std::string data_str;
};
@@ -116,7 +119,7 @@
// missing required data. Unspecified optional fields are set to -1.
void ParseAndReadTestVideoData(base::FilePath::StringType data,
size_t num_concurrent_decoders,
- int reset_after_frame_num,
+ int reset_point,
std::vector<TestVideoFile*>* test_video_files) {
std::vector<base::FilePath::StringType> entries;
base::SplitString(data, ';', &entries);
@@ -135,8 +138,14 @@
CHECK(base::StringToInt(fields[3], &video_file->num_frames));
// If we reset mid-stream and start playback over, account for frames
// that are decoded twice in our expectations.
- if (video_file->num_frames > 0 && reset_after_frame_num >= 0)
- video_file->num_frames += reset_after_frame_num;
+ if (video_file->num_frames > 0 && reset_point == MID_STREAM_RESET) {
+ // Reset should not go beyond the last frame; reset after the first
+ // frame for short videos.
+ video_file->reset_after_frame_num = kMaxResetAfterFrameNum;
+ if (video_file->num_frames <= kMaxResetAfterFrameNum)
+ video_file->reset_after_frame_num = 1;
+ video_file->num_frames += video_file->reset_after_frame_num;
+ }
}
if (!fields[4].empty())
CHECK(base::StringToInt(fields[4], &video_file->num_fragments));
@@ -214,13 +223,6 @@
return ret;
}
-// Magic constants for differentiating the reasons for NotifyResetDone being
-// called.
-enum ResetPoint {
- MID_STREAM_RESET = -2,
- END_OF_STREAM_RESET = -1
-};
-
// Client that can accept callbacks from a VideoDecodeAccelerator and is used by
// the TESTs below.
class GLRenderingVDAClient : public VideoDecodeAccelerator::Client {
@@ -361,9 +363,7 @@
SetState(CS_DESTROYED);
}
-#if !defined(OS_MACOSX)
static bool DoNothingReturnTrue() { return true; }
-#endif
void GLRenderingVDAClient::CreateDecoder() {
CHECK(decoder_deleted());
@@ -371,24 +371,13 @@
#if defined(OS_WIN)
decoder_.reset(new DXVAVideoDecodeAccelerator(
this, base::Bind(&DoNothingReturnTrue)));
-#elif defined(OS_MACOSX)
- decoder_.reset(new MacVideoDecodeAccelerator(
- static_cast<CGLContextObj>(rendering_helper_->GetGLContext()), this));
#elif defined(OS_CHROMEOS)
#if defined(ARCH_CPU_ARMEL)
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseExynosVda)) {
- decoder_.reset(
- new ExynosVideoDecodeAccelerator(
- static_cast<EGLDisplay>(rendering_helper_->GetGLDisplay()),
- static_cast<EGLContext>(rendering_helper_->GetGLContext()),
- this, base::Bind(&DoNothingReturnTrue)));
- } else {
- decoder_.reset(
- new OmxVideoDecodeAccelerator(
- static_cast<EGLDisplay>(rendering_helper_->GetGLDisplay()),
- static_cast<EGLContext>(rendering_helper_->GetGLContext()),
- this, base::Bind(&DoNothingReturnTrue)));
- }
+ decoder_.reset(
+ new ExynosVideoDecodeAccelerator(
+ static_cast<EGLDisplay>(rendering_helper_->GetGLDisplay()),
+ static_cast<EGLContext>(rendering_helper_->GetGLContext()),
+ this, base::Bind(&DoNothingReturnTrue)));
#elif defined(ARCH_CPU_X86_FAMILY)
decoder_.reset(new VaapiVideoDecodeAccelerator(
static_cast<Display*>(rendering_helper_->GetGLDisplay()),
@@ -710,11 +699,7 @@
// We assert a minimal number of concurrent decoders we expect to succeed.
// Different platforms can support more concurrent decoders, so we don't assert
// failure above this.
-#if defined(OS_MACOSX)
-enum { kMinSupportedNumConcurrentDecoders = 1 };
-#else
enum { kMinSupportedNumConcurrentDecoders = 3 };
-#endif
// Test the most straightforward case possible: data is decoded from a single
// chunk and rendered to the screen.
@@ -729,12 +714,12 @@
const size_t num_concurrent_decoders = GetParam().b;
const size_t num_in_flight_decodes = GetParam().c;
const int num_play_throughs = GetParam().d;
- const int reset_after_frame_num = GetParam().e;
+ const int reset_point = GetParam().e;
const int delete_decoder_state = GetParam().f;
std::vector<TestVideoFile*> test_video_files;
ParseAndReadTestVideoData(test_video_data, num_concurrent_decoders,
- reset_after_frame_num, &test_video_files);
+ reset_point, &test_video_files);
// Suppress GL swapping in all but a few tests, to cut down overall test
// runtime.
@@ -746,11 +731,11 @@
// Initialize the rendering helper.
base::Thread rendering_thread("GLRenderingVDAClientThread");
base::Thread::Options options;
- options.message_loop_type = MessageLoop::TYPE_DEFAULT;
+ options.message_loop_type = base::MessageLoop::TYPE_DEFAULT;
#if defined(OS_WIN)
// For windows the decoding thread initializes the media foundation decoder
// which uses COM. We need the thread to be a UI thread.
- options.message_loop_type = MessageLoop::TYPE_UI;
+ options.message_loop_type = base::MessageLoop::TYPE_UI;
#endif // OS_WIN
rendering_thread.StartWithOptions(options);
@@ -779,8 +764,8 @@
GLRenderingVDAClient* client = new GLRenderingVDAClient(
rendering_helper.get(), index, note, video_file->data_str,
num_fragments_per_decode, num_in_flight_decodes, num_play_throughs,
- reset_after_frame_num, delete_decoder_state, video_file->width,
- video_file->height, video_file->profile);
+ video_file->reset_after_frame_num, delete_decoder_state,
+ video_file->width, video_file->height, video_file->profile);
clients[index] = client;
rendering_thread.message_loop()->PostTask(
@@ -838,9 +823,15 @@
continue;
GLRenderingVDAClient* client = clients[i];
TestVideoFile* video_file = test_video_files[i % test_video_files.size()];
- if (video_file->num_frames > 0)
- EXPECT_EQ(client->num_decoded_frames(), video_file->num_frames);
- if (reset_after_frame_num < 0) {
+ if (video_file->num_frames > 0) {
+ // Expect the decoded frames may be more than the video frames as frames
+ // could still be returned until resetting done.
+ if (video_file->reset_after_frame_num > 0)
+ EXPECT_GE(client->num_decoded_frames(), video_file->num_frames);
+ else
+ EXPECT_EQ(client->num_decoded_frames(), video_file->num_frames);
+ }
+ if (reset_point == END_OF_STREAM_RESET) {
EXPECT_EQ(video_file->num_fragments, client->num_skipped_fragments() +
client->num_queued_fragments());
EXPECT_EQ(client->num_done_bitstream_buffers(),
@@ -886,7 +877,7 @@
INSTANTIATE_TEST_CASE_P(
MidStreamReset, VideoDecodeAcceleratorTest,
::testing::Values(
- MakeTuple(1, 1, 1, 1, static_cast<ResetPoint>(100), CS_RESET)));
+ MakeTuple(1, 1, 1, 1, MID_STREAM_RESET, CS_RESET)));
// Test that Destroy() mid-stream works fine (primarily this is testing that no
// crashes occur).
@@ -974,10 +965,6 @@
}
if (it->first == "v" || it->first == "vmodule")
continue;
-#if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL)
- if (it->first == switches::kUseExynosVda)
- continue;
-#endif
LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second;
}
@@ -988,10 +975,7 @@
content::DXVAVideoDecodeAccelerator::PreSandboxInitialization();
#elif defined(OS_CHROMEOS)
#if defined(ARCH_CPU_ARMEL)
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseExynosVda))
- content::ExynosVideoDecodeAccelerator::PreSandboxInitialization();
- else
- content::OmxVideoDecodeAccelerator::PreSandboxInitialization();
+ content::ExynosVideoDecodeAccelerator::PreSandboxInitialization();
#elif defined(ARCH_CPU_X86_FAMILY)
content::VaapiVideoDecodeAccelerator::PreSandboxInitialization();
#endif // ARCH_CPU_ARMEL
diff --git a/content/common/gpu/stream_texture_manager_android.cc b/content/common/gpu/stream_texture_manager_android.cc
index 6eb7a10..8b663a9 100644
--- a/content/common/gpu/stream_texture_manager_android.cc
+++ b/content/common/gpu/stream_texture_manager_android.cc
@@ -5,17 +5,17 @@
#include "content/common/gpu/stream_texture_manager_android.h"
#include "base/bind.h"
-#include "content/common/android/surface_texture_bridge.h"
#include "content/common/gpu/gpu_channel.h"
#include "content/common/gpu/gpu_messages.h"
#include "gpu/command_buffer/service/stream_texture.h"
#include "ui/gfx/size.h"
+#include "ui/gl/android/surface_texture_bridge.h"
namespace content {
StreamTextureManagerAndroid::StreamTextureAndroid::StreamTextureAndroid(
GpuChannel* channel, int service_id)
- : surface_texture_bridge_(new SurfaceTextureBridge(service_id)),
+ : surface_texture_bridge_(new gfx::SurfaceTextureBridge(service_id)),
has_updated_(false),
channel_(channel) {
memset(current_matrix_, 0, sizeof(current_matrix_));
diff --git a/content/common/gpu/stream_texture_manager_android.h b/content/common/gpu/stream_texture_manager_android.h
index e514fc9..0f7dea9 100644
--- a/content/common/gpu/stream_texture_manager_android.h
+++ b/content/common/gpu/stream_texture_manager_android.h
@@ -17,13 +17,12 @@
namespace gfx {
class Size;
+class SurfaceTextureBridge;
}
namespace content {
class GpuChannel;
-class SurfaceTextureBridge;
-
// Class for managing the stream texture.
class StreamTextureManagerAndroid : public gpu::StreamTextureManager {
public:
@@ -57,7 +56,7 @@
virtual void Update() OVERRIDE;
- scoped_refptr<SurfaceTextureBridge> surface_texture_bridge() {
+ scoped_refptr<gfx::SurfaceTextureBridge> surface_texture_bridge() {
return surface_texture_bridge_;
}
@@ -75,7 +74,7 @@
}
private:
- scoped_refptr<SurfaceTextureBridge> surface_texture_bridge_;
+ scoped_refptr<gfx::SurfaceTextureBridge> surface_texture_bridge_;
// Current transform matrix of the surface texture.
float current_matrix_[16];
diff --git a/content/common/gpu/testdata/bear.README b/content/common/gpu/testdata/bear.README
new file mode 100644
index 0000000..177951d
--- /dev/null
+++ b/content/common/gpu/testdata/bear.README
@@ -0,0 +1,7 @@
+bear video files in this directory and their provenance:
+
+bear.h264:
+ Using ffmpeg version 0.8.6-4:0.8.6-0ubuntu0.12.04.1, generated with
+ bear.mp4 (https://chromiumcodereview.appspot.com/10805089):
+ ffmpeg -i bear.mp4 -vcodec copy -vbsf h264_mp4toannexb \
+ -an bear.h264
diff --git a/content/common/gpu/testdata/bear.h264 b/content/common/gpu/testdata/bear.h264
new file mode 100644
index 0000000..aaf0a9f
--- /dev/null
+++ b/content/common/gpu/testdata/bear.h264
Binary files differ
diff --git a/content/common/gpu/testdata/npot-video.README b/content/common/gpu/testdata/npot-video.README
new file mode 100644
index 0000000..ff1378b
--- /dev/null
+++ b/content/common/gpu/testdata/npot-video.README
@@ -0,0 +1,29 @@
+npot-video video files in this directory and their provenance:
+
+npot-video.h264:
+ Using ffmpeg version 0.8.6-4:0.8.6-0ubuntu0.12.04.1, generated with
+ npot-video.mp4 (https://codereview.chromium.org/8342021):
+ ffmpeg -i npot-video.mp4 -vcodec copy -vbsf h264_mp4toannexb \
+ -an npot-video.h264
+
+
+Copyright (c) 2012 The Khronos Group Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and/or associated documentation files (the
+"Materials"), to deal in the Materials without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Materials, and to
+permit persons to whom the Materials are furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Materials.
+
+THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
diff --git a/content/common/gpu/testdata/npot-video.h264 b/content/common/gpu/testdata/npot-video.h264
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/content/common/gpu/testdata/npot-video.h264
diff --git a/content/common/gpu/testdata/red-green.README b/content/common/gpu/testdata/red-green.README
new file mode 100644
index 0000000..0f31b90
--- /dev/null
+++ b/content/common/gpu/testdata/red-green.README
@@ -0,0 +1,29 @@
+red-green video files in this directory and their provenance:
+
+red-green.h264:
+ Using ffmpeg version 0.8.6-4:0.8.6-0ubuntu0.12.04.1, generated with
+ red-green.mp4 (https://codereview.chromium.org/8342021):
+ ffmpeg -i red-green.mp4 -vcodec copy -vbsf h264_mp4toannexb \
+ -an red-green.h264
+
+
+Copyright (c) 2012 The Khronos Group Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and/or associated documentation files (the
+"Materials"), to deal in the Materials without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Materials, and to
+permit persons to whom the Materials are furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Materials.
+
+THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
diff --git a/content/common/gpu/testdata/red-green.h264 b/content/common/gpu/testdata/red-green.h264
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/content/common/gpu/testdata/red-green.h264
diff --git a/content/common/gpu/testdata/README b/content/common/gpu/testdata/test-25fps.README
similarity index 88%
rename from content/common/gpu/testdata/README
rename to content/common/gpu/testdata/test-25fps.README
index 0c0e63f..ba46586 100644
--- a/content/common/gpu/testdata/README
+++ b/content/common/gpu/testdata/test-25fps.README
@@ -1,4 +1,4 @@
-Files in this directory and their provenance:
+test-25fps video files in this directory and their provenance:
test-25fps.h264:
Using ffmpeg SVN-r0.5.9-4:0.5.9-0ubuntu0.10.04.1 @ WebKit r122718, generated
diff --git a/content/common/gpu/texture_image_transport_surface.cc b/content/common/gpu/texture_image_transport_surface.cc
index 5eeb2a1..9710b35 100644
--- a/content/common/gpu/texture_image_transport_surface.cc
+++ b/content/common/gpu/texture_image_transport_surface.cc
@@ -54,7 +54,7 @@
GpuChannelManager* manager = helper_->manager();
surface_ = manager->GetDefaultOffscreenSurface();
- if (!surface_.get())
+ if (!surface_)
return false;
if (!helper_->Initialize())
@@ -71,7 +71,7 @@
}
void TextureImageTransportSurface::Destroy() {
- if (surface_.get())
+ if (surface_)
surface_ = NULL;
helper_->Destroy();
@@ -173,10 +173,8 @@
CreateBackTexture();
}
-void TextureImageTransportSurface::OnWillDestroyStub(
- GpuCommandBufferStub* stub) {
- DCHECK(stub == helper_->stub());
- stub->RemoveDestructionObserver(this);
+void TextureImageTransportSurface::OnWillDestroyStub() {
+ helper_->stub()->RemoveDestructionObserver(this);
GpuHostMsg_AcceleratedSurfaceRelease_Params params;
helper_->SendAcceleratedSurfaceRelease(params);
@@ -194,8 +192,14 @@
stub_destroyed_ = true;
}
+void TextureImageTransportSurface::SetLatencyInfo(
+ const cc::LatencyInfo& latency_info) {
+ latency_info_ = latency_info;
+}
+
bool TextureImageTransportSurface::SwapBuffers() {
DCHECK(backbuffer_suggested_allocation_);
+
if (!frontbuffer_suggested_allocation_)
return true;
@@ -217,6 +221,7 @@
// so we do not leak a texture in the mailbox.
AddRef();
+ params.latency_info = latency_info_;
helper_->SendAcceleratedSurfaceBuffersSwapped(params);
DCHECK(!is_swap_buffers_pending_);
@@ -258,6 +263,7 @@
// so we do not leak a texture in the mailbox.
AddRef();
+ params.latency_info = latency_info_;
helper_->SendAcceleratedSurfacePostSubBuffer(params);
DCHECK(!is_swap_buffers_pending_);
@@ -321,7 +327,7 @@
// of the service ids.
DCHECK(context_.get() && surface_.get());
uint32 service_id = backbuffer_->ReleaseServiceId();
- if (context_->MakeCurrent(surface_.get()))
+ if (context_->MakeCurrent(surface_))
glDeleteTextures(1, &service_id);
return;
@@ -461,6 +467,7 @@
GL_CLAMP_TO_EDGE,
GL_NONE,
true,
+ false,
level_infos);
}
diff --git a/content/common/gpu/texture_image_transport_surface.h b/content/common/gpu/texture_image_transport_surface.h
index 93a54c5..9ab9abc 100644
--- a/content/common/gpu/texture_image_transport_surface.h
+++ b/content/common/gpu/texture_image_transport_surface.h
@@ -55,9 +55,11 @@
const AcceleratedSurfaceMsg_BufferPresented_Params& params) OVERRIDE;
virtual void OnResizeViewACK() OVERRIDE;
virtual void OnResize(gfx::Size size) OVERRIDE;
+ virtual void SetLatencyInfo(
+ const cc::LatencyInfo& latency_info) OVERRIDE;
// GpuCommandBufferStub::DestructionObserver implementation.
- virtual void OnWillDestroyStub(GpuCommandBufferStub* stub) OVERRIDE;
+ virtual void OnWillDestroyStub() OVERRIDE;
private:
@@ -117,6 +119,7 @@
// Holds a reference to the mailbox manager for cleanup.
scoped_refptr<gpu::gles2::MailboxManager> mailbox_manager_;
+ cc::LatencyInfo latency_info_;
DISALLOW_COPY_AND_ASSIGN(TextureImageTransportSurface);
};
diff --git a/content/common/icon_messages.h b/content/common/icon_messages.h
deleted file mode 100644
index 63f9ab9..0000000
--- a/content/common/icon_messages.h
+++ /dev/null
@@ -1,46 +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.
-
-// Multiply-included message file, no traditional include guard.
-#include <vector>
-
-#include "content/public/common/favicon_url.h"
-#include "ipc/ipc_message.h"
-#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_param_traits.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-#define IPC_MESSAGE_START IconMsgStart
-
-IPC_ENUM_TRAITS(content::FaviconURL::IconType)
-
-IPC_STRUCT_TRAITS_BEGIN(content::FaviconURL)
- IPC_STRUCT_TRAITS_MEMBER(icon_url)
- IPC_STRUCT_TRAITS_MEMBER(icon_type)
-IPC_STRUCT_TRAITS_END()
-
-// Messages sent from the browser to the renderer.
-
-// Requests the renderer to download the specified favicon image, decode it,
-// and send the image data back via IconHostMsg_DidDownloadFavicon.
-IPC_MESSAGE_ROUTED4(IconMsg_DownloadFavicon,
- int /* identifier for the request */,
- GURL /* URL of the image */,
- bool /* is favicon (turn off cookies) */,
- int /* Preferred favicon size. Passed on to
- IconHostMsg_DidDownloadFavicon, unused otherwise */)
-
-// Messages sent from the renderer to the browser.
-
-// Notification that the urls for the favicon of a site has been determined.
-IPC_MESSAGE_ROUTED2(IconHostMsg_UpdateFaviconURL,
- int32 /* page_id */,
- std::vector<content::FaviconURL> /* urls of the favicon */)
-
-IPC_MESSAGE_ROUTED4(IconHostMsg_DidDownloadFavicon,
- int /* Identifier of the request */,
- GURL /* URL of the image */,
- int /* Preferred icon size passed to
- IconMsg_DownloadFavicon */,
- std::vector<SkBitmap> /* image_data */)
diff --git a/content/common/image_messages.h b/content/common/image_messages.h
new file mode 100644
index 0000000..78d7cff
--- /dev/null
+++ b/content/common/image_messages.h
@@ -0,0 +1,33 @@
+// 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.
+
+// Multiply-included message file, no traditional include guard.
+#include <vector>
+
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_message_macros.h"
+#include "ipc/ipc_param_traits.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+#define IPC_MESSAGE_START ImageMsgStart
+
+// Messages sent from the browser to the renderer.
+
+// Requests the renderer to download the specified image, decode it,
+// and send the image data back via ImageHostMsg_DidDownloadImage.
+IPC_MESSAGE_ROUTED4(ImageMsg_DownloadImage,
+ int /* identifier for the request */,
+ GURL /* URL of the image */,
+ bool /* is favicon (turn off cookies) */,
+ int /* Preferred image size. Passed on to
+ ImageHostMsg_DidDownloadFavicon, unused otherwise */)
+
+// Messages sent from the renderer to the browser.
+
+IPC_MESSAGE_ROUTED4(ImageHostMsg_DidDownloadImage,
+ int /* Identifier of the request */,
+ GURL /* URL of the image */,
+ int /* Preferred image size passed to
+ ImageMsg_DownloadImage */,
+ std::vector<SkBitmap> /* image_data */)
diff --git a/content/common/indexed_db/OWNERS b/content/common/indexed_db/OWNERS
index ba0cc18..ed5258c 100644
--- a/content/common/indexed_db/OWNERS
+++ b/content/common/indexed_db/OWNERS
@@ -12,3 +12,4 @@
per-file *_messages.h=jschuh@chromium.org
per-file *_messages.h=palmer@chromium.org
per-file *_messages.h=tsepez@chromium.org
+per-file *_messages.h=kenrb@chromium.org
diff --git a/content/common/indexed_db/indexed_db_dispatcher.cc b/content/common/indexed_db/indexed_db_dispatcher.cc
index f79b9dd..fc9f1a7 100644
--- a/content/common/indexed_db/indexed_db_dispatcher.cc
+++ b/content/common/indexed_db/indexed_db_dispatcher.cc
@@ -13,16 +13,12 @@
#include "content/common/indexed_db/proxy_webidbcursor_impl.h"
#include "content/common/indexed_db/proxy_webidbdatabase_impl.h"
#include "ipc/ipc_channel.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/WebIDBDatabaseException.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBKeyRange.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabaseCallbacks.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabaseError.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabaseException.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBKeyRange.h"
-using WebKit::WebDOMStringList;
using WebKit::WebData;
-using WebKit::WebExceptionCode;
-using WebKit::WebFrame;
using WebKit::WebIDBCallbacks;
using WebKit::WebIDBDatabase;
using WebKit::WebIDBDatabaseCallbacks;
@@ -170,6 +166,11 @@
}
bool IndexedDBDispatcher::Send(IPC::Message* msg) {
+ if (!ChildThread::current()) {
+ // Unexpected - this may be happening during shutdown.
+ NOTREACHED();
+ return false;
+ }
if (CurrentWorkerId()) {
scoped_refptr<IPC::SyncMessageFilter> filter(
ChildThread::current()->sync_message_filter());
@@ -181,8 +182,7 @@
void IndexedDBDispatcher::RequestIDBCursorAdvance(
unsigned long count,
WebIDBCallbacks* callbacks_ptr,
- int32 ipc_cursor_id,
- WebExceptionCode* ec) {
+ int32 ipc_cursor_id) {
// Reset all cursor prefetch caches except for this cursor.
ResetCursorPrefetchCaches(ipc_cursor_id);
@@ -196,8 +196,7 @@
void IndexedDBDispatcher::RequestIDBCursorContinue(
const IndexedDBKey& key,
WebIDBCallbacks* callbacks_ptr,
- int32 ipc_cursor_id,
- WebExceptionCode* ec) {
+ int32 ipc_cursor_id) {
// Reset all cursor prefetch caches except for this cursor.
ResetCursorPrefetchCaches(ipc_cursor_id);
@@ -212,8 +211,7 @@
void IndexedDBDispatcher::RequestIDBCursorPrefetch(
int n,
WebIDBCallbacks* callbacks_ptr,
- int32 ipc_cursor_id,
- WebExceptionCode* ec) {
+ int32 ipc_cursor_id) {
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
int32 ipc_callbacks_id = pending_callbacks_.Add(callbacks.release());
@@ -230,8 +228,7 @@
void IndexedDBDispatcher::RequestIDBCursorDelete(
WebIDBCallbacks* callbacks_ptr,
- int32 ipc_cursor_id,
- WebExceptionCode* ec) {
+ int32 ipc_cursor_id) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
@@ -243,54 +240,21 @@
void IndexedDBDispatcher::RequestIDBFactoryOpen(
const string16& name,
int64 version,
- WebIDBCallbacks* callbacks_ptr,
- WebIDBDatabaseCallbacks* database_callbacks_ptr,
- const string16& origin,
- WebFrame* web_frame) {
- ResetCursorPrefetchCaches();
- scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
- scoped_ptr<WebIDBDatabaseCallbacks>
- database_callbacks(database_callbacks_ptr);
-
- if (!CurrentWorkerId() &&
- !ChildThread::current()->IsWebFrameValid(web_frame))
- return;
-
- IndexedDBHostMsg_FactoryOpen_Params params;
- params.ipc_thread_id = CurrentWorkerId();
- params.ipc_callbacks_id = pending_callbacks_.Add(callbacks.release());
- params.ipc_database_callbacks_id = pending_database_callbacks_.Add(
- database_callbacks.release());
- params.origin = origin;
- params.name = name;
- params.transaction_id = 0;
- params.version = version;
- Send(new IndexedDBHostMsg_FactoryOpen(params));
-}
-
-void IndexedDBDispatcher::RequestIDBFactoryOpen(
- const string16& name,
- int64 version,
int64 transaction_id,
WebIDBCallbacks* callbacks_ptr,
WebIDBDatabaseCallbacks* database_callbacks_ptr,
- const string16& origin,
- WebFrame* web_frame) {
+ const string16& database_identifier) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
scoped_ptr<WebIDBDatabaseCallbacks>
database_callbacks(database_callbacks_ptr);
- if (!CurrentWorkerId() &&
- !ChildThread::current()->IsWebFrameValid(web_frame))
- return;
-
IndexedDBHostMsg_FactoryOpen_Params params;
params.ipc_thread_id = CurrentWorkerId();
params.ipc_callbacks_id = pending_callbacks_.Add(callbacks.release());
params.ipc_database_callbacks_id = pending_database_callbacks_.Add(
database_callbacks.release());
- params.origin = origin;
+ params.database_identifier = database_identifier;
params.name = name;
params.transaction_id = transaction_id;
params.version = version;
@@ -299,38 +263,28 @@
void IndexedDBDispatcher::RequestIDBFactoryGetDatabaseNames(
WebIDBCallbacks* callbacks_ptr,
- const string16& origin,
- WebFrame* web_frame) {
+ const string16& database_identifier) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
- if (!CurrentWorkerId() &&
- !ChildThread::current()->IsWebFrameValid(web_frame))
- return;
-
IndexedDBHostMsg_FactoryGetDatabaseNames_Params params;
params.ipc_thread_id = CurrentWorkerId();
params.ipc_callbacks_id = pending_callbacks_.Add(callbacks.release());
- params.origin = origin;
+ params.database_identifier = database_identifier;
Send(new IndexedDBHostMsg_FactoryGetDatabaseNames(params));
}
void IndexedDBDispatcher::RequestIDBFactoryDeleteDatabase(
const string16& name,
WebIDBCallbacks* callbacks_ptr,
- const string16& origin,
- WebFrame* web_frame) {
+ const string16& database_identifier) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
- if (!CurrentWorkerId() &&
- !ChildThread::current()->IsWebFrameValid(web_frame))
- return;
-
IndexedDBHostMsg_FactoryDeleteDatabase_Params params;
params.ipc_thread_id = CurrentWorkerId();
params.ipc_callbacks_id = pending_callbacks_.Add(callbacks.release());
- params.origin = origin;
+ params.database_identifier = database_identifier;
params.name = name;
Send(new IndexedDBHostMsg_FactoryDeleteDatabase(params));
}
@@ -558,11 +512,7 @@
WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id);
if (!callbacks)
return;
- WebDOMStringList string_list;
- for (std::vector<string16>::const_iterator it = value.begin();
- it != value.end(); ++it)
- string_list.append(*it);
- callbacks->onSuccess(string_list);
+ callbacks->onSuccess(WebVector<WebString>(value));
pending_callbacks_.Remove(ipc_callbacks_id);
}
diff --git a/content/common/indexed_db/indexed_db_dispatcher.h b/content/common/indexed_db/indexed_db_dispatcher.h
index bf17dba..a9a287c 100644
--- a/content/common/indexed_db/indexed_db_dispatcher.h
+++ b/content/common/indexed_db/indexed_db_dispatcher.h
@@ -13,11 +13,10 @@
#include "base/nullable_string16.h"
#include "content/common/content_export.h"
#include "ipc/ipc_sync_message_filter.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/WebIDBCursor.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabase.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabaseCallbacks.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBCallbacks.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBCursor.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabase.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabaseCallbacks.h"
#include "webkit/glue/worker_task_runner.h"
struct IndexedDBDatabaseMetadata;
@@ -28,7 +27,6 @@
namespace WebKit {
class WebData;
-class WebFrame;
}
namespace content {
@@ -64,16 +62,7 @@
void RequestIDBFactoryGetDatabaseNames(
WebKit::WebIDBCallbacks* callbacks,
- const string16& origin,
- WebKit::WebFrame* web_frame);
-
- void RequestIDBFactoryOpen(
- const string16& name,
- int64 version,
- WebKit::WebIDBCallbacks* callbacks,
- WebKit::WebIDBDatabaseCallbacks* database_callbacks,
- const string16& origin,
- WebKit::WebFrame* web_frame);
+ const string16& database_identifier);
void RequestIDBFactoryOpen(
const string16& name,
@@ -81,40 +70,34 @@
int64 transaction_id,
WebKit::WebIDBCallbacks* callbacks,
WebKit::WebIDBDatabaseCallbacks* database_callbacks,
- const string16& origin,
- WebKit::WebFrame* web_frame);
+ const string16& database_identifier);
void RequestIDBFactoryDeleteDatabase(
const string16& name,
WebKit::WebIDBCallbacks* callbacks,
- const string16& origin,
- WebKit::WebFrame* web_frame);
+ const string16& database_identifier);
void RequestIDBCursorAdvance(
unsigned long count,
WebKit::WebIDBCallbacks* callbacks_ptr,
- int32 ipc_cursor_id,
- WebKit::WebExceptionCode* ec);
+ int32 ipc_cursor_id);
virtual void RequestIDBCursorContinue(
const IndexedDBKey& key,
WebKit::WebIDBCallbacks* callbacks_ptr,
- int32 ipc_cursor_id,
- WebKit::WebExceptionCode* ec);
+ int32 ipc_cursor_id);
virtual void RequestIDBCursorPrefetch(
int n,
WebKit::WebIDBCallbacks* callbacks_ptr,
- int32 ipc_cursor_id,
- WebKit::WebExceptionCode* ec);
+ int32 ipc_cursor_id);
void RequestIDBCursorPrefetchReset(int used_prefetches, int unused_prefetches,
int32 ipc_cursor_id);
void RequestIDBCursorDelete(
WebKit::WebIDBCallbacks* callbacks_ptr,
- int32 ipc_cursor_id,
- WebKit::WebExceptionCode* ec);
+ int32 ipc_cursor_id);
void RequestIDBDatabaseClose(
int32 ipc_database_id,
diff --git a/content/common/indexed_db/indexed_db_dispatcher_unittest.cc b/content/common/indexed_db/indexed_db_dispatcher_unittest.cc
index 3d815c9..f9be36d 100644
--- a/content/common/indexed_db/indexed_db_dispatcher_unittest.cc
+++ b/content/common/indexed_db/indexed_db_dispatcher_unittest.cc
@@ -8,7 +8,7 @@
#include "content/common/indexed_db/indexed_db_key.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebData.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBCallbacks.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBCallbacks.h"
using WebKit::WebData;
using WebKit::WebIDBCallbacks;
diff --git a/content/common/indexed_db/indexed_db_key.h b/content/common/indexed_db/indexed_db_key.h
index 0e11bf9..4a546f4 100644
--- a/content/common/indexed_db/indexed_db_key.h
+++ b/content/common/indexed_db/indexed_db_key.h
@@ -10,7 +10,7 @@
#include "base/basictypes.h"
#include "base/string16.h"
#include "content/common/content_export.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBKey.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBKey.h"
namespace content {
diff --git a/content/common/indexed_db/indexed_db_key_path.h b/content/common/indexed_db/indexed_db_key_path.h
index fd44e60..185c894 100644
--- a/content/common/indexed_db/indexed_db_key_path.h
+++ b/content/common/indexed_db/indexed_db_key_path.h
@@ -10,7 +10,7 @@
#include "base/basictypes.h"
#include "base/string16.h"
#include "content/common/content_export.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBKeyPath.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBKeyPath.h"
namespace content {
diff --git a/content/common/indexed_db/indexed_db_key_range.h b/content/common/indexed_db/indexed_db_key_range.h
index dd390f5..9cc9043 100644
--- a/content/common/indexed_db/indexed_db_key_range.h
+++ b/content/common/indexed_db/indexed_db_key_range.h
@@ -8,7 +8,7 @@
#include "base/basictypes.h"
#include "content/common/content_export.h"
#include "content/common/indexed_db/indexed_db_key.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBKeyRange.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBKeyRange.h"
namespace content {
diff --git a/content/common/indexed_db/indexed_db_message_filter.cc b/content/common/indexed_db/indexed_db_message_filter.cc
index 189f568..29265c3 100644
--- a/content/common/indexed_db/indexed_db_message_filter.cc
+++ b/content/common/indexed_db/indexed_db_message_filter.cc
@@ -8,6 +8,7 @@
#include "base/location.h"
#include "base/message_loop_proxy.h"
#include "base/pickle.h"
+#include "content/common/child_thread.h"
#include "content/common/indexed_db/indexed_db_dispatcher.h"
#include "content/common/indexed_db/indexed_db_messages.h"
#include "webkit/glue/worker_task_runner.h"
@@ -28,10 +29,15 @@
DCHECK(result);
base::Closure closure = base::Bind(
&IndexedDBMessageFilter::DispatchMessage, this, msg);
- if (ipc_thread_id)
- WorkerTaskRunner::Instance()->PostTask(ipc_thread_id, closure);
- else
+ if (!ipc_thread_id) {
main_thread_loop_proxy_->PostTask(FROM_HERE, closure);
+ return true;
+ }
+ if (WorkerTaskRunner::Instance()->PostTask(ipc_thread_id, closure))
+ return true;
+
+ // Message for a terminated worker - perform necessary cleanup
+ OnStaleMessageReceived(msg);
return true;
}
@@ -41,4 +47,33 @@
IndexedDBDispatcher::ThreadSpecificInstance()->OnMessageReceived(msg);
}
+void IndexedDBMessageFilter::OnStaleMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(IndexedDBMessageFilter, msg)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBDatabase,
+ OnStaleSuccessIDBDatabase)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksUpgradeNeeded,
+ OnStaleUpgradeNeeded)
+ IPC_END_MESSAGE_MAP()
+}
+
+void IndexedDBMessageFilter::OnStaleSuccessIDBDatabase(
+ int32 ipc_thread_id,
+ int32 ipc_callbacks_id,
+ int32 ipc_database_callbacks_id,
+ int32 ipc_database_id,
+ const IndexedDBDatabaseMetadata& idb_metadata) {
+ scoped_refptr<IPC::SyncMessageFilter> filter(
+ ChildThread::current()->sync_message_filter());
+ filter->Send(
+ new IndexedDBHostMsg_DatabaseClose(ipc_database_id));
+}
+
+void IndexedDBMessageFilter::OnStaleUpgradeNeeded(
+ const IndexedDBMsg_CallbacksUpgradeNeeded_Params& p) {
+ scoped_refptr<IPC::SyncMessageFilter> filter(
+ ChildThread::current()->sync_message_filter());
+ filter->Send(
+ new IndexedDBHostMsg_DatabaseClose(p.ipc_database_id));
+}
+
} // namespace content
diff --git a/content/common/indexed_db/indexed_db_message_filter.h b/content/common/indexed_db/indexed_db_message_filter.h
index 749564b..d09af93 100644
--- a/content/common/indexed_db/indexed_db_message_filter.h
+++ b/content/common/indexed_db/indexed_db_message_filter.h
@@ -7,6 +7,9 @@
#include "ipc/ipc_channel_proxy.h"
+struct IndexedDBDatabaseMetadata;
+struct IndexedDBMsg_CallbacksUpgradeNeeded_Params;
+
namespace base {
class MessageLoopProxy;
} // namespace base
@@ -26,6 +29,14 @@
private:
void DispatchMessage(const IPC::Message& msg);
+ void OnStaleMessageReceived(const IPC::Message& msg);
+ void OnStaleSuccessIDBDatabase(int32 ipc_thread_id,
+ int32 ipc_callbacks_id,
+ int32 ipc_database_callbacks_id,
+ int32 ipc_object_id,
+ const IndexedDBDatabaseMetadata&);
+ void OnStaleUpgradeNeeded(const IndexedDBMsg_CallbacksUpgradeNeeded_Params&);
+
scoped_refptr<base::MessageLoopProxy> main_thread_loop_proxy_;
DISALLOW_COPY_AND_ASSIGN(IndexedDBMessageFilter);
diff --git a/content/common/indexed_db/indexed_db_messages.h b/content/common/indexed_db/indexed_db_messages.h
index 0e2d61c..54c8403 100644
--- a/content/common/indexed_db/indexed_db_messages.h
+++ b/content/common/indexed_db/indexed_db_messages.h
@@ -12,10 +12,9 @@
#include "content/common/indexed_db/indexed_db_param_traits.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_param_traits.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebExceptionCode.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBCursor.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabase.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBMetadata.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBCursor.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabase.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBMetadata.h"
#define IPC_MESSAGE_START IndexedDBMsgStart
@@ -30,8 +29,8 @@
// The response should have these ids.
IPC_STRUCT_MEMBER(int32, ipc_thread_id)
IPC_STRUCT_MEMBER(int32, ipc_callbacks_id)
- // The origin doing the initiating.
- IPC_STRUCT_MEMBER(string16, origin)
+ // The string id of the origin doing the initiating.
+ IPC_STRUCT_MEMBER(string16, database_identifier)
IPC_STRUCT_END()
// Used to open an indexed database.
@@ -42,8 +41,8 @@
IPC_STRUCT_MEMBER(int32, ipc_callbacks_id)
// Identifier for database callbacks
IPC_STRUCT_MEMBER(int32, ipc_database_callbacks_id)
- // The origin doing the initiating.
- IPC_STRUCT_MEMBER(string16, origin)
+ // The string id of the origin doing the initiating.
+ IPC_STRUCT_MEMBER(string16, database_identifier)
// The name of the database.
IPC_STRUCT_MEMBER(string16, name)
// The transaction id used if a database upgrade is needed.
@@ -57,8 +56,8 @@
// The response should have these ids.
IPC_STRUCT_MEMBER(int32, ipc_thread_id)
IPC_STRUCT_MEMBER(int32, ipc_callbacks_id)
- // The origin doing the initiating.
- IPC_STRUCT_MEMBER(string16, origin)
+ // The string id of the origin doing the initiating.
+ IPC_STRUCT_MEMBER(string16, database_identifier)
// The name of the database.
IPC_STRUCT_MEMBER(string16, name)
IPC_STRUCT_END()
diff --git a/content/common/indexed_db/proxy_webidbcursor_impl.cc b/content/common/indexed_db/proxy_webidbcursor_impl.cc
index 56810a4..16ccf6b 100644
--- a/content/common/indexed_db/proxy_webidbcursor_impl.cc
+++ b/content/common/indexed_db/proxy_webidbcursor_impl.cc
@@ -11,7 +11,6 @@
#include "content/common/indexed_db/indexed_db_dispatcher.h"
using WebKit::WebData;
-using WebKit::WebExceptionCode;
using WebKit::WebIDBCallbacks;
using WebKit::WebIDBKey;
@@ -42,19 +41,18 @@
}
void RendererWebIDBCursorImpl::advance(unsigned long count,
- WebIDBCallbacks* callbacks_ptr,
- WebExceptionCode& ec) {
+ WebIDBCallbacks* callbacks_ptr) {
IndexedDBDispatcher* dispatcher =
IndexedDBDispatcher::ThreadSpecificInstance();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
ResetPrefetchCache();
dispatcher->RequestIDBCursorAdvance(count, callbacks.release(),
- ipc_cursor_id_, &ec);
+ ipc_cursor_id_);
}
-void RendererWebIDBCursorImpl::continueFunction(const WebIDBKey& key,
- WebIDBCallbacks* callbacks_ptr,
- WebExceptionCode& ec) {
+void RendererWebIDBCursorImpl::continueFunction(
+ const WebIDBKey& key,
+ WebIDBCallbacks* callbacks_ptr) {
IndexedDBDispatcher* dispatcher =
IndexedDBDispatcher::ThreadSpecificInstance();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
@@ -74,7 +72,7 @@
++pending_onsuccess_callbacks_;
dispatcher->RequestIDBCursorPrefetch(prefetch_amount_,
callbacks.release(),
- ipc_cursor_id_, &ec);
+ ipc_cursor_id_);
// Increase prefetch_amount_ exponentially.
prefetch_amount_ *= 2;
@@ -90,14 +88,13 @@
dispatcher->RequestIDBCursorContinue(IndexedDBKey(key),
callbacks.release(),
- ipc_cursor_id_, &ec);
+ ipc_cursor_id_);
}
-void RendererWebIDBCursorImpl::deleteFunction(WebIDBCallbacks* callbacks,
- WebExceptionCode& ec) {
+void RendererWebIDBCursorImpl::deleteFunction(WebIDBCallbacks* callbacks) {
IndexedDBDispatcher* dispatcher =
IndexedDBDispatcher::ThreadSpecificInstance();
- dispatcher->RequestIDBCursorDelete(callbacks, ipc_cursor_id_, &ec);
+ dispatcher->RequestIDBCursorDelete(callbacks, ipc_cursor_id_);
}
void RendererWebIDBCursorImpl::postSuccessHandlerCallback() {
diff --git a/content/common/indexed_db/proxy_webidbcursor_impl.h b/content/common/indexed_db/proxy_webidbcursor_impl.h
index 0383cbe..1fc72e0 100644
--- a/content/common/indexed_db/proxy_webidbcursor_impl.h
+++ b/content/common/indexed_db/proxy_webidbcursor_impl.h
@@ -14,9 +14,9 @@
#include "content/common/content_export.h"
#include "content/common/indexed_db/indexed_db_key.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebData.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBCallbacks.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBCursor.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBKey.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBCallbacks.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBCursor.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBKey.h"
namespace content {
@@ -27,13 +27,10 @@
virtual ~RendererWebIDBCursorImpl();
virtual void advance(unsigned long count,
- WebKit::WebIDBCallbacks* callback,
- WebKit::WebExceptionCode& ec);
+ WebKit::WebIDBCallbacks* callback);
virtual void continueFunction(const WebKit::WebIDBKey& key,
- WebKit::WebIDBCallbacks* callback,
- WebKit::WebExceptionCode& ec);
- virtual void deleteFunction(WebKit::WebIDBCallbacks* callback,
- WebKit::WebExceptionCode& ec);
+ WebKit::WebIDBCallbacks* callback);
+ virtual void deleteFunction(WebKit::WebIDBCallbacks* callback);
virtual void postSuccessHandlerCallback();
void SetPrefetchData(
diff --git a/content/common/indexed_db/proxy_webidbcursor_impl_unittest.cc b/content/common/indexed_db/proxy_webidbcursor_impl_unittest.cc
index 0c2984e..ffbd02c 100644
--- a/content/common/indexed_db/proxy_webidbcursor_impl_unittest.cc
+++ b/content/common/indexed_db/proxy_webidbcursor_impl_unittest.cc
@@ -9,11 +9,9 @@
#include "content/common/indexed_db/proxy_webidbcursor_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebData.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/Platform/chromium/public/WebIDBCallbacks.h"
using WebKit::WebData;
-using WebKit::WebExceptionCode;
using WebKit::WebIDBCallbacks;
using WebKit::WebIDBDatabase;
using WebKit::WebIDBDatabaseError;
@@ -35,8 +33,7 @@
virtual void RequestIDBCursorPrefetch(
int n,
WebIDBCallbacks* callbacks,
- int32 ipc_cursor_id,
- WebExceptionCode*) OVERRIDE {
+ int32 ipc_cursor_id) OVERRIDE {
++prefetch_calls_;
last_prefetch_count_ = n;
callbacks_.reset(callbacks);
@@ -45,8 +42,7 @@
virtual void RequestIDBCursorContinue(
const IndexedDBKey&,
WebIDBCallbacks* callbacks,
- int32 ipc_cursor_id,
- WebExceptionCode*) OVERRIDE {
+ int32 ipc_cursor_id) OVERRIDE {
++continue_calls_;
callbacks_.reset(callbacks);
}
@@ -91,7 +87,6 @@
WebIDBKey null_key;
null_key.assignNull();
- WebExceptionCode ec = 0;
MockDispatcher dispatcher;
@@ -103,8 +98,7 @@
EXPECT_EQ(dispatcher.continue_calls(), 0);
for (int i = 0; i < RendererWebIDBCursorImpl::kPrefetchContinueThreshold;
++i) {
- cursor.continueFunction(null_key, new MockContinueCallbacks(), ec);
- EXPECT_EQ(ec, 0);
+ cursor.continueFunction(null_key, new MockContinueCallbacks());
EXPECT_EQ(dispatcher.continue_calls(), ++continue_calls);
EXPECT_EQ(dispatcher.prefetch_calls(), 0);
}
@@ -119,8 +113,7 @@
++repetitions) {
// Initiate the prefetch
- cursor.continueFunction(null_key, new MockContinueCallbacks(), ec);
- EXPECT_EQ(ec, 0);
+ cursor.continueFunction(null_key, new MockContinueCallbacks());
EXPECT_EQ(dispatcher.continue_calls(), continue_calls);
EXPECT_EQ(dispatcher.prefetch_calls(), repetitions + 1);
@@ -145,8 +138,7 @@
// Verify that the cache is used for subsequent continue() calls.
for (int i = 0; i < prefetch_count; ++i) {
IndexedDBKey key;
- cursor.continueFunction(null_key, new MockContinueCallbacks(&key), ec);
- EXPECT_EQ(ec, 0);
+ cursor.continueFunction(null_key, new MockContinueCallbacks(&key));
EXPECT_EQ(dispatcher.continue_calls(), continue_calls);
EXPECT_EQ(dispatcher.prefetch_calls(), repetitions + 1);
diff --git a/content/common/indexed_db/proxy_webidbdatabase_impl.cc b/content/common/indexed_db/proxy_webidbdatabase_impl.cc
index 81a59f9..b032b3d 100644
--- a/content/common/indexed_db/proxy_webidbdatabase_impl.cc
+++ b/content/common/indexed_db/proxy_webidbdatabase_impl.cc
@@ -7,17 +7,14 @@
#include <vector>
#include "content/common/child_thread.h"
-#include "content/common/indexed_db/indexed_db_messages.h"
#include "content/common/indexed_db/indexed_db_dispatcher.h"
+#include "content/common/indexed_db/indexed_db_messages.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBKeyPath.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBMetadata.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBKeyPath.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBMetadata.h"
#include "webkit/glue/worker_task_runner.h"
-using WebKit::WebDOMStringList;
-using WebKit::WebExceptionCode;
-using WebKit::WebFrame;
using WebKit::WebIDBCallbacks;
using WebKit::WebIDBDatabaseCallbacks;
using WebKit::WebIDBMetadata;
diff --git a/content/common/indexed_db/proxy_webidbdatabase_impl.h b/content/common/indexed_db/proxy_webidbdatabase_impl.h
index 9795516..ed6aa61 100644
--- a/content/common/indexed_db/proxy_webidbdatabase_impl.h
+++ b/content/common/indexed_db/proxy_webidbdatabase_impl.h
@@ -6,7 +6,7 @@
#define CONTENT_COMMON_INDEXED_DB_PROXY_WEBIDBDATABASE_IMPL_H_
#include "base/basictypes.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabase.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabase.h"
namespace WebKit {
class WebIDBCallbacks;
diff --git a/content/common/indexed_db/proxy_webidbfactory_impl.cc b/content/common/indexed_db/proxy_webidbfactory_impl.cc
index 0b053e8..a927e44 100644
--- a/content/common/indexed_db/proxy_webidbfactory_impl.cc
+++ b/content/common/indexed_db/proxy_webidbfactory_impl.cc
@@ -7,14 +7,10 @@
#include "content/common/indexed_db/indexed_db_dispatcher.h"
#include "content/common/child_thread.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMStringList.h"
-using WebKit::WebDOMStringList;
-using WebKit::WebFrame;
using WebKit::WebIDBCallbacks;
using WebKit::WebIDBDatabase;
using WebKit::WebIDBDatabaseCallbacks;
-using WebKit::WebSecurityOrigin;
using WebKit::WebString;
namespace content {
@@ -27,30 +23,12 @@
void RendererWebIDBFactoryImpl::getDatabaseNames(
WebIDBCallbacks* callbacks,
- const WebSecurityOrigin& origin,
- WebFrame* web_frame,
+ const WebString& database_identifier,
const WebString& data_dir_unused) {
IndexedDBDispatcher* dispatcher =
IndexedDBDispatcher::ThreadSpecificInstance();
dispatcher->RequestIDBFactoryGetDatabaseNames(
- callbacks, origin.databaseIdentifier(), web_frame);
-}
-
-void RendererWebIDBFactoryImpl::open(
- const WebString& name,
- long long version,
- WebIDBCallbacks* callbacks,
- WebIDBDatabaseCallbacks* database_callbacks,
- const WebSecurityOrigin& origin,
- WebFrame* web_frame,
- const WebString& data_dir) {
- // Don't send the data_dir. We know what we want on the Browser side of
- // things.
- IndexedDBDispatcher* dispatcher =
- IndexedDBDispatcher::ThreadSpecificInstance();
- dispatcher->RequestIDBFactoryOpen(
- name, version, callbacks, database_callbacks, origin.databaseIdentifier(),
- web_frame);
+ callbacks, database_identifier);
}
void RendererWebIDBFactoryImpl::open(
@@ -59,8 +37,7 @@
long long transaction_id,
WebIDBCallbacks* callbacks,
WebIDBDatabaseCallbacks* database_callbacks,
- const WebSecurityOrigin& origin,
- WebFrame* web_frame,
+ const WebString& database_identifier,
const WebString& data_dir) {
// Don't send the data_dir. We know what we want on the Browser side of
// things.
@@ -68,22 +45,20 @@
IndexedDBDispatcher::ThreadSpecificInstance();
dispatcher->RequestIDBFactoryOpen(
name, version, transaction_id, callbacks, database_callbacks,
- origin.databaseIdentifier(),
- web_frame);
+ database_identifier);
}
void RendererWebIDBFactoryImpl::deleteDatabase(
const WebString& name,
WebIDBCallbacks* callbacks,
- const WebSecurityOrigin& origin,
- WebFrame* web_frame,
+ const WebString& database_identifier,
const WebString& data_dir) {
// Don't send the data_dir. We know what we want on the Browser side of
// things.
IndexedDBDispatcher* dispatcher =
IndexedDBDispatcher::ThreadSpecificInstance();
dispatcher->RequestIDBFactoryDeleteDatabase(
- name, callbacks, origin.databaseIdentifier(), web_frame);
+ name, callbacks, database_identifier);
}
} // namespace content
diff --git a/content/common/indexed_db/proxy_webidbfactory_impl.h b/content/common/indexed_db/proxy_webidbfactory_impl.h
index e550b05..b50a162 100644
--- a/content/common/indexed_db/proxy_webidbfactory_impl.h
+++ b/content/common/indexed_db/proxy_webidbfactory_impl.h
@@ -5,14 +5,12 @@
#ifndef CONTENT_COMMON_INDEXED_DB_PROXY_WEBIDBFACTORY_IMPL_H_
#define CONTENT_COMMON_INDEXED_DB_PROXY_WEBIDBFACTORY_IMPL_H_
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBCallbacks.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabaseCallbacks.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBFactory.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBCallbacks.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBDatabaseCallbacks.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBFactory.h"
namespace WebKit {
-class WebFrame;
-class WebSecurityOrigin;
class WebString;
}
@@ -26,16 +24,7 @@
// See WebIDBFactory.h for documentation on these functions.
virtual void getDatabaseNames(
WebKit::WebIDBCallbacks* callbacks,
- const WebKit::WebSecurityOrigin& origin,
- WebKit::WebFrame* web_frame,
- const WebKit::WebString& data_dir);
- virtual void open(
- const WebKit::WebString& name,
- long long version,
- WebKit::WebIDBCallbacks* callbacks,
- WebKit::WebIDBDatabaseCallbacks* databaseCallbacks,
- const WebKit::WebSecurityOrigin& origin,
- WebKit::WebFrame* web_frame,
+ const WebKit::WebString& database_identifier,
const WebKit::WebString& data_dir);
virtual void open(
const WebKit::WebString& name,
@@ -43,14 +32,12 @@
long long transaction_id,
WebKit::WebIDBCallbacks* callbacks,
WebKit::WebIDBDatabaseCallbacks* databaseCallbacks,
- const WebKit::WebSecurityOrigin& origin,
- WebKit::WebFrame* web_frame,
+ const WebKit::WebString& database_identifier,
const WebKit::WebString& data_dir);
virtual void deleteDatabase(
const WebKit::WebString& name,
WebKit::WebIDBCallbacks* callbacks,
- const WebKit::WebSecurityOrigin& origin,
- WebKit::WebFrame* web_frame,
+ const WebKit::WebString& database_identifier,
const WebKit::WebString& data_dir);
};
diff --git a/content/common/input_messages.h b/content/common/input_messages.h
new file mode 100644
index 0000000..2c9c0b9
--- /dev/null
+++ b/content/common/input_messages.h
@@ -0,0 +1,135 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// IPC messages for input events and other messages that require processing in
+// order relative to input events.
+// Multiply-included message file, hence no include guard.
+
+#include "base/string16.h"
+#include "content/common/content_export.h"
+#include "content/common/content_param_traits.h"
+#include "content/common/edit_command.h"
+#include "content/port/common/input_event_ack_state.h"
+#include "content/public/common/common_param_traits.h"
+#include "ipc/ipc_message_macros.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
+#include "ui/gfx/point.h"
+#include "ui/gfx/rect.h"
+
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
+
+#ifdef IPC_MESSAGE_START
+#error IPC_MESSAGE_START
+#endif
+
+#define IPC_MESSAGE_START InputMsgStart
+
+IPC_ENUM_TRAITS(content::InputEventAckState)
+
+IPC_STRUCT_TRAITS_BEGIN(content::EditCommand)
+ IPC_STRUCT_TRAITS_MEMBER(name)
+ IPC_STRUCT_TRAITS_MEMBER(value)
+IPC_STRUCT_TRAITS_END()
+
+// Sends an input event to the render widget.
+IPC_MESSAGE_ROUTED2(InputMsg_HandleInputEvent,
+ IPC::WebInputEventPointer /* event */,
+ bool /* is_keyboard_shortcut */)
+
+// Sends the cursor visibility state to the render widget.
+IPC_MESSAGE_ROUTED1(InputMsg_CursorVisibilityChange,
+ bool /* is_visible */)
+
+// This message notifies the renderer that the next key event is bound to one
+// or more pre-defined edit commands. If the next key event is not handled
+// by webkit, the specified edit commands shall be executed against current
+// focused frame.
+// Parameters
+// * edit_commands (see chrome/common/edit_command_types.h)
+// Contains one or more edit commands.
+// See third_party/WebKit/Source/WebCore/editing/EditorCommand.cpp for detailed
+// definition of webkit edit commands.
+//
+// This message must be sent just before sending a key event.
+IPC_MESSAGE_ROUTED1(InputMsg_SetEditCommandsForNextKeyEvent,
+ std::vector<content::EditCommand> /* edit_commands */)
+
+// Message payload is the name/value of a WebCore edit command to execute.
+IPC_MESSAGE_ROUTED2(InputMsg_ExecuteEditCommand,
+ std::string, /* name */
+ std::string /* value */)
+
+IPC_MESSAGE_ROUTED0(InputMsg_MouseCaptureLost)
+
+// TODO(darin): figure out how this meshes with RestoreFocus
+IPC_MESSAGE_ROUTED1(InputMsg_SetFocus,
+ bool /* enable */)
+
+// Tells the renderer to focus the first (last if reverse is true) focusable
+// node.
+IPC_MESSAGE_ROUTED1(InputMsg_SetInitialFocus,
+ bool /* reverse */)
+
+// Tells the renderer to scroll the currently focused node into rect only if
+// the currently focused node is a Text node (textfield, text area or content
+// editable divs).
+IPC_MESSAGE_ROUTED1(InputMsg_ScrollFocusedEditableNodeIntoRect, gfx::Rect)
+
+// These messages are typically generated from context menus and request the
+// renderer to apply the specified operation to the current selection.
+IPC_MESSAGE_ROUTED0(InputMsg_Undo)
+IPC_MESSAGE_ROUTED0(InputMsg_Redo)
+IPC_MESSAGE_ROUTED0(InputMsg_Cut)
+IPC_MESSAGE_ROUTED0(InputMsg_Copy)
+#if defined(OS_MACOSX)
+IPC_MESSAGE_ROUTED0(InputMsg_CopyToFindPboard)
+#endif
+IPC_MESSAGE_ROUTED0(InputMsg_Paste)
+IPC_MESSAGE_ROUTED0(InputMsg_PasteAndMatchStyle)
+// Replaces the selected region or a word around the cursor with the
+// specified string.
+IPC_MESSAGE_ROUTED1(InputMsg_Replace,
+ string16)
+// Replaces the misspelling in the selected region with the specified string.
+IPC_MESSAGE_ROUTED1(InputMsg_ReplaceMisspelling,
+ string16)
+IPC_MESSAGE_ROUTED0(InputMsg_Delete)
+IPC_MESSAGE_ROUTED0(InputMsg_SelectAll)
+
+IPC_MESSAGE_ROUTED0(InputMsg_Unselect)
+
+// Requests the renderer to select the region between two points.
+// Expects a SelectRange_ACK message when finished.
+IPC_MESSAGE_ROUTED2(InputMsg_SelectRange,
+ gfx::Point /* start */,
+ gfx::Point /* end */)
+
+// Requests the renderer to move the caret selection toward the point.
+// Expects a MoveCaret_ACK message when finished.
+IPC_MESSAGE_ROUTED1(InputMsg_MoveCaret,
+ gfx::Point /* location */)
+
+#if defined(OS_ANDROID)
+// Sent when the user clicks on the find result bar to activate a find result.
+// The point (x,y) is in fractions of the content document's width and height.
+IPC_MESSAGE_ROUTED3(InputMsg_ActivateNearestFindResult,
+ int /* request_id */,
+ float /* x */,
+ float /* y */)
+#endif
+
+// -----------------------------------------------------------------------------
+// Messages sent from the renderer to the browser.
+
+// Acknowledges receipt of a InputMsg_HandleInputEvent message.
+IPC_MESSAGE_ROUTED2(InputHostMsg_HandleInputEvent_ACK,
+ WebKit::WebInputEvent::Type,
+ content::InputEventAckState /* ack_result */)
+
+
+// Adding a new message? Stick to the sort order above: first platform
+// independent InputMsg, then ifdefs for platform specific InputMsg, then
+// platform independent InputHostMsg, then ifdefs for platform specific
+// InputHostMsg.
diff --git a/content/common/inter_process_time_ticks_converter.cc b/content/common/inter_process_time_ticks_converter.cc
index 6ae309c..de3fb13 100644
--- a/content/common/inter_process_time_ticks_converter.cc
+++ b/content/common/inter_process_time_ticks_converter.cc
@@ -48,7 +48,7 @@
}
LocalTimeTicks InterProcessTimeTicksConverter::ToLocalTimeTicks(
- const RemoteTimeTicks& remote_ms) {
+ const RemoteTimeTicks& remote_ms) const {
// If input time is "null", return another "null" time.
if (remote_ms.value_ == 0)
return LocalTimeTicks(0);
@@ -60,12 +60,12 @@
}
LocalTimeDelta InterProcessTimeTicksConverter::ToLocalTimeDelta(
- const RemoteTimeDelta& remote_delta) {
+ const RemoteTimeDelta& remote_delta) const {
DCHECK_GE(remote_upper_bound_, remote_lower_bound_ + remote_delta.value_);
return LocalTimeDelta(Convert(remote_delta.value_));
}
-int64 InterProcessTimeTicksConverter::Convert(int64 value) {
+int64 InterProcessTimeTicksConverter::Convert(int64 value) const {
if (value <= 0) {
return value;
}
diff --git a/content/common/inter_process_time_ticks_converter.h b/content/common/inter_process_time_ticks_converter.h
index cd95594..d1d405f 100644
--- a/content/common/inter_process_time_ticks_converter.h
+++ b/content/common/inter_process_time_ticks_converter.h
@@ -55,14 +55,14 @@
// Returns the value within the local's bounds that correlates to
// |remote_ms|.
- LocalTimeTicks ToLocalTimeTicks(const RemoteTimeTicks& remote_ms);
+ LocalTimeTicks ToLocalTimeTicks(const RemoteTimeTicks& remote_ms) const;
// Returns the equivalent delta after applying remote-to-local scaling to
// |remote_delta|.
- LocalTimeDelta ToLocalTimeDelta(const RemoteTimeDelta& remote_delta);
+ LocalTimeDelta ToLocalTimeDelta(const RemoteTimeDelta& remote_delta) const;
private:
- int64 Convert(int64 value);
+ int64 Convert(int64 value) const;
// The local time which |remote_lower_bound_| is mapped to.
int64 local_base_time_;
diff --git a/content/common/mac/attributed_string_coder.mm b/content/common/mac/attributed_string_coder.mm
index 78a1efb..a2c1f50 100644
--- a/content/common/mac/attributed_string_coder.mm
+++ b/content/common/mac/attributed_string_coder.mm
@@ -8,7 +8,7 @@
#include "base/logging.h"
#include "base/memory/scoped_nsobject.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "content/common/view_messages.h"
#include "content/public/common/common_param_traits.h"
diff --git a/content/common/mac/font_descriptor.mm b/content/common/mac/font_descriptor.mm
index 65ab40e..3b5a577 100644
--- a/content/common/mac/font_descriptor.mm
+++ b/content/common/mac/font_descriptor.mm
@@ -6,7 +6,7 @@
#include <Cocoa/Cocoa.h>
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
FontDescriptor::FontDescriptor(NSFont* font) {
font_name = base::SysNSStringToUTF16([font fontName]);
diff --git a/content/common/mac/font_descriptor_unittest.mm b/content/common/mac/font_descriptor_unittest.mm
index f3ce5e9..9b78d37 100644
--- a/content/common/mac/font_descriptor_unittest.mm
+++ b/content/common/mac/font_descriptor_unittest.mm
@@ -8,7 +8,7 @@
#include "base/logging.h"
#include "base/utf_string_conversions.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "testing/gtest_mac.h"
#include "testing/platform_test.h"
diff --git a/content/common/mac/font_loader.mm b/content/common/mac/font_loader.mm
index faf965f..1cd6fc3 100644
--- a/content/common/mac/font_loader.mm
+++ b/content/common/mac/font_loader.mm
@@ -13,7 +13,7 @@
#include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "content/common/mac/font_descriptor.h"
diff --git a/content/common/media/OWNERS b/content/common/media/OWNERS
index dccdcaf..e8994e1 100644
--- a/content/common/media/OWNERS
+++ b/content/common/media/OWNERS
@@ -17,3 +17,4 @@
per-file *_messages.h=jschuh@chromium.org
per-file *_messages.h=palmer@chromium.org
per-file *_messages.h=tsepez@chromium.org
+per-file *_messages.h=kenrb@chromium.org
diff --git a/content/common/media/audio_messages.h b/content/common/media/audio_messages.h
index 63b81e4..dc844eb 100644
--- a/content/common/media/audio_messages.h
+++ b/content/common/media/audio_messages.h
@@ -23,6 +23,12 @@
IPC_ENUM_TRAITS(media::AudioInputIPCDelegate::State)
IPC_ENUM_TRAITS(media::AudioOutputIPCDelegate::State)
+IPC_STRUCT_BEGIN(AudioInputHostMsg_CreateStream_Config)
+ IPC_STRUCT_MEMBER(media::AudioParameters, params)
+ IPC_STRUCT_MEMBER(bool, automatic_gain_control)
+ IPC_STRUCT_MEMBER(uint32, shared_memory_count)
+IPC_STRUCT_END()
+
// Messages sent from the browser to the renderer.
// Tell the renderer process that an audio stream has been created.
@@ -87,28 +93,22 @@
// Messages sent from the renderer to the browser.
-// Request that got sent to browser for creating an audio output stream
-IPC_MESSAGE_CONTROL2(AudioHostMsg_CreateStream,
+// Request that is sent to the browser for creating an audio output stream.
+// |render_view_id| is the routing ID for the render view producing the audio
+// data.
+IPC_MESSAGE_CONTROL3(AudioHostMsg_CreateStream,
int /* stream_id */,
+ int /* render_view_id */,
media::AudioParameters /* params */)
-// Request that got sent to browser for creating an audio input stream
-IPC_MESSAGE_CONTROL5(AudioInputHostMsg_CreateStream,
+// Request that is sent to the browser for creating an audio input stream.
+// |render_view_id| is the routing ID for the render view consuming the audio
+// data.
+IPC_MESSAGE_CONTROL4(AudioInputHostMsg_CreateStream,
int /* stream_id */,
+ int /* render_view_id */,
int /* session_id */,
- media::AudioParameters /* params */,
- bool /* automatic_gain_control */,
- uint32 /* shared memory count */)
-
-// Indicate that audio for a stream is produced by the specified render view.
-IPC_MESSAGE_CONTROL2(AudioHostMsg_AssociateStreamWithProducer,
- int /* stream_id */,
- int /* render_view_id */)
-
-// Indicate that audio for a stream is consumed by the specified render view.
-IPC_MESSAGE_CONTROL2(AudioInputHostMsg_AssociateStreamWithConsumer,
- int /* stream_id */,
- int /* render_view_id */)
+ AudioInputHostMsg_CreateStream_Config)
// Start buffering and play the audio stream specified by stream_id.
IPC_MESSAGE_CONTROL1(AudioHostMsg_PlayStream,
@@ -122,10 +122,6 @@
IPC_MESSAGE_CONTROL1(AudioHostMsg_PauseStream,
int /* stream_id */)
-// Discard all buffered audio data for the specified audio stream.
-IPC_MESSAGE_CONTROL1(AudioHostMsg_FlushStream,
- int /* stream_id */)
-
// Close an audio stream specified by stream_id.
IPC_MESSAGE_CONTROL1(AudioHostMsg_CloseStream,
int /* stream_id */)
diff --git a/content/common/media/media_player_messages.h b/content/common/media/media_player_messages.h
index 4cf8c3a..3df3c0c 100644
--- a/content/common/media/media_player_messages.h
+++ b/content/common/media/media_player_messages.h
@@ -11,11 +11,56 @@
#include "content/common/content_export.h"
#include "googleurl/src/gurl.h"
#include "ipc/ipc_message_macros.h"
+#include "ui/gfx/rect_f.h"
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
#define IPC_MESSAGE_START MediaPlayerMsgStart
+#if defined(GOOGLE_TV)
+#include "media/base/android/demuxer_stream_player_params.h"
+
+IPC_ENUM_TRAITS(media::AudioCodec)
+IPC_ENUM_TRAITS(media::DemuxerStream::Status)
+IPC_ENUM_TRAITS(media::DemuxerStream::Type)
+IPC_ENUM_TRAITS(media::VideoCodec)
+
+IPC_STRUCT_TRAITS_BEGIN(media::MediaPlayerHostMsg_DemuxerReady_Params)
+ IPC_STRUCT_TRAITS_MEMBER(audio_codec)
+ IPC_STRUCT_TRAITS_MEMBER(audio_channels)
+ IPC_STRUCT_TRAITS_MEMBER(audio_sampling_rate)
+ IPC_STRUCT_TRAITS_MEMBER(is_audio_encrypted)
+
+ IPC_STRUCT_TRAITS_MEMBER(video_codec)
+ IPC_STRUCT_TRAITS_MEMBER(video_size)
+ IPC_STRUCT_TRAITS_MEMBER(is_video_encrypted)
+
+ IPC_STRUCT_TRAITS_MEMBER(duration_ms)
+ IPC_STRUCT_TRAITS_MEMBER(key_system)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params)
+ IPC_STRUCT_TRAITS_MEMBER(type)
+ IPC_STRUCT_TRAITS_MEMBER(access_units)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(
+ media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params::AccessUnit)
+ IPC_STRUCT_TRAITS_MEMBER(status)
+ IPC_STRUCT_TRAITS_MEMBER(end_of_stream)
+ IPC_STRUCT_TRAITS_MEMBER(data)
+ IPC_STRUCT_TRAITS_MEMBER(timestamp)
+ IPC_STRUCT_TRAITS_MEMBER(key_id)
+ IPC_STRUCT_TRAITS_MEMBER(iv)
+ IPC_STRUCT_TRAITS_MEMBER(subsamples)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(media::SubsampleEntry)
+ IPC_STRUCT_TRAITS_MEMBER(clear_bytes)
+ IPC_STRUCT_TRAITS_MEMBER(cypher_bytes)
+IPC_STRUCT_TRAITS_END()
+#endif
+
// Messages for notifying the render process of media playback status -------
// Media buffering has updated.
@@ -32,10 +77,13 @@
IPC_MESSAGE_ROUTED1(MediaPlayerMsg_MediaPlaybackCompleted,
int /* player_id */)
-// Player is prepared.
-IPC_MESSAGE_ROUTED2(MediaPlayerMsg_MediaPrepared,
+// Media metadata has changed.
+IPC_MESSAGE_ROUTED5(MediaPlayerMsg_MediaMetadataChanged,
int /* player_id */,
- base::TimeDelta /* duration */)
+ base::TimeDelta /* duration */,
+ int /* width */,
+ int /* height */,
+ bool /* success */)
// Media seek is completed.
IPC_MESSAGE_ROUTED2(MediaPlayerMsg_MediaSeekCompleted,
@@ -73,6 +121,14 @@
IPC_MESSAGE_ROUTED1(MediaPlayerMsg_DidMediaPlayerPause,
int /* player_id */)
+#if defined(GOOGLE_TV)
+// The media source player reads data from demuxer
+IPC_MESSAGE_ROUTED3(MediaPlayerMsg_ReadFromDemuxer,
+ int /* player_id */,
+ media::DemuxerStream::Type /* type */,
+ bool /* seek_done */)
+#endif
+
// Messages for controllering the media playback in browser process ----------
// Destroy the media player object.
@@ -83,9 +139,10 @@
IPC_MESSAGE_ROUTED0(MediaPlayerHostMsg_DestroyAllMediaPlayers)
// Initialize a media player object with the given player_id.
-IPC_MESSAGE_ROUTED3(MediaPlayerHostMsg_MediaPlayerInitialize,
+IPC_MESSAGE_ROUTED4(MediaPlayerHostMsg_MediaPlayerInitialize,
int /* player_id */,
GURL /* url */,
+ bool /* is_media_source */,
GURL /* first_party_for_cookies */)
// Pause the player.
@@ -113,6 +170,23 @@
IPC_MESSAGE_ROUTED1(MediaPlayerHostMsg_ExitFullscreen,
int /* player_id */)
+#if defined(GOOGLE_TV)
// Request the player to use external surface for rendering.
IPC_MESSAGE_ROUTED1(MediaPlayerHostMsg_RequestExternalSurface,
int /* player_id */)
+
+// Request the player to use external surface for rendering.
+IPC_MESSAGE_ROUTED2(MediaPlayerHostMsg_NotifyGeometryChange,
+ int /* player_id */,
+ gfx::RectF /* rect */)
+
+// Inform the media source player that the demuxer is ready.
+IPC_MESSAGE_ROUTED2(MediaPlayerHostMsg_DemuxerReady,
+ int /* player_id */,
+ media::MediaPlayerHostMsg_DemuxerReady_Params)
+
+// Sent when the data was read from the ChunkDemuxer.
+IPC_MESSAGE_ROUTED2(MediaPlayerHostMsg_ReadFromDemuxerAck,
+ int /* player_id */,
+ media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params)
+#endif
diff --git a/content/common/media/video_capture.h b/content/common/media/video_capture.h
index 6494c8b..f6e24ba 100644
--- a/content/common/media/video_capture.h
+++ b/content/common/media/video_capture.h
@@ -20,6 +20,7 @@
VIDEO_CAPTURE_STATE_STOPPING,
VIDEO_CAPTURE_STATE_STOPPED,
VIDEO_CAPTURE_STATE_ERROR,
+ VIDEO_CAPTURE_STATE_ENDED,
};
} // namespace content
diff --git a/content/common/media/webrtc_logging_messages.h b/content/common/media/webrtc_logging_messages.h
new file mode 100644
index 0000000..d15d9ac
--- /dev/null
+++ b/content/common/media/webrtc_logging_messages.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// IPC messages for WebRTC logging.
+// Multiply-included message file, hence no include guard.
+
+#include "base/shared_memory.h"
+#include "ipc/ipc_message_macros.h"
+
+#define IPC_MESSAGE_START WebRtcLoggingMsgStart
+
+// Messages sent from the renderer to the browser.
+
+// Request to open a log.
+IPC_MESSAGE_CONTROL0(WebRtcLoggingMsg_OpenLog)
+
+// Messages sent from the browser to the renderer.
+
+// Notification that a log could not be opened.
+IPC_MESSAGE_CONTROL0(WebRtcLoggingMsg_OpenLogFailed)
+
+// Notification that a log has been opened.
+IPC_MESSAGE_CONTROL2(WebRtcLoggingMsg_LogOpened,
+ base::SharedMemoryHandle /* handle */,
+ uint32 /* length */)
diff --git a/content/common/message_router.cc b/content/common/message_router.cc
index d3eef77..f73e654 100644
--- a/content/common/message_router.cc
+++ b/content/common/message_router.cc
@@ -42,7 +42,7 @@
}
bool MessageRouter::RouteMessage(const IPC::Message& msg) {
- IPC::Listener* listener = ResolveRoute(msg.routing_id());
+ IPC::Listener* listener = routes_.Lookup(msg.routing_id());
if (!listener)
return false;
@@ -50,8 +50,4 @@
return true;
}
-IPC::Listener* MessageRouter::ResolveRoute(int32 routing_id) {
- return routes_.Lookup(routing_id);
-}
-
} // namespace content
diff --git a/content/common/message_router.h b/content/common/message_router.h
index 0b34e0c..56acead 100644
--- a/content/common/message_router.h
+++ b/content/common/message_router.h
@@ -52,8 +52,6 @@
void AddRoute(int32 routing_id, IPC::Listener* listener);
void RemoveRoute(int32 routing_id);
- IPC::Listener* ResolveRoute(int32 routing_id);
-
private:
// A list of all listeners with assigned routing IDs.
IDMap<IPC::Listener> routes_;
diff --git a/content/common/np_channel_base.cc b/content/common/np_channel_base.cc
index a85fdb5..a1a2338 100644
--- a/content/common/np_channel_base.cc
+++ b/content/common/np_channel_base.cc
@@ -141,7 +141,7 @@
}
bool NPChannelBase::Send(IPC::Message* message) {
- if (!channel_.get()) {
+ if (!channel_) {
VLOG(1) << "Channel is NULL; dropping message";
delete message;
return false;
diff --git a/content/common/npobject_proxy.cc b/content/common/npobject_proxy.cc
index 4203b13..eb01acb 100644
--- a/content/common/npobject_proxy.cc
+++ b/content/common/npobject_proxy.cc
@@ -70,7 +70,7 @@
}
NPObjectProxy::~NPObjectProxy() {
- if (channel_.get()) {
+ if (channel_) {
// This NPObjectProxy instance is now invalid and should not be reused for
// requests initiated by plugins. We may receive requests for the
// same NPObject in the context of the outgoing NPObjectMsg_Release call.
@@ -94,7 +94,7 @@
}
bool NPObjectProxy::Send(IPC::Message* msg) {
- if (channel_.get())
+ if (channel_)
return channel_->Send(msg);
delete msg;
diff --git a/content/common/npobject_stub.cc b/content/common/npobject_stub.cc
index 668cb08..0e677ee 100644
--- a/content/common/npobject_stub.cc
+++ b/content/common/npobject_stub.cc
@@ -58,7 +58,7 @@
WebBindings::releaseObject(npobject);
- MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
}
diff --git a/content/common/p2p_messages.h b/content/common/p2p_messages.h
index 59f6a8f..6b13831 100644
--- a/content/common/p2p_messages.h
+++ b/content/common/p2p_messages.h
@@ -35,6 +35,9 @@
int /* socket_id */,
net::IPEndPoint /* socket_address */)
+IPC_MESSAGE_CONTROL1(P2PMsg_OnSendComplete,
+ int /* socket_id */)
+
IPC_MESSAGE_CONTROL1(P2PMsg_OnError,
int /* socket_id */)
diff --git a/content/common/partial_circular_buffer.cc b/content/common/partial_circular_buffer.cc
new file mode 100644
index 0000000..cba2243
--- /dev/null
+++ b/content/common/partial_circular_buffer.cc
@@ -0,0 +1,166 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/partial_circular_buffer.h"
+
+#include <algorithm>
+
+#include "base/logging.h"
+
+namespace content {
+
+namespace {
+
+inline uint32 Min3(uint32 a, uint32 b, uint32 c) {
+ return std::min(a, std::min(b, c));
+}
+
+} // namespace
+
+PartialCircularBuffer::PartialCircularBuffer(void* buffer,
+ uint32 buffer_size)
+ : buffer_data_(reinterpret_cast<BufferData*>(buffer)),
+ memory_buffer_size_(buffer_size),
+ data_size_(0),
+ position_(0),
+ total_read_(0) {
+ uint32 header_size =
+ buffer_data_->data - reinterpret_cast<uint8*>(buffer_data_);
+ data_size_ = memory_buffer_size_ - header_size;
+
+ DCHECK(buffer_data_);
+ DCHECK_GE(memory_buffer_size_, header_size);
+ DCHECK_LE(buffer_data_->total_written, data_size_);
+ DCHECK_LT(buffer_data_->wrap_position, data_size_);
+ DCHECK_LT(buffer_data_->end_position, data_size_);
+}
+
+PartialCircularBuffer::PartialCircularBuffer(void* buffer,
+ uint32 buffer_size,
+ uint32 wrap_position)
+ : buffer_data_(reinterpret_cast<BufferData*>(buffer)),
+ memory_buffer_size_(buffer_size),
+ data_size_(0),
+ position_(0),
+ total_read_(0) {
+ uint32 header_size =
+ buffer_data_->data - reinterpret_cast<uint8*>(buffer_data_);
+ data_size_ = memory_buffer_size_ - header_size;
+
+ DCHECK(buffer_data_);
+ DCHECK_GE(memory_buffer_size_, header_size);
+ DCHECK_LT(wrap_position, data_size_);
+
+ buffer_data_->total_written = 0;
+ buffer_data_->wrap_position = wrap_position;
+ buffer_data_->end_position = 0;
+}
+
+uint32 PartialCircularBuffer::Read(void* buffer, uint32 buffer_size) {
+ DCHECK(buffer_data_);
+ if (total_read_ >= buffer_data_->total_written)
+ return 0;
+
+ uint8* buffer_uint8 = reinterpret_cast<uint8*>(buffer);
+ uint32 read = 0;
+
+ // Read from beginning part.
+ if (position_ < buffer_data_->wrap_position) {
+ uint32 to_wrap_pos = buffer_data_->wrap_position - position_;
+ uint32 to_eow = buffer_data_->total_written - total_read_;
+ uint32 to_read = Min3(buffer_size, to_wrap_pos, to_eow);
+ memcpy(buffer_uint8, buffer_data_->data + position_, to_read);
+ position_ += to_read;
+ total_read_ += to_read;
+ read += to_read;
+ if (position_ == buffer_data_->wrap_position &&
+ buffer_data_->total_written == data_size_) {
+ // We've read all the beginning part, set the position to the middle part.
+ // (The second condition above checks if the wrapping part is filled, i.e.
+ // writing has wrapped.)
+ position_ = buffer_data_->end_position;
+ }
+ if (read >= buffer_size) {
+ DCHECK_EQ(read, buffer_size);
+ return read;
+ }
+ if (read >= to_eow) {
+ DCHECK_EQ(read, to_eow);
+ DCHECK_EQ(total_read_, buffer_data_->total_written);
+ return read;
+ }
+ }
+
+ // Read from middle part.
+ DCHECK_GE(position_, buffer_data_->wrap_position);
+ if (position_ >= buffer_data_->end_position) {
+ uint32 remaining_buffer_size = buffer_size - read;
+ uint32 to_eof = data_size_ - position_;
+ uint32 to_eow = buffer_data_->total_written - total_read_;
+ uint32 to_read = Min3(remaining_buffer_size, to_eof, to_eow);
+ memcpy(buffer_uint8 + read, buffer_data_->data + position_, to_read);
+ position_ += to_read;
+ total_read_ += to_read;
+ read += to_read;
+ if (position_ == data_size_) {
+ // We've read all the middle part, set position to the end part.
+ position_ = buffer_data_->wrap_position;
+ }
+ if (read >= buffer_size) {
+ DCHECK_EQ(read, buffer_size);
+ return read;
+ }
+ if (total_read_ >= buffer_data_->total_written) {
+ DCHECK_EQ(total_read_, buffer_data_->total_written);
+ return read;
+ }
+ }
+
+ // Read from end part.
+ DCHECK_GE(position_, buffer_data_->wrap_position);
+ DCHECK_LT(position_, buffer_data_->end_position);
+ uint32 remaining_buffer_size = buffer_size - read;
+ uint32 to_eob = buffer_data_->end_position - position_;
+ uint32 to_eow = buffer_data_->total_written - total_read_;
+ uint32 to_read = Min3(remaining_buffer_size, to_eob, to_eow);
+ memcpy(buffer_uint8 + read, buffer_data_->data + position_, to_read);
+ position_ += to_read;
+ total_read_ += to_read;
+ read += to_read;
+ DCHECK_LE(read, buffer_size);
+ DCHECK_LE(total_read_, buffer_data_->total_written);
+ return read;
+}
+
+void PartialCircularBuffer::Write(const void* buffer, uint32 buffer_size) {
+ DCHECK(buffer_data_);
+ uint32 position_before_write = position_;
+
+ uint32 to_eof = data_size_ - position_;
+ uint32 to_write = std::min(buffer_size, to_eof);
+ DoWrite(buffer_data_->data + position_, buffer, to_write);
+ if (position_ >= data_size_) {
+ DCHECK_EQ(position_, data_size_);
+ position_ = buffer_data_->wrap_position;
+ }
+
+ if (to_write < buffer_size) {
+ uint32 remainder_to_write = buffer_size - to_write;
+ DCHECK_LT(position_, position_before_write);
+ DCHECK_LE(position_ + remainder_to_write, position_before_write);
+ DoWrite(buffer_data_->data + position_,
+ reinterpret_cast<const uint8*>(buffer) + to_write,
+ remainder_to_write);
+ }
+}
+
+void PartialCircularBuffer::DoWrite(void* dest, const void* src, uint32 num) {
+ memcpy(dest, src, num);
+ position_ += num;
+ buffer_data_->total_written =
+ std::min(buffer_data_->total_written + num, data_size_);
+ buffer_data_->end_position = position_;
+}
+
+} // namespace content
diff --git a/content/common/partial_circular_buffer.h b/content/common/partial_circular_buffer.h
new file mode 100644
index 0000000..b692ac5
--- /dev/null
+++ b/content/common/partial_circular_buffer.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_PARTIAL_CIRCULAR_BUFFER_H_
+#define CONTENT_COMMON_PARTIAL_CIRCULAR_BUFFER_H_
+
+#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// A wrapper around a memory buffer that allows circular read and write with a
+// selectable wrapping position. Buffer layout (after wrap; H is header):
+// -----------------------------------------------------------
+// | H | Beginning | End | Middle |
+// -----------------------------------------------------------
+// ^---- Non-wrapping -----^ ^--------- Wrapping ----------^
+// The non-wrapping part is never overwritten. The wrapping part will be
+// circular. The very first part is the header (see the BufferData struct
+// below). It consists of the following information:
+// - Length written to the buffer (not including header).
+// - Wrapping position.
+// - End position of buffer. (If the last byte is at x, this will be x + 1.)
+// Users of wrappers around the same underlying buffer must ensure that writing
+// is finished before reading is started.
+class CONTENT_EXPORT PartialCircularBuffer {
+ public:
+ // Use for reading. |buffer_size| is in bytes and must be larger than the
+ // header size (see above).
+ PartialCircularBuffer(void* buffer, uint32 buffer_size);
+
+ // Use for writing. |buffer_size| is in bytes and must be larger than the
+ // header size (see above).
+ PartialCircularBuffer(void* buffer,
+ uint32 buffer_size,
+ uint32 wrap_position);
+
+ uint32 Read(void* buffer, uint32 buffer_size);
+ void Write(const void* buffer, uint32 buffer_size);
+
+ private:
+ friend class PartialCircularBufferTest;
+
+#pragma pack(push)
+#pragma pack(4)
+ struct BufferData {
+ uint32 total_written;
+ uint32 wrap_position;
+ uint32 end_position;
+ uint8 data[1];
+ };
+#pragma pack(pop)
+
+ void DoWrite(void* dest, const void* src, uint32 num);
+
+ // Used for reading and writing.
+ BufferData* buffer_data_;
+ uint32 memory_buffer_size_;
+ uint32 data_size_;
+ uint32 position_;
+
+ // Used for reading.
+ uint32 total_read_;
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_PARTIAL_CIRCULAR_BUFFER_H_
diff --git a/content/common/partial_circular_buffer_unittest.cc b/content/common/partial_circular_buffer_unittest.cc
new file mode 100644
index 0000000..5925667
--- /dev/null
+++ b/content/common/partial_circular_buffer_unittest.cc
@@ -0,0 +1,138 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// The test buffer data is 52 bytes, wrap position is set to 20 (this is
+// arbitrarily chosen). The total buffer size is allocated dynamically based on
+// the actual header size. This gives:
+// Header of some size, non-wrapping part 20 bytes, wrapping part 32 bytes.
+// As input data, a 14 byte array is used and repeatedly written. It's chosen
+// not to be an integer factor smaller than the wrapping part. This ensures that
+// the wrapped data isn't repeated at the same position.
+// Note that desipte the number of wraps (if one or more), the reference output
+// data is the same since the offset at each wrap is always the same.
+
+#include "base/memory/scoped_ptr.h"
+#include "content/common/partial_circular_buffer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+const uint32 kWrapPosition = 20;
+const uint8 kInputData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
+const uint8 kOutputRefDataWrap[] =
+ // The 20 bytes in the non-wrapping part.
+ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 2, 3, 4, 5, 6,
+ // The 32 bytes in wrapping part.
+ 11, 12, 13, 14,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
+
+class PartialCircularBufferTest : public testing::Test {
+ public:
+ PartialCircularBufferTest() {
+ PartialCircularBuffer::BufferData test_struct;
+ buffer_header_size_ =
+ &test_struct.data[0] - reinterpret_cast<uint8*>(&test_struct);
+
+ buffer_.reset(new uint8[buffer_header_size_ + sizeof(kOutputRefDataWrap)]);
+ pcb_write_.reset(new PartialCircularBuffer(
+ buffer_.get(),
+ buffer_header_size_ + sizeof(kOutputRefDataWrap),
+ kWrapPosition));
+ }
+
+ void WriteToBuffer(int num) {
+ for (int i = 0; i < num; ++i)
+ pcb_write_->Write(kInputData, sizeof(kInputData));
+ }
+
+ void InitReadBuffer() {
+ pcb_read_.reset(new PartialCircularBuffer(
+ buffer_.get(), buffer_header_size_ + sizeof(kOutputRefDataWrap)));
+ }
+
+ protected:
+ scoped_ptr<PartialCircularBuffer> pcb_write_;
+ scoped_ptr<PartialCircularBuffer> pcb_read_;
+ scoped_ptr<uint8[]> buffer_;
+ uint32 buffer_header_size_;
+
+ DISALLOW_COPY_AND_ASSIGN(PartialCircularBufferTest);
+};
+
+TEST_F(PartialCircularBufferTest, NoWrapBeginningPartOnly) {
+ WriteToBuffer(1);
+ InitReadBuffer();
+
+ uint8 output_data[sizeof(kInputData)] = {0};
+ EXPECT_EQ(sizeof(output_data),
+ pcb_read_->Read(output_data, sizeof(output_data)));
+
+ EXPECT_EQ(0, memcmp(kInputData, output_data, sizeof(kInputData)));
+
+ EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
+}
+
+TEST_F(PartialCircularBufferTest, NoWrapBeginningAndEndParts) {
+ WriteToBuffer(2);
+ InitReadBuffer();
+
+ uint8 output_data[2 * sizeof(kInputData)] = {0};
+ EXPECT_EQ(sizeof(output_data),
+ pcb_read_->Read(output_data, sizeof(output_data)));
+
+ const uint8 output_ref_data[2 * sizeof(kInputData)] =
+ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
+ EXPECT_EQ(0, memcmp(output_ref_data, output_data, sizeof(output_data)));
+
+ EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
+}
+
+TEST_F(PartialCircularBufferTest, WrapOnce) {
+ WriteToBuffer(4);
+ InitReadBuffer();
+
+ uint8 output_data[sizeof(kOutputRefDataWrap)] = {0};
+ EXPECT_EQ(sizeof(output_data),
+ pcb_read_->Read(output_data, sizeof(output_data)));
+
+ EXPECT_EQ(0, memcmp(kOutputRefDataWrap, output_data, sizeof(output_data)));
+
+ EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
+}
+
+TEST_F(PartialCircularBufferTest, WrapTwice) {
+ WriteToBuffer(7);
+ InitReadBuffer();
+
+ uint8 output_data[sizeof(kOutputRefDataWrap)] = {0};
+ EXPECT_EQ(sizeof(output_data),
+ pcb_read_->Read(output_data, sizeof(output_data)));
+
+ EXPECT_EQ(0, memcmp(kOutputRefDataWrap, output_data, sizeof(output_data)));
+
+ EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
+}
+
+TEST_F(PartialCircularBufferTest, WrapOnceSmallerOutputBuffer) {
+ WriteToBuffer(4);
+ InitReadBuffer();
+
+ uint8 output_data[sizeof(kOutputRefDataWrap)] = {0};
+ const uint32 size_per_read = 16;
+ uint32 read = 0;
+ for (; read + size_per_read <= sizeof(output_data); read += size_per_read) {
+ EXPECT_EQ(size_per_read,
+ pcb_read_->Read(output_data + read, size_per_read));
+ }
+ EXPECT_EQ(sizeof(output_data) - read,
+ pcb_read_->Read(output_data + read, size_per_read));
+
+ EXPECT_EQ(0, memcmp(kOutputRefDataWrap, output_data, sizeof(output_data)));
+
+ EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
+}
+
+} // namespace content
diff --git a/content/common/resource_dispatcher.cc b/content/common/resource_dispatcher.cc
index 3c0f789..b4addcb 100644
--- a/content/common/resource_dispatcher.cc
+++ b/content/common/resource_dispatcher.cc
@@ -33,6 +33,20 @@
namespace content {
+namespace {
+
+// Converts |time| from a remote to local TimeTicks, overwriting the original
+// value.
+void RemoteToLocalTimeTicks(
+ const InterProcessTimeTicksConverter& converter,
+ base::TimeTicks* time) {
+ RemoteTimeTicks remote_time = RemoteTimeTicks::FromTimeTicks(*time);
+ *time = converter.ToLocalTimeTicks(remote_time).ToTimeTicks();
+}
+
+
+} // namespace
+
static void CrashOnMapFailure() {
#if defined(OS_WIN)
DWORD last_err = GetLastError();
@@ -232,8 +246,6 @@
response->request_time = result.request_time;
response->response_time = result.response_time;
response->encoded_data_length = result.encoded_data_length;
- response->connection_id = result.connection_id;
- response->connection_reused = result.connection_reused;
response->load_timing = result.load_timing;
response->devtools_info = result.devtools_info;
response->data.swap(result.data);
@@ -244,7 +256,7 @@
ResourceDispatcher::ResourceDispatcher(IPC::Sender* sender)
: message_sender_(sender),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+ weak_factory_(this),
delegate_(NULL) {
}
@@ -555,9 +567,11 @@
FollowPendingRedirect(request_id, request_info);
- MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
base::Bind(&ResourceDispatcher::FlushDeferredMessages,
- weak_factory_.GetWeakPtr(), request_id));
+ weak_factory_.GetWeakPtr(),
+ request_id));
}
}
@@ -647,7 +661,7 @@
request_info.response_start.is_null() ||
browser_info.request_start.is_null() ||
browser_info.response_start.is_null() ||
- browser_info.load_timing.base_ticks.is_null()) {
+ browser_info.load_timing.request_start.is_null()) {
return;
}
InterProcessTimeTicksConverter converter(
@@ -656,28 +670,19 @@
RemoteTimeTicks::FromTimeTicks(browser_info.request_start),
RemoteTimeTicks::FromTimeTicks(browser_info.response_start));
- LocalTimeTicks renderer_base_ticks = converter.ToLocalTimeTicks(
- RemoteTimeTicks::FromTimeTicks(browser_info.load_timing.base_ticks));
- renderer_info->load_timing.base_ticks = renderer_base_ticks.ToTimeTicks();
-
-#define CONVERT(field) \
- LocalTimeDelta renderer_##field = converter.ToLocalTimeDelta( \
- RemoteTimeDelta::FromRawDelta(browser_info.load_timing.field)); \
- renderer_info->load_timing.field = renderer_##field.ToInt32()
-
- CONVERT(proxy_start);
- CONVERT(dns_start);
- CONVERT(dns_end);
- CONVERT(connect_start);
- CONVERT(connect_end);
- CONVERT(ssl_start);
- CONVERT(ssl_end);
- CONVERT(send_start);
- CONVERT(send_end);
- CONVERT(receive_headers_start);
- CONVERT(receive_headers_end);
-
-#undef CONVERT
+ net::LoadTimingInfo* load_timing = &renderer_info->load_timing;
+ RemoteToLocalTimeTicks(converter, &load_timing->request_start);
+ RemoteToLocalTimeTicks(converter, &load_timing->proxy_resolve_start);
+ RemoteToLocalTimeTicks(converter, &load_timing->proxy_resolve_end);
+ RemoteToLocalTimeTicks(converter, &load_timing->connect_timing.dns_start);
+ RemoteToLocalTimeTicks(converter, &load_timing->connect_timing.dns_end);
+ RemoteToLocalTimeTicks(converter, &load_timing->connect_timing.connect_start);
+ RemoteToLocalTimeTicks(converter, &load_timing->connect_timing.connect_end);
+ RemoteToLocalTimeTicks(converter, &load_timing->connect_timing.ssl_start);
+ RemoteToLocalTimeTicks(converter, &load_timing->connect_timing.ssl_end);
+ RemoteToLocalTimeTicks(converter, &load_timing->send_start);
+ RemoteToLocalTimeTicks(converter, &load_timing->send_end);
+ RemoteToLocalTimeTicks(converter, &load_timing->receive_headers_end);
}
base::TimeTicks ResourceDispatcher::ToRendererCompletionTime(
diff --git a/content/common/resource_dispatcher_unittest.cc b/content/common/resource_dispatcher_unittest.cc
index df65112..7465cec 100644
--- a/content/common/resource_dispatcher_unittest.cc
+++ b/content/common/resource_dispatcher_unittest.cc
@@ -329,7 +329,7 @@
};
TEST_F(DeferredResourceLoadingTest, DeferredLoadTest) {
- MessageLoop message_loop(MessageLoop::TYPE_IO);
+ base::MessageLoop message_loop(base::MessageLoop::TYPE_IO);
ResourceLoaderBridge* bridge = CreateBridge();
@@ -400,16 +400,19 @@
response_head.error_code = net::OK;
response_head.request_start = base::TimeTicks::FromInternalValue(5);
response_head.response_start = base::TimeTicks::FromInternalValue(15);
- response_head.load_timing.base_time = base::Time::Now();
- response_head.load_timing.base_ticks = base::TimeTicks::FromInternalValue(10);
- response_head.load_timing.dns_start = -1;
- response_head.load_timing.connect_start = 3;
+ response_head.load_timing.request_start_time = base::Time::Now();
+ response_head.load_timing.request_start =
+ base::TimeTicks::FromInternalValue(10);
+ response_head.load_timing.connect_timing.connect_start =
+ base::TimeTicks::FromInternalValue(13);
PerformTest(response_head);
- EXPECT_LT(0, response_info().load_timing.base_ticks.ToInternalValue());
- EXPECT_EQ(-1, response_info().load_timing.dns_start);
- EXPECT_LE(0, response_info().load_timing.connect_start);
+ EXPECT_LT(base::TimeTicks(), response_info().load_timing.request_start);
+ EXPECT_EQ(base::TimeTicks(),
+ response_info().load_timing.connect_timing.dns_start);
+ EXPECT_LE(response_head.load_timing.request_start,
+ response_info().load_timing.connect_timing.connect_start);
}
TEST_F(TimeConversionTest, PartiallyInitialized) {
@@ -420,8 +423,9 @@
PerformTest(response_head);
- EXPECT_EQ(0, response_info().load_timing.base_ticks.ToInternalValue());
- EXPECT_EQ(-1, response_info().load_timing.dns_start);
+ EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
+ EXPECT_EQ(base::TimeTicks(),
+ response_info().load_timing.connect_timing.dns_start);
}
TEST_F(TimeConversionTest, NotInitialized) {
@@ -430,8 +434,9 @@
PerformTest(response_head);
- EXPECT_EQ(0, response_info().load_timing.base_ticks.ToInternalValue());
- EXPECT_EQ(-1, response_info().load_timing.dns_start);
+ EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
+ EXPECT_EQ(base::TimeTicks(),
+ response_info().load_timing.connect_timing.dns_start);
}
} // namespace content
diff --git a/content/common/resource_messages.cc b/content/common/resource_messages.cc
index 3edaee3..ad4bd7f 100644
--- a/content/common/resource_messages.cc
+++ b/content/common/resource_messages.cc
@@ -4,6 +4,7 @@
#include "content/common/resource_messages.h"
+#include "net/base/load_timing_info.h"
#include "net/http/http_response_headers.h"
#include "webkit/glue/resource_loader_bridge.h"
@@ -137,7 +138,7 @@
void ParamTraits<scoped_refptr<webkit_glue::ResourceDevToolsInfo> >::Write(
Message* m, const param_type& p) {
WriteParam(m, p.get() != NULL);
- if (p.get()) {
+ if (p) {
WriteParam(m, p->http_status_code);
WriteParam(m, p->http_status_text);
WriteParam(m, p->request_headers);
@@ -175,81 +176,86 @@
l->append(")");
}
-void ParamTraits<webkit_glue::ResourceLoadTimingInfo>::Write(
+void ParamTraits<net::LoadTimingInfo>::Write(
Message* m, const param_type& p) {
- WriteParam(m, p.base_time.is_null());
- if (p.base_time.is_null())
+ WriteParam(m, p.socket_log_id);
+ WriteParam(m, p.socket_reused);
+ WriteParam(m, p.request_start_time.is_null());
+ if (p.request_start_time.is_null())
return;
- WriteParam(m, p.base_ticks);
- WriteParam(m, p.base_time);
- WriteParam(m, p.proxy_start);
- WriteParam(m, p.proxy_end);
- WriteParam(m, p.dns_start);
- WriteParam(m, p.dns_end);
- WriteParam(m, p.connect_start);
- WriteParam(m, p.connect_end);
- WriteParam(m, p.ssl_start);
- WriteParam(m, p.ssl_end);
+ WriteParam(m, p.request_start_time);
+ WriteParam(m, p.request_start);
+ WriteParam(m, p.proxy_resolve_start);
+ WriteParam(m, p.proxy_resolve_end);
+ WriteParam(m, p.connect_timing.dns_start);
+ WriteParam(m, p.connect_timing.dns_end);
+ WriteParam(m, p.connect_timing.connect_start);
+ WriteParam(m, p.connect_timing.connect_end);
+ WriteParam(m, p.connect_timing.ssl_start);
+ WriteParam(m, p.connect_timing.ssl_end);
WriteParam(m, p.send_start);
WriteParam(m, p.send_end);
- WriteParam(m, p.receive_headers_start);
WriteParam(m, p.receive_headers_end);
}
-bool ParamTraits<webkit_glue::ResourceLoadTimingInfo>::Read(
+bool ParamTraits<net::LoadTimingInfo>::Read(
const Message* m, PickleIterator* iter, param_type* r) {
- bool is_null;
- if (!ReadParam(m, iter, &is_null))
+ bool has_no_times;
+ if (!ReadParam(m, iter, &r->socket_log_id) ||
+ !ReadParam(m, iter, &r->socket_reused) ||
+ !ReadParam(m, iter, &has_no_times)) {
return false;
- if (is_null)
+ }
+ if (has_no_times)
return true;
return
- ReadParam(m, iter, &r->base_ticks) &&
- ReadParam(m, iter, &r->base_time) &&
- ReadParam(m, iter, &r->proxy_start) &&
- ReadParam(m, iter, &r->proxy_end) &&
- ReadParam(m, iter, &r->dns_start) &&
- ReadParam(m, iter, &r->dns_end) &&
- ReadParam(m, iter, &r->connect_start) &&
- ReadParam(m, iter, &r->connect_end) &&
- ReadParam(m, iter, &r->ssl_start) &&
- ReadParam(m, iter, &r->ssl_end) &&
+ ReadParam(m, iter, &r->request_start_time) &&
+ ReadParam(m, iter, &r->request_start) &&
+ ReadParam(m, iter, &r->proxy_resolve_start) &&
+ ReadParam(m, iter, &r->proxy_resolve_end) &&
+ ReadParam(m, iter, &r->connect_timing.dns_start) &&
+ ReadParam(m, iter, &r->connect_timing.dns_end) &&
+ ReadParam(m, iter, &r->connect_timing.connect_start) &&
+ ReadParam(m, iter, &r->connect_timing.connect_end) &&
+ ReadParam(m, iter, &r->connect_timing.ssl_start) &&
+ ReadParam(m, iter, &r->connect_timing.ssl_end) &&
ReadParam(m, iter, &r->send_start) &&
ReadParam(m, iter, &r->send_end) &&
- ReadParam(m, iter, &r->receive_headers_start) &&
ReadParam(m, iter, &r->receive_headers_end);
}
-void ParamTraits<webkit_glue::ResourceLoadTimingInfo>::Log(const param_type& p,
- std::string* l) {
+void ParamTraits<net::LoadTimingInfo>::Log(const param_type& p,
+ std::string* l) {
l->append("(");
- LogParam(p.base_ticks, l);
+ LogParam(p.socket_log_id, l);
+ l->append(",");
+ LogParam(p.socket_reused, l);
+ l->append(",");
+ LogParam(p.request_start_time, l);
l->append(", ");
- LogParam(p.base_time, l);
+ LogParam(p.request_start, l);
l->append(", ");
- LogParam(p.proxy_start, l);
+ LogParam(p.proxy_resolve_start, l);
l->append(", ");
- LogParam(p.proxy_end, l);
+ LogParam(p.proxy_resolve_end, l);
l->append(", ");
- LogParam(p.dns_start, l);
+ LogParam(p.connect_timing.dns_start, l);
l->append(", ");
- LogParam(p.dns_end, l);
+ LogParam(p.connect_timing.dns_end, l);
l->append(", ");
- LogParam(p.connect_start, l);
+ LogParam(p.connect_timing.connect_start, l);
l->append(", ");
- LogParam(p.connect_end, l);
+ LogParam(p.connect_timing.connect_end, l);
l->append(", ");
- LogParam(p.ssl_start, l);
+ LogParam(p.connect_timing.ssl_start, l);
l->append(", ");
- LogParam(p.ssl_end, l);
+ LogParam(p.connect_timing.ssl_end, l);
l->append(", ");
LogParam(p.send_start, l);
l->append(", ");
LogParam(p.send_end, l);
l->append(", ");
- LogParam(p.receive_headers_start, l);
- l->append(", ");
LogParam(p.receive_headers_end, l);
l->append(")");
}
diff --git a/content/common/resource_messages.h b/content/common/resource_messages.h
index abe4964..7aebd09 100644
--- a/content/common/resource_messages.h
+++ b/content/common/resource_messages.h
@@ -19,9 +19,12 @@
#ifndef CONTENT_COMMON_RESOURCE_MESSAGES_H_
#define CONTENT_COMMON_RESOURCE_MESSAGES_H_
+namespace net {
+struct LoadTimingInfo;
+}
+
namespace webkit_glue {
struct ResourceDevToolsInfo;
-struct ResourceLoadTimingInfo;
}
namespace IPC {
@@ -51,8 +54,8 @@
};
template <>
-struct ParamTraits<webkit_glue::ResourceLoadTimingInfo> {
- typedef webkit_glue::ResourceLoadTimingInfo param_type;
+struct ParamTraits<net::LoadTimingInfo> {
+ typedef net::LoadTimingInfo param_type;
static void Write(Message* m, const param_type& p);
static bool Read(const Message* m, PickleIterator* iter, param_type* r);
static void Log(const param_type& p, std::string* l);
@@ -99,8 +102,6 @@
IPC_STRUCT_TRAITS_MEMBER(encoded_data_length)
IPC_STRUCT_TRAITS_MEMBER(appcache_id)
IPC_STRUCT_TRAITS_MEMBER(appcache_manifest_url)
- IPC_STRUCT_TRAITS_MEMBER(connection_id)
- IPC_STRUCT_TRAITS_MEMBER(connection_reused)
IPC_STRUCT_TRAITS_MEMBER(load_timing)
IPC_STRUCT_TRAITS_MEMBER(devtools_info)
IPC_STRUCT_TRAITS_MEMBER(download_file_path)
diff --git a/content/common/sandbox_init_linux.cc b/content/common/sandbox_init_linux.cc
deleted file mode 100644
index 25cbf95..0000000
--- a/content/common/sandbox_init_linux.cc
+++ /dev/null
@@ -1,50 +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 <string>
-
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "content/common/sandbox_linux.h"
-#include "content/public/common/content_switches.h"
-#include "content/public/common/sandbox_init.h"
-
-namespace content {
-
-// TODO(jln): have call sites provide a process / policy type to
-// InitializeSandbox().
-bool InitializeSandbox() {
- bool seccomp_legacy_started = false;
- bool seccomp_bpf_started = false;
- LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance();
- const std::string process_type =
- CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kProcessType);
-
- // No matter what, it's always an error to call InitializeSandbox() after
- // threads have been created.
- if (!linux_sandbox->IsSingleThreaded()) {
- std::string error_message = "InitializeSandbox() called with multiple "
- "threads in process " + process_type;
- // TODO(jln): change this into a CHECK() once we are more comfortable it
- // does not trigger.
- LOG(ERROR) << error_message;
- return false;
- }
-
- // Attempt to limit the future size of the address space of the process.
- linux_sandbox->LimitAddressSpace(process_type);
-
- // First, try to enable seccomp-bpf.
- seccomp_bpf_started = linux_sandbox->StartSeccompBpf(process_type);
-
- // If that fails, try to enable seccomp-legacy.
- if (!seccomp_bpf_started) {
- seccomp_legacy_started = linux_sandbox->StartSeccompLegacy(process_type);
- }
-
- return seccomp_legacy_started || seccomp_bpf_started;
-}
-
-} // namespace content
diff --git a/content/common/sandbox_linux.cc b/content/common/sandbox_linux.cc
index ec443ec..c3e842b 100644
--- a/content/common/sandbox_linux.cc
+++ b/content/common/sandbox_linux.cc
@@ -10,6 +10,8 @@
#include <limits>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/logging.h"
@@ -17,7 +19,6 @@
#include "base/posix/eintr_wrapper.h"
#include "base/time.h"
#include "content/common/sandbox_linux.h"
-#include "content/common/seccomp_sandbox.h"
#include "content/common/sandbox_seccomp_bpf_linux.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/sandbox_linux.h"
@@ -39,35 +40,6 @@
#endif
}
-// Implement the command line enabling logic for seccomp-legacy.
-bool IsSeccompLegacyDesired() {
- CommandLine* command_line = CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(switches::kNoSandbox)) {
- return false;
- }
-#if defined(SECCOMP_SANDBOX)
-#if defined(NDEBUG)
- // Off by default. Allow turning on with a switch.
- return command_line->HasSwitch(switches::kEnableSeccompSandbox);
-#else
- // On by default. Allow turning off with a switch.
- return !command_line->HasSwitch(switches::kDisableSeccompSandbox);
-#endif // NDEBUG
-#endif // SECCOMP_SANDBOX
- return false;
-}
-
-// Our "policy" on whether or not to enable seccomp-legacy. Only renderers are
-// supported.
-bool ShouldEnableSeccompLegacy(const std::string& process_type) {
- if (IsSeccompLegacyDesired() &&
- process_type == switches::kRendererProcess) {
- return true;
- } else {
- return false;
- }
-}
-
bool AddResourceLimit(int resource, rlim_t limit) {
struct rlimit old_rlimit;
if (getrlimit(resource, &old_rlimit))
@@ -89,7 +61,6 @@
: proc_fd_(-1),
seccomp_bpf_started_(false),
pre_initialized_(false),
- seccomp_legacy_supported_(false),
seccomp_bpf_supported_(false),
setuid_sandbox_client_(sandbox::SetuidSandboxClient::Create()) {
if (setuid_sandbox_client_ == NULL) {
@@ -111,38 +82,22 @@
extern "C" void __sanitizer_sandbox_on_notify(void *reserved);
#endif
-void LinuxSandbox::PreinitializeSandboxBegin() {
+void LinuxSandbox::PreinitializeSandbox() {
CHECK(!pre_initialized_);
- seccomp_legacy_supported_ = false;
seccomp_bpf_supported_ = false;
#if defined(ADDRESS_SANITIZER) && defined(OS_LINUX)
// ASan needs to open some resources before the sandbox is enabled.
// This should not fork, not launch threads, not open a directory.
__sanitizer_sandbox_on_notify(/*reserved*/NULL);
#endif
-#if defined(SECCOMP_SANDBOX)
- if (IsSeccompLegacyDesired()) {
- proc_fd_ = open("/proc", O_DIRECTORY | O_RDONLY);
- if (proc_fd_ < 0) {
- LOG(ERROR) << "Cannot access \"/proc\". Disabling seccomp-legacy "
- "sandboxing.";
- // Now is a good time to figure out if we can support seccomp sandboxing
- // at all. We will call SupportsSeccompSandbox again later, when actually
- // enabling it, but we allow the implementation to cache some information.
- // This is the only place where we will log full lack of seccomp-legacy
- // support.
- } else if (!SupportsSeccompSandbox(proc_fd_)) {
- VLOG(1) << "Lacking support for seccomp-legacy sandbox.";
- CHECK_EQ(HANDLE_EINTR(close(proc_fd_)), 0);
- proc_fd_ = -1;
- } else {
- seccomp_legacy_supported_ = true;
- }
- }
-#endif // SECCOMP_SANDBOX
- // Similarly, we "pre-warm" the code that detects supports for seccomp BPF.
- // TODO(jln): Use proc_fd_ here too once we're comfortable it does not create
- // an additional security risk.
+
+#if !defined(NDEBUG)
+ // Open proc_fd_ only in Debug mode so that forgetting to close it doesn't
+ // produce a sandbox escape in Release mode.
+ proc_fd_ = open("/proc", O_DIRECTORY | O_RDONLY);
+ CHECK(proc_fd_ >= 0);
+#endif // !defined(NDEBUG)
+ // We "pre-warm" the code that detects supports for seccomp BPF.
if (SandboxSeccompBpf::IsSeccompBpfDesired()) {
if (!SandboxSeccompBpf::SupportsSandbox()) {
VLOG(1) << "Lacking support for seccomp-bpf sandbox.";
@@ -153,27 +108,37 @@
pre_initialized_ = true;
}
-// Once we finally know our process type, we can cleanup proc_fd_
-// or pass it to seccomp-legacy.
-void LinuxSandbox::PreinitializeSandboxFinish(
- const std::string& process_type) {
- CHECK(pre_initialized_);
- if (proc_fd_ >= 0) {
- if (ShouldEnableSeccompLegacy(process_type)) {
-#if defined(SECCOMP_SANDBOX)
- SeccompSandboxSetProcFd(proc_fd_);
-#endif
- } else {
- DCHECK_GE(proc_fd_, 0);
- CHECK_EQ(HANDLE_EINTR(close(proc_fd_)), 0);
- }
- proc_fd_ = -1;
- }
-}
+bool LinuxSandbox::InitializeSandbox() {
+ bool seccomp_bpf_started = false;
+ LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance();
+ // We need to make absolutely sure that our sandbox is "sealed" before
+ // InitializeSandbox does exit.
+ base::ScopedClosureRunner sandbox_sealer(
+ base::Bind(&LinuxSandbox::SealSandbox, base::Unretained(linux_sandbox)));
+ const std::string process_type =
+ CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kProcessType);
-void LinuxSandbox::PreinitializeSandbox(const std::string& process_type) {
- PreinitializeSandboxBegin();
- PreinitializeSandboxFinish(process_type);
+ // No matter what, it's always an error to call InitializeSandbox() after
+ // threads have been created.
+ if (!linux_sandbox->IsSingleThreaded()) {
+ std::string error_message = "InitializeSandbox() called with multiple "
+ "threads in process " + process_type;
+ // The GPU process is allowed to call InitializeSandbox() with threads for
+ // now, because it loads third party libraries.
+ if (process_type != switches::kGpuProcess)
+ DCHECK(false) << error_message;
+ LOG(ERROR) << error_message;
+ return false;
+ }
+
+ // Attempt to limit the future size of the address space of the process.
+ linux_sandbox->LimitAddressSpace(process_type);
+
+ // First, try to enable seccomp-bpf.
+ seccomp_bpf_started = linux_sandbox->StartSeccompBpf(process_type);
+
+ return seccomp_bpf_started;
}
int LinuxSandbox::GetStatus() const {
@@ -194,28 +159,42 @@
sandbox_flags |= kSandboxLinuxSeccompBpf;
}
- // We only try to enable seccomp-legacy when seccomp-bpf is not supported
- // or not enabled.
- if (!(sandbox_flags & kSandboxLinuxSeccompBpf) &&
- seccomp_legacy_supported() &&
- ShouldEnableSeccompLegacy(switches::kRendererProcess)) {
- // Same here, what we report is what we will do for the renderer.
- sandbox_flags |= kSandboxLinuxSeccompLegacy;
- }
return sandbox_flags;
}
+// Threads are counted via /proc/self/task. This is a little hairy because of
+// PID namespaces and existing sandboxes, so "self" must really be used instead
+// of using the pid.
bool LinuxSandbox::IsSingleThreaded() const {
- // TODO(jln): re-implement this properly and use our proc_fd_ if available.
- // Possibly racy, but it's ok because this is more of a debug check to catch
- // new threaded situations arising during development.
- int num_threads = file_util::CountFilesCreatedAfter(
- base::FilePath("/proc/self/task"),
- base::Time::UnixEpoch());
+ struct stat task_stat;
+ int fstat_ret;
+ if (proc_fd_ >= 0) {
+ // If a handle to /proc is available, use it. This allows to bypass file
+ // system restrictions.
+ fstat_ret = fstatat(proc_fd_, "self/task/", &task_stat, 0);
+ } else {
+ // Otherwise, make an attempt to access the file system directly.
+ fstat_ret = fstatat(AT_FDCWD, "/proc/self/task/", &task_stat, 0);
+ }
+ // In Debug mode, it's mandatory to be able to count threads to catch bugs.
+#if !defined(NDEBUG)
+ // Using DCHECK here would be incorrect. DCHECK can be enabled in non
+ // official release mode.
+ CHECK_EQ(0, fstat_ret) << "Could not count threads, the sandbox was not "
+ << "pre-initialized properly.";
+#endif // !defined(NDEBUG)
+ if (fstat_ret) {
+ // Pretend to be monothreaded if it can't be determined (for instance the
+ // setuid sandbox is already engaged but no proc_fd_ is available).
+ return true;
+ }
- // We pass the test if we don't know ( == 0), because the setuid sandbox
- // will prevent /proc access in some contexts.
- return num_threads == 1 || num_threads == 0;
+ // At least "..", "." and the current thread should be present.
+ CHECK_LE(3UL, task_stat.st_nlink);
+ // Counting threads via /proc/self/task could be racy. For the purpose of
+ // determining if the current proces is monothreaded it works: if at any
+ // time it becomes monothreaded, it'll stay so.
+ return task_stat.st_nlink == 3;
}
bool LinuxSandbox::seccomp_bpf_started() const {
@@ -227,30 +206,11 @@
return setuid_sandbox_client_.get();
}
-// For seccomp-legacy, we implement the policy inline, here.
-bool LinuxSandbox::StartSeccompLegacy(const std::string& process_type) {
- if (!pre_initialized_)
- PreinitializeSandbox(process_type);
- if (seccomp_legacy_supported() && ShouldEnableSeccompLegacy(process_type)) {
- // SupportsSeccompSandbox() returns a cached result, as we already
- // called it earlier in the PreinitializeSandbox(). Thus, it is OK for us
- // to not pass in a file descriptor for "/proc".
-#if defined(SECCOMP_SANDBOX)
- if (SupportsSeccompSandbox(-1)) {
- StartSeccompSandbox();
- LogSandboxStarted("seccomp-legacy");
- return true;
- }
-#endif
- }
- return false;
-}
-
// For seccomp-bpf, we use the SandboxSeccompBpf class.
bool LinuxSandbox::StartSeccompBpf(const std::string& process_type) {
CHECK(!seccomp_bpf_started_);
if (!pre_initialized_)
- PreinitializeSandbox(process_type);
+ PreinitializeSandbox();
if (seccomp_bpf_supported())
seccomp_bpf_started_ = SandboxSeccompBpf::StartSandbox(process_type);
@@ -260,11 +220,6 @@
return seccomp_bpf_started_;
}
-bool LinuxSandbox::seccomp_legacy_supported() const {
- CHECK(pre_initialized_);
- return seccomp_legacy_supported_;
-}
-
bool LinuxSandbox::seccomp_bpf_supported() const {
CHECK(pre_initialized_);
return seccomp_bpf_supported_;
@@ -307,5 +262,13 @@
#endif // !defined(ADDRESS_SANITIZER)
}
+void LinuxSandbox::SealSandbox() {
+ if (proc_fd_ >= 0) {
+ int ret = HANDLE_EINTR(close(proc_fd_));
+ CHECK_EQ(0, ret);
+ proc_fd_ = -1;
+ }
+}
+
} // namespace content
diff --git a/content/common/sandbox_linux.h b/content/common/sandbox_linux.h
index 3df65ea..f8753c5 100644
--- a/content/common/sandbox_linux.h
+++ b/content/common/sandbox_linux.h
@@ -37,29 +37,25 @@
static LinuxSandbox* GetInstance();
// Do some initialization that can only be done before any of the sandboxes
- // is enabled.
- //
- // There are two versions of this function. One takes a process_type
- // as an argument, the other doesn't.
- // It may be necessary to call PreinitializeSandboxBegin before knowing the
- // process type (this is for instance the case with the Zygote).
- // In that case, it is crucial that PreinitializeSandboxFinish() gets
- // called for every child process.
- // TODO(markus, jln) we know this is not always done at the moment
- // (crbug.com/139877).
- void PreinitializeSandbox(const std::string& process_type);
- // These should be called together.
- void PreinitializeSandboxBegin();
- void PreinitializeSandboxFinish(const std::string& process_type);
+ // are enabled. If using the setuid sandbox, this should be called manually
+ // before the setuid sandbox is engaged.
+ void PreinitializeSandbox();
- // Returns the Status of the sandbox. Can only be queried if we went through
- // PreinitializeSandbox() or PreinitializeSandboxBegin(). This is a bitmask
- // and uses the constants defined in "enum LinuxSandboxStatus".
- // Since we need to provide the status before the sandboxes are actually
- // started, this returns what will actually happen once the various Start*
- // functions are called from inside a renderer.
+ // Initialize the sandbox with the given pre-built configuration. Currently
+ // seccomp-bpf and address space limitations (the setuid sandbox works
+ // differently and is set-up in the Zygote). This will instantiate the
+ // LinuxSandbox singleton if it doesn't already exist.
+ static bool InitializeSandbox();
+
+ // Returns the Status of the renderers' sandbox. Can only be queried after
+ // going through PreinitializeSandbox(). This is a bitmask and uses the
+ // constants defined in "enum LinuxSandboxStatus". Since the status needs to
+ // be provided before the sandboxes are actually started, this returns what
+ // will actually happen once the various Start* functions are called from
+ // inside a renderer.
int GetStatus() const;
- // Is the current process single threaded?
+ // Returns true if the current process is single-threaded or if the number
+ // of threads cannot be determined.
bool IsSingleThreaded() const;
// Did we start Seccomp BPF?
bool seccomp_bpf_started() const;
@@ -70,10 +66,8 @@
// be used directly.
sandbox::SetuidSandboxClient* setuid_sandbox_client() const;
- // Check the policy and eventually start the seccomp-legacy sandbox.
- bool StartSeccompLegacy(const std::string& process_type);
// Check the policy and eventually start the seccomp-bpf sandbox. This should
- // never be called with threads started. If we detect that thread have
+ // never be called with threads started. If we detect that threads have
// started we will crash.
bool StartSeccompBpf(const std::string& process_type);
@@ -84,15 +78,19 @@
private:
friend struct DefaultSingletonTraits<LinuxSandbox>;
- // We must have been pre_initialized_ before using either of these.
- bool seccomp_legacy_supported() const;
+ // We must have been pre_initialized_ before using this.
bool seccomp_bpf_supported() const;
+ // The last part of the initialization is to make sure any temporary "hole"
+ // in the sandbox is closed. For now, this consists of closing proc_fd_.
+ void SealSandbox();
+ // A file descriptor to /proc. It's dangerous to have it around as it could
+ // allow for sandbox bypasses. It needs to be closed before we consider
+ // ourselves sandboxed.
int proc_fd_;
bool seccomp_bpf_started_;
- // Have we been through PreinitializeSandbox or PreinitializeSandboxBegin?
+ // Did PreinitializeSandbox() run?
bool pre_initialized_;
- bool seccomp_legacy_supported_; // Accurate if pre_initialized_.
bool seccomp_bpf_supported_; // Accurate if pre_initialized_.
scoped_ptr<sandbox::SetuidSandboxClient> setuid_sandbox_client_;
diff --git a/content/common/sandbox_mac.mm b/content/common/sandbox_mac.mm
index 6ae12c2..8265ff1 100644
--- a/content/common/sandbox_mac.mm
+++ b/content/common/sandbox_mac.mm
@@ -23,11 +23,11 @@
#include "base/memory/scoped_nsobject.h"
#include "base/rand_util.h"
#include "base/string16.h"
-#include "base/string_piece.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/sys_info.h"
-#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
diff --git a/content/common/sandbox_mac_diraccess_unittest.mm b/content/common/sandbox_mac_diraccess_unittest.mm
index f3c8e97..ede6ba0 100644
--- a/content/common/sandbox_mac_diraccess_unittest.mm
+++ b/content/common/sandbox_mac_diraccess_unittest.mm
@@ -11,7 +11,7 @@
#include "base/file_util.h"
#include "base/files/file_path.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/test/multiprocess_test.h"
#include "base/utf_string_conversions.h"
#include "content/common/sandbox_mac.h"
diff --git a/content/common/sandbox_mac_fontloading_unittest.mm b/content/common/sandbox_mac_fontloading_unittest.mm
index 959af35..77b211f 100644
--- a/content/common/sandbox_mac_fontloading_unittest.mm
+++ b/content/common/sandbox_mac_fontloading_unittest.mm
@@ -44,7 +44,7 @@
}
font_shmem_.reset(new base::SharedMemory);
- if (!font_shmem_.get()) {
+ if (!font_shmem_) {
LOG(ERROR) << "Failed to create shared memory object.";
return false;
}
diff --git a/content/common/sandbox_mac_system_access_unittest.mm b/content/common/sandbox_mac_system_access_unittest.mm
index 6eb681a..1b4eea3 100644
--- a/content/common/sandbox_mac_system_access_unittest.mm
+++ b/content/common/sandbox_mac_system_access_unittest.mm
@@ -6,7 +6,7 @@
#include "base/file_util.h"
#include "base/logging.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "content/common/sandbox_mac.h"
#include "content/common/sandbox_mac_unittest_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/content/common/sandbox_mac_unittest_helper.mm b/content/common/sandbox_mac_unittest_helper.mm
index 6417e68..4c64b55 100644
--- a/content/common/sandbox_mac_unittest_helper.mm
+++ b/content/common/sandbox_mac_unittest_helper.mm
@@ -139,7 +139,7 @@
// Find Test Function to run;
scoped_ptr<MacSandboxTestCase>
test_case(SandboxTestForName(sandbox_test_name));
- if (!test_case.get()) {
+ if (!test_case) {
LOG(ERROR) << "Invalid sandbox test name (" << sandbox_test_name << ")";
return -1;
}
diff --git a/content/common/sandbox_seccomp_bpf_linux.cc b/content/common/sandbox_seccomp_bpf_linux.cc
index 2f3f0ef..8f2e886 100644
--- a/content/common/sandbox_seccomp_bpf_linux.cc
+++ b/content/common/sandbox_seccomp_bpf_linux.cc
@@ -175,12 +175,15 @@
return is_enabled;
}
-intptr_t GpuOpenSIGSYS_Handler(const struct arch_seccomp_data& args,
- void* aux_broker_process) {
+intptr_t GpuSIGSYS_Handler(const struct arch_seccomp_data& args,
+ void* aux_broker_process) {
RAW_CHECK(aux_broker_process);
BrokerProcess* broker_process =
static_cast<BrokerProcess*>(aux_broker_process);
switch(args.nr) {
+ case __NR_access:
+ return broker_process->Access(reinterpret_cast<const char*>(args.args[0]),
+ static_cast<int>(args.args[1]));
case __NR_open:
return broker_process->Open(reinterpret_cast<const char*>(args.args[0]),
static_cast<int>(args.args[1]));
@@ -1269,11 +1272,11 @@
// be denied gracefully right away.
return sandbox->Trap(CrashSIGSYS_Handler, NULL);
}
- // In any other case crash the program with our SIGSYS handler
+ // In any other case crash the program with our SIGSYS handler.
return sandbox->Trap(CrashSIGSYS_Handler, NULL);
}
-// x86_64/i386 for now. Needs to be adapted and tested for ARM.
+// Main policy for x86_64/i386. Extended by ArmMaliGpuProcessPolicy.
ErrorCode GpuProcessPolicy(Sandbox *sandbox, int sysno,
void *broker_process) {
switch(sysno) {
@@ -1281,9 +1284,10 @@
case __NR_sched_getaffinity:
case __NR_sched_setaffinity:
return ErrorCode(ErrorCode::ERR_ALLOWED);
+ case __NR_access:
case __NR_open:
case __NR_openat:
- return sandbox->Trap(GpuOpenSIGSYS_Handler, broker_process);
+ return sandbox->Trap(GpuSIGSYS_Handler, broker_process);
default:
#if defined(__x86_64__) || defined(__arm__)
if (IsSystemVSharedMemory(sysno))
@@ -1297,13 +1301,14 @@
}
}
-// x86_64/i386 for now. Needs to be adapted and tested for ARM.
+// x86_64/i386.
// A GPU broker policy is the same as a GPU policy with open and
// openat allowed.
ErrorCode GpuBrokerProcessPolicy(Sandbox *sandbox, int sysno, void *aux) {
// "aux" would typically be NULL, when called from
// "EnableGpuBrokerPolicyCallBack"
switch(sysno) {
+ case __NR_access:
case __NR_open:
case __NR_openat:
return ErrorCode(ErrorCode::ERR_ALLOWED);
@@ -1312,6 +1317,48 @@
}
}
+// ARM Mali GPU process sandbox, inheriting from GpuProcessPolicy.
+ErrorCode ArmMaliGpuProcessPolicy(Sandbox *sandbox, int sysno,
+ void *broker_process) {
+ switch(sysno) {
+#if defined(__arm__)
+ // ARM GPU sandbox is started earlier so we need to allow networking
+ // in the sandbox.
+ // TODO(jorgelo): tighten this (crbug.com/235609).
+ case __NR_connect:
+ case __NR_getpeername:
+ case __NR_getsockname:
+ case __NR_socket:
+ case __NR_socketpair:
+ case __NR_sysinfo:
+ case __NR_uname:
+ return ErrorCode(ErrorCode::ERR_ALLOWED);
+#endif // defined(__arm__)
+ default:
+ if (IsAdvancedScheduler(sysno))
+ return ErrorCode(ErrorCode::ERR_ALLOWED);
+
+ // Default to the generic GPU policy.
+ return GpuProcessPolicy(sandbox, sysno, broker_process);
+ }
+}
+
+// A GPU broker policy is the same as a GPU policy with open and
+// openat allowed.
+ErrorCode ArmMaliGpuBrokerProcessPolicy(Sandbox *sandbox,
+ int sysno, void *aux) {
+ // "aux" would typically be NULL, when called from
+ // "EnableGpuBrokerPolicyCallBack"
+ switch(sysno) {
+ case __NR_access:
+ case __NR_open:
+ case __NR_openat:
+ return ErrorCode(ErrorCode::ERR_ALLOWED);
+ default:
+ return ArmMaliGpuProcessPolicy(sandbox, sysno, aux);
+ }
+}
+
// Allow clone for threads, crash if anything else is attempted.
// Don't restrict on ASAN.
ErrorCode RestrictCloneToThreads(Sandbox *sandbox) {
@@ -1453,28 +1500,79 @@
}
}
-bool EnableGpuBrokerPolicyCallBack() {
+bool EnableGpuBrokerPolicyCallback() {
StartSandboxWithPolicy(GpuBrokerProcessPolicy, NULL);
return true;
}
+bool EnableArmMaliGpuBrokerPolicyCallback() {
+ StartSandboxWithPolicy(ArmMaliGpuBrokerProcessPolicy, NULL);
+ return true;
+}
+
+void AddArmMaliGpuWhitelist(std::vector<std::string>* read_whitelist,
+ std::vector<std::string>* write_whitelist) {
+ // On ARM we're enabling the sandbox before the X connection is made,
+ // so we need to allow access to |.Xauthority|.
+ static const char kXAutorityPath[] = "/home/chronos/.Xauthority";
+
+ // Devices and files needed by the ARM GPU userspace.
+ static const char kMali0Path[] = "/dev/mali0";
+ static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2";
+ static const char kLibEglPath[] = "/usr/lib/libEGL.so.1";
+
+ // Devices needed for video decode acceleration on ARM.
+ static const char kDevMfcDecPath[] = "/dev/mfc-dec";
+ static const char kDevGsc1Path[] = "/dev/gsc1";
+
+ read_whitelist->push_back(kXAutorityPath);
+ read_whitelist->push_back(kMali0Path);
+ read_whitelist->push_back(kLibGlesPath);
+ read_whitelist->push_back(kLibEglPath);
+ read_whitelist->push_back(kDevMfcDecPath);
+ read_whitelist->push_back(kDevGsc1Path);
+
+ write_whitelist->push_back(kMali0Path);
+ write_whitelist->push_back(kDevMfcDecPath);
+ write_whitelist->push_back(kDevGsc1Path);
+}
+
// Start a broker process to handle open() inside the sandbox.
-void InitGpuBrokerProcess(BrokerProcess** broker_process) {
+void InitGpuBrokerProcess(Sandbox::EvaluateSyscall gpu_policy,
+ BrokerProcess** broker_process) {
static const char kDriRcPath[] = "/etc/drirc";
static const char kDriCard0Path[] = "/dev/dri/card0";
CHECK(broker_process);
CHECK(*broker_process == NULL);
+ bool (*sandbox_callback)(void) = NULL;
+
+ // All GPU process policies need these files brokered out.
std::vector<std::string> read_whitelist;
read_whitelist.push_back(kDriCard0Path);
read_whitelist.push_back(kDriRcPath);
+
std::vector<std::string> write_whitelist;
write_whitelist.push_back(kDriCard0Path);
+ if (gpu_policy == ArmMaliGpuProcessPolicy) {
+ // We shouldn't be using this policy on non-ARM architectures.
+ CHECK(IsArchitectureArm());
+
+ AddArmMaliGpuWhitelist(&read_whitelist, &write_whitelist);
+ sandbox_callback = EnableArmMaliGpuBrokerPolicyCallback;
+ } else if (gpu_policy == GpuProcessPolicy) {
+ sandbox_callback = EnableGpuBrokerPolicyCallback;
+ } else {
+ // We shouldn't be initializing a GPU broker process without a GPU process
+ // policy.
+ NOTREACHED();
+ }
+
*broker_process = new BrokerProcess(read_whitelist, write_whitelist);
- // Initialize the broker process and give it a sandbox call back.
- CHECK((*broker_process)->Init(EnableGpuBrokerPolicyCallBack));
+ // Initialize the broker process and give it a sandbox callback.
+ CHECK((*broker_process)->Init(sandbox_callback));
}
// Warms up/preloads resources needed by the policies.
@@ -1482,10 +1580,10 @@
void WarmupPolicy(Sandbox::EvaluateSyscall policy,
BrokerProcess** broker_process) {
if (policy == GpuProcessPolicy) {
- if (IsArchitectureX86_64() || IsArchitectureI386()) {
- // Create a new broker process.
- InitGpuBrokerProcess(broker_process);
+ // Create a new broker process.
+ InitGpuBrokerProcess(policy, broker_process);
+ if (IsArchitectureX86_64() || IsArchitectureI386()) {
// Accelerated video decode dlopen()'s a shared object
// inside the sandbox, so preload it now.
if (IsAcceleratedVideoDecodeEnabled()) {
@@ -1500,6 +1598,9 @@
dlopen(I965DrvVideoPath, RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
}
}
+ } else if (policy == ArmMaliGpuProcessPolicy) {
+ // Create a new broker process.
+ InitGpuBrokerProcess(policy, broker_process);
}
}
@@ -1507,12 +1608,9 @@
const CommandLine& command_line,
const std::string& process_type) {
if (process_type == switches::kGpuProcess) {
- // On Chrome OS, --enable-gpu-sandbox enables the more restrictive policy.
- // However, we don't yet enable the more restrictive GPU process policy
- // on ARM.
- if (IsArchitectureArm() ||
- (IsChromeOS() && !command_line.HasSwitch(switches::kEnableGpuSandbox)))
- return BlacklistDebugAndNumaPolicy;
+ // On Chrome OS ARM, we need a specific GPU process policy.
+ if (IsChromeOS() && IsArchitectureArm())
+ return ArmMaliGpuProcessPolicy;
else
return GpuProcessPolicy;
}
diff --git a/content/common/sandbox_win.cc b/content/common/sandbox_win.cc
index cc29215..e86d433 100644
--- a/content/common/sandbox_win.cc
+++ b/content/common/sandbox_win.cc
@@ -69,17 +69,6 @@
L"npggNT.des", // GameGuard 2008.
L"npggNT.dll", // GameGuard (older).
L"oawatch.dll", // Online Armor.
- L"owexplorer-10513.dll", // Overwolf.
- L"owexplorer-10514.dll", // Overwolf.
- L"owexplorer-10515.dll", // Overwolf.
- L"owexplorer-10516.dll", // Overwolf.
- L"owexplorer-10517.dll", // Overwolf.
- L"owexplorer-10518.dll", // Overwolf.
- L"owexplorer-10519.dll", // Overwolf.
- L"owexplorer-10520.dll", // Overwolf.
- L"owexplorer-10521.dll", // Overwolf.
- L"owexplorer-10522.dll", // Overwolf.
- L"owexplorer-10523.dll", // Overwolf.
L"pavhook.dll", // Panda Internet Security.
L"pavlsphook.dll", // Panda Antivirus.
L"pavshook.dll", // Panda Antivirus.
@@ -121,10 +110,8 @@
if (!PathService::Get(path, &directory))
return false;
- if (sub_dir) {
- directory = directory.Append(sub_dir);
- file_util::AbsolutePath(&directory);
- }
+ if (sub_dir)
+ directory = base::MakeAbsoluteFilePath(directory.Append(sub_dir));
sandbox::ResultCode result;
result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, access,
diff --git a/content/common/seccomp_sandbox.h b/content/common/seccomp_sandbox.h
deleted file mode 100644
index 06cf9f8..0000000
--- a/content/common/seccomp_sandbox.h
+++ /dev/null
@@ -1,20 +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_COMMON_SECCOMP_SANDBOX_H_
-#define CONTENT_COMMON_SECCOMP_SANDBOX_H_
-
-// Seccomp enable/disable logic is centralized here.
-// - We define SECCOMP_SANDBOX if seccomp is compiled in at all: currently,
-// on non-views (non-ChromeOS) non-ARM non-Clang Linux only.
-
-#include "build/build_config.h"
-
-#if defined(ARCH_CPU_X86_FAMILY) && !defined(CHROMIUM_SELINUX) && \
- !defined(OS_CHROMEOS) && !defined(TOOLKIT_VIEWS) && !defined(OS_OPENBSD)
-#define SECCOMP_SANDBOX
-#include "sandbox/linux/seccomp-legacy/sandbox.h"
-#endif
-
-#endif // CONTENT_COMMON_SECCOMP_SANDBOX_H_
diff --git a/content/common/socket_stream_dispatcher.cc b/content/common/socket_stream_dispatcher.cc
index 13a7ddf..0d35135 100644
--- a/content/common/socket_stream_dispatcher.cc
+++ b/content/common/socket_stream_dispatcher.cc
@@ -11,11 +11,14 @@
#include "base/lazy_instance.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
+#include "base/string16.h"
+#include "base/utf_string_conversions.h"
#include "content/common/child_thread.h"
#include "content/common/socket_stream.h"
#include "content/common/socket_stream_handle_data.h"
#include "content/common/socket_stream_messages.h"
#include "googleurl/src/gurl.h"
+#include "net/base/net_errors.h"
#include "webkit/glue/websocketstreamhandle_bridge.h"
#include "webkit/glue/websocketstreamhandle_delegate.h"
@@ -48,18 +51,23 @@
void OnSentData(int amount_sent);
void OnReceivedData(const std::vector<char>& data);
void OnClosed();
+ void OnFailed(int error_code, const char* error_msg);
private:
virtual ~IPCWebSocketStreamHandleBridge();
void DoConnect(const GURL& url);
void DoClose();
+
+ // The ID for this bridge and corresponding SocketStream instance in the
+ // browser process.
int socket_id_;
ChildThread* child_thread_;
WebKit::WebSocketStreamHandle* handle_;
webkit_glue::WebSocketStreamHandleDelegate* delegate_;
+ // Map from ID to bridge instance.
static base::LazyInstance<IDMap<IPCWebSocketStreamHandleBridge> >::Leaky
all_bridges;
};
@@ -75,17 +83,20 @@
}
IPCWebSocketStreamHandleBridge::~IPCWebSocketStreamHandleBridge() {
- DVLOG(1) << "IPCWebSocketStreamHandleBridge destructor socket_id="
- << socket_id_;
- if (socket_id_ != kNoSocketId) {
- child_thread_->Send(new SocketStreamHostMsg_Close(socket_id_));
- socket_id_ = kNoSocketId;
- }
+ DVLOG(1) << "Bridge (" << this << ", socket_id_=" << socket_id_
+ << ") Destructor";
+
+ if (socket_id_ == kNoSocketId)
+ return;
+
+ child_thread_->Send(new SocketStreamHostMsg_Close(socket_id_));
+ socket_id_ = kNoSocketId;
}
void IPCWebSocketStreamHandleBridge::Connect(const GURL& url) {
DCHECK(child_thread_);
- DVLOG(1) << "Connect url=" << url;
+ DVLOG(1) << "Bridge (" << this << ") Connect (url=" << url << ")";
+
child_thread_->message_loop()->PostTask(
FROM_HERE,
base::Bind(&IPCWebSocketStreamHandleBridge::DoConnect, this, url));
@@ -93,7 +104,9 @@
bool IPCWebSocketStreamHandleBridge::Send(
const std::vector<char>& data) {
- DVLOG(1) << "Send data.size=" << data.size();
+ DVLOG(1) << "Bridge #" << socket_id_ << " Send (" << data.size()
+ << " bytes)";
+
if (child_thread_->Send(
new SocketStreamHostMsg_SendData(socket_id_, data))) {
if (delegate_)
@@ -104,7 +117,8 @@
}
void IPCWebSocketStreamHandleBridge::Close() {
- DVLOG(1) << "Close socket_id" << socket_id_;
+ DVLOG(1) << "Bridge #" << socket_id_ << " Close";
+
AddRef(); // Released in DoClose().
child_thread_->message_loop()->PostTask(
FROM_HERE,
@@ -112,25 +126,33 @@
}
void IPCWebSocketStreamHandleBridge::OnConnected(int max_pending_send_allowed) {
- DVLOG(1) << "IPCWebSocketStreamHandleBridge::OnConnected socket_id="
- << socket_id_;
+ DVLOG(1) << "Bridge #" << socket_id_
+ << " OnConnected (max_pending_send_allowed="
+ << max_pending_send_allowed << ")";
+
if (delegate_)
delegate_->DidOpenStream(handle_, max_pending_send_allowed);
}
void IPCWebSocketStreamHandleBridge::OnSentData(int amount_sent) {
+ DVLOG(1) << "Bridge #" << socket_id_ << " OnSentData (" << amount_sent
+ << " bytes)";
+
if (delegate_)
delegate_->DidSendData(handle_, amount_sent);
}
void IPCWebSocketStreamHandleBridge::OnReceivedData(
const std::vector<char>& data) {
+ DVLOG(1) << "Bridge #" << socket_id_ << " OnReceiveData (" << data.size()
+ << " bytes)";
if (delegate_)
delegate_->DidReceiveData(handle_, &data[0], data.size());
}
void IPCWebSocketStreamHandleBridge::OnClosed() {
- DVLOG(1) << "IPCWebSocketStreamHandleBridge::OnClosed";
+ DVLOG(1) << "Bridge #" << socket_id_ << " OnClosed";
+
if (socket_id_ != kNoSocketId) {
all_bridges.Get().Remove(socket_id_);
socket_id_ = kNoSocketId;
@@ -141,6 +163,14 @@
Release();
}
+void IPCWebSocketStreamHandleBridge::OnFailed(int error_code,
+ const char* error_msg) {
+ DVLOG(1) << "Bridge #" << socket_id_ << " OnFailed (error_code=" << error_code
+ << ")";
+ if (delegate_)
+ delegate_->DidFail(handle_, error_code, ASCIIToUTF16(error_msg));
+}
+
void IPCWebSocketStreamHandleBridge::DoConnect(const GURL& url) {
DCHECK(child_thread_);
DCHECK_EQ(socket_id_, kNoSocketId);
@@ -157,10 +187,10 @@
AddRef(); // Released in OnClosed().
if (child_thread_->Send(
new SocketStreamHostMsg_Connect(render_view_id, url, socket_id_))) {
- DVLOG(1) << "Connect socket_id=" << socket_id_;
+ DVLOG(1) << "Bridge #" << socket_id_ << " sent IPC Connect";
// TODO(ukai): timeout to OnConnected.
} else {
- DLOG(ERROR) << "IPC SocketStream_Connect failed.";
+ DLOG(ERROR) << "Bridge #" << socket_id_ << " failed to send IPC Connect";
OnClosed();
}
}
@@ -189,6 +219,7 @@
IPC_MESSAGE_HANDLER(SocketStreamMsg_SentData, OnSentData)
IPC_MESSAGE_HANDLER(SocketStreamMsg_ReceivedData, OnReceivedData)
IPC_MESSAGE_HANDLER(SocketStreamMsg_Closed, OnClosed)
+ IPC_MESSAGE_HANDLER(SocketStreamMsg_Failed, OnFailed)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -196,42 +227,60 @@
void SocketStreamDispatcher::OnConnected(int socket_id,
int max_pending_send_allowed) {
- DVLOG(1) << "SocketStreamDispatcher::OnConnected socket_id=" << socket_id
- << " max_pending_send_allowed=" << max_pending_send_allowed;
+ DVLOG(1) << "SocketStreamDispatcher::OnConnected (max_pending_send_allowed="
+ << max_pending_send_allowed << ") to socket_id=" << socket_id;
+
IPCWebSocketStreamHandleBridge* bridge =
IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
if (bridge)
bridge->OnConnected(max_pending_send_allowed);
else
- DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id;
+ DLOG(ERROR) << "No bridge for socket_id=" << socket_id;
}
void SocketStreamDispatcher::OnSentData(int socket_id, int amount_sent) {
+ DVLOG(1) << "SocketStreamDispatcher::OnSentData (" << amount_sent
+ << " bytes) to socket_id=" << socket_id;
+
IPCWebSocketStreamHandleBridge* bridge =
IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
if (bridge)
bridge->OnSentData(amount_sent);
else
- DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id;
+ DLOG(ERROR) << "No bridge for socket_id=" << socket_id;
}
void SocketStreamDispatcher::OnReceivedData(
int socket_id, const std::vector<char>& data) {
+ DVLOG(1) << "SocketStreamDispatcher::OnReceivedData (" << data.size()
+ << " bytes) to socket_id=" << socket_id;
+
IPCWebSocketStreamHandleBridge* bridge =
IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
if (bridge)
bridge->OnReceivedData(data);
else
- DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id;
+ DLOG(ERROR) << "No bridge for socket_id=" << socket_id;
}
void SocketStreamDispatcher::OnClosed(int socket_id) {
+ DVLOG(1) << "SocketStreamDispatcher::OnClosed to socket_id=" << socket_id;
+
IPCWebSocketStreamHandleBridge* bridge =
IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
if (bridge)
bridge->OnClosed();
else
- DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id;
+ DLOG(ERROR) << "No bridge for socket_id=" << socket_id;
+}
+
+void SocketStreamDispatcher::OnFailed(int socket_id, int error_code) {
+ IPCWebSocketStreamHandleBridge* bridge =
+ IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
+ if (bridge)
+ bridge->OnFailed(error_code, net::ErrorToString(error_code));
+ else
+ DLOG(ERROR) << "No bridge for socket_id=" << socket_id;
}
} // namespace content
diff --git a/content/common/socket_stream_dispatcher.h b/content/common/socket_stream_dispatcher.h
index 2a67f73..b619623 100644
--- a/content/common/socket_stream_dispatcher.h
+++ b/content/common/socket_stream_dispatcher.h
@@ -43,6 +43,7 @@
void OnSentData(int socket_id, int amount_sent);
void OnReceivedData(int socket_id, const std::vector<char>& data);
void OnClosed(int socket_id);
+ void OnFailed(int socket_id, int error_code);
DISALLOW_COPY_AND_ASSIGN(SocketStreamDispatcher);
};
diff --git a/content/common/socket_stream_messages.h b/content/common/socket_stream_messages.h
index 020796d..47eea33 100644
--- a/content/common/socket_stream_messages.h
+++ b/content/common/socket_stream_messages.h
@@ -73,3 +73,8 @@
// The Socket Stream is closed.
IPC_MESSAGE_CONTROL1(SocketStreamMsg_Closed,
int /* socket_id */)
+
+// The Socket Stream is failed.
+IPC_MESSAGE_CONTROL2(SocketStreamMsg_Failed,
+ int /* socket_id */,
+ int /* error_code */)
diff --git a/content/common/ssl_status_serialization.h b/content/common/ssl_status_serialization.h
index d913453..e3db1a2 100644
--- a/content/common/ssl_status_serialization.h
+++ b/content/common/ssl_status_serialization.h
@@ -7,7 +7,7 @@
#include <string>
-#include "net/base/cert_status_flags.h"
+#include "net/cert/cert_status_flags.h"
namespace content {
diff --git a/content/common/swapped_out_messages.cc b/content/common/swapped_out_messages.cc
index d94f0b9..5fe91cb 100644
--- a/content/common/swapped_out_messages.cc
+++ b/content/common/swapped_out_messages.cc
@@ -5,6 +5,7 @@
#include "content/common/swapped_out_messages.h"
#include "content/common/accessibility_messages.h"
+#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_client.h"
@@ -16,7 +17,7 @@
// consistent in case we later return to the same renderer.
switch (msg->type()) {
// Handled by RenderWidget.
- case ViewHostMsg_HandleInputEvent_ACK::ID:
+ case InputHostMsg_HandleInputEvent_ACK::ID:
case ViewHostMsg_PaintAtSize_ACK::ID:
case ViewHostMsg_UpdateRect::ID:
// Allow targeted navigations while swapped out.
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index c87ff49..2f3756e 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -12,13 +12,13 @@
#include "cc/output/compositor_frame_ack.h"
#include "content/common/content_export.h"
#include "content/common/content_param_traits.h"
-#include "content/common/edit_command.h"
#include "content/common/navigation_gesture.h"
#include "content/common/pepper_renderer_instance_data.h"
#include "content/common/view_message_enums.h"
#include "content/port/common/input_event_ack_state.h"
#include "content/public/common/common_param_traits.h"
#include "content/public/common/context_menu_params.h"
+#include "content/public/common/favicon_url.h"
#include "content/public/common/file_chooser_params.h"
#include "content/public/common/frame_navigate_params.h"
#include "content/public/common/javascript_message_type.h"
@@ -38,7 +38,6 @@
#include "third_party/WebKit/Source/Platform/chromium/public/WebFloatRect.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositionUnderline.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFindOptions.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerAction.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginAction.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupType.h"
@@ -74,8 +73,8 @@
IPC_ENUM_TRAITS(WebKit::WebTextDirection)
IPC_ENUM_TRAITS(WebMenuItem::Type)
IPC_ENUM_TRAITS(WindowContainerType)
+IPC_ENUM_TRAITS(content::FaviconURL::IconType)
IPC_ENUM_TRAITS(content::FileChooserParams::Mode)
-IPC_ENUM_TRAITS(content::InputEventAckState)
IPC_ENUM_TRAITS(content::JavaScriptMessageType)
IPC_ENUM_TRAITS(content::NavigationGesture)
IPC_ENUM_TRAITS(content::PageZoom)
@@ -193,9 +192,9 @@
IPC_STRUCT_TRAITS_MEMBER(render_widget_id)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(content::EditCommand)
- IPC_STRUCT_TRAITS_MEMBER(name)
- IPC_STRUCT_TRAITS_MEMBER(value)
+IPC_STRUCT_TRAITS_BEGIN(content::FaviconURL)
+ IPC_STRUCT_TRAITS_MEMBER(icon_url)
+ IPC_STRUCT_TRAITS_MEMBER(icon_type)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::FileChooserParams)
@@ -422,6 +421,10 @@
// User agent override used to navigate.
IPC_STRUCT_MEMBER(bool, is_overriding_user_agent)
+
+ // Notifies the browser that for this navigation, the session history was
+ // successfully cleared.
+ IPC_STRUCT_MEMBER(bool, history_list_was_cleared)
IPC_STRUCT_END()
IPC_STRUCT_BEGIN(ViewHostMsg_OpenURL_Params)
@@ -573,6 +576,11 @@
IPC_STRUCT_MEMBER(int, current_history_list_offset)
IPC_STRUCT_MEMBER(int, current_history_list_length)
+ // Informs the RenderView the session history should be cleared. In that
+ // case, the RenderView needs to notify the browser that the clearing was
+ // succesful when the navigation commits.
+ IPC_STRUCT_MEMBER(bool, should_clear_history_list)
+
// The URL to load.
IPC_STRUCT_MEMBER(GURL, url)
@@ -629,6 +637,9 @@
// If not empty, which frame to navigate.
IPC_STRUCT_MEMBER(std::string, frame_to_navigate)
+
+ // The navigationStart time to expose to JS for this navigation.
+ IPC_STRUCT_MEMBER(base::TimeTicks, browser_navigation_start)
IPC_STRUCT_END()
IPC_STRUCT_BEGIN(ViewMsg_New_Params)
@@ -636,7 +647,7 @@
IPC_STRUCT_MEMBER(content::RendererPreferences, renderer_preferences)
// Preferences for this view.
- IPC_STRUCT_MEMBER(webkit_glue::WebPreferences, web_preferences)
+ IPC_STRUCT_MEMBER(WebPreferences, web_preferences)
// The ID of the view to be created.
IPC_STRUCT_MEMBER(int32, view_id)
@@ -682,14 +693,6 @@
// the source process. The browser replaces it with the routing ID of the
// equivalent (swapped out) frame in the destination process.
IPC_STRUCT_MEMBER(int, source_routing_id)
- // The identifier of the source frame in the source process.
- IPC_STRUCT_MEMBER(int, source_frame_id)
-
- // The full set of identifiers to uniquely describe the target frame. See
- // the comment on ViewMsg_FrameTreeUpdated for details.
- IPC_STRUCT_MEMBER(int, target_process_id)
- IPC_STRUCT_MEMBER(int, target_routing_id)
- IPC_STRUCT_MEMBER(int, target_frame_id)
// The origin of the source frame.
IPC_STRUCT_MEMBER(string16, source_origin)
@@ -750,7 +753,7 @@
IPC_MESSAGE_ROUTED1(ViewMsg_OrientationChangeEvent,
int /* orientation */)
-// Sent by the renderer when the parameters for vsync alignment have changed.
+// Sent by the browser when the parameters for vsync alignment have changed.
IPC_MESSAGE_ROUTED2(ViewMsg_UpdateVSyncParameters,
base::TimeTicks /* timebase */,
base::TimeDelta /* interval */)
@@ -790,7 +793,7 @@
// This passes a set of webkit preferences down to the renderer.
IPC_MESSAGE_ROUTED1(ViewMsg_UpdateWebPreferences,
- webkit_glue::WebPreferences)
+ WebPreferences)
// Informs the renderer that the timezone has changed.
IPC_MESSAGE_ROUTED0(ViewMsg_TimezoneChange)
@@ -856,50 +859,14 @@
// compositor path.
IPC_MESSAGE_ROUTED0(ViewMsg_SwapBuffers_ACK)
-// Sends an input event to the render widget.
-IPC_MESSAGE_ROUTED2(ViewMsg_HandleInputEvent,
- IPC::WebInputEventPointer /* event */,
- bool /* is_keyboard_shortcut */)
-
// Tells the render widget that a smooth scroll completed.
-IPC_MESSAGE_ROUTED1(ViewMsg_SmoothScrollCompleted,
- int /* gesture_id */)
-
-// This message notifies the renderer that the next key event is bound to one
-// or more pre-defined edit commands. If the next key event is not handled
-// by webkit, the specified edit commands shall be executed against current
-// focused frame.
-// Parameters
-// * edit_commands (see chrome/common/edit_command_types.h)
-// Contains one or more edit commands.
-// See third_party/WebKit/Source/WebCore/editing/EditorCommand.cpp for detailed
-// definition of webkit edit commands.
-//
-// This message must be sent just before sending a key event.
-IPC_MESSAGE_ROUTED1(ViewMsg_SetEditCommandsForNextKeyEvent,
- std::vector<content::EditCommand> /* edit_commands */)
-
-// Message payload is the name/value of a WebCore edit command to execute.
-IPC_MESSAGE_ROUTED2(ViewMsg_ExecuteEditCommand,
- std::string, /* name */
- std::string /* value */)
-
-IPC_MESSAGE_ROUTED0(ViewMsg_MouseCaptureLost)
-
-// TODO(darin): figure out how this meshes with RestoreFocus
-IPC_MESSAGE_ROUTED1(ViewMsg_SetFocus,
- bool /* enable */)
+IPC_MESSAGE_ROUTED0(ViewMsg_SmoothScrollCompleted)
// Tells the renderer to focus the first (last if reverse is true) focusable
// node.
IPC_MESSAGE_ROUTED1(ViewMsg_SetInitialFocus,
bool /* reverse */)
-// Tells the renderer to scroll the currently focused node into rect only if
-// the currently focused node is a Text node (textfield, text area or content
-// editable divs).
-IPC_MESSAGE_ROUTED1(ViewMsg_ScrollFocusedEditableNodeIntoRect, gfx::Rect)
-
// Executes custom context menu action that was provided from WebKit.
IPC_MESSAGE_ROUTED2(ViewMsg_CustomContextMenuAction,
content::CustomContextMenuContext /* custom_context */,
@@ -910,6 +877,9 @@
IPC_MESSAGE_ROUTED1(ViewMsg_ContextMenuClosed,
content::CustomContextMenuContext /* custom_context */)
+// Sent to inform the renderer to invoke a context menu.
+IPC_MESSAGE_ROUTED0(ViewMsg_ShowContextMenu)
+
// Tells the renderer to perform the specified navigation, interrupting any
// existing navigation.
IPC_MESSAGE_ROUTED1(ViewMsg_Navigate, ViewMsg_Navigate_Params)
@@ -930,44 +900,10 @@
IPC_MESSAGE_ROUTED1(ViewMsg_StopFinding,
content::StopFindAction /* action */)
-// These messages are typically generated from context menus and request the
-// renderer to apply the specified operation to the current selection.
-IPC_MESSAGE_ROUTED0(ViewMsg_Undo)
-IPC_MESSAGE_ROUTED0(ViewMsg_Redo)
-IPC_MESSAGE_ROUTED0(ViewMsg_Cut)
-IPC_MESSAGE_ROUTED0(ViewMsg_Copy)
-#if defined(OS_MACOSX)
-IPC_MESSAGE_ROUTED0(ViewMsg_CopyToFindPboard)
-#endif
-IPC_MESSAGE_ROUTED0(ViewMsg_Paste)
-IPC_MESSAGE_ROUTED0(ViewMsg_PasteAndMatchStyle)
-// Replaces the selected region or a word around the cursor with the
-// specified string.
-IPC_MESSAGE_ROUTED1(ViewMsg_Replace,
- string16)
-// Replaces the misspelling in the selected region with the specified string.
-IPC_MESSAGE_ROUTED1(ViewMsg_ReplaceMisspelling,
- string16)
-IPC_MESSAGE_ROUTED0(ViewMsg_Delete)
-IPC_MESSAGE_ROUTED0(ViewMsg_SelectAll)
-
// Replaces a date time input field.
IPC_MESSAGE_ROUTED1(ViewMsg_ReplaceDateTime,
ViewHostMsg_DateTimeDialogValue_Params /* value */)
-IPC_MESSAGE_ROUTED0(ViewMsg_Unselect)
-
-// Requests the renderer to select the region between two points.
-// Expects a SelectRange_ACK message when finished.
-IPC_MESSAGE_ROUTED2(ViewMsg_SelectRange,
- gfx::Point /* start */,
- gfx::Point /* end */)
-
-// Requests the renderer to move the caret selection toward the point.
-// Expects a MoveCaret_ACK message when finished.
-IPC_MESSAGE_ROUTED1(ViewMsg_MoveCaret,
- gfx::Point /* location */)
-
// Copies the image at location x, y to the clipboard (if there indeed is an
// image at that location).
IPC_MESSAGE_ROUTED2(ViewMsg_CopyImageAt,
@@ -1022,16 +958,6 @@
// Requests that the RenderView's main frame sets its opener to null.
IPC_MESSAGE_ROUTED0(ViewMsg_DisownOpener)
-// Sends a JSON serialized frame tree to RenderView along with the process id
-// and route id of the source renderer.
-//
-// This message must be sent to swapped out RenderViews every time the browser
-// receives a ViewHostMsg_FrameTreeUpdated message.
-IPC_MESSAGE_ROUTED3(ViewMsg_UpdateFrameTree,
- int, /* the child process id of the active renderer */
- int, /* route_id of the active renderer */
- std::string /* json encoded frame tree */)
-
// Request for the renderer to evaluate an xpath to a frame and insert css
// into that frame's document. See ViewMsg_ScriptEvalRequest for details on
// allowed xpath expressions.
@@ -1245,9 +1171,6 @@
IPC_MESSAGE_ROUTED1(ViewMsg_SetActive,
bool /* active */)
-IPC_MESSAGE_ROUTED1(ViewMsg_SetNavigationStartTime,
- base::TimeTicks /* browser_navigation_start */)
-
// Response message to ViewHostMsg_CreateShared/DedicatedWorker.
// Sent when the worker has started.
IPC_MESSAGE_ROUTED0(ViewMsg_WorkerCreated)
@@ -1319,13 +1242,6 @@
bool /* suspend */)
#if defined(OS_ANDROID)
-// Sent when the user clicks on the find result bar to activate a find result.
-// The point (x,y) is in fractions of the content document's width and height.
-IPC_MESSAGE_ROUTED3(ViewMsg_ActivateNearestFindResult,
- int /* request_id */,
- float /* x */,
- float /* y */)
-
// Sent when the browser wants the bounding boxes of the current find matches.
//
// If match rects are already cached on the browser side, |current_version|
@@ -1352,12 +1268,20 @@
IPC_MESSAGE_ROUTED1(ViewMsg_ImeBatchStateChanged,
bool /* is_begin */)
-// Notifies the renderer whether hiding the top controls is enabled.
-IPC_MESSAGE_ROUTED1(ViewMsg_EnableHidingTopControls,
- bool /* enable */)
+// Notifies the renderer whether hiding/showing the top controls is enabled
+// and whether or not to animate to the proper state.
+IPC_MESSAGE_ROUTED3(ViewMsg_UpdateTopControlsState,
+ bool /* enable_hiding */,
+ bool /* enable_showing */,
+ bool /* animate */)
IPC_MESSAGE_ROUTED0(ViewMsg_ShowImeIfNeeded)
+// Sent by the browser when the display vsync signal was triggered and the
+// renderer should generate a new frame.
+IPC_MESSAGE_ROUTED1(ViewMsg_DidVSync,
+ base::TimeTicks /* frame_time */)
+
#elif defined(OS_MACOSX)
// Let the RenderView know its window has changed visibility.
IPC_MESSAGE_ROUTED1(ViewMsg_SetWindowVisibility,
@@ -1387,13 +1311,9 @@
IPC_MESSAGE_ROUTED1(ViewMsg_SwapCompositorFrameAck,
cc::CompositorFrameAck /* ack */)
-// Sent from the browser to ask the renderer for a snapshot of the current view.
-// The renderer replies with whether the snapshot succeeded and the SkBitmap.
+// Sent by the browser to ask the renderer for a snapshot of the current view.
IPC_MESSAGE_ROUTED1(ViewMsg_Snapshot,
gfx::Rect /* src_subrect */)
-IPC_MESSAGE_ROUTED2(ViewHostMsg_Snapshot,
- bool, /* success */
- SkBitmap /* bitmap */)
// -----------------------------------------------------------------------------
// Messages sent from the renderer to the browser.
@@ -1679,11 +1599,6 @@
IPC_MESSAGE_ROUTED1(ViewHostMsg_DidActivateAcceleratedCompositing,
bool /* true if the accelerated compositor is actve */)
-// Acknowledges receipt of a ViewMsg_HandleInputEvent message.
-IPC_MESSAGE_ROUTED2(ViewHostMsg_HandleInputEvent_ACK,
- WebKit::WebInputEvent::Type,
- content::InputEventAckState /* ack_result */)
-
IPC_STRUCT_BEGIN(ViewHostMsg_BeginSmoothScroll_Params)
IPC_STRUCT_MEMBER(bool, scroll_down)
IPC_STRUCT_MEMBER(int, pixels_to_scroll)
@@ -1691,8 +1606,7 @@
IPC_STRUCT_MEMBER(int, mouse_event_y)
IPC_STRUCT_END()
-IPC_MESSAGE_ROUTED2(ViewHostMsg_BeginSmoothScroll,
- int /* gesture_id */,
+IPC_MESSAGE_ROUTED1(ViewHostMsg_BeginSmoothScroll,
ViewHostMsg_BeginSmoothScroll_Params /* params */)
IPC_MESSAGE_ROUTED0(ViewHostMsg_Focus)
@@ -2122,6 +2036,12 @@
int /* flags */,
int /* message_id */)
+// Reply to a snapshot request containing whether snapshotting succeeded and the
+// SkBitmap if it succeeded.
+IPC_MESSAGE_ROUTED2(ViewHostMsg_Snapshot,
+ bool, /* success */
+ SkBitmap /* bitmap */)
+
//---------------------------------------------------------------------------
// Request for cryptographic operation messages:
// These are messages from the renderer to the browser to perform a
@@ -2193,8 +2113,8 @@
int32 /* complete status */)
// Notifies the browser of an event occurring in the media pipeline.
-IPC_MESSAGE_CONTROL1(ViewHostMsg_MediaLogEvent,
- media::MediaLogEvent /* event */)
+IPC_MESSAGE_CONTROL1(ViewHostMsg_MediaLogEvents,
+ std::vector<media::MediaLogEvent> /* events */)
// Requests to lock the mouse. Will result in a ViewMsg_LockMouse_ACK message
// being sent back.
@@ -2229,37 +2149,6 @@
base::FilePath /* path */,
bool /* is_hung */)
-// Chrome allows JavaScript calls to be routed across process boundaries. To
-// achieve this, each active RenderView in the source process has a swapped out
-// "mirror" in the target process. The active RenderView and its mirror
-// need to have identical frame tree structure, so calls originating in and
-// targeting subframes can be routed properly. This is achieved by each active
-// RenderView sending a ViewHostMsg_FrameTreeUpdated message to the browser,
-// which in turn sends the update to the corresponding mirror RenderView(s)
-// through the ViewMsg_UpdateFrameTree. We use best effort to keep these
-// trees synchronized across processes.
-//
-// When routing JavaScript calls across processes, the target information
-// is kept in the renderer process instead of the browser process. This design
-// was chosen because frame ids are allocated by the renderer process. If the
-// browser was to keep a mapping of the frame ids across processes, it would
-// require an extra IPC message with the newly allocated frame ids, as a
-// response to this particular message.
-//
-// The frame tree for a RenderView is serialized to JSON, so it can be sent to
-// the browser process. Each node in the tree is an object with three
-// properties:
-// * id - (integer) the frame identifier in this RenderView
-// * name - (string) the name of the frame, if one has been assigned
-// * subtree - an array of the same type of objects for each frame that is a
-// direct child of the current frame. This property can be omitted if
-// there are no direct child frames, so less data is transferred.
-//
-// This message must be sent on any events that modify the tree structure or
-// the names of any frames.
-IPC_MESSAGE_ROUTED1(ViewHostMsg_FrameTreeUpdated,
- std::string /* json encoded frame tree */)
-
// Notifies that multiple touch targets may have been pressed, and to show
// the disambiguation popup.
IPC_MESSAGE_ROUTED3(ViewHostMsg_ShowDisambiguationPopup,
@@ -2292,6 +2181,16 @@
// first paint.
IPC_MESSAGE_ROUTED0(ViewHostMsg_WillInsertBody)
+// Notification that the urls for the favicon of a site has been determined.
+IPC_MESSAGE_ROUTED2(ViewHostMsg_UpdateFaviconURL,
+ int32 /* page_id */,
+ std::vector<content::FaviconURL> /* candidates */)
+
+// Sent once a paint happens after the first non empty layout. In other words
+// after the page has painted something.
+IPC_MESSAGE_ROUTED1(ViewHostMsg_DidFirstVisuallyNonEmptyPaint,
+ int /* page_id */)
+
#if defined(OS_ANDROID)
// Response to ViewMsg_FindMatchRects.
//
@@ -2321,20 +2220,23 @@
IPC_MESSAGE_ROUTED1(ViewHostMsg_DidChangeBodyBackgroundColor,
uint32 /* bg_color */)
-// Information about current document scroll, scale and size. Sent on a
-// best-effort basis.
-IPC_MESSAGE_ROUTED5(ViewHostMsg_UpdateFrameInfo,
- gfx::Vector2d /* scroll_offset */,
- float /* page_scale_factor */,
- float /* min_page_scale_factor */,
- float /* max_page_scale_factor */,
- gfx::Size /* content_size */)
-
// This message is an ACK that the batch state change has been received by
// the renderer and all IME related messages should be processed accordingly.
IPC_MESSAGE_ROUTED1(ViewHostMsg_ImeBatchStateChanged_ACK,
bool /* is_begin */)
+// This message runs the MediaCodec for decoding audio for webaudio.
+IPC_MESSAGE_CONTROL3(ViewHostMsg_RunWebAudioMediaCodec,
+ base::SharedMemoryHandle /* encoded_data_handle */,
+ base::FileDescriptor /* pcm_output */,
+ size_t /* data_size*/)
+
+// Sent by renderer to request a ViewMsg_VSync message for upcoming display
+// vsync events. If |enabled| is true, the vsync message will continue to be be
+// delivered until the notification is disabled.
+IPC_MESSAGE_ROUTED1(ViewHostMsg_SetVSyncNotificationEnabled,
+ bool /* enabled */)
+
#elif defined(OS_MACOSX)
// Request that the browser load a font into shared memory for us.
IPC_SYNC_MESSAGE_CONTROL1_3(ViewHostMsg_LoadFont,
diff --git a/content/common/webkitplatformsupport_impl.cc b/content/common/webkitplatformsupport_impl.cc
index 1af22f8..b6c0728 100644
--- a/content/common/webkitplatformsupport_impl.cc
+++ b/content/common/webkitplatformsupport_impl.cc
@@ -9,6 +9,25 @@
#include "content/public/common/content_client.h"
#include "googleurl/src/gurl.h"
+#if defined(OS_ANDROID)
+#include "base/file_descriptor_posix.h"
+#include "base/shared_memory.h"
+#include "content/common/view_messages.h"
+
+namespace {
+void RunWebAudioMediaCodec(
+ base::SharedMemoryHandle encoded_data_handle,
+ base::FileDescriptor pcm_output,
+ size_t data_size) {
+ content::ChildThread::current()->Send(
+ new ViewHostMsg_RunWebAudioMediaCodec(encoded_data_handle,
+ pcm_output,
+ data_size));
+}
+
+} // anonymous namespace
+#endif
+
namespace content {
WebKitPlatformSupportImpl::WebKitPlatformSupportImpl() {
@@ -49,4 +68,11 @@
return dispatcher->CreateBridge(handle, delegate);
}
+#if defined(OS_ANDROID)
+webkit_media::WebAudioMediaCodecRunner
+WebKitPlatformSupportImpl::GetWebAudioMediaCodecRunner() {
+ return base::Bind(&RunWebAudioMediaCodec);
+}
+#endif
+
} // namespace content
diff --git a/content/common/webkitplatformsupport_impl.h b/content/common/webkitplatformsupport_impl.h
index de778a2..c56ed05 100644
--- a/content/common/webkitplatformsupport_impl.h
+++ b/content/common/webkitplatformsupport_impl.h
@@ -34,6 +34,10 @@
virtual webkit_glue::WebSocketStreamHandleBridge* CreateWebSocketBridge(
WebKit::WebSocketStreamHandle* handle,
webkit_glue::WebSocketStreamHandleDelegate* delegate) OVERRIDE;
+#if defined(OS_ANDROID)
+ virtual webkit_media::WebAudioMediaCodecRunner GetWebAudioMediaCodecRunner()
+ OVERRIDE;
+#endif
};
} // namespace content
diff --git a/content/common/webmessageportchannel_impl.cc b/content/common/webmessageportchannel_impl.cc
index 1833ec1..93e0232 100644
--- a/content/common/webmessageportchannel_impl.cc
+++ b/content/common/webmessageportchannel_impl.cc
@@ -80,11 +80,11 @@
void WebMessagePortChannelImpl::postMessage(
const WebString& message,
WebMessagePortChannelArray* channels) {
- if (MessageLoop::current() != ChildThread::current()->message_loop()) {
+ if (base::MessageLoop::current() != ChildThread::current()->message_loop()) {
ChildThread::current()->message_loop()->PostTask(
FROM_HERE,
- base::Bind(&WebMessagePortChannelImpl::postMessage, this,
- message, channels));
+ base::Bind(
+ &WebMessagePortChannelImpl::postMessage, this, message, channels));
return;
}
@@ -127,10 +127,9 @@
}
void WebMessagePortChannelImpl::Init() {
- if (MessageLoop::current() != ChildThread::current()->message_loop()) {
+ if (base::MessageLoop::current() != ChildThread::current()->message_loop()) {
ChildThread::current()->message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&WebMessagePortChannelImpl::Init, this));
+ FROM_HERE, base::Bind(&WebMessagePortChannelImpl::Init, this));
return;
}
@@ -145,7 +144,7 @@
void WebMessagePortChannelImpl::Entangle(
scoped_refptr<WebMessagePortChannelImpl> channel) {
- if (MessageLoop::current() != ChildThread::current()->message_loop()) {
+ if (base::MessageLoop::current() != ChildThread::current()->message_loop()) {
ChildThread::current()->message_loop()->PostTask(
FROM_HERE,
base::Bind(&WebMessagePortChannelImpl::Entangle, this, channel));
@@ -157,10 +156,9 @@
}
void WebMessagePortChannelImpl::QueueMessages() {
- if (MessageLoop::current() != ChildThread::current()->message_loop()) {
+ if (base::MessageLoop::current() != ChildThread::current()->message_loop()) {
ChildThread::current()->message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&WebMessagePortChannelImpl::QueueMessages, this));
+ FROM_HERE, base::Bind(&WebMessagePortChannelImpl::QueueMessages, this));
return;
}
// This message port is being sent elsewhere (perhaps to another process).
@@ -177,7 +175,7 @@
}
void WebMessagePortChannelImpl::Send(IPC::Message* message) {
- if (MessageLoop::current() != ChildThread::current()->message_loop()) {
+ if (base::MessageLoop::current() != ChildThread::current()->message_loop()) {
DCHECK(!message->is_sync());
ChildThread::current()->message_loop()->PostTask(
FROM_HERE,
diff --git a/content/common_aidl.target.darwin-arm.mk b/content/common_aidl.target.darwin-arm.mk
new file mode 100644
index 0000000..a4ade8f
--- /dev/null
+++ b/content/common_aidl.target.darwin-arm.mk
@@ -0,0 +1,153 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_common_aidl_gyp
+LOCAL_MODULE_STEM := common_aidl
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+
+### Generated for rule "content_content_gyp_common_aidl_target_compile_aidl":
+# "{'inputs': ['$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/framework.aidl', 'public/android/java/src/org/chromium/content/common/common.aidl'], 'extension': 'aidl', 'rule_sources': ['public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl', 'public/android/java/src/org/chromium/content/common/IChildProcessService.aidl'], 'rule_name': 'compile_aidl', 'outputs': ['$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java'], 'action': ['$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/tools/darwin/aidl', '-p$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/framework.aidl', '-ppublic/android/java/src/org/chromium/content/common/common.aidl', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java']}":
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/framework.aidl $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/common.aidl $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/common_aidl/aidl; cd $(gyp_local_path)/content; "$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/tools/darwin/aidl" "-p$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/framework.aidl" -ppublic/android/java/src/org/chromium/content/common/common.aidl public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl "$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java"
+
+.PHONY: content_common_aidl_gyp_rule_trigger
+content_common_aidl_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java
+
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/IChildProcessService.aidl $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/framework.aidl $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/common.aidl $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/common_aidl/aidl; cd $(gyp_local_path)/content; "$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/tools/darwin/aidl" "-p$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/framework.aidl" -ppublic/android/java/src/org/chromium/content/common/common.aidl public/android/java/src/org/chromium/content/common/IChildProcessService.aidl "$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java"
+
+.PHONY: content_common_aidl_gyp_rule_trigger
+content_common_aidl_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java \
+ $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES := \
+ content_common_aidl_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_common_aidl_gyp
+
+# Alias gyp target name.
+.PHONY: common_aidl
+common_aidl: content_common_aidl_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/common_aidl.target.darwin-x86.mk b/content/common_aidl.target.darwin-x86.mk
new file mode 100644
index 0000000..6ed321b
--- /dev/null
+++ b/content/common_aidl.target.darwin-x86.mk
@@ -0,0 +1,154 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_common_aidl_gyp
+LOCAL_MODULE_STEM := common_aidl
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+
+### Generated for rule "content_content_gyp_common_aidl_target_compile_aidl":
+# "{'inputs': ['$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/framework.aidl', 'public/android/java/src/org/chromium/content/common/common.aidl'], 'extension': 'aidl', 'rule_sources': ['public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl', 'public/android/java/src/org/chromium/content/common/IChildProcessService.aidl'], 'rule_name': 'compile_aidl', 'outputs': ['$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java'], 'action': ['$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/tools/darwin/aidl', '-p$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/framework.aidl', '-ppublic/android/java/src/org/chromium/content/common/common.aidl', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java']}":
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/framework.aidl $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/common.aidl $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/common_aidl/aidl; cd $(gyp_local_path)/content; "$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/tools/darwin/aidl" "-p$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/framework.aidl" -ppublic/android/java/src/org/chromium/content/common/common.aidl public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl "$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java"
+
+.PHONY: content_common_aidl_gyp_rule_trigger
+content_common_aidl_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java
+
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/IChildProcessService.aidl $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/framework.aidl $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/common.aidl $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/common_aidl/aidl; cd $(gyp_local_path)/content; "$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/tools/darwin/aidl" "-p$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/framework.aidl" -ppublic/android/java/src/org/chromium/content/common/common.aidl public/android/java/src/org/chromium/content/common/IChildProcessService.aidl "$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java"
+
+.PHONY: content_common_aidl_gyp_rule_trigger
+content_common_aidl_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java \
+ $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES := \
+ content_common_aidl_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_common_aidl_gyp
+
+# Alias gyp target name.
+.PHONY: common_aidl
+common_aidl: content_common_aidl_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/common_aidl.target.linux-arm.mk b/content/common_aidl.target.linux-arm.mk
index 8eb0fd7..28907e6 100644
--- a/content/common_aidl.target.linux-arm.mk
+++ b/content/common_aidl.target.linux-arm.mk
@@ -90,7 +90,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -98,7 +97,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
diff --git a/content/common_aidl.target.linux-x86.mk b/content/common_aidl.target.linux-x86.mk
index 2e8a975..aed9897 100644
--- a/content/common_aidl.target.linux-x86.mk
+++ b/content/common_aidl.target.linux-x86.mk
@@ -70,6 +70,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -91,7 +92,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -99,7 +99,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
diff --git a/content/content.gyp b/content/content.gyp
index 1068b7e..f790279 100644
--- a/content/content.gyp
+++ b/content/content.gyp
@@ -301,6 +301,21 @@
'includes': [ '../build/java_aidl.gypi' ],
},
{
+ 'target_name': 'content_native_libraries_gen',
+ 'type': 'none',
+ 'sources': [
+ 'public/android/java/templates/NativeLibraries.template',
+ ],
+ 'variables': {
+ 'package_name': 'org/chromium/content/app',
+ 'include_path': 'public/android/java/templates',
+ 'template_deps': [
+ 'public/android/java/templates/native_libraries_array.h'
+ ],
+ },
+ 'includes': [ '../build/android/java_cpp_template.gypi' ],
+ },
+ {
'target_name': 'content_java',
'type': 'none',
'dependencies': [
@@ -312,9 +327,11 @@
'content_common',
'page_transition_types_java',
'result_codes_java',
+ 'content_native_libraries_gen',
],
'variables': {
'java_in_dir': '../content/public/android/java',
+ 'jar_excluded_classes': [ '*/NativeLibraries.class' ],
'has_java_resources': 1,
'R_package': 'org.chromium.content',
'R_package_relpath': 'org/chromium/content',
@@ -355,24 +372,6 @@
'includes': [ '../build/android/java_cpp_template.gypi' ],
},
{
- 'target_name': 'surface_texture_jni_headers',
- 'type': 'none',
- 'variables': {
- 'jni_gen_package': 'content',
- 'input_java_class': 'android/graphics/SurfaceTexture.class',
- },
- 'includes': [ '../build/jar_file_jni_generator.gypi' ],
- },
- {
- 'target_name': 'surface_jni_headers',
- 'type': 'none',
- 'variables': {
- 'jni_gen_package': 'content',
- 'input_java_class': 'android/view/Surface.class',
- },
- 'includes': [ '../build/jar_file_jni_generator.gypi' ],
- },
- {
'target_name': 'java_set_jni_headers',
'type': 'none',
'variables': {
@@ -387,8 +386,6 @@
'type': 'none',
'dependencies': [
'java_set_jni_headers',
- 'surface_texture_jni_headers',
- 'surface_jni_headers',
],
'direct_dependent_settings': {
'include_dirs': [
diff --git a/content/content.target.darwin-arm.mk b/content/content.target.darwin-arm.mk
new file mode 100644
index 0000000..7426d36
--- /dev/null
+++ b/content/content.target.darwin-arm.mk
@@ -0,0 +1,47 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_content_gyp
+LOCAL_MODULE_STEM := content
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_app_gyp)/content_content_app_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_browser_gyp)/content_content_browser_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_common_gyp)/content_content_common_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_gpu_gyp)/content_content_gpu_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_plugin_gyp)/content_content_plugin_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_ppapi_plugin_gyp)/content_content_ppapi_plugin_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_renderer_gyp)/content_content_renderer_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_utility_gyp)/content_content_utility_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_worker_gyp)/content_content_worker_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_gyp
+
+# Alias gyp target name.
+.PHONY: content
+content: content_content_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/content.target.darwin-x86.mk b/content/content.target.darwin-x86.mk
new file mode 100644
index 0000000..7426d36
--- /dev/null
+++ b/content/content.target.darwin-x86.mk
@@ -0,0 +1,47 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_content_gyp
+LOCAL_MODULE_STEM := content
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_app_gyp)/content_content_app_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_browser_gyp)/content_content_browser_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_common_gyp)/content_content_common_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_gpu_gyp)/content_content_gpu_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_plugin_gyp)/content_content_plugin_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_ppapi_plugin_gyp)/content_content_ppapi_plugin_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_renderer_gyp)/content_content_renderer_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_utility_gyp)/content_content_utility_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_content_worker_gyp)/content_content_worker_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_gyp
+
+# Alias gyp target name.
+.PHONY: content
+content: content_content_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/content_app.target.darwin-arm.mk b/content/content_app.target.darwin-arm.mk
new file mode 100644
index 0000000..a20d349
--- /dev/null
+++ b/content/content_app.target.darwin-arm.mk
@@ -0,0 +1,187 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_app_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_ui_gyp)/ui_ui_gyp.a \
+ $(call intermediates-dir-for,GYP,content_content_jni_headers_gyp)/content_jni_headers.stamp \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ content/app/android/app_jni_registrar.cc \
+ content/app/android/child_process_service.cc \
+ content/app/android/content_main.cc \
+ content/app/android/library_loader_hooks.cc \
+ content/app/content_main_runner.cc \
+ content/public/app/content_main_delegate.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DPOSIX_AVOID_MMAP' \
+ '-DU_USING_ICU_NAMESPACE=0' \
+ '-DSK_BUILD_NO_IMAGE_ENCODE' \
+ '-DSK_DEFERRED_CANVAS_USES_GPIPE=1' \
+ '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
+ '-DGR_AGGRESSIVE_SHADER_OPTS=1' \
+ '-DSK_ENABLE_INST_COUNT=0' \
+ '-DSK_USE_POSIX_THREADS' \
+ '-DSK_BUILD_FOR_ANDROID_NDK' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH)/third_party/khronos \
+ $(LOCAL_PATH)/gpu \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
+ $(gyp_shared_intermediate_dir)/content \
+ $(LOCAL_PATH)/skia/config \
+ $(LOCAL_PATH)/third_party/skia/src/core \
+ $(LOCAL_PATH)/third_party/skia/include/config \
+ $(LOCAL_PATH)/third_party/skia/include/core \
+ $(LOCAL_PATH)/third_party/skia/include/effects \
+ $(LOCAL_PATH)/third_party/skia/include/pdf \
+ $(LOCAL_PATH)/third_party/skia/include/gpu \
+ $(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
+ $(LOCAL_PATH)/third_party/skia/include/pipe \
+ $(LOCAL_PATH)/third_party/skia/include/ports \
+ $(LOCAL_PATH)/third_party/skia/include/utils \
+ $(LOCAL_PATH)/skia/ext \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES := \
+ cpufeatures \
+ ui_ui_gyp \
+ skia_skia_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_app_gyp
+
+# Alias gyp target name.
+.PHONY: content_app
+content_app: content_content_app_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_app.target.darwin-x86.mk b/content/content_app.target.darwin-x86.mk
new file mode 100644
index 0000000..911a3e8
--- /dev/null
+++ b/content/content_app.target.darwin-x86.mk
@@ -0,0 +1,185 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_app_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_ui_gyp)/ui_ui_gyp.a \
+ $(call intermediates-dir-for,GYP,content_content_jni_headers_gyp)/content_jni_headers.stamp \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ content/app/android/app_jni_registrar.cc \
+ content/app/android/child_process_service.cc \
+ content/app/android/content_main.cc \
+ content/app/android/library_loader_hooks.cc \
+ content/app/content_main_runner.cc \
+ content/public/app/content_main_delegate.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DU_USING_ICU_NAMESPACE=0' \
+ '-DSK_BUILD_NO_IMAGE_ENCODE' \
+ '-DSK_DEFERRED_CANVAS_USES_GPIPE=1' \
+ '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
+ '-DGR_AGGRESSIVE_SHADER_OPTS=1' \
+ '-DSK_ENABLE_INST_COUNT=0' \
+ '-DSK_USE_POSIX_THREADS' \
+ '-DSK_BUILD_FOR_ANDROID_NDK' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH)/third_party/khronos \
+ $(LOCAL_PATH)/gpu \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
+ $(gyp_shared_intermediate_dir)/content \
+ $(LOCAL_PATH)/skia/config \
+ $(LOCAL_PATH)/third_party/skia/src/core \
+ $(LOCAL_PATH)/third_party/skia/include/config \
+ $(LOCAL_PATH)/third_party/skia/include/core \
+ $(LOCAL_PATH)/third_party/skia/include/effects \
+ $(LOCAL_PATH)/third_party/skia/include/pdf \
+ $(LOCAL_PATH)/third_party/skia/include/gpu \
+ $(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
+ $(LOCAL_PATH)/third_party/skia/include/pipe \
+ $(LOCAL_PATH)/third_party/skia/include/ports \
+ $(LOCAL_PATH)/third_party/skia/include/utils \
+ $(LOCAL_PATH)/skia/ext \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES := \
+ cpufeatures \
+ ui_ui_gyp \
+ skia_skia_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_app_gyp
+
+# Alias gyp target name.
+.PHONY: content_app
+content_app: content_content_app_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_app.target.linux-arm.mk b/content/content_app.target.linux-arm.mk
index dfbd8db..a20d349 100644
--- a/content/content_app.target.linux-arm.mk
+++ b/content/content_app.target.linux-arm.mk
@@ -11,6 +11,7 @@
# Make sure our deps are built first.
GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_ui_gyp)/ui_ui_gyp.a \
$(call intermediates-dir-for,GYP,content_content_jni_headers_gyp)/content_jni_headers.stamp \
$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a
@@ -70,7 +71,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -78,7 +78,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -107,9 +106,10 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
- $(LOCAL_PATH) \
$(LOCAL_PATH)/third_party/khronos \
$(LOCAL_PATH)/gpu \
$(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
@@ -123,6 +123,7 @@
$(LOCAL_PATH)/third_party/skia/include/pdf \
$(LOCAL_PATH)/third_party/skia/include/gpu \
$(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
$(LOCAL_PATH)/third_party/skia/include/pipe \
$(LOCAL_PATH)/third_party/skia/include/ports \
$(LOCAL_PATH)/third_party/skia/include/utils \
@@ -158,13 +159,14 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES := \
cpufeatures \
+ ui_ui_gyp \
skia_skia_gyp
# Enable grouping to fix circular references
diff --git a/content/content_app.target.linux-x86.mk b/content/content_app.target.linux-x86.mk
index 251d86c..911a3e8 100644
--- a/content/content_app.target.linux-x86.mk
+++ b/content/content_app.target.linux-x86.mk
@@ -11,6 +11,7 @@
# Make sure our deps are built first.
GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_ui_gyp)/ui_ui_gyp.a \
$(call intermediates-dir-for,GYP,content_content_jni_headers_gyp)/content_jni_headers.stamp \
$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a
@@ -50,6 +51,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -71,7 +73,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -79,7 +80,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -107,9 +107,10 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
- $(LOCAL_PATH) \
$(LOCAL_PATH)/third_party/khronos \
$(LOCAL_PATH)/gpu \
$(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
@@ -123,6 +124,7 @@
$(LOCAL_PATH)/third_party/skia/include/pdf \
$(LOCAL_PATH)/third_party/skia/include/gpu \
$(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
$(LOCAL_PATH)/third_party/skia/include/pipe \
$(LOCAL_PATH)/third_party/skia/include/ports \
$(LOCAL_PATH)/third_party/skia/include/utils \
@@ -151,16 +153,18 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES := \
cpufeatures \
+ ui_ui_gyp \
skia_skia_gyp
# Enable grouping to fix circular references
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index d70e151..8fcfbc3 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -10,7 +10,9 @@
'../google_apis/google_apis.gyp:google_apis',
'../net/net.gyp:net',
'../skia/skia.gyp:skia',
+ '../sql/sql.gyp:sql',
'../third_party/re2/re2.gyp:re2',
+ '../third_party/zlib/zlib.gyp:zip',
'../third_party/zlib/zlib.gyp:zlib',
'../ui/snapshot/snapshot.gyp:snapshot',
'../ui/ui.gyp:ui',
@@ -58,8 +60,11 @@
'public/browser/compositor_util.h',
'public/browser/content_browser_client.cc',
'public/browser/content_browser_client.h',
+ 'public/browser/cookie_store_factory.h',
'public/browser/devtools_agent_host.h',
'public/browser/devtools_client_host.h',
+ 'public/browser/devtools_external_agent_proxy.h',
+ 'public/browser/devtools_external_agent_proxy_delegate.h',
'public/browser/download_danger_type.h',
'public/browser/download_id.h',
'public/browser/devtools_frontend_host_delegate.h',
@@ -91,6 +96,8 @@
'public/browser/histogram_fetcher.h',
'public/browser/host_zoom_map.h',
'public/browser/indexed_db_context.h',
+ 'public/browser/indexed_db_info.cc',
+ 'public/browser/indexed_db_info.h',
'public/browser/interstitial_page.h',
'public/browser/invalidate_type.h',
'public/browser/javascript_dialog_manager.cc',
@@ -238,8 +245,8 @@
'browser/android/interstitial_page_delegate_android.h',
'browser/android/load_url_params.cc',
'browser/android/load_url_params.h',
- 'browser/android/media_player_manager_android.cc',
- 'browser/android/media_player_manager_android.h',
+ 'browser/android/media_player_manager_impl.cc',
+ 'browser/android/media_player_manager_impl.h',
'browser/android/media_resource_getter_impl.cc',
'browser/android/media_resource_getter_impl.h',
'browser/android/surface_texture_peer_browser_impl.cc',
@@ -304,6 +311,8 @@
'browser/devtools/devtools_agent_host_impl.h',
'browser/devtools/devtools_browser_target.cc',
'browser/devtools/devtools_browser_target.h',
+ 'browser/devtools/devtools_external_agent_proxy_impl.cc',
+ 'browser/devtools/devtools_external_agent_proxy_impl.h',
'browser/devtools/devtools_frontend_host.cc',
'browser/devtools/devtools_frontend_host.h',
'browser/devtools/devtools_http_handler_impl.cc',
@@ -318,10 +327,14 @@
'browser/devtools/devtools_protocol_constants.h',
'browser/devtools/devtools_tracing_handler.h',
'browser/devtools/devtools_tracing_handler.cc',
+ 'browser/devtools/ipc_devtools_agent_host.cc',
+ 'browser/devtools/ipc_devtools_agent_host.h',
'browser/devtools/render_view_devtools_agent_host.cc',
'browser/devtools/render_view_devtools_agent_host.h',
'browser/devtools/renderer_overrides_handler.cc',
'browser/devtools/renderer_overrides_handler.h',
+ 'browser/devtools/tethering_handler.h',
+ 'browser/devtools/tethering_handler.cc',
'browser/devtools/worker_devtools_manager.cc',
'browser/devtools/worker_devtools_manager.h',
'browser/devtools/worker_devtools_message_filter.cc',
@@ -335,6 +348,8 @@
'browser/device_orientation/data_fetcher.h',
'browser/device_orientation/data_fetcher_impl_android.cc',
'browser/device_orientation/data_fetcher_impl_android.h',
+ 'browser/device_orientation/data_fetcher_impl_win.cc',
+ 'browser/device_orientation/data_fetcher_impl_win.h',
'browser/device_orientation/device_data.h',
'browser/device_orientation/message_filter.cc',
'browser/device_orientation/message_filter.h',
@@ -522,16 +537,18 @@
'browser/in_process_webkit/browser_webkitplatformsupport_impl.h',
'browser/in_process_webkit/indexed_db_callbacks.cc',
'browser/in_process_webkit/indexed_db_callbacks.h',
- 'browser/in_process_webkit/indexed_db_context_impl.cc',
- 'browser/in_process_webkit/indexed_db_context_impl.h',
'browser/in_process_webkit/indexed_db_database_callbacks.cc',
'browser/in_process_webkit/indexed_db_database_callbacks.h',
'browser/in_process_webkit/indexed_db_dispatcher_host.cc',
'browser/in_process_webkit/indexed_db_dispatcher_host.h',
- 'browser/in_process_webkit/indexed_db_quota_client.cc',
- 'browser/in_process_webkit/indexed_db_quota_client.h',
'browser/in_process_webkit/webkit_thread.cc',
'browser/in_process_webkit/webkit_thread.h',
+ 'browser/indexed_db/indexed_db_context_impl.cc',
+ 'browser/indexed_db/indexed_db_context_impl.h',
+ 'browser/indexed_db/indexed_db_internals_ui.cc',
+ 'browser/indexed_db/indexed_db_internals_ui.h',
+ 'browser/indexed_db/indexed_db_quota_client.cc',
+ 'browser/indexed_db/indexed_db_quota_client.h',
'browser/loader/async_resource_handler.cc',
'browser/loader/async_resource_handler.h',
'browser/loader/buffered_resource_handler.cc',
@@ -542,8 +559,11 @@
'browser/loader/cross_site_resource_handler.h',
'browser/loader/doomed_resource_handler.cc',
'browser/loader/doomed_resource_handler.h',
+ 'browser/loader/global_routing_id.h',
'browser/loader/layered_resource_handler.cc',
'browser/loader/layered_resource_handler.h',
+ 'browser/loader/offline_policy.cc',
+ 'browser/loader/offline_policy.h',
'browser/loader/power_save_block_resource_throttle.cc',
'browser/loader/power_save_block_resource_throttle.h',
'browser/loader/redirect_to_file_resource_handler.cc',
@@ -577,7 +597,7 @@
'browser/loader/throttling_resource_handler.h',
'browser/loader/transfer_navigation_resource_throttle.cc',
'browser/loader/transfer_navigation_resource_throttle.h',
- 'browser/mach_broker_mac.cc',
+ 'browser/mach_broker_mac.mm',
'browser/mach_broker_mac.h',
'browser/media_devices_monitor.cc',
'browser/media/media_internals.cc',
@@ -599,6 +619,8 @@
'browser/mime_registry_message_filter.h',
'browser/net/browser_online_state_observer.cc',
'browser/net/browser_online_state_observer.h',
+ 'browser/net/sqlite_persistent_cookie_store.cc',
+ 'browser/net/sqlite_persistent_cookie_store.h',
'browser/net/view_blob_internals_job_factory.cc',
'browser/net/view_blob_internals_job_factory.h',
'browser/net/view_http_cache_job_factory.cc',
@@ -620,9 +642,9 @@
'browser/power_save_blocker_chromeos.cc',
'browser/power_save_blocker_impl.cc',
'browser/power_save_blocker_impl.h',
- 'browser/power_save_blocker_linux.cc',
'browser/power_save_blocker_mac.cc',
'browser/power_save_blocker_win.cc',
+ 'browser/power_save_blocker_x11.cc',
'browser/ppapi_plugin_process_host.cc',
'browser/ppapi_plugin_process_host.h',
'browser/profiler_controller_impl.cc',
@@ -648,6 +670,8 @@
'browser/renderer_host/clipboard_message_filter_mac.mm',
'browser/renderer_host/compositor_impl_android.cc',
'browser/renderer_host/compositor_impl_android.h',
+ 'browser/renderer_host/compositing_iosurface_context_mac.mm',
+ 'browser/renderer_host/compositing_iosurface_context_mac.h',
'browser/renderer_host/compositing_iosurface_mac.h',
'browser/renderer_host/compositing_iosurface_mac.mm',
'browser/renderer_host/compositing_iosurface_shader_programs_mac.cc',
@@ -729,6 +753,8 @@
'browser/renderer_host/media/web_contents_tracker.h',
'browser/renderer_host/media/web_contents_video_capture_device.cc',
'browser/renderer_host/media/web_contents_video_capture_device.h',
+ 'browser/renderer_host/media/webrtc_logging_handler_host.cc',
+ 'browser/renderer_host/media/webrtc_logging_handler_host.h',
'browser/renderer_host/native_web_keyboard_event_android.cc',
'browser/renderer_host/native_web_keyboard_event_aura.cc',
'browser/renderer_host/native_web_keyboard_event.cc',
@@ -811,6 +837,8 @@
'browser/renderer_host/render_widget_host_view_mac.mm',
'browser/renderer_host/render_widget_host_view_win.cc',
'browser/renderer_host/render_widget_host_view_win.h',
+ 'browser/renderer_host/smooth_scroll_gesture_controller.cc',
+ 'browser/renderer_host/smooth_scroll_gesture_controller.h',
'browser/renderer_host/socket_stream_dispatcher_host.cc',
'browser/renderer_host/socket_stream_dispatcher_host.h',
'browser/renderer_host/socket_stream_host.cc',
@@ -925,6 +953,10 @@
'browser/user_metrics.cc',
'browser/utility_process_host_impl.cc',
'browser/utility_process_host_impl.h',
+ 'browser/web_contents/aura/image_window_delegate.cc',
+ 'browser/web_contents/aura/image_window_delegate.h',
+ 'browser/web_contents/aura/shadow_layer_delegate.cc',
+ 'browser/web_contents/aura/shadow_layer_delegate.h',
'browser/web_contents/debug_urls.cc',
'browser/web_contents/debug_urls.h',
'browser/web_contents/drag_utils_gtk.cc',
@@ -937,10 +969,14 @@
'browser/web_contents/navigation_entry_impl.h',
'browser/web_contents/render_view_host_manager.cc',
'browser/web_contents/render_view_host_manager.h',
+ 'browser/web_contents/touch_editable_impl_aura.cc',
+ 'browser/web_contents/touch_editable_impl_aura.h',
'browser/web_contents/web_contents_drag_win.cc',
'browser/web_contents/web_contents_drag_win.h',
'browser/web_contents/web_contents_impl.cc',
'browser/web_contents/web_contents_impl.h',
+ 'browser/web_contents/web_contents_screenshot_manager.cc',
+ 'browser/web_contents/web_contents_screenshot_manager.h',
'browser/web_contents/web_contents_view_android.cc',
'browser/web_contents/web_contents_view_android.h',
'browser/web_contents/web_contents_view_aura.cc',
@@ -1100,14 +1136,17 @@
'libraries': [
'-lcomctl32.lib',
'-ldinput8.lib',
+ '-ldwmapi.lib',
'-llocationapi.lib',
'-lsensorsapi.lib',
+ '-lportabledeviceguids.lib',
],
'msvs_settings': {
'VCLinkerTool': {
'DelayLoadDLLs': [
'dinput8.dll',
'user32.dll',
+ 'dwmapi.dll',
],
},
},
@@ -1148,6 +1187,10 @@
['use_x11==1', {
'dependencies': [
'../build/linux/system.gyp:x11',
+ ],
+ }],
+ ['OS=="linux"', {
+ 'dependencies': [
'../build/linux/system.gyp:pangocairo',
],
}],
@@ -1169,11 +1212,6 @@
'browser/tracing/tracing_ui.cc',
'browser/tracing/tracing_ui.h',
],
- }, { # OS!="android"
- 'dependencies': [
- '../third_party/flac/flac.gyp:libflac',
- '../third_party/speex/speex.gyp:libspeex',
- ],
}],
['OS=="mac"', {
'sources': [
@@ -1190,6 +1228,11 @@
'dependencies': [
'../third_party/sudden_motion_sensor/sudden_motion_sensor.gyp:sudden_motion_sensor',
],
+ 'link_settings': {
+ 'libraries': [
+ '$(SDKROOT)/usr/lib/libbsm.dylib',
+ ],
+ },
}],
['chromeos==1', {
'dependencies': [
@@ -1197,7 +1240,7 @@
],
'sources!': [
'browser/geolocation/wifi_data_provider_linux.cc',
- 'browser/power_save_blocker_linux.cc',
+ 'browser/power_save_blocker_x11.cc',
'browser/renderer_host/gtk_key_bindings_handler.cc',
'browser/renderer_host/gtk_key_bindings_handler.h',
],
@@ -1223,6 +1266,7 @@
['use_aura==1', {
'dependencies': [
'../ui/aura/aura.gyp:aura',
+ '../ui/base/strings/ui_strings.gyp:ui_strings',
'../ui/compositor/compositor.gyp:compositor',
],
'sources/': [
@@ -1255,6 +1299,8 @@
['exclude', '^browser/renderer_host/software_output_device_x11.cc'],
['exclude', '^browser/renderer_host/software_output_device_x11.h'],
['exclude', '^browser/renderer_host/touchpad_tap_suppression_controller_aura.cc'],
+ ['exclude', '^browser/web_contents/touch_editable_impl_aura.cc'],
+ ['exclude', '^browser/web_contents/touch_editable_impl_aura.h'],
],
}],
['enable_plugins==1', {
@@ -1293,6 +1339,11 @@
'sources/': [
['exclude', '^browser/speech/'],
],
+ }, { # input_speech==1
+ 'dependencies': [
+ '../third_party/flac/flac.gyp:libflac',
+ '../third_party/speex/speex.gyp:libspeex',
+ ],
}],
['linux_use_libgps==1', {
'dependencies': [
diff --git a/content/content_browser.target.darwin-arm.mk b/content/content_browser.target.darwin-arm.mk
new file mode 100644
index 0000000..6d993c9
--- /dev/null
+++ b/content/content_browser.target.darwin-arm.mk
@@ -0,0 +1,536 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,GYP,content_content_resources_gyp)/content_resources.stamp \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_browser_speech_proto_speech_proto_gyp)/content_browser_speech_proto_speech_proto_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_ui_gyp)/ui_ui_gyp.a \
+ $(call intermediates-dir-for,GYP,ui_ui_resources_gyp)/ui_resources.stamp \
+ $(call intermediates-dir-for,GYP,content_browser_devtools_devtools_resources_gyp)/devtools_resources.stamp \
+ $(call intermediates-dir-for,GYP,webkit_support_webkit_resources_gyp)/webkit_resources.stamp \
+ $(call intermediates-dir-for,GYP,webkit_support_webkit_strings_gyp)/webkit_strings.stamp \
+ $(call intermediates-dir-for,GYP,sandbox_sandbox_gyp)/sandbox.stamp \
+ $(call intermediates-dir-for,GYP,content_content_jni_headers_gyp)/content_jni_headers.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+$(gyp_intermediate_dir)/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc
+ mkdir -p $(@D); cp $< $@
+$(gyp_intermediate_dir)/webui_resources_map.cc: $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources_map.cc
+ mkdir -p $(@D); cp $< $@
+LOCAL_GENERATED_SOURCES := \
+ $(gyp_intermediate_dir)/devtools_resources_map.cc \
+ $(gyp_intermediate_dir)/webui_resources_map.cc
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS := \
+ $(gyp_shared_intermediate_dir)/webkit/grit \
+ $(gyp_shared_intermediate_dir)/ui/ui_resources/grit
+
+LOCAL_SRC_FILES := \
+ content/public/browser/browser_child_process_host_delegate.cc \
+ content/public/browser/browser_child_process_host_iterator.cc \
+ content/public/browser/browser_child_process_observer.cc \
+ content/public/browser/browser_main_parts.cc \
+ content/public/browser/browser_message_filter.cc \
+ content/public/browser/content_browser_client.cc \
+ content/public/browser/download_manager_delegate.cc \
+ content/public/browser/download_save_info.cc \
+ content/public/browser/download_url_parameters.cc \
+ content/public/browser/favicon_status.cc \
+ content/public/browser/indexed_db_info.cc \
+ content/public/browser/javascript_dialog_manager.cc \
+ content/public/browser/load_from_memory_cache_details.cc \
+ content/public/browser/navigation_controller.cc \
+ content/public/browser/navigation_details.cc \
+ content/public/browser/notification_registrar.cc \
+ content/public/browser/page_navigator.cc \
+ content/public/browser/render_view_host_observer.cc \
+ content/public/browser/resource_dispatcher_host_delegate.cc \
+ content/public/browser/resource_request_details.cc \
+ content/public/browser/speech_recognition_session_config.cc \
+ content/public/browser/speech_recognition_session_context.cc \
+ content/public/browser/web_contents.cc \
+ content/public/browser/web_contents_delegate.cc \
+ content/public/browser/web_contents_observer.cc \
+ content/public/browser/web_ui_controller.cc \
+ content/public/browser/url_data_source.cc \
+ content/browser/accessibility/accessibility_tree_formatter.cc \
+ content/browser/accessibility/accessibility_ui.cc \
+ content/browser/accessibility/browser_accessibility.cc \
+ content/browser/accessibility/browser_accessibility_manager.cc \
+ content/browser/accessibility/browser_accessibility_state_impl.cc \
+ content/browser/android/android_browser_process.cc \
+ content/browser/android/browser_jni_registrar.cc \
+ content/browser/android/child_process_launcher_android.cc \
+ content/browser/android/content_settings.cc \
+ content/browser/android/content_startup_flags.cc \
+ content/browser/android/content_video_view.cc \
+ content/browser/android/content_view_core_impl.cc \
+ content/browser/android/content_view_render_view.cc \
+ content/browser/android/content_view_statics.cc \
+ content/browser/android/date_time_chooser_android.cc \
+ content/browser/android/download_controller_android_impl.cc \
+ content/browser/android/devtools_auth.cc \
+ content/browser/android/interstitial_page_delegate_android.cc \
+ content/browser/android/load_url_params.cc \
+ content/browser/android/media_player_manager_impl.cc \
+ content/browser/android/media_resource_getter_impl.cc \
+ content/browser/android/surface_texture_peer_browser_impl.cc \
+ content/browser/android/sync_input_event_filter.cc \
+ content/browser/android/touch_point.cc \
+ content/browser/android/tracing_intent_handler.cc \
+ content/browser/android/web_contents_observer_android.cc \
+ content/browser/appcache/appcache_dispatcher_host.cc \
+ content/browser/appcache/appcache_frontend_proxy.cc \
+ content/browser/appcache/chrome_appcache_service.cc \
+ content/browser/browser_child_process_host_impl.cc \
+ content/browser/browser_context.cc \
+ content/browser/browser_ipc_logging.cc \
+ content/browser/browser_main.cc \
+ content/browser/browser_main_loop.cc \
+ content/browser/browser_main_runner.cc \
+ content/browser/browser_plugin/browser_plugin_embedder.cc \
+ content/browser/browser_plugin/browser_plugin_geolocation_permission_context.cc \
+ content/browser/browser_plugin/browser_plugin_guest.cc \
+ content/browser/browser_plugin/browser_plugin_guest_helper.cc \
+ content/browser/browser_plugin/browser_plugin_guest_manager.cc \
+ content/browser/browser_plugin/browser_plugin_message_filter.cc \
+ content/browser/browser_process_sub_thread.cc \
+ content/browser/browser_thread_impl.cc \
+ content/browser/browser_url_handler_impl.cc \
+ content/browser/browsing_instance.cc \
+ content/browser/byte_stream.cc \
+ content/browser/cert_store_impl.cc \
+ content/browser/child_process_launcher.cc \
+ content/browser/child_process_security_policy_impl.cc \
+ content/browser/cross_site_request_manager.cc \
+ content/browser/devtools/devtools_agent_host_impl.cc \
+ content/browser/devtools/devtools_browser_target.cc \
+ content/browser/devtools/devtools_external_agent_proxy_impl.cc \
+ content/browser/devtools/devtools_frontend_host.cc \
+ content/browser/devtools/devtools_http_handler_impl.cc \
+ content/browser/devtools/devtools_manager_impl.cc \
+ content/browser/devtools/devtools_netlog_observer.cc \
+ content/browser/devtools/devtools_protocol.cc \
+ content/browser/devtools/devtools_protocol_constants.cc \
+ content/browser/devtools/devtools_tracing_handler.cc \
+ content/browser/devtools/ipc_devtools_agent_host.cc \
+ content/browser/devtools/render_view_devtools_agent_host.cc \
+ content/browser/devtools/renderer_overrides_handler.cc \
+ content/browser/devtools/tethering_handler.cc \
+ content/browser/devtools/worker_devtools_manager.cc \
+ content/browser/devtools/worker_devtools_message_filter.cc \
+ content/browser/device_orientation/data_fetcher_impl_android.cc \
+ content/browser/device_orientation/message_filter.cc \
+ content/browser/device_orientation/motion.cc \
+ content/browser/device_orientation/motion_message_filter.cc \
+ content/browser/device_orientation/observer_delegate.cc \
+ content/browser/device_orientation/orientation.cc \
+ content/browser/device_orientation/orientation_message_filter.cc \
+ content/browser/device_orientation/provider.cc \
+ content/browser/device_orientation/provider_impl.cc \
+ content/browser/dom_storage/dom_storage_context_impl.cc \
+ content/browser/dom_storage/dom_storage_message_filter.cc \
+ content/browser/dom_storage/session_storage_namespace_impl.cc \
+ content/browser/download/base_file.cc \
+ content/browser/download/base_file_posix.cc \
+ content/browser/download/download_create_info.cc \
+ content/browser/download/download_file_factory.cc \
+ content/browser/download/download_file_impl.cc \
+ content/browser/download/download_interrupt_reasons_impl.cc \
+ content/browser/download/download_item_impl.cc \
+ content/browser/download/download_item_impl_delegate.cc \
+ content/browser/download/download_manager_impl.cc \
+ content/browser/download/download_net_log_parameters.cc \
+ content/browser/download/download_request_handle.cc \
+ content/browser/download/download_resource_handler.cc \
+ content/browser/download/download_stats.cc \
+ content/browser/download/drag_download_file.cc \
+ content/browser/download/drag_download_util.cc \
+ content/browser/download/mhtml_generation_manager.cc \
+ content/browser/download/save_file.cc \
+ content/browser/download/save_file_manager.cc \
+ content/browser/download/save_file_resource_handler.cc \
+ content/browser/download/save_item.cc \
+ content/browser/download/save_package.cc \
+ content/browser/download/save_types.cc \
+ content/browser/fileapi/browser_file_system_helper.cc \
+ content/browser/fileapi/chrome_blob_storage_context.cc \
+ content/browser/fileapi/fileapi_message_filter.cc \
+ content/browser/font_list_async.cc \
+ content/browser/gamepad/gamepad_provider.cc \
+ content/browser/gamepad/gamepad_service.cc \
+ content/browser/geolocation/device_data_provider.cc \
+ content/browser/geolocation/empty_device_data_provider.cc \
+ content/browser/geolocation/geolocation.cc \
+ content/browser/geolocation/geolocation_dispatcher_host.cc \
+ content/browser/geolocation/geolocation_provider.cc \
+ content/browser/geolocation/location_api_adapter_android.cc \
+ content/browser/geolocation/location_arbitrator_impl.cc \
+ content/browser/geolocation/location_provider_android.cc \
+ content/browser/geolocation/location_provider.cc \
+ content/browser/geolocation/wifi_data_provider_common.cc \
+ content/browser/gpu/browser_gpu_channel_host_factory.cc \
+ content/browser/gpu/compositor_util.cc \
+ content/browser/gpu/gpu_blacklist.cc \
+ content/browser/gpu/gpu_control_list.cc \
+ content/browser/gpu/gpu_data_manager_impl.cc \
+ content/browser/gpu/gpu_driver_bug_list.cc \
+ content/browser/gpu/gpu_internals_ui.cc \
+ content/browser/gpu/gpu_process_host.cc \
+ content/browser/gpu/gpu_process_host_ui_shim.cc \
+ content/browser/gpu/gpu_surface_tracker.cc \
+ content/browser/gpu/gpu_switching_list.cc \
+ content/browser/gpu/gpu_util.cc \
+ content/browser/gpu/shader_disk_cache.cc \
+ content/browser/histogram_controller.cc \
+ content/browser/histogram_internals_request_job.cc \
+ content/browser/histogram_message_filter.cc \
+ content/browser/histogram_synchronizer.cc \
+ content/browser/host_zoom_map_impl.cc \
+ content/browser/hyphenator/hyphenator_message_filter.cc \
+ content/browser/in_process_webkit/browser_webkitplatformsupport_impl.cc \
+ content/browser/in_process_webkit/indexed_db_callbacks.cc \
+ content/browser/in_process_webkit/indexed_db_database_callbacks.cc \
+ content/browser/in_process_webkit/indexed_db_dispatcher_host.cc \
+ content/browser/in_process_webkit/webkit_thread.cc \
+ content/browser/indexed_db/indexed_db_context_impl.cc \
+ content/browser/indexed_db/indexed_db_internals_ui.cc \
+ content/browser/indexed_db/indexed_db_quota_client.cc \
+ content/browser/loader/async_resource_handler.cc \
+ content/browser/loader/buffered_resource_handler.cc \
+ content/browser/loader/certificate_resource_handler.cc \
+ content/browser/loader/cross_site_resource_handler.cc \
+ content/browser/loader/doomed_resource_handler.cc \
+ content/browser/loader/layered_resource_handler.cc \
+ content/browser/loader/offline_policy.cc \
+ content/browser/loader/power_save_block_resource_throttle.cc \
+ content/browser/loader/redirect_to_file_resource_handler.cc \
+ content/browser/loader/render_view_host_tracker.cc \
+ content/browser/loader/resource_buffer.cc \
+ content/browser/loader/resource_dispatcher_host_impl.cc \
+ content/browser/loader/resource_handler.cc \
+ content/browser/loader/resource_loader.cc \
+ content/browser/loader/resource_message_delegate.cc \
+ content/browser/loader/resource_message_filter.cc \
+ content/browser/loader/resource_request_info_impl.cc \
+ content/browser/loader/resource_scheduler.cc \
+ content/browser/loader/resource_scheduler_filter.cc \
+ content/browser/loader/stream_resource_handler.cc \
+ content/browser/loader/sync_resource_handler.cc \
+ content/browser/loader/throttling_resource_handler.cc \
+ content/browser/loader/transfer_navigation_resource_throttle.cc \
+ content/browser/media_devices_monitor.cc \
+ content/browser/media/media_internals.cc \
+ content/browser/media/media_internals_handler.cc \
+ content/browser/media/media_internals_proxy.cc \
+ content/browser/media/media_internals_ui.cc \
+ content/browser/media/webrtc_internals.cc \
+ content/browser/media/webrtc_internals_message_handler.cc \
+ content/browser/media/webrtc_internals_ui.cc \
+ content/browser/mime_registry_message_filter.cc \
+ content/browser/net/browser_online_state_observer.cc \
+ content/browser/net/sqlite_persistent_cookie_store.cc \
+ content/browser/net/view_blob_internals_job_factory.cc \
+ content/browser/net/view_http_cache_job_factory.cc \
+ content/browser/notification_service_impl.cc \
+ content/browser/power_save_blocker_android.cc \
+ content/browser/power_save_blocker_impl.cc \
+ content/browser/profiler_controller_impl.cc \
+ content/browser/profiler_message_filter.cc \
+ content/browser/renderer_host/backing_store.cc \
+ content/browser/renderer_host/backing_store_manager.cc \
+ content/browser/renderer_host/basic_mouse_wheel_smooth_scroll_gesture.cc \
+ content/browser/renderer_host/clipboard_message_filter.cc \
+ content/browser/renderer_host/compositor_impl_android.cc \
+ content/browser/renderer_host/database_message_filter.cc \
+ content/browser/renderer_host/dip_util.cc \
+ content/browser/renderer_host/file_utilities_message_filter.cc \
+ content/browser/renderer_host/gamepad_browser_message_filter.cc \
+ content/browser/renderer_host/gesture_event_filter.cc \
+ content/browser/renderer_host/gpu_message_filter.cc \
+ content/browser/renderer_host/image_transport_factory_android.cc \
+ content/browser/renderer_host/ime_adapter_android.cc \
+ content/browser/renderer_host/java/java_bound_object.cc \
+ content/browser/renderer_host/java/java_bridge_channel_host.cc \
+ content/browser/renderer_host/java/java_bridge_dispatcher_host.cc \
+ content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.cc \
+ content/browser/renderer_host/java/java_method.cc \
+ content/browser/renderer_host/java/java_type.cc \
+ content/browser/renderer_host/media/audio_input_device_manager.cc \
+ content/browser/renderer_host/media/audio_input_renderer_host.cc \
+ content/browser/renderer_host/media/audio_input_sync_writer.cc \
+ content/browser/renderer_host/media/audio_mirroring_manager.cc \
+ content/browser/renderer_host/media/audio_renderer_host.cc \
+ content/browser/renderer_host/media/audio_sync_reader.cc \
+ content/browser/renderer_host/media/media_stream_dispatcher_host.cc \
+ content/browser/renderer_host/media/media_stream_manager.cc \
+ content/browser/renderer_host/media/media_stream_ui_controller.cc \
+ content/browser/renderer_host/media/video_capture_buffer_pool.cc \
+ content/browser/renderer_host/media/video_capture_controller.cc \
+ content/browser/renderer_host/media/video_capture_controller_event_handler.cc \
+ content/browser/renderer_host/media/video_capture_host.cc \
+ content/browser/renderer_host/media/video_capture_manager.cc \
+ content/browser/renderer_host/media/web_contents_audio_input_stream.cc \
+ content/browser/renderer_host/media/web_contents_capture_util.cc \
+ content/browser/renderer_host/media/web_contents_tracker.cc \
+ content/browser/renderer_host/media/web_contents_video_capture_device.cc \
+ content/browser/renderer_host/media/webrtc_logging_handler_host.cc \
+ content/browser/renderer_host/native_web_keyboard_event_android.cc \
+ content/browser/renderer_host/native_web_keyboard_event.cc \
+ content/browser/renderer_host/overscroll_configuration.cc \
+ content/browser/renderer_host/overscroll_controller.cc \
+ content/browser/renderer_host/quota_dispatcher_host.cc \
+ content/browser/renderer_host/render_message_filter.cc \
+ content/browser/renderer_host/render_process_host_impl.cc \
+ content/browser/renderer_host/render_view_host_delegate.cc \
+ content/browser/renderer_host/render_view_host_factory.cc \
+ content/browser/renderer_host/render_view_host_impl.cc \
+ content/browser/renderer_host/render_widget_helper.cc \
+ content/browser/renderer_host/render_widget_host_delegate.cc \
+ content/browser/renderer_host/render_widget_host_impl.cc \
+ content/browser/renderer_host/render_widget_host_view_android.cc \
+ content/browser/renderer_host/render_widget_host_view_base.cc \
+ content/browser/renderer_host/render_widget_host_view_guest.cc \
+ content/browser/renderer_host/smooth_scroll_gesture_controller.cc \
+ content/browser/renderer_host/socket_stream_dispatcher_host.cc \
+ content/browser/renderer_host/socket_stream_host.cc \
+ content/browser/renderer_host/surface_texture_transport_client_android.cc \
+ content/browser/renderer_host/touch_event_queue.cc \
+ content/browser/renderer_host/touchpad_tap_suppression_controller.cc \
+ content/browser/renderer_host/touchscreen_tap_suppression_controller_stub.cc \
+ content/browser/resolve_proxy_msg_helper.cc \
+ content/browser/resource_context_impl.cc \
+ content/browser/site_instance_impl.cc \
+ content/browser/ssl/ssl_cert_error_handler.cc \
+ content/browser/ssl/ssl_client_auth_handler.cc \
+ content/browser/ssl/ssl_error_handler.cc \
+ content/browser/ssl/ssl_host_state.cc \
+ content/browser/ssl/ssl_manager.cc \
+ content/browser/ssl/ssl_policy_backend.cc \
+ content/browser/ssl/ssl_policy.cc \
+ content/browser/ssl/ssl_request_info.cc \
+ content/browser/streams/stream.cc \
+ content/browser/streams/stream_context.cc \
+ content/browser/streams/stream_handle_impl.cc \
+ content/browser/streams/stream_registry.cc \
+ content/browser/streams/stream_url_request_job.cc \
+ content/browser/storage_partition_impl.cc \
+ content/browser/storage_partition_impl_map.cc \
+ content/browser/tcmalloc_internals_request_job.cc \
+ content/browser/tracing/trace_controller_impl.cc \
+ content/browser/tracing/trace_message_filter.cc \
+ content/browser/tracing/trace_subscriber_stdio.cc \
+ content/browser/user_metrics.cc \
+ content/browser/utility_process_host_impl.cc \
+ content/browser/web_contents/debug_urls.cc \
+ content/browser/web_contents/interstitial_page_impl.cc \
+ content/browser/web_contents/navigation_controller_impl.cc \
+ content/browser/web_contents/navigation_entry_impl.cc \
+ content/browser/web_contents/render_view_host_manager.cc \
+ content/browser/web_contents/web_contents_impl.cc \
+ content/browser/web_contents/web_contents_screenshot_manager.cc \
+ content/browser/web_contents/web_contents_view_android.cc \
+ content/browser/web_contents/web_contents_view_guest.cc \
+ content/browser/webui/content_web_ui_controller_factory.cc \
+ content/browser/webui/generic_handler.cc \
+ content/browser/webui/shared_resources_data_source.cc \
+ content/browser/webui/url_data_manager.cc \
+ content/browser/webui/url_data_manager_backend.cc \
+ content/browser/webui/url_data_source_impl.cc \
+ content/browser/webui/web_ui_data_source_impl.cc \
+ content/browser/webui/web_ui_controller_factory_registry.cc \
+ content/browser/webui/web_ui_impl.cc \
+ content/browser/webui/web_ui_message_handler.cc \
+ content/browser/worker_host/message_port_service.cc \
+ content/browser/worker_host/worker_document_set.cc \
+ content/browser/worker_host/worker_message_filter.cc \
+ content/browser/worker_host/worker_process_host.cc \
+ content/browser/worker_host/worker_service_impl.cc \
+ content/browser/worker_host/worker_storage_partition.cc \
+ content/browser/gamepad/gamepad_platform_data_fetcher.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DENABLE_JAVA_BRIDGE' \
+ '-DPROTOBUF_USE_DLLS' \
+ '-DGOOGLE_PROTOBUF_NO_RTTI' \
+ '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DPOSIX_AVOID_MMAP' \
+ '-DSK_BUILD_NO_IMAGE_ENCODE' \
+ '-DSK_DEFERRED_CANVAS_USES_GPIPE=1' \
+ '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
+ '-DGR_AGGRESSIVE_SHADER_OPTS=1' \
+ '-DSK_ENABLE_INST_COUNT=0' \
+ '-DSK_USE_POSIX_THREADS' \
+ '-DSK_BUILD_FOR_ANDROID_NDK' \
+ '-DU_USING_ICU_NAMESPACE=0' \
+ '-DMEDIA_DISABLE_LIBVPX' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_intermediate_dir) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH)/third_party/khronos \
+ $(LOCAL_PATH)/gpu \
+ $(gyp_shared_intermediate_dir)/content \
+ $(gyp_shared_intermediate_dir)/protoc_out \
+ $(LOCAL_PATH)/third_party/protobuf \
+ $(LOCAL_PATH)/third_party/protobuf/src \
+ $(LOCAL_PATH)/skia/config \
+ $(LOCAL_PATH)/third_party/skia/src/core \
+ $(LOCAL_PATH)/third_party/skia/include/config \
+ $(LOCAL_PATH)/third_party/skia/include/core \
+ $(LOCAL_PATH)/third_party/skia/include/effects \
+ $(LOCAL_PATH)/third_party/skia/include/pdf \
+ $(LOCAL_PATH)/third_party/skia/include/gpu \
+ $(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
+ $(LOCAL_PATH)/third_party/skia/include/pipe \
+ $(LOCAL_PATH)/third_party/skia/include/ports \
+ $(LOCAL_PATH)/third_party/skia/include/utils \
+ $(LOCAL_PATH)/skia/ext \
+ $(LOCAL_PATH)/third_party/re2 \
+ $(LOCAL_PATH)/third_party/zlib \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
+ $(gyp_shared_intermediate_dir)/ui/ui_resources \
+ $(gyp_shared_intermediate_dir)/webkit \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(LOCAL_PATH)/third_party/npapi \
+ $(LOCAL_PATH)/third_party/npapi/bindings \
+ $(LOCAL_PATH)/v8/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES := \
+ content_browser_speech_proto_speech_proto_gyp \
+ skia_skia_gyp \
+ ui_ui_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_browser_gyp
+
+# Alias gyp target name.
+.PHONY: content_browser
+content_browser: content_content_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_browser.target.darwin-x86.mk b/content/content_browser.target.darwin-x86.mk
new file mode 100644
index 0000000..44e619e
--- /dev/null
+++ b/content/content_browser.target.darwin-x86.mk
@@ -0,0 +1,534 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,GYP,content_content_resources_gyp)/content_resources.stamp \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,content_browser_speech_proto_speech_proto_gyp)/content_browser_speech_proto_speech_proto_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_ui_gyp)/ui_ui_gyp.a \
+ $(call intermediates-dir-for,GYP,ui_ui_resources_gyp)/ui_resources.stamp \
+ $(call intermediates-dir-for,GYP,content_browser_devtools_devtools_resources_gyp)/devtools_resources.stamp \
+ $(call intermediates-dir-for,GYP,webkit_support_webkit_resources_gyp)/webkit_resources.stamp \
+ $(call intermediates-dir-for,GYP,webkit_support_webkit_strings_gyp)/webkit_strings.stamp \
+ $(call intermediates-dir-for,GYP,sandbox_sandbox_gyp)/sandbox.stamp \
+ $(call intermediates-dir-for,GYP,content_content_jni_headers_gyp)/content_jni_headers.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+$(gyp_intermediate_dir)/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc
+ mkdir -p $(@D); cp $< $@
+$(gyp_intermediate_dir)/webui_resources_map.cc: $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources_map.cc
+ mkdir -p $(@D); cp $< $@
+LOCAL_GENERATED_SOURCES := \
+ $(gyp_intermediate_dir)/devtools_resources_map.cc \
+ $(gyp_intermediate_dir)/webui_resources_map.cc
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS := \
+ $(gyp_shared_intermediate_dir)/webkit/grit \
+ $(gyp_shared_intermediate_dir)/ui/ui_resources/grit
+
+LOCAL_SRC_FILES := \
+ content/public/browser/browser_child_process_host_delegate.cc \
+ content/public/browser/browser_child_process_host_iterator.cc \
+ content/public/browser/browser_child_process_observer.cc \
+ content/public/browser/browser_main_parts.cc \
+ content/public/browser/browser_message_filter.cc \
+ content/public/browser/content_browser_client.cc \
+ content/public/browser/download_manager_delegate.cc \
+ content/public/browser/download_save_info.cc \
+ content/public/browser/download_url_parameters.cc \
+ content/public/browser/favicon_status.cc \
+ content/public/browser/indexed_db_info.cc \
+ content/public/browser/javascript_dialog_manager.cc \
+ content/public/browser/load_from_memory_cache_details.cc \
+ content/public/browser/navigation_controller.cc \
+ content/public/browser/navigation_details.cc \
+ content/public/browser/notification_registrar.cc \
+ content/public/browser/page_navigator.cc \
+ content/public/browser/render_view_host_observer.cc \
+ content/public/browser/resource_dispatcher_host_delegate.cc \
+ content/public/browser/resource_request_details.cc \
+ content/public/browser/speech_recognition_session_config.cc \
+ content/public/browser/speech_recognition_session_context.cc \
+ content/public/browser/web_contents.cc \
+ content/public/browser/web_contents_delegate.cc \
+ content/public/browser/web_contents_observer.cc \
+ content/public/browser/web_ui_controller.cc \
+ content/public/browser/url_data_source.cc \
+ content/browser/accessibility/accessibility_tree_formatter.cc \
+ content/browser/accessibility/accessibility_ui.cc \
+ content/browser/accessibility/browser_accessibility.cc \
+ content/browser/accessibility/browser_accessibility_manager.cc \
+ content/browser/accessibility/browser_accessibility_state_impl.cc \
+ content/browser/android/android_browser_process.cc \
+ content/browser/android/browser_jni_registrar.cc \
+ content/browser/android/child_process_launcher_android.cc \
+ content/browser/android/content_settings.cc \
+ content/browser/android/content_startup_flags.cc \
+ content/browser/android/content_video_view.cc \
+ content/browser/android/content_view_core_impl.cc \
+ content/browser/android/content_view_render_view.cc \
+ content/browser/android/content_view_statics.cc \
+ content/browser/android/date_time_chooser_android.cc \
+ content/browser/android/download_controller_android_impl.cc \
+ content/browser/android/devtools_auth.cc \
+ content/browser/android/interstitial_page_delegate_android.cc \
+ content/browser/android/load_url_params.cc \
+ content/browser/android/media_player_manager_impl.cc \
+ content/browser/android/media_resource_getter_impl.cc \
+ content/browser/android/surface_texture_peer_browser_impl.cc \
+ content/browser/android/sync_input_event_filter.cc \
+ content/browser/android/touch_point.cc \
+ content/browser/android/tracing_intent_handler.cc \
+ content/browser/android/web_contents_observer_android.cc \
+ content/browser/appcache/appcache_dispatcher_host.cc \
+ content/browser/appcache/appcache_frontend_proxy.cc \
+ content/browser/appcache/chrome_appcache_service.cc \
+ content/browser/browser_child_process_host_impl.cc \
+ content/browser/browser_context.cc \
+ content/browser/browser_ipc_logging.cc \
+ content/browser/browser_main.cc \
+ content/browser/browser_main_loop.cc \
+ content/browser/browser_main_runner.cc \
+ content/browser/browser_plugin/browser_plugin_embedder.cc \
+ content/browser/browser_plugin/browser_plugin_geolocation_permission_context.cc \
+ content/browser/browser_plugin/browser_plugin_guest.cc \
+ content/browser/browser_plugin/browser_plugin_guest_helper.cc \
+ content/browser/browser_plugin/browser_plugin_guest_manager.cc \
+ content/browser/browser_plugin/browser_plugin_message_filter.cc \
+ content/browser/browser_process_sub_thread.cc \
+ content/browser/browser_thread_impl.cc \
+ content/browser/browser_url_handler_impl.cc \
+ content/browser/browsing_instance.cc \
+ content/browser/byte_stream.cc \
+ content/browser/cert_store_impl.cc \
+ content/browser/child_process_launcher.cc \
+ content/browser/child_process_security_policy_impl.cc \
+ content/browser/cross_site_request_manager.cc \
+ content/browser/devtools/devtools_agent_host_impl.cc \
+ content/browser/devtools/devtools_browser_target.cc \
+ content/browser/devtools/devtools_external_agent_proxy_impl.cc \
+ content/browser/devtools/devtools_frontend_host.cc \
+ content/browser/devtools/devtools_http_handler_impl.cc \
+ content/browser/devtools/devtools_manager_impl.cc \
+ content/browser/devtools/devtools_netlog_observer.cc \
+ content/browser/devtools/devtools_protocol.cc \
+ content/browser/devtools/devtools_protocol_constants.cc \
+ content/browser/devtools/devtools_tracing_handler.cc \
+ content/browser/devtools/ipc_devtools_agent_host.cc \
+ content/browser/devtools/render_view_devtools_agent_host.cc \
+ content/browser/devtools/renderer_overrides_handler.cc \
+ content/browser/devtools/tethering_handler.cc \
+ content/browser/devtools/worker_devtools_manager.cc \
+ content/browser/devtools/worker_devtools_message_filter.cc \
+ content/browser/device_orientation/data_fetcher_impl_android.cc \
+ content/browser/device_orientation/message_filter.cc \
+ content/browser/device_orientation/motion.cc \
+ content/browser/device_orientation/motion_message_filter.cc \
+ content/browser/device_orientation/observer_delegate.cc \
+ content/browser/device_orientation/orientation.cc \
+ content/browser/device_orientation/orientation_message_filter.cc \
+ content/browser/device_orientation/provider.cc \
+ content/browser/device_orientation/provider_impl.cc \
+ content/browser/dom_storage/dom_storage_context_impl.cc \
+ content/browser/dom_storage/dom_storage_message_filter.cc \
+ content/browser/dom_storage/session_storage_namespace_impl.cc \
+ content/browser/download/base_file.cc \
+ content/browser/download/base_file_posix.cc \
+ content/browser/download/download_create_info.cc \
+ content/browser/download/download_file_factory.cc \
+ content/browser/download/download_file_impl.cc \
+ content/browser/download/download_interrupt_reasons_impl.cc \
+ content/browser/download/download_item_impl.cc \
+ content/browser/download/download_item_impl_delegate.cc \
+ content/browser/download/download_manager_impl.cc \
+ content/browser/download/download_net_log_parameters.cc \
+ content/browser/download/download_request_handle.cc \
+ content/browser/download/download_resource_handler.cc \
+ content/browser/download/download_stats.cc \
+ content/browser/download/drag_download_file.cc \
+ content/browser/download/drag_download_util.cc \
+ content/browser/download/mhtml_generation_manager.cc \
+ content/browser/download/save_file.cc \
+ content/browser/download/save_file_manager.cc \
+ content/browser/download/save_file_resource_handler.cc \
+ content/browser/download/save_item.cc \
+ content/browser/download/save_package.cc \
+ content/browser/download/save_types.cc \
+ content/browser/fileapi/browser_file_system_helper.cc \
+ content/browser/fileapi/chrome_blob_storage_context.cc \
+ content/browser/fileapi/fileapi_message_filter.cc \
+ content/browser/font_list_async.cc \
+ content/browser/gamepad/gamepad_provider.cc \
+ content/browser/gamepad/gamepad_service.cc \
+ content/browser/geolocation/device_data_provider.cc \
+ content/browser/geolocation/empty_device_data_provider.cc \
+ content/browser/geolocation/geolocation.cc \
+ content/browser/geolocation/geolocation_dispatcher_host.cc \
+ content/browser/geolocation/geolocation_provider.cc \
+ content/browser/geolocation/location_api_adapter_android.cc \
+ content/browser/geolocation/location_arbitrator_impl.cc \
+ content/browser/geolocation/location_provider_android.cc \
+ content/browser/geolocation/location_provider.cc \
+ content/browser/geolocation/wifi_data_provider_common.cc \
+ content/browser/gpu/browser_gpu_channel_host_factory.cc \
+ content/browser/gpu/compositor_util.cc \
+ content/browser/gpu/gpu_blacklist.cc \
+ content/browser/gpu/gpu_control_list.cc \
+ content/browser/gpu/gpu_data_manager_impl.cc \
+ content/browser/gpu/gpu_driver_bug_list.cc \
+ content/browser/gpu/gpu_internals_ui.cc \
+ content/browser/gpu/gpu_process_host.cc \
+ content/browser/gpu/gpu_process_host_ui_shim.cc \
+ content/browser/gpu/gpu_surface_tracker.cc \
+ content/browser/gpu/gpu_switching_list.cc \
+ content/browser/gpu/gpu_util.cc \
+ content/browser/gpu/shader_disk_cache.cc \
+ content/browser/histogram_controller.cc \
+ content/browser/histogram_internals_request_job.cc \
+ content/browser/histogram_message_filter.cc \
+ content/browser/histogram_synchronizer.cc \
+ content/browser/host_zoom_map_impl.cc \
+ content/browser/hyphenator/hyphenator_message_filter.cc \
+ content/browser/in_process_webkit/browser_webkitplatformsupport_impl.cc \
+ content/browser/in_process_webkit/indexed_db_callbacks.cc \
+ content/browser/in_process_webkit/indexed_db_database_callbacks.cc \
+ content/browser/in_process_webkit/indexed_db_dispatcher_host.cc \
+ content/browser/in_process_webkit/webkit_thread.cc \
+ content/browser/indexed_db/indexed_db_context_impl.cc \
+ content/browser/indexed_db/indexed_db_internals_ui.cc \
+ content/browser/indexed_db/indexed_db_quota_client.cc \
+ content/browser/loader/async_resource_handler.cc \
+ content/browser/loader/buffered_resource_handler.cc \
+ content/browser/loader/certificate_resource_handler.cc \
+ content/browser/loader/cross_site_resource_handler.cc \
+ content/browser/loader/doomed_resource_handler.cc \
+ content/browser/loader/layered_resource_handler.cc \
+ content/browser/loader/offline_policy.cc \
+ content/browser/loader/power_save_block_resource_throttle.cc \
+ content/browser/loader/redirect_to_file_resource_handler.cc \
+ content/browser/loader/render_view_host_tracker.cc \
+ content/browser/loader/resource_buffer.cc \
+ content/browser/loader/resource_dispatcher_host_impl.cc \
+ content/browser/loader/resource_handler.cc \
+ content/browser/loader/resource_loader.cc \
+ content/browser/loader/resource_message_delegate.cc \
+ content/browser/loader/resource_message_filter.cc \
+ content/browser/loader/resource_request_info_impl.cc \
+ content/browser/loader/resource_scheduler.cc \
+ content/browser/loader/resource_scheduler_filter.cc \
+ content/browser/loader/stream_resource_handler.cc \
+ content/browser/loader/sync_resource_handler.cc \
+ content/browser/loader/throttling_resource_handler.cc \
+ content/browser/loader/transfer_navigation_resource_throttle.cc \
+ content/browser/media_devices_monitor.cc \
+ content/browser/media/media_internals.cc \
+ content/browser/media/media_internals_handler.cc \
+ content/browser/media/media_internals_proxy.cc \
+ content/browser/media/media_internals_ui.cc \
+ content/browser/media/webrtc_internals.cc \
+ content/browser/media/webrtc_internals_message_handler.cc \
+ content/browser/media/webrtc_internals_ui.cc \
+ content/browser/mime_registry_message_filter.cc \
+ content/browser/net/browser_online_state_observer.cc \
+ content/browser/net/sqlite_persistent_cookie_store.cc \
+ content/browser/net/view_blob_internals_job_factory.cc \
+ content/browser/net/view_http_cache_job_factory.cc \
+ content/browser/notification_service_impl.cc \
+ content/browser/power_save_blocker_android.cc \
+ content/browser/power_save_blocker_impl.cc \
+ content/browser/profiler_controller_impl.cc \
+ content/browser/profiler_message_filter.cc \
+ content/browser/renderer_host/backing_store.cc \
+ content/browser/renderer_host/backing_store_manager.cc \
+ content/browser/renderer_host/basic_mouse_wheel_smooth_scroll_gesture.cc \
+ content/browser/renderer_host/clipboard_message_filter.cc \
+ content/browser/renderer_host/compositor_impl_android.cc \
+ content/browser/renderer_host/database_message_filter.cc \
+ content/browser/renderer_host/dip_util.cc \
+ content/browser/renderer_host/file_utilities_message_filter.cc \
+ content/browser/renderer_host/gamepad_browser_message_filter.cc \
+ content/browser/renderer_host/gesture_event_filter.cc \
+ content/browser/renderer_host/gpu_message_filter.cc \
+ content/browser/renderer_host/image_transport_factory_android.cc \
+ content/browser/renderer_host/ime_adapter_android.cc \
+ content/browser/renderer_host/java/java_bound_object.cc \
+ content/browser/renderer_host/java/java_bridge_channel_host.cc \
+ content/browser/renderer_host/java/java_bridge_dispatcher_host.cc \
+ content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.cc \
+ content/browser/renderer_host/java/java_method.cc \
+ content/browser/renderer_host/java/java_type.cc \
+ content/browser/renderer_host/media/audio_input_device_manager.cc \
+ content/browser/renderer_host/media/audio_input_renderer_host.cc \
+ content/browser/renderer_host/media/audio_input_sync_writer.cc \
+ content/browser/renderer_host/media/audio_mirroring_manager.cc \
+ content/browser/renderer_host/media/audio_renderer_host.cc \
+ content/browser/renderer_host/media/audio_sync_reader.cc \
+ content/browser/renderer_host/media/media_stream_dispatcher_host.cc \
+ content/browser/renderer_host/media/media_stream_manager.cc \
+ content/browser/renderer_host/media/media_stream_ui_controller.cc \
+ content/browser/renderer_host/media/video_capture_buffer_pool.cc \
+ content/browser/renderer_host/media/video_capture_controller.cc \
+ content/browser/renderer_host/media/video_capture_controller_event_handler.cc \
+ content/browser/renderer_host/media/video_capture_host.cc \
+ content/browser/renderer_host/media/video_capture_manager.cc \
+ content/browser/renderer_host/media/web_contents_audio_input_stream.cc \
+ content/browser/renderer_host/media/web_contents_capture_util.cc \
+ content/browser/renderer_host/media/web_contents_tracker.cc \
+ content/browser/renderer_host/media/web_contents_video_capture_device.cc \
+ content/browser/renderer_host/media/webrtc_logging_handler_host.cc \
+ content/browser/renderer_host/native_web_keyboard_event_android.cc \
+ content/browser/renderer_host/native_web_keyboard_event.cc \
+ content/browser/renderer_host/overscroll_configuration.cc \
+ content/browser/renderer_host/overscroll_controller.cc \
+ content/browser/renderer_host/quota_dispatcher_host.cc \
+ content/browser/renderer_host/render_message_filter.cc \
+ content/browser/renderer_host/render_process_host_impl.cc \
+ content/browser/renderer_host/render_view_host_delegate.cc \
+ content/browser/renderer_host/render_view_host_factory.cc \
+ content/browser/renderer_host/render_view_host_impl.cc \
+ content/browser/renderer_host/render_widget_helper.cc \
+ content/browser/renderer_host/render_widget_host_delegate.cc \
+ content/browser/renderer_host/render_widget_host_impl.cc \
+ content/browser/renderer_host/render_widget_host_view_android.cc \
+ content/browser/renderer_host/render_widget_host_view_base.cc \
+ content/browser/renderer_host/render_widget_host_view_guest.cc \
+ content/browser/renderer_host/smooth_scroll_gesture_controller.cc \
+ content/browser/renderer_host/socket_stream_dispatcher_host.cc \
+ content/browser/renderer_host/socket_stream_host.cc \
+ content/browser/renderer_host/surface_texture_transport_client_android.cc \
+ content/browser/renderer_host/touch_event_queue.cc \
+ content/browser/renderer_host/touchpad_tap_suppression_controller.cc \
+ content/browser/renderer_host/touchscreen_tap_suppression_controller_stub.cc \
+ content/browser/resolve_proxy_msg_helper.cc \
+ content/browser/resource_context_impl.cc \
+ content/browser/site_instance_impl.cc \
+ content/browser/ssl/ssl_cert_error_handler.cc \
+ content/browser/ssl/ssl_client_auth_handler.cc \
+ content/browser/ssl/ssl_error_handler.cc \
+ content/browser/ssl/ssl_host_state.cc \
+ content/browser/ssl/ssl_manager.cc \
+ content/browser/ssl/ssl_policy_backend.cc \
+ content/browser/ssl/ssl_policy.cc \
+ content/browser/ssl/ssl_request_info.cc \
+ content/browser/streams/stream.cc \
+ content/browser/streams/stream_context.cc \
+ content/browser/streams/stream_handle_impl.cc \
+ content/browser/streams/stream_registry.cc \
+ content/browser/streams/stream_url_request_job.cc \
+ content/browser/storage_partition_impl.cc \
+ content/browser/storage_partition_impl_map.cc \
+ content/browser/tcmalloc_internals_request_job.cc \
+ content/browser/tracing/trace_controller_impl.cc \
+ content/browser/tracing/trace_message_filter.cc \
+ content/browser/tracing/trace_subscriber_stdio.cc \
+ content/browser/user_metrics.cc \
+ content/browser/utility_process_host_impl.cc \
+ content/browser/web_contents/debug_urls.cc \
+ content/browser/web_contents/interstitial_page_impl.cc \
+ content/browser/web_contents/navigation_controller_impl.cc \
+ content/browser/web_contents/navigation_entry_impl.cc \
+ content/browser/web_contents/render_view_host_manager.cc \
+ content/browser/web_contents/web_contents_impl.cc \
+ content/browser/web_contents/web_contents_screenshot_manager.cc \
+ content/browser/web_contents/web_contents_view_android.cc \
+ content/browser/web_contents/web_contents_view_guest.cc \
+ content/browser/webui/content_web_ui_controller_factory.cc \
+ content/browser/webui/generic_handler.cc \
+ content/browser/webui/shared_resources_data_source.cc \
+ content/browser/webui/url_data_manager.cc \
+ content/browser/webui/url_data_manager_backend.cc \
+ content/browser/webui/url_data_source_impl.cc \
+ content/browser/webui/web_ui_data_source_impl.cc \
+ content/browser/webui/web_ui_controller_factory_registry.cc \
+ content/browser/webui/web_ui_impl.cc \
+ content/browser/webui/web_ui_message_handler.cc \
+ content/browser/worker_host/message_port_service.cc \
+ content/browser/worker_host/worker_document_set.cc \
+ content/browser/worker_host/worker_message_filter.cc \
+ content/browser/worker_host/worker_process_host.cc \
+ content/browser/worker_host/worker_service_impl.cc \
+ content/browser/worker_host/worker_storage_partition.cc \
+ content/browser/gamepad/gamepad_platform_data_fetcher.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DENABLE_JAVA_BRIDGE' \
+ '-DPROTOBUF_USE_DLLS' \
+ '-DGOOGLE_PROTOBUF_NO_RTTI' \
+ '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DSK_BUILD_NO_IMAGE_ENCODE' \
+ '-DSK_DEFERRED_CANVAS_USES_GPIPE=1' \
+ '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
+ '-DGR_AGGRESSIVE_SHADER_OPTS=1' \
+ '-DSK_ENABLE_INST_COUNT=0' \
+ '-DSK_USE_POSIX_THREADS' \
+ '-DSK_BUILD_FOR_ANDROID_NDK' \
+ '-DU_USING_ICU_NAMESPACE=0' \
+ '-DMEDIA_DISABLE_LIBVPX' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_intermediate_dir) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH)/third_party/khronos \
+ $(LOCAL_PATH)/gpu \
+ $(gyp_shared_intermediate_dir)/content \
+ $(gyp_shared_intermediate_dir)/protoc_out \
+ $(LOCAL_PATH)/third_party/protobuf \
+ $(LOCAL_PATH)/third_party/protobuf/src \
+ $(LOCAL_PATH)/skia/config \
+ $(LOCAL_PATH)/third_party/skia/src/core \
+ $(LOCAL_PATH)/third_party/skia/include/config \
+ $(LOCAL_PATH)/third_party/skia/include/core \
+ $(LOCAL_PATH)/third_party/skia/include/effects \
+ $(LOCAL_PATH)/third_party/skia/include/pdf \
+ $(LOCAL_PATH)/third_party/skia/include/gpu \
+ $(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
+ $(LOCAL_PATH)/third_party/skia/include/pipe \
+ $(LOCAL_PATH)/third_party/skia/include/ports \
+ $(LOCAL_PATH)/third_party/skia/include/utils \
+ $(LOCAL_PATH)/skia/ext \
+ $(LOCAL_PATH)/third_party/re2 \
+ $(LOCAL_PATH)/third_party/zlib \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
+ $(gyp_shared_intermediate_dir)/ui/ui_resources \
+ $(gyp_shared_intermediate_dir)/webkit \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(LOCAL_PATH)/third_party/npapi \
+ $(LOCAL_PATH)/third_party/npapi/bindings \
+ $(LOCAL_PATH)/v8/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES := \
+ content_browser_speech_proto_speech_proto_gyp \
+ skia_skia_gyp \
+ ui_ui_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_browser_gyp
+
+# Alias gyp target name.
+.PHONY: content_browser
+content_browser: content_content_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_browser.target.linux-arm.mk b/content/content_browser.target.linux-arm.mk
index 9d32fc3..6d993c9 100644
--- a/content/content_browser.target.linux-arm.mk
+++ b/content/content_browser.target.linux-arm.mk
@@ -14,6 +14,7 @@
$(call intermediates-dir-for,GYP,content_content_resources_gyp)/content_resources.stamp \
$(call intermediates-dir-for,STATIC_LIBRARIES,content_browser_speech_proto_speech_proto_gyp)/content_browser_speech_proto_speech_proto_gyp.a \
$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_ui_gyp)/ui_ui_gyp.a \
$(call intermediates-dir-for,GYP,ui_ui_resources_gyp)/ui_resources.stamp \
$(call intermediates-dir-for,GYP,content_browser_devtools_devtools_resources_gyp)/devtools_resources.stamp \
$(call intermediates-dir-for,GYP,webkit_support_webkit_resources_gyp)/webkit_resources.stamp \
@@ -50,6 +51,7 @@
content/public/browser/download_save_info.cc \
content/public/browser/download_url_parameters.cc \
content/public/browser/favicon_status.cc \
+ content/public/browser/indexed_db_info.cc \
content/public/browser/javascript_dialog_manager.cc \
content/public/browser/load_from_memory_cache_details.cc \
content/public/browser/navigation_controller.cc \
@@ -85,7 +87,7 @@
content/browser/android/devtools_auth.cc \
content/browser/android/interstitial_page_delegate_android.cc \
content/browser/android/load_url_params.cc \
- content/browser/android/media_player_manager_android.cc \
+ content/browser/android/media_player_manager_impl.cc \
content/browser/android/media_resource_getter_impl.cc \
content/browser/android/surface_texture_peer_browser_impl.cc \
content/browser/android/sync_input_event_filter.cc \
@@ -118,6 +120,7 @@
content/browser/cross_site_request_manager.cc \
content/browser/devtools/devtools_agent_host_impl.cc \
content/browser/devtools/devtools_browser_target.cc \
+ content/browser/devtools/devtools_external_agent_proxy_impl.cc \
content/browser/devtools/devtools_frontend_host.cc \
content/browser/devtools/devtools_http_handler_impl.cc \
content/browser/devtools/devtools_manager_impl.cc \
@@ -125,8 +128,10 @@
content/browser/devtools/devtools_protocol.cc \
content/browser/devtools/devtools_protocol_constants.cc \
content/browser/devtools/devtools_tracing_handler.cc \
+ content/browser/devtools/ipc_devtools_agent_host.cc \
content/browser/devtools/render_view_devtools_agent_host.cc \
content/browser/devtools/renderer_overrides_handler.cc \
+ content/browser/devtools/tethering_handler.cc \
content/browser/devtools/worker_devtools_manager.cc \
content/browser/devtools/worker_devtools_message_filter.cc \
content/browser/device_orientation/data_fetcher_impl_android.cc \
@@ -200,17 +205,19 @@
content/browser/hyphenator/hyphenator_message_filter.cc \
content/browser/in_process_webkit/browser_webkitplatformsupport_impl.cc \
content/browser/in_process_webkit/indexed_db_callbacks.cc \
- content/browser/in_process_webkit/indexed_db_context_impl.cc \
content/browser/in_process_webkit/indexed_db_database_callbacks.cc \
content/browser/in_process_webkit/indexed_db_dispatcher_host.cc \
- content/browser/in_process_webkit/indexed_db_quota_client.cc \
content/browser/in_process_webkit/webkit_thread.cc \
+ content/browser/indexed_db/indexed_db_context_impl.cc \
+ content/browser/indexed_db/indexed_db_internals_ui.cc \
+ content/browser/indexed_db/indexed_db_quota_client.cc \
content/browser/loader/async_resource_handler.cc \
content/browser/loader/buffered_resource_handler.cc \
content/browser/loader/certificate_resource_handler.cc \
content/browser/loader/cross_site_resource_handler.cc \
content/browser/loader/doomed_resource_handler.cc \
content/browser/loader/layered_resource_handler.cc \
+ content/browser/loader/offline_policy.cc \
content/browser/loader/power_save_block_resource_throttle.cc \
content/browser/loader/redirect_to_file_resource_handler.cc \
content/browser/loader/render_view_host_tracker.cc \
@@ -237,6 +244,7 @@
content/browser/media/webrtc_internals_ui.cc \
content/browser/mime_registry_message_filter.cc \
content/browser/net/browser_online_state_observer.cc \
+ content/browser/net/sqlite_persistent_cookie_store.cc \
content/browser/net/view_blob_internals_job_factory.cc \
content/browser/net/view_http_cache_job_factory.cc \
content/browser/notification_service_impl.cc \
@@ -281,6 +289,7 @@
content/browser/renderer_host/media/web_contents_capture_util.cc \
content/browser/renderer_host/media/web_contents_tracker.cc \
content/browser/renderer_host/media/web_contents_video_capture_device.cc \
+ content/browser/renderer_host/media/webrtc_logging_handler_host.cc \
content/browser/renderer_host/native_web_keyboard_event_android.cc \
content/browser/renderer_host/native_web_keyboard_event.cc \
content/browser/renderer_host/overscroll_configuration.cc \
@@ -297,6 +306,7 @@
content/browser/renderer_host/render_widget_host_view_android.cc \
content/browser/renderer_host/render_widget_host_view_base.cc \
content/browser/renderer_host/render_widget_host_view_guest.cc \
+ content/browser/renderer_host/smooth_scroll_gesture_controller.cc \
content/browser/renderer_host/socket_stream_dispatcher_host.cc \
content/browser/renderer_host/socket_stream_host.cc \
content/browser/renderer_host/surface_texture_transport_client_android.cc \
@@ -333,6 +343,7 @@
content/browser/web_contents/navigation_entry_impl.cc \
content/browser/web_contents/render_view_host_manager.cc \
content/browser/web_contents/web_contents_impl.cc \
+ content/browser/web_contents/web_contents_screenshot_manager.cc \
content/browser/web_contents/web_contents_view_android.cc \
content/browser/web_contents/web_contents_view_guest.cc \
content/browser/webui/content_web_ui_controller_factory.cc \
@@ -391,7 +402,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -399,7 +409,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -433,10 +442,11 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
- $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
- $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
$(LOCAL_PATH) \
$(gyp_intermediate_dir) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
$(LOCAL_PATH)/third_party/khronos \
$(LOCAL_PATH)/gpu \
$(gyp_shared_intermediate_dir)/content \
@@ -451,6 +461,7 @@
$(LOCAL_PATH)/third_party/skia/include/pdf \
$(LOCAL_PATH)/third_party/skia/include/gpu \
$(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
$(LOCAL_PATH)/third_party/skia/include/pipe \
$(LOCAL_PATH)/third_party/skia/include/ports \
$(LOCAL_PATH)/third_party/skia/include/utils \
@@ -463,7 +474,6 @@
$(gyp_shared_intermediate_dir)/webkit \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
- $(gyp_shared_intermediate_dir)/webcore_headers \
$(LOCAL_PATH)/third_party/npapi \
$(LOCAL_PATH)/third_party/npapi/bindings \
$(LOCAL_PATH)/v8/include \
@@ -498,14 +508,15 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES := \
content_browser_speech_proto_speech_proto_gyp \
- skia_skia_gyp
+ skia_skia_gyp \
+ ui_ui_gyp
# Enable grouping to fix circular references
LOCAL_GROUP_STATIC_LIBRARIES := true
diff --git a/content/content_browser.target.linux-x86.mk b/content/content_browser.target.linux-x86.mk
index 62486e9..44e619e 100644
--- a/content/content_browser.target.linux-x86.mk
+++ b/content/content_browser.target.linux-x86.mk
@@ -14,6 +14,7 @@
$(call intermediates-dir-for,GYP,content_content_resources_gyp)/content_resources.stamp \
$(call intermediates-dir-for,STATIC_LIBRARIES,content_browser_speech_proto_speech_proto_gyp)/content_browser_speech_proto_speech_proto_gyp.a \
$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_ui_gyp)/ui_ui_gyp.a \
$(call intermediates-dir-for,GYP,ui_ui_resources_gyp)/ui_resources.stamp \
$(call intermediates-dir-for,GYP,content_browser_devtools_devtools_resources_gyp)/devtools_resources.stamp \
$(call intermediates-dir-for,GYP,webkit_support_webkit_resources_gyp)/webkit_resources.stamp \
@@ -50,6 +51,7 @@
content/public/browser/download_save_info.cc \
content/public/browser/download_url_parameters.cc \
content/public/browser/favicon_status.cc \
+ content/public/browser/indexed_db_info.cc \
content/public/browser/javascript_dialog_manager.cc \
content/public/browser/load_from_memory_cache_details.cc \
content/public/browser/navigation_controller.cc \
@@ -85,7 +87,7 @@
content/browser/android/devtools_auth.cc \
content/browser/android/interstitial_page_delegate_android.cc \
content/browser/android/load_url_params.cc \
- content/browser/android/media_player_manager_android.cc \
+ content/browser/android/media_player_manager_impl.cc \
content/browser/android/media_resource_getter_impl.cc \
content/browser/android/surface_texture_peer_browser_impl.cc \
content/browser/android/sync_input_event_filter.cc \
@@ -118,6 +120,7 @@
content/browser/cross_site_request_manager.cc \
content/browser/devtools/devtools_agent_host_impl.cc \
content/browser/devtools/devtools_browser_target.cc \
+ content/browser/devtools/devtools_external_agent_proxy_impl.cc \
content/browser/devtools/devtools_frontend_host.cc \
content/browser/devtools/devtools_http_handler_impl.cc \
content/browser/devtools/devtools_manager_impl.cc \
@@ -125,8 +128,10 @@
content/browser/devtools/devtools_protocol.cc \
content/browser/devtools/devtools_protocol_constants.cc \
content/browser/devtools/devtools_tracing_handler.cc \
+ content/browser/devtools/ipc_devtools_agent_host.cc \
content/browser/devtools/render_view_devtools_agent_host.cc \
content/browser/devtools/renderer_overrides_handler.cc \
+ content/browser/devtools/tethering_handler.cc \
content/browser/devtools/worker_devtools_manager.cc \
content/browser/devtools/worker_devtools_message_filter.cc \
content/browser/device_orientation/data_fetcher_impl_android.cc \
@@ -200,17 +205,19 @@
content/browser/hyphenator/hyphenator_message_filter.cc \
content/browser/in_process_webkit/browser_webkitplatformsupport_impl.cc \
content/browser/in_process_webkit/indexed_db_callbacks.cc \
- content/browser/in_process_webkit/indexed_db_context_impl.cc \
content/browser/in_process_webkit/indexed_db_database_callbacks.cc \
content/browser/in_process_webkit/indexed_db_dispatcher_host.cc \
- content/browser/in_process_webkit/indexed_db_quota_client.cc \
content/browser/in_process_webkit/webkit_thread.cc \
+ content/browser/indexed_db/indexed_db_context_impl.cc \
+ content/browser/indexed_db/indexed_db_internals_ui.cc \
+ content/browser/indexed_db/indexed_db_quota_client.cc \
content/browser/loader/async_resource_handler.cc \
content/browser/loader/buffered_resource_handler.cc \
content/browser/loader/certificate_resource_handler.cc \
content/browser/loader/cross_site_resource_handler.cc \
content/browser/loader/doomed_resource_handler.cc \
content/browser/loader/layered_resource_handler.cc \
+ content/browser/loader/offline_policy.cc \
content/browser/loader/power_save_block_resource_throttle.cc \
content/browser/loader/redirect_to_file_resource_handler.cc \
content/browser/loader/render_view_host_tracker.cc \
@@ -237,6 +244,7 @@
content/browser/media/webrtc_internals_ui.cc \
content/browser/mime_registry_message_filter.cc \
content/browser/net/browser_online_state_observer.cc \
+ content/browser/net/sqlite_persistent_cookie_store.cc \
content/browser/net/view_blob_internals_job_factory.cc \
content/browser/net/view_http_cache_job_factory.cc \
content/browser/notification_service_impl.cc \
@@ -281,6 +289,7 @@
content/browser/renderer_host/media/web_contents_capture_util.cc \
content/browser/renderer_host/media/web_contents_tracker.cc \
content/browser/renderer_host/media/web_contents_video_capture_device.cc \
+ content/browser/renderer_host/media/webrtc_logging_handler_host.cc \
content/browser/renderer_host/native_web_keyboard_event_android.cc \
content/browser/renderer_host/native_web_keyboard_event.cc \
content/browser/renderer_host/overscroll_configuration.cc \
@@ -297,6 +306,7 @@
content/browser/renderer_host/render_widget_host_view_android.cc \
content/browser/renderer_host/render_widget_host_view_base.cc \
content/browser/renderer_host/render_widget_host_view_guest.cc \
+ content/browser/renderer_host/smooth_scroll_gesture_controller.cc \
content/browser/renderer_host/socket_stream_dispatcher_host.cc \
content/browser/renderer_host/socket_stream_host.cc \
content/browser/renderer_host/surface_texture_transport_client_android.cc \
@@ -333,6 +343,7 @@
content/browser/web_contents/navigation_entry_impl.cc \
content/browser/web_contents/render_view_host_manager.cc \
content/browser/web_contents/web_contents_impl.cc \
+ content/browser/web_contents/web_contents_screenshot_manager.cc \
content/browser/web_contents/web_contents_view_android.cc \
content/browser/web_contents/web_contents_view_guest.cc \
content/browser/webui/content_web_ui_controller_factory.cc \
@@ -371,6 +382,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -392,7 +404,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -400,7 +411,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -433,10 +443,11 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
- $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
- $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
$(LOCAL_PATH) \
$(gyp_intermediate_dir) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
$(LOCAL_PATH)/third_party/khronos \
$(LOCAL_PATH)/gpu \
$(gyp_shared_intermediate_dir)/content \
@@ -451,6 +462,7 @@
$(LOCAL_PATH)/third_party/skia/include/pdf \
$(LOCAL_PATH)/third_party/skia/include/gpu \
$(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
$(LOCAL_PATH)/third_party/skia/include/pipe \
$(LOCAL_PATH)/third_party/skia/include/ports \
$(LOCAL_PATH)/third_party/skia/include/utils \
@@ -463,7 +475,6 @@
$(gyp_shared_intermediate_dir)/webkit \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
- $(gyp_shared_intermediate_dir)/webcore_headers \
$(LOCAL_PATH)/third_party/npapi \
$(LOCAL_PATH)/third_party/npapi/bindings \
$(LOCAL_PATH)/v8/include \
@@ -491,17 +502,19 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES := \
content_browser_speech_proto_speech_proto_gyp \
- skia_skia_gyp
+ skia_skia_gyp \
+ ui_ui_gyp
# Enable grouping to fix circular references
LOCAL_GROUP_STATIC_LIBRARIES := true
diff --git a/content/content_common.gypi b/content/content_common.gypi
index 1e40703..9537c6c 100644
--- a/content/content_common.gypi
+++ b/content/content_common.gypi
@@ -114,12 +114,6 @@
'common/android/device_telephony_info.h',
'common/android/hash_set.cc',
'common/android/hash_set.h',
- 'common/android/scoped_java_surface.cc',
- 'common/android/scoped_java_surface.h',
- 'common/android/surface_texture_bridge.cc',
- 'common/android/surface_texture_bridge.h',
- 'common/android/surface_texture_listener.cc',
- 'common/android/surface_texture_listener.h',
'common/android/surface_texture_peer.cc',
'common/android/surface_texture_peer.h',
'common/android/trace_event_binding.cc',
@@ -192,6 +186,7 @@
'common/font_cache_dispatcher_win.h',
'common/font_config_ipc_linux.cc',
'common/font_config_ipc_linux.h',
+ 'common/font_list.cc',
'common/font_list.h',
'common/font_list_android.cc',
'common/font_list_linux.cc',
@@ -245,17 +240,13 @@
'common/gpu/image_transport_surface.h',
'common/gpu/image_transport_surface.cc',
'common/gpu/image_transport_surface_android.cc',
- 'common/gpu/image_transport_surface_linux.cc',
'common/gpu/image_transport_surface_mac.cc',
'common/gpu/image_transport_surface_win.cc',
- 'common/gpu/media/avc_config_record_builder.cc',
- 'common/gpu/media/avc_config_record_builder.h',
+ 'common/gpu/image_transport_surface_x11.cc',
'common/gpu/media/h264_bit_reader.cc',
'common/gpu/media/h264_bit_reader.h',
'common/gpu/media/h264_parser.cc',
'common/gpu/media/h264_parser.h',
- 'common/gpu/media/mac_video_decode_accelerator.h',
- 'common/gpu/media/mac_video_decode_accelerator.mm',
'common/gpu/media/gpu_video_decode_accelerator.cc',
'common/gpu/media/gpu_video_decode_accelerator.h',
'common/gpu/sync_point_manager.h',
@@ -264,7 +255,7 @@
'common/gpu/texture_image_transport_surface.cc',
'common/handle_enumerator_win.cc',
'common/handle_enumerator_win.h',
- 'common/icon_messages.h',
+ 'common/image_messages.h',
'common/indexed_db/indexed_db_key.cc',
'common/indexed_db/indexed_db_key.h',
'common/indexed_db/indexed_db_key_path.cc',
@@ -284,6 +275,7 @@
'common/indexed_db/proxy_webidbdatabase_impl.h',
'common/indexed_db/proxy_webidbfactory_impl.cc',
'common/indexed_db/proxy_webidbfactory_impl.h',
+ 'common/input_messages.h',
'common/inter_process_time_ticks_converter.cc',
'common/inter_process_time_ticks_converter.h',
'common/java_bridge_messages.h',
@@ -302,6 +294,7 @@
'common/media/media_stream_options.h',
'common/media/video_capture.h',
'common/media/video_capture_messages.h',
+ 'common/media/webrtc_logging_messages.h',
'common/message_router.cc',
'common/message_router.h',
'common/mime_registry_messages.h',
@@ -321,6 +314,8 @@
'common/p2p_messages.h',
'common/p2p_sockets.h',
'common/page_zoom.cc',
+ 'common/partial_circular_buffer.cc',
+ 'common/partial_circular_buffer.h',
'common/pepper_messages.h',
'common/pepper_plugin_registry.cc',
'common/pepper_plugin_registry.h',
@@ -342,7 +337,6 @@
'common/sandbox_init_mac.cc',
'common/sandbox_init_mac.h',
'common/sandbox_init_win.cc',
- 'common/sandbox_init_linux.cc',
'common/sandbox_mac.h',
'common/sandbox_mac.mm',
'common/sandbox_linux.h',
@@ -451,10 +445,12 @@
'../build/linux/system.gyp:gtk',
],
}],
- ['use_x11 == 1', {
+ ['OS=="linux"', {
'dependencies': [
'../build/linux/system.gyp:pangocairo',
],
+ }],
+ ['use_x11 == 1', {
'include_dirs': [
'<(DEPTH)/third_party/angle/include',
],
diff --git a/content/content_common.target.darwin-arm.mk b/content/content_common.target.darwin-arm.mk
new file mode 100644
index 0000000..f9269a2
--- /dev/null
+++ b/content/content_common.target.darwin-arm.mk
@@ -0,0 +1,317 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a \
+ $(call intermediates-dir-for,GYP,third_party_icu_icuuc_gyp)/icuuc.stamp \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_ui_gyp)/ui_ui_gyp.a \
+ $(call intermediates-dir-for,GYP,content_content_resources_gyp)/content_resources.stamp \
+ $(call intermediates-dir-for,GYP,third_party_npapi_npapi_gyp)/npapi.stamp \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp)/ui_gl_gl_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,webkit_support_glue_gyp)/webkit_support_glue_gyp.a \
+ $(call intermediates-dir-for,GYP,content_content_jni_headers_gyp)/content_jni_headers.stamp \
+ $(call intermediates-dir-for,GYP,content_common_aidl_gyp)/common_aidl.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ content/public/common/child_process_host_delegate.cc \
+ content/public/common/content_constants.cc \
+ content/public/common/content_switches.cc \
+ content/public/common/context_menu_params.cc \
+ content/public/common/dx_diag_node.cc \
+ content/public/common/favicon_url.cc \
+ content/public/common/file_chooser_params.cc \
+ content/public/common/frame_navigate_params.cc \
+ content/public/common/geoposition.cc \
+ content/public/common/gpu_info.cc \
+ content/public/common/gpu_memory_stats.cc \
+ content/public/common/media_stream_request.cc \
+ content/public/common/page_transition_types.cc \
+ content/public/common/password_form.cc \
+ content/public/common/pepper_plugin_info.cc \
+ content/public/common/renderer_preferences.cc \
+ content/public/common/show_desktop_notification_params.cc \
+ content/public/common/speech_recognition_result.cc \
+ content/public/common/ssl_status.cc \
+ content/public/common/url_constants.cc \
+ content/common/accessibility_node_data.cc \
+ content/common/android/address_parser.cc \
+ content/common/android/address_parser_internal.cc \
+ content/common/android/command_line.cc \
+ content/common/android/common_jni_registrar.cc \
+ content/common/android/device_telephony_info.cc \
+ content/common/android/hash_set.cc \
+ content/common/android/surface_texture_peer.cc \
+ content/common/android/trace_event_binding.cc \
+ content/common/appcache/appcache_backend_proxy.cc \
+ content/common/appcache/appcache_dispatcher.cc \
+ content/common/browser_plugin/browser_plugin_constants.cc \
+ content/common/cc_messages.cc \
+ content/common/child_histogram_message_filter.cc \
+ content/common/child_process.cc \
+ content/common/child_process_host_impl.cc \
+ content/common/child_thread.cc \
+ content/common/clipboard_messages.cc \
+ content/common/content_constants_internal.cc \
+ content/common/content_ipc_logging.cc \
+ content/common/content_message_generator.cc \
+ content/common/content_param_traits.cc \
+ content/common/content_paths.cc \
+ content/common/database_util.cc \
+ content/common/db_message_filter.cc \
+ content/common/fileapi/file_system_dispatcher.cc \
+ content/common/fileapi/webblobregistry_impl.cc \
+ content/common/fileapi/webfilesystem_callback_dispatcher.cc \
+ content/common/fileapi/webfilesystem_impl.cc \
+ content/common/fileapi/webfilewriter_impl.cc \
+ content/common/find_match_rect_android.cc \
+ content/common/font_list.cc \
+ content/common/font_list_android.cc \
+ content/common/gamepad_seqlock.cc \
+ content/common/gamepad_user_gesture.cc \
+ content/common/gpu/client/command_buffer_proxy_impl.cc \
+ content/common/gpu/client/context_provider_command_buffer.cc \
+ content/common/gpu/client/gl_helper.cc \
+ content/common/gpu/client/gpu_channel_host.cc \
+ content/common/gpu/client/gpu_video_decode_accelerator_host.cc \
+ content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc \
+ content/common/gpu/gl_scoped_binders.cc \
+ content/common/gpu/gpu_channel.cc \
+ content/common/gpu/gpu_channel_manager.cc \
+ content/common/gpu/gpu_command_buffer_stub.cc \
+ content/common/gpu/gpu_memory_manager.cc \
+ content/common/gpu/gpu_memory_manager_client.cc \
+ content/common/gpu/gpu_memory_tracking.cc \
+ content/common/gpu/gpu_rendering_stats.cc \
+ content/common/gpu/gpu_surface_lookup.cc \
+ content/common/gpu/stream_texture_manager_android.cc \
+ content/common/gpu/image_transport_surface.cc \
+ content/common/gpu/image_transport_surface_android.cc \
+ content/common/gpu/media/h264_bit_reader.cc \
+ content/common/gpu/media/h264_parser.cc \
+ content/common/gpu/media/gpu_video_decode_accelerator.cc \
+ content/common/gpu/sync_point_manager.cc \
+ content/common/gpu/texture_image_transport_surface.cc \
+ content/common/indexed_db/indexed_db_key.cc \
+ content/common/indexed_db/indexed_db_key_path.cc \
+ content/common/indexed_db/indexed_db_key_range.cc \
+ content/common/indexed_db/indexed_db_param_traits.cc \
+ content/common/indexed_db/indexed_db_dispatcher.cc \
+ content/common/indexed_db/indexed_db_message_filter.cc \
+ content/common/indexed_db/proxy_webidbcursor_impl.cc \
+ content/common/indexed_db/proxy_webidbdatabase_impl.cc \
+ content/common/indexed_db/proxy_webidbfactory_impl.cc \
+ content/common/inter_process_time_ticks_converter.cc \
+ content/common/media/media_param_traits.cc \
+ content/common/media/media_stream_options.cc \
+ content/common/message_router.cc \
+ content/common/net/url_fetcher.cc \
+ content/common/net/url_request_user_data.cc \
+ content/common/np_channel_base.cc \
+ content/common/npobject_proxy.cc \
+ content/common/npobject_stub.cc \
+ content/common/npobject_util.cc \
+ content/common/page_zoom.cc \
+ content/common/partial_circular_buffer.cc \
+ content/common/pepper_renderer_instance_data.cc \
+ content/common/process_type.cc \
+ content/common/quota_dispatcher.cc \
+ content/common/request_extra_data.cc \
+ content/common/resource_dispatcher.cc \
+ content/common/resource_messages.cc \
+ content/common/sandbox_util.cc \
+ content/common/savable_url_schemes.cc \
+ content/common/set_process_title.cc \
+ content/common/socket_stream_dispatcher.cc \
+ content/common/socket_stream_handle_data.cc \
+ content/common/ssl_status_serialization.cc \
+ content/common/swapped_out_messages.cc \
+ content/common/thread_safe_sender.cc \
+ content/common/url_schemes.cc \
+ content/common/web_database_observer_impl.cc \
+ content/common/webkitplatformsupport_impl.cc \
+ content/common/webmessageportchannel_impl.cc \
+ content/public/common/common_param_traits.cc \
+ content/public/common/content_client.cc \
+ content/public/common/window_container_type.cc \
+ content/common/gpu/media/android_video_decode_accelerator.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DMEDIA_DISABLE_LIBVPX' \
+ '-DPOSIX_AVOID_MMAP' \
+ '-DSK_BUILD_NO_IMAGE_ENCODE' \
+ '-DSK_DEFERRED_CANVAS_USES_GPIPE=1' \
+ '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
+ '-DGR_AGGRESSIVE_SHADER_OPTS=1' \
+ '-DSK_ENABLE_INST_COUNT=0' \
+ '-DSK_USE_POSIX_THREADS' \
+ '-DSK_BUILD_FOR_ANDROID_NDK' \
+ '-DU_USING_ICU_NAMESPACE=0' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH)/third_party/khronos \
+ $(LOCAL_PATH)/gpu \
+ $(LOCAL_PATH)/skia/config \
+ $(LOCAL_PATH)/third_party/skia/src/core \
+ $(LOCAL_PATH)/third_party/skia/include/config \
+ $(LOCAL_PATH)/third_party/skia/include/core \
+ $(LOCAL_PATH)/third_party/skia/include/effects \
+ $(LOCAL_PATH)/third_party/skia/include/pdf \
+ $(LOCAL_PATH)/third_party/skia/include/gpu \
+ $(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
+ $(LOCAL_PATH)/third_party/skia/include/pipe \
+ $(LOCAL_PATH)/third_party/skia/include/ports \
+ $(LOCAL_PATH)/third_party/skia/include/utils \
+ $(LOCAL_PATH)/skia/ext \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
+ $(gyp_shared_intermediate_dir)/content \
+ $(LOCAL_PATH)/third_party/npapi \
+ $(LOCAL_PATH)/third_party/npapi/bindings \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(LOCAL_PATH)/v8/include \
+ $(gyp_shared_intermediate_dir)/ui/gl \
+ $(LOCAL_PATH)/third_party/mesa/MesaLib/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES := \
+ skia_skia_gyp \
+ ui_ui_gyp \
+ ui_gl_gl_gyp \
+ webkit_support_glue_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_common_gyp
+
+# Alias gyp target name.
+.PHONY: content_common
+content_common: content_content_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_common.target.darwin-x86.mk b/content/content_common.target.darwin-x86.mk
new file mode 100644
index 0000000..452cf6d
--- /dev/null
+++ b/content/content_common.target.darwin-x86.mk
@@ -0,0 +1,315 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a \
+ $(call intermediates-dir-for,GYP,third_party_icu_icuuc_gyp)/icuuc.stamp \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_ui_gyp)/ui_ui_gyp.a \
+ $(call intermediates-dir-for,GYP,content_content_resources_gyp)/content_resources.stamp \
+ $(call intermediates-dir-for,GYP,third_party_npapi_npapi_gyp)/npapi.stamp \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp)/ui_gl_gl_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,webkit_support_glue_gyp)/webkit_support_glue_gyp.a \
+ $(call intermediates-dir-for,GYP,content_content_jni_headers_gyp)/content_jni_headers.stamp \
+ $(call intermediates-dir-for,GYP,content_common_aidl_gyp)/common_aidl.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ content/public/common/child_process_host_delegate.cc \
+ content/public/common/content_constants.cc \
+ content/public/common/content_switches.cc \
+ content/public/common/context_menu_params.cc \
+ content/public/common/dx_diag_node.cc \
+ content/public/common/favicon_url.cc \
+ content/public/common/file_chooser_params.cc \
+ content/public/common/frame_navigate_params.cc \
+ content/public/common/geoposition.cc \
+ content/public/common/gpu_info.cc \
+ content/public/common/gpu_memory_stats.cc \
+ content/public/common/media_stream_request.cc \
+ content/public/common/page_transition_types.cc \
+ content/public/common/password_form.cc \
+ content/public/common/pepper_plugin_info.cc \
+ content/public/common/renderer_preferences.cc \
+ content/public/common/show_desktop_notification_params.cc \
+ content/public/common/speech_recognition_result.cc \
+ content/public/common/ssl_status.cc \
+ content/public/common/url_constants.cc \
+ content/common/accessibility_node_data.cc \
+ content/common/android/address_parser.cc \
+ content/common/android/address_parser_internal.cc \
+ content/common/android/command_line.cc \
+ content/common/android/common_jni_registrar.cc \
+ content/common/android/device_telephony_info.cc \
+ content/common/android/hash_set.cc \
+ content/common/android/surface_texture_peer.cc \
+ content/common/android/trace_event_binding.cc \
+ content/common/appcache/appcache_backend_proxy.cc \
+ content/common/appcache/appcache_dispatcher.cc \
+ content/common/browser_plugin/browser_plugin_constants.cc \
+ content/common/cc_messages.cc \
+ content/common/child_histogram_message_filter.cc \
+ content/common/child_process.cc \
+ content/common/child_process_host_impl.cc \
+ content/common/child_thread.cc \
+ content/common/clipboard_messages.cc \
+ content/common/content_constants_internal.cc \
+ content/common/content_ipc_logging.cc \
+ content/common/content_message_generator.cc \
+ content/common/content_param_traits.cc \
+ content/common/content_paths.cc \
+ content/common/database_util.cc \
+ content/common/db_message_filter.cc \
+ content/common/fileapi/file_system_dispatcher.cc \
+ content/common/fileapi/webblobregistry_impl.cc \
+ content/common/fileapi/webfilesystem_callback_dispatcher.cc \
+ content/common/fileapi/webfilesystem_impl.cc \
+ content/common/fileapi/webfilewriter_impl.cc \
+ content/common/find_match_rect_android.cc \
+ content/common/font_list.cc \
+ content/common/font_list_android.cc \
+ content/common/gamepad_seqlock.cc \
+ content/common/gamepad_user_gesture.cc \
+ content/common/gpu/client/command_buffer_proxy_impl.cc \
+ content/common/gpu/client/context_provider_command_buffer.cc \
+ content/common/gpu/client/gl_helper.cc \
+ content/common/gpu/client/gpu_channel_host.cc \
+ content/common/gpu/client/gpu_video_decode_accelerator_host.cc \
+ content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc \
+ content/common/gpu/gl_scoped_binders.cc \
+ content/common/gpu/gpu_channel.cc \
+ content/common/gpu/gpu_channel_manager.cc \
+ content/common/gpu/gpu_command_buffer_stub.cc \
+ content/common/gpu/gpu_memory_manager.cc \
+ content/common/gpu/gpu_memory_manager_client.cc \
+ content/common/gpu/gpu_memory_tracking.cc \
+ content/common/gpu/gpu_rendering_stats.cc \
+ content/common/gpu/gpu_surface_lookup.cc \
+ content/common/gpu/stream_texture_manager_android.cc \
+ content/common/gpu/image_transport_surface.cc \
+ content/common/gpu/image_transport_surface_android.cc \
+ content/common/gpu/media/h264_bit_reader.cc \
+ content/common/gpu/media/h264_parser.cc \
+ content/common/gpu/media/gpu_video_decode_accelerator.cc \
+ content/common/gpu/sync_point_manager.cc \
+ content/common/gpu/texture_image_transport_surface.cc \
+ content/common/indexed_db/indexed_db_key.cc \
+ content/common/indexed_db/indexed_db_key_path.cc \
+ content/common/indexed_db/indexed_db_key_range.cc \
+ content/common/indexed_db/indexed_db_param_traits.cc \
+ content/common/indexed_db/indexed_db_dispatcher.cc \
+ content/common/indexed_db/indexed_db_message_filter.cc \
+ content/common/indexed_db/proxy_webidbcursor_impl.cc \
+ content/common/indexed_db/proxy_webidbdatabase_impl.cc \
+ content/common/indexed_db/proxy_webidbfactory_impl.cc \
+ content/common/inter_process_time_ticks_converter.cc \
+ content/common/media/media_param_traits.cc \
+ content/common/media/media_stream_options.cc \
+ content/common/message_router.cc \
+ content/common/net/url_fetcher.cc \
+ content/common/net/url_request_user_data.cc \
+ content/common/np_channel_base.cc \
+ content/common/npobject_proxy.cc \
+ content/common/npobject_stub.cc \
+ content/common/npobject_util.cc \
+ content/common/page_zoom.cc \
+ content/common/partial_circular_buffer.cc \
+ content/common/pepper_renderer_instance_data.cc \
+ content/common/process_type.cc \
+ content/common/quota_dispatcher.cc \
+ content/common/request_extra_data.cc \
+ content/common/resource_dispatcher.cc \
+ content/common/resource_messages.cc \
+ content/common/sandbox_util.cc \
+ content/common/savable_url_schemes.cc \
+ content/common/set_process_title.cc \
+ content/common/socket_stream_dispatcher.cc \
+ content/common/socket_stream_handle_data.cc \
+ content/common/ssl_status_serialization.cc \
+ content/common/swapped_out_messages.cc \
+ content/common/thread_safe_sender.cc \
+ content/common/url_schemes.cc \
+ content/common/web_database_observer_impl.cc \
+ content/common/webkitplatformsupport_impl.cc \
+ content/common/webmessageportchannel_impl.cc \
+ content/public/common/common_param_traits.cc \
+ content/public/common/content_client.cc \
+ content/public/common/window_container_type.cc \
+ content/common/gpu/media/android_video_decode_accelerator.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DMEDIA_DISABLE_LIBVPX' \
+ '-DSK_BUILD_NO_IMAGE_ENCODE' \
+ '-DSK_DEFERRED_CANVAS_USES_GPIPE=1' \
+ '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
+ '-DGR_AGGRESSIVE_SHADER_OPTS=1' \
+ '-DSK_ENABLE_INST_COUNT=0' \
+ '-DSK_USE_POSIX_THREADS' \
+ '-DSK_BUILD_FOR_ANDROID_NDK' \
+ '-DU_USING_ICU_NAMESPACE=0' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH)/third_party/khronos \
+ $(LOCAL_PATH)/gpu \
+ $(LOCAL_PATH)/skia/config \
+ $(LOCAL_PATH)/third_party/skia/src/core \
+ $(LOCAL_PATH)/third_party/skia/include/config \
+ $(LOCAL_PATH)/third_party/skia/include/core \
+ $(LOCAL_PATH)/third_party/skia/include/effects \
+ $(LOCAL_PATH)/third_party/skia/include/pdf \
+ $(LOCAL_PATH)/third_party/skia/include/gpu \
+ $(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
+ $(LOCAL_PATH)/third_party/skia/include/pipe \
+ $(LOCAL_PATH)/third_party/skia/include/ports \
+ $(LOCAL_PATH)/third_party/skia/include/utils \
+ $(LOCAL_PATH)/skia/ext \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
+ $(gyp_shared_intermediate_dir)/content \
+ $(LOCAL_PATH)/third_party/npapi \
+ $(LOCAL_PATH)/third_party/npapi/bindings \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(LOCAL_PATH)/v8/include \
+ $(gyp_shared_intermediate_dir)/ui/gl \
+ $(LOCAL_PATH)/third_party/mesa/MesaLib/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES := \
+ skia_skia_gyp \
+ ui_ui_gyp \
+ ui_gl_gl_gyp \
+ webkit_support_glue_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_common_gyp
+
+# Alias gyp target name.
+.PHONY: content_common
+content_common: content_content_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_common.target.linux-arm.mk b/content/content_common.target.linux-arm.mk
index 132444d..f9269a2 100644
--- a/content/content_common.target.linux-arm.mk
+++ b/content/content_common.target.linux-arm.mk
@@ -13,6 +13,7 @@
GYP_TARGET_DEPENDENCIES := \
$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a \
$(call intermediates-dir-for,GYP,third_party_icu_icuuc_gyp)/icuuc.stamp \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_ui_gyp)/ui_ui_gyp.a \
$(call intermediates-dir-for,GYP,content_content_resources_gyp)/content_resources.stamp \
$(call intermediates-dir-for,GYP,third_party_npapi_npapi_gyp)/npapi.stamp \
$(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp)/ui_gl_gl_gyp.a \
@@ -58,9 +59,6 @@
content/common/android/common_jni_registrar.cc \
content/common/android/device_telephony_info.cc \
content/common/android/hash_set.cc \
- content/common/android/scoped_java_surface.cc \
- content/common/android/surface_texture_bridge.cc \
- content/common/android/surface_texture_listener.cc \
content/common/android/surface_texture_peer.cc \
content/common/android/trace_event_binding.cc \
content/common/appcache/appcache_backend_proxy.cc \
@@ -85,6 +83,7 @@
content/common/fileapi/webfilesystem_impl.cc \
content/common/fileapi/webfilewriter_impl.cc \
content/common/find_match_rect_android.cc \
+ content/common/font_list.cc \
content/common/font_list_android.cc \
content/common/gamepad_seqlock.cc \
content/common/gamepad_user_gesture.cc \
@@ -106,7 +105,6 @@
content/common/gpu/stream_texture_manager_android.cc \
content/common/gpu/image_transport_surface.cc \
content/common/gpu/image_transport_surface_android.cc \
- content/common/gpu/media/avc_config_record_builder.cc \
content/common/gpu/media/h264_bit_reader.cc \
content/common/gpu/media/h264_parser.cc \
content/common/gpu/media/gpu_video_decode_accelerator.cc \
@@ -132,6 +130,7 @@
content/common/npobject_stub.cc \
content/common/npobject_util.cc \
content/common/page_zoom.cc \
+ content/common/partial_circular_buffer.cc \
content/common/pepper_renderer_instance_data.cc \
content/common/process_type.cc \
content/common/quota_dispatcher.cc \
@@ -193,7 +192,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -201,7 +199,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -231,9 +228,10 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
- $(LOCAL_PATH) \
$(LOCAL_PATH)/third_party/khronos \
$(LOCAL_PATH)/gpu \
$(LOCAL_PATH)/skia/config \
@@ -244,6 +242,7 @@
$(LOCAL_PATH)/third_party/skia/include/pdf \
$(LOCAL_PATH)/third_party/skia/include/gpu \
$(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
$(LOCAL_PATH)/third_party/skia/include/pipe \
$(LOCAL_PATH)/third_party/skia/include/ports \
$(LOCAL_PATH)/third_party/skia/include/utils \
@@ -255,7 +254,6 @@
$(LOCAL_PATH)/third_party/npapi/bindings \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
- $(gyp_shared_intermediate_dir)/webcore_headers \
$(LOCAL_PATH)/v8/include \
$(gyp_shared_intermediate_dir)/ui/gl \
$(LOCAL_PATH)/third_party/mesa/MesaLib/include \
@@ -290,13 +288,14 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES := \
skia_skia_gyp \
+ ui_ui_gyp \
ui_gl_gl_gyp \
webkit_support_glue_gyp
diff --git a/content/content_common.target.linux-x86.mk b/content/content_common.target.linux-x86.mk
index 5282915..452cf6d 100644
--- a/content/content_common.target.linux-x86.mk
+++ b/content/content_common.target.linux-x86.mk
@@ -13,6 +13,7 @@
GYP_TARGET_DEPENDENCIES := \
$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a \
$(call intermediates-dir-for,GYP,third_party_icu_icuuc_gyp)/icuuc.stamp \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_ui_gyp)/ui_ui_gyp.a \
$(call intermediates-dir-for,GYP,content_content_resources_gyp)/content_resources.stamp \
$(call intermediates-dir-for,GYP,third_party_npapi_npapi_gyp)/npapi.stamp \
$(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp)/ui_gl_gl_gyp.a \
@@ -58,9 +59,6 @@
content/common/android/common_jni_registrar.cc \
content/common/android/device_telephony_info.cc \
content/common/android/hash_set.cc \
- content/common/android/scoped_java_surface.cc \
- content/common/android/surface_texture_bridge.cc \
- content/common/android/surface_texture_listener.cc \
content/common/android/surface_texture_peer.cc \
content/common/android/trace_event_binding.cc \
content/common/appcache/appcache_backend_proxy.cc \
@@ -85,6 +83,7 @@
content/common/fileapi/webfilesystem_impl.cc \
content/common/fileapi/webfilewriter_impl.cc \
content/common/find_match_rect_android.cc \
+ content/common/font_list.cc \
content/common/font_list_android.cc \
content/common/gamepad_seqlock.cc \
content/common/gamepad_user_gesture.cc \
@@ -106,7 +105,6 @@
content/common/gpu/stream_texture_manager_android.cc \
content/common/gpu/image_transport_surface.cc \
content/common/gpu/image_transport_surface_android.cc \
- content/common/gpu/media/avc_config_record_builder.cc \
content/common/gpu/media/h264_bit_reader.cc \
content/common/gpu/media/h264_parser.cc \
content/common/gpu/media/gpu_video_decode_accelerator.cc \
@@ -132,6 +130,7 @@
content/common/npobject_stub.cc \
content/common/npobject_util.cc \
content/common/page_zoom.cc \
+ content/common/partial_circular_buffer.cc \
content/common/pepper_renderer_instance_data.cc \
content/common/process_type.cc \
content/common/quota_dispatcher.cc \
@@ -173,6 +172,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -194,7 +194,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -202,7 +201,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -231,9 +229,10 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
- $(LOCAL_PATH) \
$(LOCAL_PATH)/third_party/khronos \
$(LOCAL_PATH)/gpu \
$(LOCAL_PATH)/skia/config \
@@ -244,6 +243,7 @@
$(LOCAL_PATH)/third_party/skia/include/pdf \
$(LOCAL_PATH)/third_party/skia/include/gpu \
$(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
$(LOCAL_PATH)/third_party/skia/include/pipe \
$(LOCAL_PATH)/third_party/skia/include/ports \
$(LOCAL_PATH)/third_party/skia/include/utils \
@@ -255,7 +255,6 @@
$(LOCAL_PATH)/third_party/npapi/bindings \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
- $(gyp_shared_intermediate_dir)/webcore_headers \
$(LOCAL_PATH)/v8/include \
$(gyp_shared_intermediate_dir)/ui/gl \
$(LOCAL_PATH)/third_party/mesa/MesaLib/include \
@@ -283,16 +282,18 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES := \
skia_skia_gyp \
+ ui_ui_gyp \
ui_gl_gl_gyp \
webkit_support_glue_gyp
diff --git a/content/content_gpu.gypi b/content/content_gpu.gypi
index ec4f552..9be835e 100644
--- a/content/content_gpu.gypi
+++ b/content/content_gpu.gypi
@@ -12,9 +12,9 @@
'sources': [
'gpu/gpu_dx_diagnostics_win.cc',
'gpu/gpu_info_collector_android.cc',
- 'gpu/gpu_info_collector_linux.cc',
'gpu/gpu_info_collector_mac.mm',
'gpu/gpu_info_collector_win.cc',
+ 'gpu/gpu_info_collector_x11.cc',
'gpu/gpu_info_collector.cc',
'gpu/gpu_info_collector.h',
'gpu/gpu_main.cc',
@@ -85,7 +85,7 @@
'../third_party/amd/amd_videocard_info_win.cc',
],
}],
- ['OS=="linux"', {
+ ['OS=="linux" and use_x11==1', {
'dependencies': [
'../build/linux/system.gyp:libpci',
'../third_party/libXNVCtrl/libXNVCtrl.gyp:libXNVCtrl',
diff --git a/content/content_gpu.target.darwin-arm.mk b/content/content_gpu.target.darwin-arm.mk
new file mode 100644
index 0000000..aecbc53
--- /dev/null
+++ b/content/content_gpu.target.darwin-arm.mk
@@ -0,0 +1,183 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_gpu_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp)/ui_gl_gl_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ content/gpu/gpu_info_collector_android.cc \
+ content/gpu/gpu_info_collector.cc \
+ content/gpu/gpu_main.cc \
+ content/gpu/gpu_process.cc \
+ content/gpu/gpu_child_thread.cc \
+ content/gpu/gpu_watchdog_thread.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DSK_BUILD_NO_IMAGE_ENCODE' \
+ '-DSK_DEFERRED_CANVAS_USES_GPIPE=1' \
+ '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
+ '-DGR_AGGRESSIVE_SHADER_OPTS=1' \
+ '-DSK_ENABLE_INST_COUNT=0' \
+ '-DSK_USE_POSIX_THREADS' \
+ '-DSK_BUILD_FOR_ANDROID_NDK' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH)/third_party/khronos \
+ $(LOCAL_PATH)/gpu \
+ $(LOCAL_PATH)/skia/config \
+ $(LOCAL_PATH)/third_party/skia/src/core \
+ $(LOCAL_PATH)/third_party/skia/include/config \
+ $(LOCAL_PATH)/third_party/skia/include/core \
+ $(LOCAL_PATH)/third_party/skia/include/effects \
+ $(LOCAL_PATH)/third_party/skia/include/pdf \
+ $(LOCAL_PATH)/third_party/skia/include/gpu \
+ $(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
+ $(LOCAL_PATH)/third_party/skia/include/pipe \
+ $(LOCAL_PATH)/third_party/skia/include/ports \
+ $(LOCAL_PATH)/third_party/skia/include/utils \
+ $(LOCAL_PATH)/skia/ext \
+ $(LOCAL_PATH)/third_party/re2 \
+ $(gyp_shared_intermediate_dir)/ui/gl \
+ $(LOCAL_PATH)/third_party/mesa/MesaLib/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES := \
+ skia_skia_gyp \
+ ui_gl_gl_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_gpu_gyp
+
+# Alias gyp target name.
+.PHONY: content_gpu
+content_gpu: content_content_gpu_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_gpu.target.darwin-x86.mk b/content/content_gpu.target.darwin-x86.mk
new file mode 100644
index 0000000..02ea638
--- /dev/null
+++ b/content/content_gpu.target.darwin-x86.mk
@@ -0,0 +1,182 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_gpu_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp)/ui_gl_gl_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ content/gpu/gpu_info_collector_android.cc \
+ content/gpu/gpu_info_collector.cc \
+ content/gpu/gpu_main.cc \
+ content/gpu/gpu_process.cc \
+ content/gpu/gpu_child_thread.cc \
+ content/gpu/gpu_watchdog_thread.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DSK_BUILD_NO_IMAGE_ENCODE' \
+ '-DSK_DEFERRED_CANVAS_USES_GPIPE=1' \
+ '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
+ '-DGR_AGGRESSIVE_SHADER_OPTS=1' \
+ '-DSK_ENABLE_INST_COUNT=0' \
+ '-DSK_USE_POSIX_THREADS' \
+ '-DSK_BUILD_FOR_ANDROID_NDK' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH)/third_party/khronos \
+ $(LOCAL_PATH)/gpu \
+ $(LOCAL_PATH)/skia/config \
+ $(LOCAL_PATH)/third_party/skia/src/core \
+ $(LOCAL_PATH)/third_party/skia/include/config \
+ $(LOCAL_PATH)/third_party/skia/include/core \
+ $(LOCAL_PATH)/third_party/skia/include/effects \
+ $(LOCAL_PATH)/third_party/skia/include/pdf \
+ $(LOCAL_PATH)/third_party/skia/include/gpu \
+ $(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
+ $(LOCAL_PATH)/third_party/skia/include/pipe \
+ $(LOCAL_PATH)/third_party/skia/include/ports \
+ $(LOCAL_PATH)/third_party/skia/include/utils \
+ $(LOCAL_PATH)/skia/ext \
+ $(LOCAL_PATH)/third_party/re2 \
+ $(gyp_shared_intermediate_dir)/ui/gl \
+ $(LOCAL_PATH)/third_party/mesa/MesaLib/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES := \
+ skia_skia_gyp \
+ ui_gl_gl_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_gpu_gyp
+
+# Alias gyp target name.
+.PHONY: content_gpu
+content_gpu: content_content_gpu_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_gpu.target.linux-arm.mk b/content/content_gpu.target.linux-arm.mk
index e26b69a..aecbc53 100644
--- a/content/content_gpu.target.linux-arm.mk
+++ b/content/content_gpu.target.linux-arm.mk
@@ -70,7 +70,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -78,7 +77,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -105,9 +103,10 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
- $(LOCAL_PATH) \
$(LOCAL_PATH)/third_party/khronos \
$(LOCAL_PATH)/gpu \
$(LOCAL_PATH)/skia/config \
@@ -118,6 +117,7 @@
$(LOCAL_PATH)/third_party/skia/include/pdf \
$(LOCAL_PATH)/third_party/skia/include/gpu \
$(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
$(LOCAL_PATH)/third_party/skia/include/pipe \
$(LOCAL_PATH)/third_party/skia/include/ports \
$(LOCAL_PATH)/third_party/skia/include/utils \
@@ -156,9 +156,9 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES := \
diff --git a/content/content_gpu.target.linux-x86.mk b/content/content_gpu.target.linux-x86.mk
index 827b7b8..02ea638 100644
--- a/content/content_gpu.target.linux-x86.mk
+++ b/content/content_gpu.target.linux-x86.mk
@@ -50,6 +50,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -71,7 +72,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -79,7 +79,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -106,9 +105,10 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
- $(LOCAL_PATH) \
$(LOCAL_PATH)/third_party/khronos \
$(LOCAL_PATH)/gpu \
$(LOCAL_PATH)/skia/config \
@@ -119,6 +119,7 @@
$(LOCAL_PATH)/third_party/skia/include/pdf \
$(LOCAL_PATH)/third_party/skia/include/gpu \
$(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
$(LOCAL_PATH)/third_party/skia/include/pipe \
$(LOCAL_PATH)/third_party/skia/include/ports \
$(LOCAL_PATH)/third_party/skia/include/utils \
@@ -150,12 +151,13 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES := \
diff --git a/content/content_jni.gypi b/content/content_jni.gypi
index 784428a..7dac8ee 100644
--- a/content/content_jni.gypi
+++ b/content/content_jni.gypi
@@ -18,19 +18,19 @@
'public/android/java/src/org/chromium/content/browser/ContentViewCore.java',
'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java',
'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java',
- 'public/android/java/src/org/chromium/content/browser/DateTimeChooserAndroid.java',
- 'public/android/java/src/org/chromium/content/browser/DeviceOrientation.java',
+ 'public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java',
'public/android/java/src/org/chromium/content/browser/DownloadController.java',
- 'public/android/java/src/org/chromium/content/browser/ImeAdapter.java',
+ 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java',
+ 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java',
'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java',
'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java',
'public/android/java/src/org/chromium/content/browser/LocationProvider.java',
+ 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java',
'public/android/java/src/org/chromium/content/browser/TouchPoint.java',
'public/android/java/src/org/chromium/content/browser/TracingIntentHandler.java',
'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java',
'public/android/java/src/org/chromium/content/common/CommandLine.java',
'public/android/java/src/org/chromium/content/common/DeviceTelephonyInfo.java',
- 'public/android/java/src/org/chromium/content/common/SurfaceTextureListener.java',
'public/android/java/src/org/chromium/content/common/TraceEvent.java',
],
'variables': {
diff --git a/content/content_jni_headers.target.darwin-arm.mk b/content/content_jni_headers.target.darwin-arm.mk
new file mode 100644
index 0000000..71a1b8e
--- /dev/null
+++ b/content/content_jni_headers.target.darwin-arm.mk
@@ -0,0 +1,420 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_content_jni_headers_gyp
+LOCAL_MODULE_STEM := content_jni_headers
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,GYP,content_java_set_jni_headers_gyp)/java_set_jni_headers.stamp
+
+
+### Generated for rule "content_content_gyp_content_jni_headers_target_generate_jni_headers":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/app/LibraryLoader.java', 'public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProvider.java', 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java', 'public/android/java/src/org/chromium/content/browser/TouchPoint.java', 'public/android/java/src/org/chromium/content/browser/TracingIntentHandler.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/common/CommandLine.java', 'public/android/java/src/org/chromium/content/common/DeviceTelephonyInfo.java', 'public/android/java/src/org/chromium/content/common/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--optimize_generation', '0'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/app/ChildProcessService.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/app/ContentMain.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/app/ContentMain.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/app/LibraryLoader.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/app/LibraryLoader.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/ContentSettings.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/ContentSettings.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/ContentVideoView.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/ContentVideoView.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/ContentViewCore.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/ContentViewStatics.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/ContentViewStatics.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/DownloadController.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/DownloadController.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/LoadUrlParams.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/LoadUrlParams.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/LocationProvider.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/LocationProvider.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/TouchPoint.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/TouchPoint.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/TracingIntentHandler.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/TracingIntentHandler.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/CommandLine.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/common/CommandLine.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/DeviceTelephonyInfo.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/common/DeviceTelephonyInfo.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/TraceEvent.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/common/TraceEvent.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES := \
+ $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h \
+ content_content_jni_headers_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_jni_headers_gyp
+
+# Alias gyp target name.
+.PHONY: content_jni_headers
+content_jni_headers: content_content_jni_headers_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/content_jni_headers.target.darwin-x86.mk b/content/content_jni_headers.target.darwin-x86.mk
new file mode 100644
index 0000000..5ef7a75
--- /dev/null
+++ b/content/content_jni_headers.target.darwin-x86.mk
@@ -0,0 +1,421 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_content_jni_headers_gyp
+LOCAL_MODULE_STEM := content_jni_headers
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,GYP,content_java_set_jni_headers_gyp)/java_set_jni_headers.stamp
+
+
+### Generated for rule "content_content_gyp_content_jni_headers_target_generate_jni_headers":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/app/LibraryLoader.java', 'public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProvider.java', 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java', 'public/android/java/src/org/chromium/content/browser/TouchPoint.java', 'public/android/java/src/org/chromium/content/browser/TracingIntentHandler.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/common/CommandLine.java', 'public/android/java/src/org/chromium/content/common/DeviceTelephonyInfo.java', 'public/android/java/src/org/chromium/content/common/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--optimize_generation', '0'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/app/ChildProcessService.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/app/ContentMain.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/app/ContentMain.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/app/LibraryLoader.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/app/LibraryLoader.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/ContentSettings.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/ContentSettings.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/ContentVideoView.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/ContentVideoView.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/ContentViewCore.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/ContentViewStatics.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/ContentViewStatics.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/DownloadController.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/DownloadController.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/LoadUrlParams.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/LoadUrlParams.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/LocationProvider.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/LocationProvider.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/TouchPoint.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/TouchPoint.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/TracingIntentHandler.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/TracingIntentHandler.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/CommandLine.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/common/CommandLine.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/DeviceTelephonyInfo.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/common/DeviceTelephonyInfo.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h
+
+$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/TraceEvent.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/common/TraceEvent.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES := \
+ $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/LibraryLoader_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/AndroidBrowserProcess_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h \
+ content_content_jni_headers_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_jni_headers_gyp
+
+# Alias gyp target name.
+.PHONY: content_jni_headers
+content_jni_headers: content_content_jni_headers_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/content_jni_headers.target.linux-arm.mk b/content/content_jni_headers.target.linux-arm.mk
index 178b89f..71a1b8e 100644
--- a/content/content_jni_headers.target.linux-arm.mk
+++ b/content/content_jni_headers.target.linux-arm.mk
@@ -12,13 +12,11 @@
# Make sure our deps are built first.
GYP_TARGET_DEPENDENCIES := \
- $(call intermediates-dir-for,GYP,content_java_set_jni_headers_gyp)/java_set_jni_headers.stamp \
- $(call intermediates-dir-for,GYP,content_surface_texture_jni_headers_gyp)/surface_texture_jni_headers.stamp \
- $(call intermediates-dir-for,GYP,content_surface_jni_headers_gyp)/surface_jni_headers.stamp
+ $(call intermediates-dir-for,GYP,content_java_set_jni_headers_gyp)/java_set_jni_headers.stamp
### Generated for rule "content_content_gyp_content_jni_headers_target_generate_jni_headers":
-# "{'inputs': ['../base/android/jni_generator/jni_generator.py'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/app/LibraryLoader.java', 'public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/DeviceOrientation.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProvider.java', 'public/android/java/src/org/chromium/content/browser/TouchPoint.java', 'public/android/java/src/org/chromium/content/browser/TracingIntentHandler.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/common/CommandLine.java', 'public/android/java/src/org/chromium/content/common/DeviceTelephonyInfo.java', 'public/android/java/src/org/chromium/content/common/SurfaceTextureListener.java', 'public/android/java/src/org/chromium/content/common/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--optimize_generation', '0'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/app/LibraryLoader.java', 'public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProvider.java', 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java', 'public/android/java/src/org/chromium/content/browser/TouchPoint.java', 'public/android/java/src/org/chromium/content/browser/TracingIntentHandler.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/common/CommandLine.java', 'public/android/java/src/org/chromium/content/common/DeviceTelephonyInfo.java', 'public/android/java/src/org/chromium/content/common/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--optimize_generation', '0'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -119,25 +117,15 @@
.PHONY: content_content_jni_headers_gyp_rule_trigger
content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h
-$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
-$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/DateTimeChooserAndroid.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/DateTimeChooserAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
.PHONY: content_content_jni_headers_gyp_rule_trigger
-content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h
-
-$(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h: gyp_local_path := $(LOCAL_PATH)
-$(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/DeviceOrientation.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/DeviceOrientation.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
-
-.PHONY: content_content_jni_headers_gyp_rule_trigger
-content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h
$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
@@ -153,12 +141,22 @@
$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/ImeAdapter.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/ImeAdapter.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
.PHONY: content_content_jni_headers_gyp_rule_trigger
content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h
+
$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -189,6 +187,16 @@
.PHONY: content_content_jni_headers_gyp_rule_trigger
content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h
+
$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -239,16 +247,6 @@
.PHONY: content_content_jni_headers_gyp_rule_trigger
content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/SurfaceTextureListener.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/common/SurfaceTextureListener.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
-
-.PHONY: content_content_jni_headers_gyp_rule_trigger
-content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h
-
$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -272,19 +270,19 @@
$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h \
- $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h \
- $(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h \
- $(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h
# Make sure our deps and generated files are built first.
@@ -301,19 +299,19 @@
$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h \
- $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h \
- $(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h \
- $(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h \
content_content_jni_headers_gyp_rule_trigger
@@ -359,7 +357,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -367,7 +364,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
diff --git a/content/content_jni_headers.target.linux-x86.mk b/content/content_jni_headers.target.linux-x86.mk
index b73f5e9..5ef7a75 100644
--- a/content/content_jni_headers.target.linux-x86.mk
+++ b/content/content_jni_headers.target.linux-x86.mk
@@ -12,13 +12,11 @@
# Make sure our deps are built first.
GYP_TARGET_DEPENDENCIES := \
- $(call intermediates-dir-for,GYP,content_java_set_jni_headers_gyp)/java_set_jni_headers.stamp \
- $(call intermediates-dir-for,GYP,content_surface_texture_jni_headers_gyp)/surface_texture_jni_headers.stamp \
- $(call intermediates-dir-for,GYP,content_surface_jni_headers_gyp)/surface_jni_headers.stamp
+ $(call intermediates-dir-for,GYP,content_java_set_jni_headers_gyp)/java_set_jni_headers.stamp
### Generated for rule "content_content_gyp_content_jni_headers_target_generate_jni_headers":
-# "{'inputs': ['../base/android/jni_generator/jni_generator.py'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/app/LibraryLoader.java', 'public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/DeviceOrientation.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProvider.java', 'public/android/java/src/org/chromium/content/browser/TouchPoint.java', 'public/android/java/src/org/chromium/content/browser/TracingIntentHandler.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/common/CommandLine.java', 'public/android/java/src/org/chromium/content/common/DeviceTelephonyInfo.java', 'public/android/java/src/org/chromium/content/common/SurfaceTextureListener.java', 'public/android/java/src/org/chromium/content/common/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--optimize_generation', '0'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/app/LibraryLoader.java', 'public/android/java/src/org/chromium/content/browser/AndroidBrowserProcess.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProvider.java', 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java', 'public/android/java/src/org/chromium/content/browser/TouchPoint.java', 'public/android/java/src/org/chromium/content/browser/TracingIntentHandler.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/common/CommandLine.java', 'public/android/java/src/org/chromium/content/common/DeviceTelephonyInfo.java', 'public/android/java/src/org/chromium/content/common/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--optimize_generation', '0'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -119,25 +117,15 @@
.PHONY: content_content_jni_headers_gyp_rule_trigger
content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h
-$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
-$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/DateTimeChooserAndroid.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/DateTimeChooserAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
.PHONY: content_content_jni_headers_gyp_rule_trigger
-content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h
-
-$(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h: gyp_local_path := $(LOCAL_PATH)
-$(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/DeviceOrientation.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/DeviceOrientation.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
-
-.PHONY: content_content_jni_headers_gyp_rule_trigger
-content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h
$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
@@ -153,12 +141,22 @@
$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/ImeAdapter.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/ImeAdapter.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
.PHONY: content_content_jni_headers_gyp_rule_trigger
content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h
+
$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -189,6 +187,16 @@
.PHONY: content_content_jni_headers_gyp_rule_trigger
content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+
+.PHONY: content_content_jni_headers_gyp_rule_trigger
+content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h
+
$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -239,16 +247,6 @@
.PHONY: content_content_jni_headers_gyp_rule_trigger
content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/SurfaceTextureListener.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/content/jni; cd $(gyp_local_path)/content; ../base/android/jni_generator/jni_generator.py --input_file public/android/java/src/org/chromium/content/common/SurfaceTextureListener.java --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
-
-.PHONY: content_content_jni_headers_gyp_rule_trigger
-content_content_jni_headers_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h
-
$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
@@ -272,19 +270,19 @@
$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h \
- $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h \
- $(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h \
- $(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h
# Make sure our deps and generated files are built first.
@@ -301,19 +299,19 @@
$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h \
- $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h \
- $(gyp_shared_intermediate_dir)/content/jni/DeviceOrientation_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DeviceMotionAndOrientation_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/LocationProvider_jni.h \
+ $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/TouchPoint_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/TracingIntentHandler_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/CommandLine_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/DeviceTelephonyInfo_jni.h \
- $(gyp_shared_intermediate_dir)/content/jni/SurfaceTextureListener_jni.h \
$(gyp_shared_intermediate_dir)/content/jni/TraceEvent_jni.h \
content_content_jni_headers_gyp_rule_trigger
@@ -339,6 +337,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -360,7 +359,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -368,7 +366,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
diff --git a/content/content_plugin.target.darwin-arm.mk b/content/content_plugin.target.darwin-arm.mk
new file mode 100644
index 0000000..b5f541c
--- /dev/null
+++ b/content/content_plugin.target.darwin-arm.mk
@@ -0,0 +1,56 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_plugin_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_plugin_gyp
+
+# Alias gyp target name.
+.PHONY: content_plugin
+content_plugin: content_content_plugin_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_plugin.target.darwin-x86.mk b/content/content_plugin.target.darwin-x86.mk
new file mode 100644
index 0000000..ce304bd
--- /dev/null
+++ b/content/content_plugin.target.darwin-x86.mk
@@ -0,0 +1,54 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_plugin_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_plugin_gyp
+
+# Alias gyp target name.
+.PHONY: content_plugin
+content_plugin: content_content_plugin_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_plugin.target.linux-arm.mk b/content/content_plugin.target.linux-arm.mk
index 6c8773c..b5f541c 100644
--- a/content/content_plugin.target.linux-arm.mk
+++ b/content/content_plugin.target.linux-arm.mk
@@ -31,9 +31,9 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/content/content_plugin.target.linux-x86.mk b/content/content_plugin.target.linux-x86.mk
index 01de08b..ce304bd 100644
--- a/content/content_plugin.target.linux-x86.mk
+++ b/content/content_plugin.target.linux-x86.mk
@@ -25,12 +25,13 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/content/content_ppapi_plugin.target.darwin-arm.mk b/content/content_ppapi_plugin.target.darwin-arm.mk
new file mode 100644
index 0000000..bb45175
--- /dev/null
+++ b/content/content_ppapi_plugin.target.darwin-arm.mk
@@ -0,0 +1,56 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_ppapi_plugin_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_ppapi_plugin_gyp
+
+# Alias gyp target name.
+.PHONY: content_ppapi_plugin
+content_ppapi_plugin: content_content_ppapi_plugin_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_ppapi_plugin.target.darwin-x86.mk b/content/content_ppapi_plugin.target.darwin-x86.mk
new file mode 100644
index 0000000..b639ccf
--- /dev/null
+++ b/content/content_ppapi_plugin.target.darwin-x86.mk
@@ -0,0 +1,54 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_ppapi_plugin_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_ppapi_plugin_gyp
+
+# Alias gyp target name.
+.PHONY: content_ppapi_plugin
+content_ppapi_plugin: content_content_ppapi_plugin_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_ppapi_plugin.target.linux-arm.mk b/content/content_ppapi_plugin.target.linux-arm.mk
index c996293..bb45175 100644
--- a/content/content_ppapi_plugin.target.linux-arm.mk
+++ b/content/content_ppapi_plugin.target.linux-arm.mk
@@ -31,9 +31,9 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/content/content_ppapi_plugin.target.linux-x86.mk b/content/content_ppapi_plugin.target.linux-x86.mk
index 7a40fe3..b639ccf 100644
--- a/content/content_ppapi_plugin.target.linux-x86.mk
+++ b/content/content_ppapi_plugin.target.linux-x86.mk
@@ -25,12 +25,13 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index 10edaad..0fb1bdb 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -27,6 +27,8 @@
'sources': [
'public/renderer/android_content_detection_prefixes.cc',
'public/renderer/android_content_detection_prefixes.h',
+ 'public/renderer/android/synchronous_compositor_client.h',
+ 'public/renderer/android/synchronous_compositor.h',
'public/renderer/content_renderer_client.cc',
'public/renderer/content_renderer_client.h',
'public/renderer/context_menu_client.h',
@@ -66,6 +68,8 @@
'renderer/android/email_detector.h',
'renderer/android/phone_number_detector.cc',
'renderer/android/phone_number_detector.h',
+ 'renderer/android/synchronous_compositor_output_surface.cc',
+ 'renderer/android/synchronous_compositor_output_surface.h',
'renderer/device_orientation_dispatcher.cc',
'renderer/device_orientation_dispatcher.h',
'renderer/devtools/devtools_agent.cc',
@@ -76,8 +80,6 @@
'renderer/devtools/devtools_client.h',
'renderer/disambiguation_popup_helper.cc',
'renderer/disambiguation_popup_helper.h',
- 'renderer/do_not_track_bindings.cc',
- 'renderer/do_not_track_bindings.h',
'renderer/dom_automation_controller.cc',
'renderer/dom_automation_controller.h',
'renderer/dom_storage/dom_storage_dispatcher.cc',
@@ -88,16 +90,14 @@
'renderer/dom_storage/webstoragenamespace_impl.h',
'renderer/external_popup_menu.cc',
'renderer/external_popup_menu.h',
- 'renderer/favicon_helper.cc',
- 'renderer/favicon_helper.h',
'renderer/gamepad_shared_memory_reader.cc',
'renderer/gamepad_shared_memory_reader.h',
'renderer/geolocation_dispatcher.cc',
'renderer/geolocation_dispatcher.h',
'renderer/gpu/compositor_output_surface.cc',
'renderer/gpu/compositor_output_surface.h',
- 'renderer/gpu/compositor_software_output_device_gl_adapter.cc',
- 'renderer/gpu/compositor_software_output_device_gl_adapter.h',
+ 'renderer/gpu/compositor_software_output_device.cc',
+ 'renderer/gpu/compositor_software_output_device.h',
'renderer/gpu/input_event_filter.cc',
'renderer/gpu/input_event_filter.h',
'renderer/gpu/input_handler_manager.cc',
@@ -114,8 +114,12 @@
'renderer/hyphenator/hyphenator.h',
'renderer/idle_user_detector.cc',
'renderer/idle_user_detector.h',
+ 'renderer/image_loading_helper.cc',
+ 'renderer/image_loading_helper.h',
'renderer/input_tag_speech_dispatcher.cc',
'renderer/input_tag_speech_dispatcher.h',
+ 'renderer/internal_document_state_data.cc',
+ 'renderer/internal_document_state_data.h',
'renderer/java/java_bridge_channel.cc',
'renderer/java/java_bridge_channel.h',
'renderer/java/java_bridge_dispatcher.cc',
@@ -130,8 +134,6 @@
'renderer/media/audio_message_filter.h',
'renderer/media/audio_renderer_mixer_manager.cc',
'renderer/media/audio_renderer_mixer_manager.h',
- 'renderer/media/local_video_capture.cc',
- 'renderer/media/local_video_capture.h',
'renderer/media/media_stream_center.h',
'renderer/media/media_stream_dependency_factory.h',
'renderer/media/media_stream_dispatcher.h',
@@ -141,8 +143,6 @@
'renderer/media/pepper_platform_video_decoder_impl.h',
'renderer/media/render_media_log.cc',
'renderer/media/render_media_log.h',
- 'renderer/media/renderer_audio_output_device.cc',
- 'renderer/media/renderer_audio_output_device.h',
'renderer/media/renderer_gpu_video_decoder_factories.cc',
'renderer/media/renderer_gpu_video_decoder_factories.h',
'renderer/media/renderer_webaudiodevice_impl.cc',
@@ -159,6 +159,10 @@
'renderer/media/video_capture_message_filter.h',
'renderer/media/webmediaplayer_proxy_impl_android.cc',
'renderer/media/webmediaplayer_proxy_impl_android.h',
+ 'renderer/media/webrtc_logging_handler_impl.cc',
+ 'renderer/media/webrtc_logging_handler_impl.h',
+ 'renderer/media/webrtc_logging_message_filter.cc',
+ 'renderer/media/webrtc_logging_message_filter.h',
'renderer/memory_benchmarking_extension.cc',
'renderer/memory_benchmarking_extension.h',
'renderer/mhtml_generator.cc',
@@ -172,6 +176,8 @@
'renderer/password_form_conversion_utils.cc',
'renderer/pepper/content_renderer_pepper_host_factory.cc',
'renderer/pepper/content_renderer_pepper_host_factory.h',
+ 'renderer/pepper/null_file_system_callback_dispatcher.cc',
+ 'renderer/pepper/null_file_system_callback_dispatcher.h',
'renderer/pepper/pepper_audio_input_host.cc',
'renderer/pepper/pepper_audio_input_host.h',
'renderer/pepper/pepper_broker_impl.cc',
@@ -180,12 +186,12 @@
'renderer/pepper/pepper_device_enumeration_event_handler.h',
'renderer/pepper/pepper_device_enumeration_host_helper.cc',
'renderer/pepper/pepper_device_enumeration_host_helper.h',
- 'renderer/pepper/pepper_directory_reader_host.cc',
- 'renderer/pepper/pepper_directory_reader_host.h',
'renderer/pepper/pepper_file_chooser_host.cc',
'renderer/pepper/pepper_file_chooser_host.h',
'renderer/pepper/pepper_file_io_host.cc',
'renderer/pepper/pepper_file_io_host.h',
+ 'renderer/pepper/pepper_file_system_host.cc',
+ 'renderer/pepper/pepper_file_system_host.h',
'renderer/pepper/pepper_graphics_2d_host.cc',
'renderer/pepper/pepper_graphics_2d_host.h',
'renderer/pepper/pepper_hung_plugin_filter.cc',
@@ -217,6 +223,10 @@
'renderer/pepper/pepper_truetype_font_win.cc',
'renderer/pepper/pepper_video_capture_host.cc',
'renderer/pepper/pepper_video_capture_host.h',
+ 'renderer/pepper/pepper_video_destination_host.cc',
+ 'renderer/pepper/pepper_video_destination_host.h',
+ 'renderer/pepper/pepper_video_source_host.cc',
+ 'renderer/pepper/pepper_video_source_host.h',
'renderer/pepper/pepper_websocket_host.cc',
'renderer/pepper/pepper_websocket_host.h',
'renderer/pepper/renderer_ppapi_host_impl.cc',
@@ -330,6 +340,9 @@
'dependencies': [
'../third_party/libphonenumber/libphonenumber.gyp:libphonenumber',
],
+ 'includes': [
+ '../build/android/cpufeatures.gypi',
+ ],
}],
# TODO(jrg): remove the OS=="android" section?
# http://crbug.com/113172
@@ -351,10 +364,15 @@
'renderer/media/media_stream_dependency_factory.cc',
'renderer/media/media_stream_dispatcher.cc',
'renderer/media/media_stream_impl.cc',
+ 'renderer/media/media_stream_registry_interface.h',
+ 'renderer/media/media_stream_source_observer.cc',
+ 'renderer/media/media_stream_source_observer.h',
'renderer/media/peer_connection_handler_base.cc',
'renderer/media/peer_connection_handler_base.h',
'renderer/media/peer_connection_tracker.cc',
'renderer/media/peer_connection_tracker.h',
+ 'renderer/media/remote_media_stream_impl.cc',
+ 'renderer/media/remote_media_stream_impl.h',
'renderer/media/rtc_data_channel_handler.cc',
'renderer/media/rtc_data_channel_handler.h',
'renderer/media/rtc_dtmf_sender_handler.cc',
@@ -367,10 +385,16 @@
'renderer/media/rtc_video_capture_delegate.h',
'renderer/media/rtc_video_capturer.cc',
'renderer/media/rtc_video_capturer.h',
+ 'renderer/media/video_destination_handler.cc',
+ 'renderer/media/video_destination_handler.h',
+ 'renderer/media/video_source_handler.cc',
+ 'renderer/media/video_source_handler.h',
'renderer/media/webaudio_capturer_source.cc',
'renderer/media/webaudio_capturer_source.h',
'renderer/media/webrtc_audio_capturer.cc',
'renderer/media/webrtc_audio_capturer.h',
+ 'renderer/media/webrtc_audio_capturer_sink_owner.cc',
+ 'renderer/media/webrtc_audio_capturer_sink_owner.h',
'renderer/media/webrtc_audio_device_impl.cc',
'renderer/media/webrtc_audio_device_impl.h',
'renderer/media/webrtc_audio_device_not_impl.cc',
@@ -379,6 +403,8 @@
'renderer/media/webrtc_audio_renderer.h',
'renderer/media/webrtc_local_audio_renderer.cc',
'renderer/media/webrtc_local_audio_renderer.h',
+ 'renderer/media/webrtc_local_audio_track.cc',
+ 'renderer/media/webrtc_local_audio_track.h',
'renderer/p2p/host_address_request.cc',
'renderer/p2p/host_address_request.h',
'renderer/p2p/ipc_network_manager.cc',
diff --git a/content/content_renderer.target.darwin-arm.mk b/content/content_renderer.target.darwin-arm.mk
new file mode 100644
index 0000000..8755e4b
--- /dev/null
+++ b/content/content_renderer.target.darwin-arm.mk
@@ -0,0 +1,318 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_renderer_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,GYP,content_content_resources_gyp)/content_resources.stamp \
+ $(call intermediates-dir-for,GYP,jingle_jingle_glue_gyp)/jingle_glue.stamp \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a \
+ $(call intermediates-dir-for,GYP,third_party_icu_icuuc_gyp)/icuuc.stamp \
+ $(call intermediates-dir-for,GYP,third_party_icu_icui18n_gyp)/icui18n.stamp \
+ $(call intermediates-dir-for,GYP,third_party_npapi_npapi_gyp)/npapi.stamp \
+ $(call intermediates-dir-for,GYP,v8_tools_gyp_v8_gyp)/v8.stamp \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,webkit_support_glue_gyp)/webkit_support_glue_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,third_party_libphonenumber_libphonenumber_without_metadata_gyp)/third_party_libphonenumber_libphonenumber_without_metadata_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ content/public/renderer/android_content_detection_prefixes.cc \
+ content/public/renderer/content_renderer_client.cc \
+ content/public/renderer/document_state.cc \
+ content/public/renderer/navigation_state.cc \
+ content/public/renderer/render_process_observer.cc \
+ content/public/renderer/render_thread.cc \
+ content/public/renderer/render_view_observer.cc \
+ content/renderer/accessibility/accessibility_node_serializer.cc \
+ content/renderer/accessibility/renderer_accessibility.cc \
+ content/renderer/accessibility/renderer_accessibility_complete.cc \
+ content/renderer/accessibility/renderer_accessibility_focus_only.cc \
+ content/renderer/all_rendering_benchmarks.cc \
+ content/renderer/android/address_detector.cc \
+ content/renderer/android/content_detector.cc \
+ content/renderer/android/email_detector.cc \
+ content/renderer/android/phone_number_detector.cc \
+ content/renderer/android/synchronous_compositor_output_surface.cc \
+ content/renderer/device_orientation_dispatcher.cc \
+ content/renderer/devtools/devtools_agent.cc \
+ content/renderer/devtools/devtools_agent_filter.cc \
+ content/renderer/devtools/devtools_client.cc \
+ content/renderer/disambiguation_popup_helper.cc \
+ content/renderer/dom_automation_controller.cc \
+ content/renderer/dom_storage/dom_storage_dispatcher.cc \
+ content/renderer/dom_storage/webstoragearea_impl.cc \
+ content/renderer/dom_storage/webstoragenamespace_impl.cc \
+ content/renderer/external_popup_menu.cc \
+ content/renderer/gamepad_shared_memory_reader.cc \
+ content/renderer/geolocation_dispatcher.cc \
+ content/renderer/gpu/compositor_output_surface.cc \
+ content/renderer/gpu/compositor_software_output_device.cc \
+ content/renderer/gpu/input_event_filter.cc \
+ content/renderer/gpu/input_handler_manager.cc \
+ content/renderer/gpu/gpu_benchmarking_extension.cc \
+ content/renderer/gpu/mailbox_output_surface.cc \
+ content/renderer/gpu/stream_texture_host_android.cc \
+ content/renderer/gpu/render_widget_compositor.cc \
+ content/renderer/hyphenator/hyphenator.cc \
+ content/renderer/idle_user_detector.cc \
+ content/renderer/image_loading_helper.cc \
+ content/renderer/internal_document_state_data.cc \
+ content/renderer/java/java_bridge_channel.cc \
+ content/renderer/java/java_bridge_dispatcher.cc \
+ content/renderer/load_progress_tracker.cc \
+ content/renderer/media/audio_device_factory.cc \
+ content/renderer/media/audio_input_message_filter.cc \
+ content/renderer/media/audio_message_filter.cc \
+ content/renderer/media/audio_renderer_mixer_manager.cc \
+ content/renderer/media/pepper_platform_video_decoder_impl.cc \
+ content/renderer/media/render_media_log.cc \
+ content/renderer/media/renderer_gpu_video_decoder_factories.cc \
+ content/renderer/media/renderer_webaudiodevice_impl.cc \
+ content/renderer/media/rtc_video_renderer.cc \
+ content/renderer/media/stream_texture_factory_impl_android.cc \
+ content/renderer/media/video_capture_impl.cc \
+ content/renderer/media/video_capture_impl_manager.cc \
+ content/renderer/media/video_capture_message_filter.cc \
+ content/renderer/media/webmediaplayer_proxy_impl_android.cc \
+ content/renderer/media/webrtc_logging_handler_impl.cc \
+ content/renderer/media/webrtc_logging_message_filter.cc \
+ content/renderer/memory_benchmarking_extension.cc \
+ content/renderer/mhtml_generator.cc \
+ content/renderer/mouse_lock_dispatcher.cc \
+ content/renderer/paint_aggregator.cc \
+ content/renderer/password_form_conversion_utils.cc \
+ content/renderer/plugin_channel_host.cc \
+ content/renderer/browser_plugin/browser_plugin.cc \
+ content/renderer/browser_plugin/browser_plugin_backing_store.cc \
+ content/renderer/browser_plugin/browser_plugin_bindings.cc \
+ content/renderer/browser_plugin/browser_plugin_manager.cc \
+ content/renderer/browser_plugin/browser_plugin_manager_impl.cc \
+ content/renderer/browser_plugin/browser_plugin_compositing_helper.cc \
+ content/renderer/date_time_formatter.cc \
+ content/renderer/render_process_impl.cc \
+ content/renderer/render_thread_impl.cc \
+ content/renderer/render_view_impl.cc \
+ content/renderer/render_view_impl_android.cc \
+ content/renderer/render_view_impl_params.cc \
+ content/renderer/render_view_linux.cc \
+ content/renderer/render_view_mouse_lock_dispatcher.cc \
+ content/renderer/render_view_pepper_helper.cc \
+ content/renderer/render_widget.cc \
+ content/renderer/render_widget_fullscreen.cc \
+ content/renderer/renderer_clipboard_client.cc \
+ content/renderer/renderer_date_time_picker.cc \
+ content/renderer/renderer_main.cc \
+ content/renderer/renderer_main_platform_delegate_android.cc \
+ content/renderer/renderer_webapplicationcachehost_impl.cc \
+ content/renderer/renderer_webcookiejar_impl.cc \
+ content/renderer/renderer_webcolorchooser_impl.cc \
+ content/renderer/renderer_webkitplatformsupport_impl.cc \
+ content/renderer/rendering_benchmark.cc \
+ content/renderer/text_input_client_observer.cc \
+ content/renderer/v8_value_converter_impl.cc \
+ content/renderer/web_ui_extension.cc \
+ content/renderer/web_ui_extension_data.cc \
+ content/renderer/webplugin_delegate_proxy.cc \
+ content/renderer/websharedworker_proxy.cc \
+ content/renderer/websharedworkerrepository_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DENABLE_JAVA_BRIDGE' \
+ '-DPOSIX_AVOID_MMAP' \
+ '-DSK_BUILD_NO_IMAGE_ENCODE' \
+ '-DSK_DEFERRED_CANVAS_USES_GPIPE=1' \
+ '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
+ '-DGR_AGGRESSIVE_SHADER_OPTS=1' \
+ '-DSK_ENABLE_INST_COUNT=0' \
+ '-DSK_USE_POSIX_THREADS' \
+ '-DSK_BUILD_FOR_ANDROID_NDK' \
+ '-DU_USING_ICU_NAMESPACE=0' \
+ '-DFEATURE_ENABLE_SSL' \
+ '-DFEATURE_ENABLE_VOICEMAIL' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DGTEST_RELATIVE_PATH' \
+ '-DJSONCPP_RELATIVE_PATH' \
+ '-DNO_MAIN_THREAD_WRAPPING' \
+ '-DNO_SOUND_SYSTEM' \
+ '-DANDROID' \
+ '-DPOSIX' \
+ '-DPROTOBUF_USE_DLLS' \
+ '-DGOOGLE_PROTOBUF_NO_RTTI' \
+ '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH)/third_party/khronos \
+ $(LOCAL_PATH)/gpu \
+ $(gyp_shared_intermediate_dir)/content \
+ $(LOCAL_PATH)/skia/config \
+ $(LOCAL_PATH)/third_party/skia/src/core \
+ $(LOCAL_PATH)/third_party/skia/include/config \
+ $(LOCAL_PATH)/third_party/skia/include/core \
+ $(LOCAL_PATH)/third_party/skia/include/effects \
+ $(LOCAL_PATH)/third_party/skia/include/pdf \
+ $(LOCAL_PATH)/third_party/skia/include/gpu \
+ $(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
+ $(LOCAL_PATH)/third_party/skia/include/pipe \
+ $(LOCAL_PATH)/third_party/skia/include/ports \
+ $(LOCAL_PATH)/third_party/skia/include/utils \
+ $(LOCAL_PATH)/skia/ext \
+ $(LOCAL_PATH)/third_party/hyphen \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
+ $(LOCAL_PATH)/third_party/libjingle/overrides \
+ $(LOCAL_PATH)/third_party/libjingle/source \
+ $(LOCAL_PATH)/testing/gtest/include \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/expat/lib \
+ $(LOCAL_PATH)/third_party/jsoncpp/overrides/include \
+ $(LOCAL_PATH)/third_party/jsoncpp/source/include \
+ $(LOCAL_PATH)/third_party/npapi \
+ $(LOCAL_PATH)/third_party/npapi/bindings \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(LOCAL_PATH)/v8/include \
+ $(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber \
+ $(LOCAL_PATH)/third_party/libphonenumber/src \
+ $(gyp_shared_intermediate_dir)/protoc_out \
+ $(LOCAL_PATH)/third_party/protobuf \
+ $(LOCAL_PATH)/third_party/protobuf/src \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES := \
+ cpufeatures \
+ skia_skia_gyp \
+ webkit_support_glue_gyp \
+ third_party_libphonenumber_libphonenumber_without_metadata_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_renderer_gyp
+
+# Alias gyp target name.
+.PHONY: content_renderer
+content_renderer: content_content_renderer_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_renderer.target.darwin-x86.mk b/content/content_renderer.target.darwin-x86.mk
new file mode 100644
index 0000000..85d76b8
--- /dev/null
+++ b/content/content_renderer.target.darwin-x86.mk
@@ -0,0 +1,316 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_renderer_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,GYP,content_content_resources_gyp)/content_resources.stamp \
+ $(call intermediates-dir-for,GYP,jingle_jingle_glue_gyp)/jingle_glue.stamp \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a \
+ $(call intermediates-dir-for,GYP,third_party_icu_icuuc_gyp)/icuuc.stamp \
+ $(call intermediates-dir-for,GYP,third_party_icu_icui18n_gyp)/icui18n.stamp \
+ $(call intermediates-dir-for,GYP,third_party_npapi_npapi_gyp)/npapi.stamp \
+ $(call intermediates-dir-for,GYP,v8_tools_gyp_v8_gyp)/v8.stamp \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,webkit_support_glue_gyp)/webkit_support_glue_gyp.a \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,third_party_libphonenumber_libphonenumber_without_metadata_gyp)/third_party_libphonenumber_libphonenumber_without_metadata_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ content/public/renderer/android_content_detection_prefixes.cc \
+ content/public/renderer/content_renderer_client.cc \
+ content/public/renderer/document_state.cc \
+ content/public/renderer/navigation_state.cc \
+ content/public/renderer/render_process_observer.cc \
+ content/public/renderer/render_thread.cc \
+ content/public/renderer/render_view_observer.cc \
+ content/renderer/accessibility/accessibility_node_serializer.cc \
+ content/renderer/accessibility/renderer_accessibility.cc \
+ content/renderer/accessibility/renderer_accessibility_complete.cc \
+ content/renderer/accessibility/renderer_accessibility_focus_only.cc \
+ content/renderer/all_rendering_benchmarks.cc \
+ content/renderer/android/address_detector.cc \
+ content/renderer/android/content_detector.cc \
+ content/renderer/android/email_detector.cc \
+ content/renderer/android/phone_number_detector.cc \
+ content/renderer/android/synchronous_compositor_output_surface.cc \
+ content/renderer/device_orientation_dispatcher.cc \
+ content/renderer/devtools/devtools_agent.cc \
+ content/renderer/devtools/devtools_agent_filter.cc \
+ content/renderer/devtools/devtools_client.cc \
+ content/renderer/disambiguation_popup_helper.cc \
+ content/renderer/dom_automation_controller.cc \
+ content/renderer/dom_storage/dom_storage_dispatcher.cc \
+ content/renderer/dom_storage/webstoragearea_impl.cc \
+ content/renderer/dom_storage/webstoragenamespace_impl.cc \
+ content/renderer/external_popup_menu.cc \
+ content/renderer/gamepad_shared_memory_reader.cc \
+ content/renderer/geolocation_dispatcher.cc \
+ content/renderer/gpu/compositor_output_surface.cc \
+ content/renderer/gpu/compositor_software_output_device.cc \
+ content/renderer/gpu/input_event_filter.cc \
+ content/renderer/gpu/input_handler_manager.cc \
+ content/renderer/gpu/gpu_benchmarking_extension.cc \
+ content/renderer/gpu/mailbox_output_surface.cc \
+ content/renderer/gpu/stream_texture_host_android.cc \
+ content/renderer/gpu/render_widget_compositor.cc \
+ content/renderer/hyphenator/hyphenator.cc \
+ content/renderer/idle_user_detector.cc \
+ content/renderer/image_loading_helper.cc \
+ content/renderer/internal_document_state_data.cc \
+ content/renderer/java/java_bridge_channel.cc \
+ content/renderer/java/java_bridge_dispatcher.cc \
+ content/renderer/load_progress_tracker.cc \
+ content/renderer/media/audio_device_factory.cc \
+ content/renderer/media/audio_input_message_filter.cc \
+ content/renderer/media/audio_message_filter.cc \
+ content/renderer/media/audio_renderer_mixer_manager.cc \
+ content/renderer/media/pepper_platform_video_decoder_impl.cc \
+ content/renderer/media/render_media_log.cc \
+ content/renderer/media/renderer_gpu_video_decoder_factories.cc \
+ content/renderer/media/renderer_webaudiodevice_impl.cc \
+ content/renderer/media/rtc_video_renderer.cc \
+ content/renderer/media/stream_texture_factory_impl_android.cc \
+ content/renderer/media/video_capture_impl.cc \
+ content/renderer/media/video_capture_impl_manager.cc \
+ content/renderer/media/video_capture_message_filter.cc \
+ content/renderer/media/webmediaplayer_proxy_impl_android.cc \
+ content/renderer/media/webrtc_logging_handler_impl.cc \
+ content/renderer/media/webrtc_logging_message_filter.cc \
+ content/renderer/memory_benchmarking_extension.cc \
+ content/renderer/mhtml_generator.cc \
+ content/renderer/mouse_lock_dispatcher.cc \
+ content/renderer/paint_aggregator.cc \
+ content/renderer/password_form_conversion_utils.cc \
+ content/renderer/plugin_channel_host.cc \
+ content/renderer/browser_plugin/browser_plugin.cc \
+ content/renderer/browser_plugin/browser_plugin_backing_store.cc \
+ content/renderer/browser_plugin/browser_plugin_bindings.cc \
+ content/renderer/browser_plugin/browser_plugin_manager.cc \
+ content/renderer/browser_plugin/browser_plugin_manager_impl.cc \
+ content/renderer/browser_plugin/browser_plugin_compositing_helper.cc \
+ content/renderer/date_time_formatter.cc \
+ content/renderer/render_process_impl.cc \
+ content/renderer/render_thread_impl.cc \
+ content/renderer/render_view_impl.cc \
+ content/renderer/render_view_impl_android.cc \
+ content/renderer/render_view_impl_params.cc \
+ content/renderer/render_view_linux.cc \
+ content/renderer/render_view_mouse_lock_dispatcher.cc \
+ content/renderer/render_view_pepper_helper.cc \
+ content/renderer/render_widget.cc \
+ content/renderer/render_widget_fullscreen.cc \
+ content/renderer/renderer_clipboard_client.cc \
+ content/renderer/renderer_date_time_picker.cc \
+ content/renderer/renderer_main.cc \
+ content/renderer/renderer_main_platform_delegate_android.cc \
+ content/renderer/renderer_webapplicationcachehost_impl.cc \
+ content/renderer/renderer_webcookiejar_impl.cc \
+ content/renderer/renderer_webcolorchooser_impl.cc \
+ content/renderer/renderer_webkitplatformsupport_impl.cc \
+ content/renderer/rendering_benchmark.cc \
+ content/renderer/text_input_client_observer.cc \
+ content/renderer/v8_value_converter_impl.cc \
+ content/renderer/web_ui_extension.cc \
+ content/renderer/web_ui_extension_data.cc \
+ content/renderer/webplugin_delegate_proxy.cc \
+ content/renderer/websharedworker_proxy.cc \
+ content/renderer/websharedworkerrepository_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DENABLE_JAVA_BRIDGE' \
+ '-DSK_BUILD_NO_IMAGE_ENCODE' \
+ '-DSK_DEFERRED_CANVAS_USES_GPIPE=1' \
+ '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
+ '-DGR_AGGRESSIVE_SHADER_OPTS=1' \
+ '-DSK_ENABLE_INST_COUNT=0' \
+ '-DSK_USE_POSIX_THREADS' \
+ '-DSK_BUILD_FOR_ANDROID_NDK' \
+ '-DU_USING_ICU_NAMESPACE=0' \
+ '-DFEATURE_ENABLE_SSL' \
+ '-DFEATURE_ENABLE_VOICEMAIL' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DGTEST_RELATIVE_PATH' \
+ '-DJSONCPP_RELATIVE_PATH' \
+ '-DNO_MAIN_THREAD_WRAPPING' \
+ '-DNO_SOUND_SYSTEM' \
+ '-DANDROID' \
+ '-DPOSIX' \
+ '-DPROTOBUF_USE_DLLS' \
+ '-DGOOGLE_PROTOBUF_NO_RTTI' \
+ '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH)/third_party/khronos \
+ $(LOCAL_PATH)/gpu \
+ $(gyp_shared_intermediate_dir)/content \
+ $(LOCAL_PATH)/skia/config \
+ $(LOCAL_PATH)/third_party/skia/src/core \
+ $(LOCAL_PATH)/third_party/skia/include/config \
+ $(LOCAL_PATH)/third_party/skia/include/core \
+ $(LOCAL_PATH)/third_party/skia/include/effects \
+ $(LOCAL_PATH)/third_party/skia/include/pdf \
+ $(LOCAL_PATH)/third_party/skia/include/gpu \
+ $(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
+ $(LOCAL_PATH)/third_party/skia/include/pipe \
+ $(LOCAL_PATH)/third_party/skia/include/ports \
+ $(LOCAL_PATH)/third_party/skia/include/utils \
+ $(LOCAL_PATH)/skia/ext \
+ $(LOCAL_PATH)/third_party/hyphen \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
+ $(LOCAL_PATH)/third_party/libjingle/overrides \
+ $(LOCAL_PATH)/third_party/libjingle/source \
+ $(LOCAL_PATH)/testing/gtest/include \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/expat/lib \
+ $(LOCAL_PATH)/third_party/jsoncpp/overrides/include \
+ $(LOCAL_PATH)/third_party/jsoncpp/source/include \
+ $(LOCAL_PATH)/third_party/npapi \
+ $(LOCAL_PATH)/third_party/npapi/bindings \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(LOCAL_PATH)/v8/include \
+ $(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber \
+ $(LOCAL_PATH)/third_party/libphonenumber/src \
+ $(gyp_shared_intermediate_dir)/protoc_out \
+ $(LOCAL_PATH)/third_party/protobuf \
+ $(LOCAL_PATH)/third_party/protobuf/src \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES := \
+ cpufeatures \
+ skia_skia_gyp \
+ webkit_support_glue_gyp \
+ third_party_libphonenumber_libphonenumber_without_metadata_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_renderer_gyp
+
+# Alias gyp target name.
+.PHONY: content_renderer
+content_renderer: content_content_renderer_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_renderer.target.linux-arm.mk b/content/content_renderer.target.linux-arm.mk
index 24c9f4f..8755e4b 100644
--- a/content/content_renderer.target.linux-arm.mk
+++ b/content/content_renderer.target.linux-arm.mk
@@ -48,22 +48,21 @@
content/renderer/android/content_detector.cc \
content/renderer/android/email_detector.cc \
content/renderer/android/phone_number_detector.cc \
+ content/renderer/android/synchronous_compositor_output_surface.cc \
content/renderer/device_orientation_dispatcher.cc \
content/renderer/devtools/devtools_agent.cc \
content/renderer/devtools/devtools_agent_filter.cc \
content/renderer/devtools/devtools_client.cc \
content/renderer/disambiguation_popup_helper.cc \
- content/renderer/do_not_track_bindings.cc \
content/renderer/dom_automation_controller.cc \
content/renderer/dom_storage/dom_storage_dispatcher.cc \
content/renderer/dom_storage/webstoragearea_impl.cc \
content/renderer/dom_storage/webstoragenamespace_impl.cc \
content/renderer/external_popup_menu.cc \
- content/renderer/favicon_helper.cc \
content/renderer/gamepad_shared_memory_reader.cc \
content/renderer/geolocation_dispatcher.cc \
content/renderer/gpu/compositor_output_surface.cc \
- content/renderer/gpu/compositor_software_output_device_gl_adapter.cc \
+ content/renderer/gpu/compositor_software_output_device.cc \
content/renderer/gpu/input_event_filter.cc \
content/renderer/gpu/input_handler_manager.cc \
content/renderer/gpu/gpu_benchmarking_extension.cc \
@@ -72,6 +71,8 @@
content/renderer/gpu/render_widget_compositor.cc \
content/renderer/hyphenator/hyphenator.cc \
content/renderer/idle_user_detector.cc \
+ content/renderer/image_loading_helper.cc \
+ content/renderer/internal_document_state_data.cc \
content/renderer/java/java_bridge_channel.cc \
content/renderer/java/java_bridge_dispatcher.cc \
content/renderer/load_progress_tracker.cc \
@@ -79,10 +80,8 @@
content/renderer/media/audio_input_message_filter.cc \
content/renderer/media/audio_message_filter.cc \
content/renderer/media/audio_renderer_mixer_manager.cc \
- content/renderer/media/local_video_capture.cc \
content/renderer/media/pepper_platform_video_decoder_impl.cc \
content/renderer/media/render_media_log.cc \
- content/renderer/media/renderer_audio_output_device.cc \
content/renderer/media/renderer_gpu_video_decoder_factories.cc \
content/renderer/media/renderer_webaudiodevice_impl.cc \
content/renderer/media/rtc_video_renderer.cc \
@@ -91,6 +90,8 @@
content/renderer/media/video_capture_impl_manager.cc \
content/renderer/media/video_capture_message_filter.cc \
content/renderer/media/webmediaplayer_proxy_impl_android.cc \
+ content/renderer/media/webrtc_logging_handler_impl.cc \
+ content/renderer/media/webrtc_logging_message_filter.cc \
content/renderer/memory_benchmarking_extension.cc \
content/renderer/mhtml_generator.cc \
content/renderer/mouse_lock_dispatcher.cc \
@@ -169,7 +170,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -177,7 +177,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -218,9 +217,10 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
- $(LOCAL_PATH) \
$(LOCAL_PATH)/third_party/khronos \
$(LOCAL_PATH)/gpu \
$(gyp_shared_intermediate_dir)/content \
@@ -232,6 +232,7 @@
$(LOCAL_PATH)/third_party/skia/include/pdf \
$(LOCAL_PATH)/third_party/skia/include/gpu \
$(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
$(LOCAL_PATH)/third_party/skia/include/pipe \
$(LOCAL_PATH)/third_party/skia/include/ports \
$(LOCAL_PATH)/third_party/skia/include/utils \
@@ -251,7 +252,6 @@
$(LOCAL_PATH)/third_party/npapi/bindings \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
- $(gyp_shared_intermediate_dir)/webcore_headers \
$(LOCAL_PATH)/v8/include \
$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber \
$(LOCAL_PATH)/third_party/libphonenumber/src \
@@ -289,12 +289,13 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES := \
+ cpufeatures \
skia_skia_gyp \
webkit_support_glue_gyp \
third_party_libphonenumber_libphonenumber_without_metadata_gyp
diff --git a/content/content_renderer.target.linux-x86.mk b/content/content_renderer.target.linux-x86.mk
index 9374709..85d76b8 100644
--- a/content/content_renderer.target.linux-x86.mk
+++ b/content/content_renderer.target.linux-x86.mk
@@ -48,22 +48,21 @@
content/renderer/android/content_detector.cc \
content/renderer/android/email_detector.cc \
content/renderer/android/phone_number_detector.cc \
+ content/renderer/android/synchronous_compositor_output_surface.cc \
content/renderer/device_orientation_dispatcher.cc \
content/renderer/devtools/devtools_agent.cc \
content/renderer/devtools/devtools_agent_filter.cc \
content/renderer/devtools/devtools_client.cc \
content/renderer/disambiguation_popup_helper.cc \
- content/renderer/do_not_track_bindings.cc \
content/renderer/dom_automation_controller.cc \
content/renderer/dom_storage/dom_storage_dispatcher.cc \
content/renderer/dom_storage/webstoragearea_impl.cc \
content/renderer/dom_storage/webstoragenamespace_impl.cc \
content/renderer/external_popup_menu.cc \
- content/renderer/favicon_helper.cc \
content/renderer/gamepad_shared_memory_reader.cc \
content/renderer/geolocation_dispatcher.cc \
content/renderer/gpu/compositor_output_surface.cc \
- content/renderer/gpu/compositor_software_output_device_gl_adapter.cc \
+ content/renderer/gpu/compositor_software_output_device.cc \
content/renderer/gpu/input_event_filter.cc \
content/renderer/gpu/input_handler_manager.cc \
content/renderer/gpu/gpu_benchmarking_extension.cc \
@@ -72,6 +71,8 @@
content/renderer/gpu/render_widget_compositor.cc \
content/renderer/hyphenator/hyphenator.cc \
content/renderer/idle_user_detector.cc \
+ content/renderer/image_loading_helper.cc \
+ content/renderer/internal_document_state_data.cc \
content/renderer/java/java_bridge_channel.cc \
content/renderer/java/java_bridge_dispatcher.cc \
content/renderer/load_progress_tracker.cc \
@@ -79,10 +80,8 @@
content/renderer/media/audio_input_message_filter.cc \
content/renderer/media/audio_message_filter.cc \
content/renderer/media/audio_renderer_mixer_manager.cc \
- content/renderer/media/local_video_capture.cc \
content/renderer/media/pepper_platform_video_decoder_impl.cc \
content/renderer/media/render_media_log.cc \
- content/renderer/media/renderer_audio_output_device.cc \
content/renderer/media/renderer_gpu_video_decoder_factories.cc \
content/renderer/media/renderer_webaudiodevice_impl.cc \
content/renderer/media/rtc_video_renderer.cc \
@@ -91,6 +90,8 @@
content/renderer/media/video_capture_impl_manager.cc \
content/renderer/media/video_capture_message_filter.cc \
content/renderer/media/webmediaplayer_proxy_impl_android.cc \
+ content/renderer/media/webrtc_logging_handler_impl.cc \
+ content/renderer/media/webrtc_logging_message_filter.cc \
content/renderer/memory_benchmarking_extension.cc \
content/renderer/mhtml_generator.cc \
content/renderer/mouse_lock_dispatcher.cc \
@@ -149,6 +150,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -170,7 +172,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -178,7 +179,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -218,9 +218,10 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
- $(LOCAL_PATH) \
$(LOCAL_PATH)/third_party/khronos \
$(LOCAL_PATH)/gpu \
$(gyp_shared_intermediate_dir)/content \
@@ -232,6 +233,7 @@
$(LOCAL_PATH)/third_party/skia/include/pdf \
$(LOCAL_PATH)/third_party/skia/include/gpu \
$(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
$(LOCAL_PATH)/third_party/skia/include/pipe \
$(LOCAL_PATH)/third_party/skia/include/ports \
$(LOCAL_PATH)/third_party/skia/include/utils \
@@ -251,7 +253,6 @@
$(LOCAL_PATH)/third_party/npapi/bindings \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
- $(gyp_shared_intermediate_dir)/webcore_headers \
$(LOCAL_PATH)/v8/include \
$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber \
$(LOCAL_PATH)/third_party/libphonenumber/src \
@@ -282,15 +283,17 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES := \
+ cpufeatures \
skia_skia_gyp \
webkit_support_glue_gyp \
third_party_libphonenumber_libphonenumber_without_metadata_gyp
diff --git a/content/content_resources.grd b/content/content_resources.grd
index b089e23..78ec631 100644
--- a/content/content_resources.grd
+++ b/content/content_resources.grd
@@ -19,6 +19,9 @@
<include name="IDR_GPU_INTERNALS_HTML" file="browser/resources/gpu/gpu_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_GPU_INTERNALS_JS" file="browser/resources/gpu/gpu_internals.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_GPU_SWITCHING_LIST" file="browser/gpu/gpu_switching_list.json" type="BINDATA" />
+ <include name="IDR_INDEXED_DB_INTERNALS_HTML" file="browser/resources/indexed_db/indexeddb_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
+ <include name="IDR_INDEXED_DB_INTERNALS_JS" file="browser/resources/indexed_db/indexeddb_internals.js" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_INDEXED_DB_INTERNALS_CSS" file="browser/resources/indexed_db/indexeddb_internals.css" flattenhtml="true" type="BINDATA" />
<include name="IDR_MEDIA_INTERNALS_HTML" file="browser/resources/media/media_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_MEDIA_INTERNALS_JS" file="browser/resources/media/media_internals.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_WEBRTC_INTERNALS_HTML" file="browser/resources/media/webrtc_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
diff --git a/content/content_resources.target.darwin-arm.mk b/content/content_resources.target.darwin-arm.mk
new file mode 100644
index 0000000..1a70a57
--- /dev/null
+++ b/content/content_resources.target.darwin-arm.mk
@@ -0,0 +1,48 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_content_resources_gyp
+LOCAL_MODULE_STEM := content_resources
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,GYP,content_generate_content_resources_gyp)/generate_content_resources.stamp
+
+### Generated for copy rule.
+$(gyp_shared_intermediate_dir)/content_resources.pak: $(gyp_shared_intermediate_dir)/content/content_resources.pak $(GYP_TARGET_DEPENDENCIES) | $(ACP)
+ @echo Copying: $@
+ $(hide) mkdir -p $(dir $@)
+ $(hide) $(ACP) -r $< $@
+
+content_content_resources_gyp_content_resources_target_copies = $(gyp_shared_intermediate_dir)/content_resources.pak
+
+GYP_GENERATED_OUTPUTS := \
+ $(content_content_resources_gyp_content_resources_target_copies)
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_resources_gyp
+
+# Alias gyp target name.
+.PHONY: content_resources
+content_resources: content_content_resources_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/content_resources.target.darwin-x86.mk b/content/content_resources.target.darwin-x86.mk
new file mode 100644
index 0000000..1a70a57
--- /dev/null
+++ b/content/content_resources.target.darwin-x86.mk
@@ -0,0 +1,48 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_content_resources_gyp
+LOCAL_MODULE_STEM := content_resources
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,GYP,content_generate_content_resources_gyp)/generate_content_resources.stamp
+
+### Generated for copy rule.
+$(gyp_shared_intermediate_dir)/content_resources.pak: $(gyp_shared_intermediate_dir)/content/content_resources.pak $(GYP_TARGET_DEPENDENCIES) | $(ACP)
+ @echo Copying: $@
+ $(hide) mkdir -p $(dir $@)
+ $(hide) $(ACP) -r $< $@
+
+content_content_resources_gyp_content_resources_target_copies = $(gyp_shared_intermediate_dir)/content_resources.pak
+
+GYP_GENERATED_OUTPUTS := \
+ $(content_content_resources_gyp_content_resources_target_copies)
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_resources_gyp
+
+# Alias gyp target name.
+.PHONY: content_resources
+content_resources: content_content_resources_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/content_shell.gypi b/content/content_shell.gypi
index 5713513..1bf233b 100644
--- a/content/content_shell.gypi
+++ b/content/content_shell.gypi
@@ -68,8 +68,16 @@
'shell/geolocation/shell_access_token_store.h',
'shell/minimal_ash.cc',
'shell/minimal_ash.h',
+ 'shell/notify_done_forwarder.cc',
+ 'shell/notify_done_forwarder.h',
'shell/paths_mac.h',
'shell/paths_mac.mm',
+ 'shell/renderer/shell_content_renderer_client.cc',
+ 'shell/renderer/shell_content_renderer_client.h',
+ 'shell/renderer/shell_render_process_observer.cc',
+ 'shell/renderer/shell_render_process_observer.h',
+ 'shell/renderer/webkit_test_runner.cc',
+ 'shell/renderer/webkit_test_runner.h',
'shell/shell.cc',
'shell/shell.h',
'shell/shell_android.cc',
@@ -90,8 +98,6 @@
'shell/shell_content_browser_client.h',
'shell/shell_content_client.cc',
'shell/shell_content_client.h',
- 'shell/shell_content_renderer_client.cc',
- 'shell/shell_content_renderer_client.h',
'shell/shell_devtools_delegate.cc',
'shell/shell_devtools_delegate.h',
'shell/shell_devtools_frontend.cc',
@@ -118,8 +124,6 @@
'shell/shell_network_delegate.h',
'shell/shell_quota_permission_context.cc',
'shell/shell_quota_permission_context.h',
- 'shell/shell_render_process_observer.cc',
- 'shell/shell_render_process_observer.h',
'shell/shell_resource_dispatcher_host_delegate.cc',
'shell/shell_resource_dispatcher_host_delegate.h',
'shell/shell_switches.cc',
@@ -143,8 +147,6 @@
'shell/webkit_test_platform_support_linux.cc',
'shell/webkit_test_platform_support_mac.mm',
'shell/webkit_test_platform_support_win.cc',
- 'shell/webkit_test_runner.cc',
- 'shell/webkit_test_runner.h',
],
'msvs_settings': {
'VCLinkerTool': {
@@ -490,6 +492,23 @@
],
},
],
+ 'conditions': [
+ ['enable_webrtc==1', {
+ 'variables': {
+ 'libpeer_target_type%': 'static_library',
+ },
+ 'conditions': [
+ ['libpeer_target_type!="static_library"', {
+ 'copies': [{
+ 'destination': '<(PRODUCT_DIR)/$(CONTENTS_FOLDER_PATH)/Libraries',
+ 'files': [
+ '<(PRODUCT_DIR)/libpeerconnection.so',
+ ],
+ }],
+ }],
+ ],
+ }],
+ ],
}, # target content_shell_framework
{
'target_name': 'content_shell_helper_app',
@@ -642,24 +661,7 @@
'dependencies': [
'content_shell_apk',
],
- # This all_dependent_settings is used for java targets only. This will
- # add the content_shell jar to the classpath of dependent java
- # targets.
- 'all_dependent_settings': {
- 'variables': {
- 'input_jars_paths': ['>(apk_output_jar_path)'],
- },
- },
- # Add an action with the appropriate output. This allows the generated
- # buildfiles to determine which target the output corresponds to.
- 'actions': [
- {
- 'action_name': 'fake_generate_jar',
- 'inputs': [],
- 'outputs': ['>(apk_output_jar_path)'],
- 'action': [],
- },
- ],
+ 'includes': [ '../build/apk_fake_jar.gypi' ],
},
{
'target_name': 'content_shell_apk',
@@ -677,8 +679,8 @@
'apk_name': 'ContentShell',
'manifest_package_name': 'org.chromium.content_shell_apk',
'java_in_dir': 'shell/android/shell_apk',
- 'resource_dir': 'res',
- 'native_libs_paths': ['<(SHARED_LIB_DIR)/libcontent_shell_content_view.so'],
+ 'resource_dir': 'shell/android/shell_apk/res',
+ 'native_lib_target': 'libcontent_shell_content_view',
'additional_input_paths': ['<(PRODUCT_DIR)/content_shell/assets/content_shell.pak'],
'asset_location': '<(ant_build_out)/content_shell/assets',
},
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index cd362a5..7818c55 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -139,8 +139,6 @@
# test support target.
'../webkit/appcache/appcache_test_helper.cc',
'../webkit/appcache/appcache_test_helper.h',
- '../webkit/quota/mock_special_storage_policy.cc',
- '../webkit/quota/mock_special_storage_policy.h',
],
'conditions': [
['OS == "ios"', {
@@ -190,6 +188,8 @@
'renderer/media/mock_media_stream_dependency_factory.h',
'renderer/media/mock_media_stream_dispatcher.cc',
'renderer/media/mock_media_stream_dispatcher.h',
+ 'renderer/media/mock_media_stream_registry.cc',
+ 'renderer/media/mock_media_stream_registry.h',
'renderer/media/mock_peer_connection_impl.cc',
'renderer/media/mock_peer_connection_impl.h',
'renderer/media/mock_web_rtc_peer_connection_handler_client.cc',
@@ -289,23 +289,31 @@
'browser/geolocation/win7_location_api_unittest_win.cc',
'browser/geolocation/win7_location_provider_unittest_win.cc',
'browser/gpu/gpu_blacklist_unittest.cc',
+ 'browser/gpu/gpu_control_list_entry_unittest.cc',
+ 'browser/gpu/gpu_control_list_machine_model_info_unittest.cc',
+ 'browser/gpu/gpu_control_list_number_info_unittest.cc',
+ 'browser/gpu/gpu_control_list_os_info_unittest.cc',
+ 'browser/gpu/gpu_control_list_string_info_unittest.cc',
'browser/gpu/gpu_control_list_unittest.cc',
+ 'browser/gpu/gpu_control_list_version_info_unittest.cc',
'browser/gpu/gpu_data_manager_impl_unittest.cc',
'browser/gpu/gpu_driver_bug_list_unittest.cc',
'browser/gpu/gpu_switching_list_unittest.cc',
'browser/gpu/gpu_util_unittest.cc',
+ 'browser/gpu/shader_disk_cache_unittest.cc',
'browser/host_zoom_map_impl_unittest.cc',
'browser/hyphenator/hyphenator_message_filter_unittest.cc',
- 'browser/in_process_webkit/indexed_db_quota_client_unittest.cc',
- 'browser/in_process_webkit/indexed_db_unittest.cc',
'browser/in_process_webkit/webkit_thread_unittest.cc',
+ 'browser/indexed_db/indexed_db_unittest.cc',
+ 'browser/indexed_db/indexed_db_quota_client_unittest.cc',
+ 'browser/loader/offline_policy_unittest.cc',
'browser/loader/resource_buffer_unittest.cc',
'browser/loader/resource_dispatcher_host_unittest.cc',
'browser/loader/resource_loader_unittest.cc',
'browser/loader/resource_scheduler_unittest.cc',
'browser/mach_broker_mac_unittest.cc',
'browser/media/media_internals_unittest.cc',
- 'browser/media/webrtc_internals_unittest.cc',
+ 'browser/net/sqlite_persistent_cookie_store_unittest.cc',
'browser/notification_service_impl_unittest.cc',
'browser/plugin_loader_posix_unittest.cc',
'browser/renderer_host/compositing_iosurface_transformer_mac_unittest.cc',
@@ -332,6 +340,7 @@
'browser/renderer_host/render_widget_host_view_guest_unittest.cc',
'browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm',
'browser/renderer_host/render_widget_host_view_mac_unittest.mm',
+ 'browser/renderer_host/smooth_scroll_gesture_controller_unittest.cc',
'browser/renderer_host/text_input_client_mac_unittest.mm',
'browser/renderer_host/web_input_event_aura_unittest.cc',
'browser/resolve_proxy_msg_helper_unittest.cc',
@@ -342,6 +351,7 @@
'browser/speech/google_streaming_remote_engine_unittest.cc',
'browser/speech/speech_recognizer_unittest.cc',
'browser/ssl/ssl_host_state_unittest.cc',
+ 'browser/storage_partition_impl_unittest.cc',
'browser/storage_partition_impl_map_unittest.cc',
'browser/streams/stream_unittest.cc',
'browser/streams/stream_url_request_job_unittest.cc',
@@ -365,11 +375,11 @@
'common/mac/font_descriptor_unittest.mm',
'common/gpu/gpu_info_unittest.cc',
'common/gpu/gpu_memory_manager_unittest.cc',
- 'common/gpu/media/avc_config_record_builder_unittest.cc',
'common/indexed_db/indexed_db_dispatcher_unittest.cc',
'common/indexed_db/proxy_webidbcursor_impl_unittest.cc',
'common/inter_process_time_ticks_converter_unittest.cc',
'common/page_zoom_unittest.cc',
+ 'common/partial_circular_buffer_unittest.cc',
'common/resource_dispatcher_unittest.cc',
'common/sandbox_mac_diraccess_unittest.mm',
'common/sandbox_mac_fontloading_unittest.mm',
@@ -420,6 +430,7 @@
'../webkit/appcache/mock_appcache_storage.cc',
'../webkit/appcache/mock_appcache_storage.h',
'../webkit/appcache/mock_appcache_storage_unittest.cc',
+ '../webkit/blob/blob_storage_context_unittest.cc',
'../webkit/blob/blob_storage_controller_unittest.cc',
'../webkit/blob/blob_url_request_job_unittest.cc',
'../webkit/blob/local_file_stream_reader_unittest.cc',
@@ -427,6 +438,7 @@
'../webkit/blob/mock_blob_url_request_context.h',
'../webkit/blob/shareable_file_reference_unittest.cc',
'../webkit/chromeos/fileapi/cros_mount_point_provider_unittest.cc',
+ '../webkit/chromeos/fileapi/file_access_permissions_unittest.cc',
'../webkit/database/database_connections_unittest.cc',
'../webkit/database/database_quota_client_unittest.cc',
'../webkit/database/databases_table_unittest.cc',
@@ -440,6 +452,7 @@
'../webkit/dom_storage/session_storage_database_unittest.cc',
'../webkit/fileapi/async_file_test_helper.cc',
'../webkit/fileapi/async_file_test_helper.h',
+ '../webkit/fileapi/copy_or_move_file_validator_unittest.cc',
'../webkit/fileapi/external_mount_points_unittest.cc',
'../webkit/fileapi/file_system_context_unittest.cc',
'../webkit/fileapi/file_system_database_test_helper.cc',
@@ -465,7 +478,6 @@
'../webkit/fileapi/local_file_system_test_helper.h',
'../webkit/fileapi/local_file_stream_writer_unittest.cc',
'../webkit/fileapi/local_file_util_unittest.cc',
- '../webkit/fileapi/media/native_media_file_util_unittest.cc',
'../webkit/fileapi/mock_file_change_observer.cc',
'../webkit/fileapi/mock_file_change_observer.h',
'../webkit/fileapi/native_file_util_unittest.cc',
@@ -486,7 +498,6 @@
'../webkit/fileapi/webfilewriter_base_unittest.cc',
'../webkit/glue/cpp_variant_unittest.cc',
'../webkit/glue/glue_serialize_unittest.cc',
- '../webkit/glue/regular_expression_unittest.cc',
'../webkit/glue/resource_request_body_unittest.cc',
'../webkit/glue/multipart_response_delegate_unittest.cc',
'../webkit/glue/touch_fling_gesture_curve_unittest.cc',
@@ -499,12 +510,23 @@
'../webkit/media/crypto/key_systems_unittest.cc',
'../webkit/media/test_response_generator.cc',
'../webkit/media/test_response_generator.h',
+ '../webkit/media/webaudiosourceprovider_impl_unittest.cc',
'../webkit/mocks/mock_weburlloader.cc',
'../webkit/mocks/mock_weburlloader.h',
'../webkit/plugins/npapi/plugin_lib_unittest.cc',
'../webkit/plugins/npapi/plugin_list_unittest.cc',
'../webkit/plugins/npapi/plugin_utils_unittest.cc',
'../webkit/plugins/npapi/webplugin_impl_unittest.cc',
+ '../webkit/plugins/ppapi/host_var_tracker_unittest.cc',
+ '../webkit/plugins/ppapi/mock_platform_image_2d.cc',
+ '../webkit/plugins/ppapi/mock_platform_image_2d.h',
+ '../webkit/plugins/ppapi/mock_plugin_delegate.cc',
+ '../webkit/plugins/ppapi/mock_plugin_delegate.h',
+ '../webkit/plugins/ppapi/mock_resource.h',
+ '../webkit/plugins/ppapi/ppapi_plugin_instance_unittest.cc',
+ '../webkit/plugins/ppapi/ppapi_unittest.cc',
+ '../webkit/plugins/ppapi/ppapi_unittest.h',
+ '../webkit/plugins/ppapi/quota_file_io_unittest.cc',
'../webkit/quota/mock_quota_manager.cc',
'../webkit/quota/mock_quota_manager.h',
'../webkit/quota/mock_quota_manager_unittest.cc',
@@ -513,6 +535,8 @@
'../webkit/quota/quota_database_unittest.cc',
'../webkit/quota/quota_manager_unittest.cc',
'../webkit/quota/quota_temporary_storage_evictor_unittest.cc',
+ '../webkit/quota/usage_tracker_unittest.cc',
+ '../webkit/user_agent/user_agent_unittest.cc',
],
'conditions': [
['OS == "ios"', {
@@ -564,6 +588,7 @@
}],
['enable_webrtc==1', {
'sources': [
+ 'browser/media/webrtc_internals_unittest.cc',
'browser/renderer_host/p2p/socket_host_test_utils.h',
'browser/renderer_host/p2p/socket_host_tcp_unittest.cc',
'browser/renderer_host/p2p/socket_host_tcp_server_unittest.cc',
@@ -572,7 +597,10 @@
'renderer/media/media_stream_dispatcher_unittest.cc',
'renderer/media/media_stream_impl_unittest.cc',
'renderer/media/rtc_peer_connection_handler_unittest.cc',
+ 'renderer/media/video_destination_handler_unittest.cc',
+ 'renderer/media/video_source_handler_unittest.cc',
'renderer/media/webrtc_audio_device_unittest.cc',
+ 'renderer/media/webrtc_local_audio_track_unittest.cc',
],
'dependencies': [
'../third_party/libjingle/libjingle.gyp:libjingle_webrtc',
@@ -634,7 +662,19 @@
'browser/accessibility/browser_accessibility_win_unittest.cc',
],
}],
+ ['use_aura==1 and OS=="linux"', {
+ 'sources!': [
+ # http://crbug.com/234172: these tests depend on single process
+ # mode, which doesn't work in content_browsertests on Linux Aura.
+ 'renderer/dom_operations_browsertest.cc',
+ 'renderer/dom_serializer_browsertest.cc',
+ 'renderer/resource_fetcher_browsertest.cc',
+ ],
+ }],
['OS == "android"', {
+ 'dependencies': [
+ '../ui/ui.gyp:shell_dialogs',
+ ],
'sources!': [
'browser/geolocation/device_data_provider_unittest.cc',
'browser/geolocation/gps_location_provider_unittest_linux.cc',
@@ -685,6 +725,7 @@
'../testing/gmock.gyp:gmock',
'../testing/gtest.gyp:gtest',
'../third_party/mesa/mesa.gyp:osmesa',
+ '../third_party/widevine/cdm/widevine_cdm.gyp:widevine_cdm_version_h',
'../ui/gl/gl.gyp:gl',
'../ui/snapshot/snapshot.gyp:snapshot',
'../ui/ui.gyp:shell_dialogs',
@@ -695,6 +736,7 @@
],
'include_dirs': [
'..',
+ '<(SHARED_INTERMEDIATE_DIR)', # Needed by encrypted_media_browsertest.cc
],
'includes': [
'browser/gpu/test_support_gpu.gypi',
@@ -726,12 +768,13 @@
'browser/fileapi/blob_layout_browsertest.cc',
'browser/fileapi/file_system_browsertest.cc',
'browser/gpu/gpu_crash_browsertest.cc',
+ 'browser/gpu/gpu_functional_browsertest.cc',
'browser/gpu/gpu_memory_test.cc',
'browser/gpu/gpu_pixel_browsertest.cc',
'browser/gpu/webgl_conformance_test.cc',
'browser/gpu/webgl_conformance_test_list_autogen.h',
'browser/in_process_webkit/indexed_db_browsertest.cc',
- 'browser/in_process_webkit/indexed_db_layout_browsertest.cc',
+ 'browser/indexed_db/indexed_db_layout_browsertest.cc',
'browser/loader/resource_dispatcher_host_browsertest.cc',
'browser/media/audio_browsertest.cc',
'browser/media/encrypted_media_browsertest.cc',
@@ -743,17 +786,18 @@
'browser/renderer_host/clipboard_browsertest.cc',
'browser/renderer_host/render_view_host_browsertest.cc',
'browser/renderer_host/render_view_host_manager_browsertest.cc',
+ 'browser/renderer_host/render_widget_host_browsertest.cc',
'browser/renderer_host/render_widget_host_view_browsertest.cc',
'browser/renderer_host/render_widget_host_view_win_browsertest.cc',
'browser/security_exploit_browsertest.cc',
'browser/session_history_browsertest.cc',
'browser/site_per_process_browsertest.cc',
'browser/speech/speech_recognition_browsertest.cc',
+ 'browser/web_contents/touch_editable_impl_aura_browsertest.cc',
+ 'browser/web_contents/web_contents_impl_browsertest.cc',
'browser/web_contents/web_contents_view_aura_browsertest.cc',
'browser/webkit_browsertest.cc',
'browser/worker_host/test/worker_browsertest.cc',
- 'common/content_constants_internal.cc',
- 'common/content_constants_internal.h',
'renderer/accessibility/renderer_accessibility_browsertest.cc',
'renderer/browser_plugin/mock_browser_plugin.h',
'renderer/browser_plugin/mock_browser_plugin.cc',
@@ -761,6 +805,9 @@
'renderer/browser_plugin/mock_browser_plugin_manager.cc',
'renderer/browser_plugin/browser_plugin_browsertest.h',
'renderer/browser_plugin/browser_plugin_browsertest.cc',
+ 'renderer/cpp_bound_class_unittest.cc',
+ 'renderer/dom_operations_browsertest.cc',
+ 'renderer/dom_serializer_browsertest.cc',
'renderer/mouse_lock_dispatcher_browsertest.cc',
'renderer/password_form_conversion_utils_browsertest.cc',
'renderer/pepper/mock_renderer_ppapi_host.cc',
@@ -768,9 +815,11 @@
'renderer/pepper/pepper_file_chooser_host_unittest.cc',
'renderer/pepper/pepper_graphics_2d_host_unittest.cc',
'renderer/pepper/pepper_url_request_unittest.cc',
+ 'renderer/render_thread_impl_browsertest.cc',
'renderer/render_view_browsertest.cc',
'renderer/render_view_browsertest_mac.mm',
'renderer/render_widget_browsertest.cc',
+ 'renderer/resource_fetcher_browsertest.cc',
'test/browser_test_message_pump_android.cc',
'test/browser_test_message_pump_android.h',
'test/content_browser_test.h',
@@ -784,12 +833,19 @@
'test/layout_browsertest.h',
'test/layout_test_http_server.cc',
'test/layout_test_http_server.h',
+ '../webkit/glue/cpp_binding_example.cc',
+ '../webkit/glue/cpp_binding_example.h',
'../webkit/plugins/ppapi/mock_platform_image_2d.cc',
'../webkit/plugins/ppapi/mock_platform_image_2d.h',
'../webkit/plugins/ppapi/mock_plugin_delegate.cc',
'../webkit/plugins/ppapi/mock_plugin_delegate.h',
],
'conditions': [
+ ['chromeos==0', {
+ 'sources!': [
+ 'browser/web_contents/touch_editable_impl_aura_browsertest.cc',
+ ],
+ }],
['OS=="win"', {
'resource_include_dirs': [
'<(SHARED_INTERMEDIATE_DIR)/webkit',
@@ -843,11 +899,6 @@
['OS=="android"', {
'sources!': [
'browser/accessibility/dump_accessibility_tree_browsertest.cc',
- # These are included via dependency on content_common and hence
- # we get multiple definition errors in a shared library build.
- # Other builds need it as the symbols are not exported.
- 'common/content_constants_internal.cc',
- 'common/content_constants_internal.h',
],
'sources': [
'shell/android/browsertests_apk/content_browser_tests_android.cc',
@@ -904,7 +955,7 @@
},
],
}],
- ['chromeos==1 or OS=="win" or OS=="mac"', {
+ ['chromeos==1 or OS=="win"', {
# TODO(felipeg): Make video_decode_accelerator_unittest work on Android.
# http://crbug.com/178647
'targets': [
@@ -924,7 +975,6 @@
],
'sources': [
'common/gpu/media/rendering_helper.h',
- 'common/gpu/media/rendering_helper_mac.mm',
'common/gpu/media/rendering_helper_gl.cc',
'common/gpu/media/video_decode_accelerator_unittest.cc',
],
@@ -934,11 +984,6 @@
'<(DEPTH)/third_party/openmax/il',
],
}],
- ['OS=="mac"', {
- 'sources!': [
- 'common/gpu/media/rendering_helper_gl.cc',
- ],
- }],
['OS=="win"', {
'dependencies': [
'../third_party/angle/src/build_angle.gyp:libEGL',
@@ -946,7 +991,7 @@
],
}],
['(OS=="win" and win_use_allocator_shim==1) or '
- '(os_posix == 1 and OS != "mac" and OS != "android" and '
+ '(os_posix == 1 and OS != "android" and '
' linux_use_tcmalloc==1)', {
'dependencies': [
'../base/allocator/allocator.gyp:allocator',
@@ -1016,8 +1061,8 @@
'variables': {
'apk_name': 'content_browsertests',
'java_in_dir': 'shell/android/browsertests_apk',
- 'resource_dir': 'res',
- 'native_libs_paths': ['<(SHARED_LIB_DIR)/<(SHARED_LIB_PREFIX)content_browsertests<(SHARED_LIB_SUFFIX)'],
+ 'resource_dir': 'shell/android/browsertests_apk/res',
+ 'native_lib_target': 'libcontent_browsertests',
'additional_input_paths': ['<(PRODUCT_DIR)/content_shell/assets/content_shell.pak'],
'asset_location': '<(ant_build_out)/content_shell/assets',
},
@@ -1059,9 +1104,9 @@
],
'variables': {
'apk_name': 'ContentShellTest',
- 'java_in_dir': '../content/shell/android/javatests',
- 'additional_src_dirs': ['../content/public/android/javatests/',],
- 'resource_dir': '../shell_apk/res',
+ 'java_in_dir': 'shell/android/javatests',
+ 'resource_dir': 'shell/android/shell_apk/res',
+ 'additional_src_dirs': ['public/android/javatests/',],
'is_test_apk': 1,
},
'includes': [ '../build/java_apk.gypi' ],
diff --git a/content/content_unittests.isolate b/content/content_unittests.isolate
index 0038388..efcd163 100644
--- a/content/content_unittests.isolate
+++ b/content/content_unittests.isolate
@@ -2,19 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
{
- 'variables': {
- 'isolate_dependency_tracked': [
- '<(PRODUCT_DIR)/content_unittests<(EXECUTABLE_SUFFIX)',
- ],
- 'isolate_dependency_untracked': [
- 'browser/gpu/gpu_driver_bug_list.json',
- 'browser/gpu/gpu_switching_list.json',
- 'browser/gpu/software_rendering_list.json',
- 'test/data/',
- '../third_party/hyphen/hyph_en_US.dic',
- '../webkit/data/',
- ],
- },
'conditions': [
['OS=="linux"', {
'variables': {
@@ -29,13 +16,20 @@
'<(PRODUCT_DIR)/test_data/',
],
},
- }, {
+ }],
+ ['OS=="linux" or OS=="mac" or OS=="win"', {
'variables': {
- 'command': [
- '../testing/test_env.py',
- '../tools/swarm_client/run_test_cases.py',
+ 'isolate_dependency_tracked': [
'<(PRODUCT_DIR)/content_unittests<(EXECUTABLE_SUFFIX)',
],
+ 'isolate_dependency_untracked': [
+ '../third_party/hyphen/hyph_en_US.dic',
+ '../webkit/data/',
+ 'browser/gpu/gpu_driver_bug_list.json',
+ 'browser/gpu/gpu_switching_list.json',
+ 'browser/gpu/software_rendering_list.json',
+ 'test/data/',
+ ],
},
}],
['OS=="mac"', {
@@ -46,6 +40,15 @@
],
},
}],
+ ['OS=="mac" or OS=="win"', {
+ 'variables': {
+ 'command': [
+ '../testing/test_env.py',
+ '../tools/swarm_client/run_test_cases.py',
+ '<(PRODUCT_DIR)/content_unittests<(EXECUTABLE_SUFFIX)',
+ ],
+ },
+ }],
['OS=="win"', {
'variables': {
'isolate_dependency_untracked': [
diff --git a/content/content_utility.target.darwin-arm.mk b/content/content_utility.target.darwin-arm.mk
new file mode 100644
index 0000000..d67b4a3
--- /dev/null
+++ b/content/content_utility.target.darwin-arm.mk
@@ -0,0 +1,154 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_utility_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ content/public/utility/content_utility_client.cc \
+ content/public/utility/utility_thread.cc \
+ content/utility/utility_main.cc \
+ content/utility/utility_thread_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH)/third_party/khronos \
+ $(LOCAL_PATH)/gpu \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_utility_gyp
+
+# Alias gyp target name.
+.PHONY: content_utility
+content_utility: content_content_utility_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_utility.target.darwin-x86.mk b/content/content_utility.target.darwin-x86.mk
new file mode 100644
index 0000000..837f0a1
--- /dev/null
+++ b/content/content_utility.target.darwin-x86.mk
@@ -0,0 +1,153 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_utility_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ content/public/utility/content_utility_client.cc \
+ content/public/utility/utility_thread.cc \
+ content/utility/utility_main.cc \
+ content/utility/utility_thread_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH)/third_party/khronos \
+ $(LOCAL_PATH)/gpu \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_utility_gyp
+
+# Alias gyp target name.
+.PHONY: content_utility
+content_utility: content_content_utility_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_utility.target.linux-arm.mk b/content/content_utility.target.linux-arm.mk
index 4214e6c..d67b4a3 100644
--- a/content/content_utility.target.linux-arm.mk
+++ b/content/content_utility.target.linux-arm.mk
@@ -66,7 +66,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -74,7 +73,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -94,9 +92,10 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
- $(LOCAL_PATH) \
$(LOCAL_PATH)/third_party/khronos \
$(LOCAL_PATH)/gpu \
$(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
@@ -130,9 +129,9 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/content/content_utility.target.linux-x86.mk b/content/content_utility.target.linux-x86.mk
index ea7ccbf..837f0a1 100644
--- a/content/content_utility.target.linux-x86.mk
+++ b/content/content_utility.target.linux-x86.mk
@@ -46,6 +46,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -67,7 +68,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -75,7 +75,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -95,9 +94,10 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
- $(LOCAL_PATH) \
$(LOCAL_PATH)/third_party/khronos \
$(LOCAL_PATH)/gpu \
$(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
@@ -124,12 +124,13 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES :=
diff --git a/content/content_worker.target.darwin-arm.mk b/content/content_worker.target.darwin-arm.mk
new file mode 100644
index 0000000..a5a8386
--- /dev/null
+++ b/content/content_worker.target.darwin-arm.mk
@@ -0,0 +1,187 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_worker_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ content/worker/shared_worker_devtools_agent.cc \
+ content/worker/websharedworker_stub.cc \
+ content/worker/websharedworkerclient_proxy.cc \
+ content/worker/worker_main.cc \
+ content/worker/worker_thread.cc \
+ content/worker/worker_webapplicationcachehost_impl.cc \
+ content/worker/worker_webkitplatformsupport_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DSK_BUILD_NO_IMAGE_ENCODE' \
+ '-DSK_DEFERRED_CANVAS_USES_GPIPE=1' \
+ '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
+ '-DGR_AGGRESSIVE_SHADER_OPTS=1' \
+ '-DSK_ENABLE_INST_COUNT=0' \
+ '-DSK_USE_POSIX_THREADS' \
+ '-DSK_BUILD_FOR_ANDROID_NDK' \
+ '-DU_USING_ICU_NAMESPACE=0' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH)/third_party/khronos \
+ $(LOCAL_PATH)/gpu \
+ $(LOCAL_PATH)/skia/config \
+ $(LOCAL_PATH)/third_party/skia/src/core \
+ $(LOCAL_PATH)/third_party/skia/include/config \
+ $(LOCAL_PATH)/third_party/skia/include/core \
+ $(LOCAL_PATH)/third_party/skia/include/effects \
+ $(LOCAL_PATH)/third_party/skia/include/pdf \
+ $(LOCAL_PATH)/third_party/skia/include/gpu \
+ $(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
+ $(LOCAL_PATH)/third_party/skia/include/pipe \
+ $(LOCAL_PATH)/third_party/skia/include/ports \
+ $(LOCAL_PATH)/third_party/skia/include/utils \
+ $(LOCAL_PATH)/skia/ext \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
+ $(LOCAL_PATH)/third_party/npapi \
+ $(LOCAL_PATH)/third_party/npapi/bindings \
+ $(LOCAL_PATH)/v8/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--icf=safe \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES := \
+ skia_skia_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_worker_gyp
+
+# Alias gyp target name.
+.PHONY: content_worker
+content_worker: content_content_worker_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_worker.target.darwin-x86.mk b/content/content_worker.target.darwin-x86.mk
new file mode 100644
index 0000000..e1389e2
--- /dev/null
+++ b/content/content_worker.target.darwin-x86.mk
@@ -0,0 +1,186 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := content_content_worker_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_gyp)/skia_skia_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ content/worker/shared_worker_devtools_agent.cc \
+ content/worker/websharedworker_stub.cc \
+ content/worker/websharedworkerclient_proxy.cc \
+ content/worker/worker_main.cc \
+ content/worker/worker_thread.cc \
+ content/worker/worker_webapplicationcachehost_impl.cc \
+ content/worker/worker_webkitplatformsupport_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-DSK_BUILD_NO_IMAGE_ENCODE' \
+ '-DSK_DEFERRED_CANVAS_USES_GPIPE=1' \
+ '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
+ '-DGR_AGGRESSIVE_SHADER_OPTS=1' \
+ '-DSK_ENABLE_INST_COUNT=0' \
+ '-DSK_USE_POSIX_THREADS' \
+ '-DSK_BUILD_FOR_ANDROID_NDK' \
+ '-DU_USING_ICU_NAMESPACE=0' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+ $(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+ $(LOCAL_PATH)/third_party/khronos \
+ $(LOCAL_PATH)/gpu \
+ $(LOCAL_PATH)/skia/config \
+ $(LOCAL_PATH)/third_party/skia/src/core \
+ $(LOCAL_PATH)/third_party/skia/include/config \
+ $(LOCAL_PATH)/third_party/skia/include/core \
+ $(LOCAL_PATH)/third_party/skia/include/effects \
+ $(LOCAL_PATH)/third_party/skia/include/pdf \
+ $(LOCAL_PATH)/third_party/skia/include/gpu \
+ $(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
+ $(LOCAL_PATH)/third_party/skia/include/pipe \
+ $(LOCAL_PATH)/third_party/skia/include/ports \
+ $(LOCAL_PATH)/third_party/skia/include/utils \
+ $(LOCAL_PATH)/skia/ext \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
+ $(LOCAL_PATH)/third_party/npapi \
+ $(LOCAL_PATH)/third_party/npapi/bindings \
+ $(LOCAL_PATH)/v8/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+
+LOCAL_LDFLAGS := \
+ -Wl,-z,now \
+ -Wl,-z,relro \
+ -Wl,-z,noexecstack \
+ -fPIC \
+ -m32 \
+ -fuse-ld=gold \
+ -nostdlib \
+ -Wl,--no-undefined \
+ -Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
+ -Wl,-O1 \
+ -Wl,--as-needed
+
+
+LOCAL_STATIC_LIBRARIES := \
+ skia_skia_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+ libstlport \
+ libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_content_worker_gyp
+
+# Alias gyp target name.
+.PHONY: content_worker
+content_worker: content_content_worker_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/content/content_worker.target.linux-arm.mk b/content/content_worker.target.linux-arm.mk
index 7142e39..a5a8386 100644
--- a/content/content_worker.target.linux-arm.mk
+++ b/content/content_worker.target.linux-arm.mk
@@ -70,7 +70,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -78,7 +77,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -106,9 +104,10 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
- $(LOCAL_PATH) \
$(LOCAL_PATH)/third_party/khronos \
$(LOCAL_PATH)/gpu \
$(LOCAL_PATH)/skia/config \
@@ -119,13 +118,13 @@
$(LOCAL_PATH)/third_party/skia/include/pdf \
$(LOCAL_PATH)/third_party/skia/include/gpu \
$(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
$(LOCAL_PATH)/third_party/skia/include/pipe \
$(LOCAL_PATH)/third_party/skia/include/ports \
$(LOCAL_PATH)/third_party/skia/include/utils \
$(LOCAL_PATH)/skia/ext \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
- $(gyp_shared_intermediate_dir)/webcore_headers \
$(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
$(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
$(LOCAL_PATH)/third_party/npapi \
@@ -162,9 +161,9 @@
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
-Wl,--icf=safe \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES := \
diff --git a/content/content_worker.target.linux-x86.mk b/content/content_worker.target.linux-x86.mk
index dcfa778..e1389e2 100644
--- a/content/content_worker.target.linux-x86.mk
+++ b/content/content_worker.target.linux-x86.mk
@@ -50,6 +50,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -71,7 +72,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -79,7 +79,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -107,9 +106,10 @@
# Include paths placed before CFLAGS/CPPFLAGS
LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
- $(LOCAL_PATH) \
$(LOCAL_PATH)/third_party/khronos \
$(LOCAL_PATH)/gpu \
$(LOCAL_PATH)/skia/config \
@@ -120,13 +120,13 @@
$(LOCAL_PATH)/third_party/skia/include/pdf \
$(LOCAL_PATH)/third_party/skia/include/gpu \
$(LOCAL_PATH)/third_party/skia/include/gpu/gl \
+ $(LOCAL_PATH)/third_party/skia/include/pathops \
$(LOCAL_PATH)/third_party/skia/include/pipe \
$(LOCAL_PATH)/third_party/skia/include/ports \
$(LOCAL_PATH)/third_party/skia/include/utils \
$(LOCAL_PATH)/skia/ext \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
$(LOCAL_PATH)/third_party/WebKit/Source/Platform/chromium \
- $(gyp_shared_intermediate_dir)/webcore_headers \
$(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/common \
$(GYP_ABS_ANDROID_TOP_DIR)/external/icu4c/i18n \
$(LOCAL_PATH)/third_party/npapi \
@@ -156,12 +156,13 @@
-Wl,-z,noexecstack \
-fPIC \
-m32 \
+ -fuse-ld=gold \
-nostdlib \
-Wl,--no-undefined \
-Wl,--exclude-libs=ALL \
+ -Wl,--gc-sections \
-Wl,-O1 \
- -Wl,--as-needed \
- -Wl,--gc-sections
+ -Wl,--as-needed
LOCAL_STATIC_LIBRARIES := \
diff --git a/content/generate_content_resources.target.darwin-arm.mk b/content/generate_content_resources.target.darwin-arm.mk
new file mode 100644
index 0000000..4f77a75
--- /dev/null
+++ b/content/generate_content_resources.target.darwin-arm.mk
@@ -0,0 +1,54 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_generate_content_resources_gyp
+LOCAL_MODULE_STEM := generate_content_resources
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+### Rules for action "content_resources":
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/content/content_resources.grd $(LOCAL_PATH)/content/browser/gpu/gpu_driver_bug_list.json $(LOCAL_PATH)/content/browser/gpu/gpu_switching_list.json $(LOCAL_PATH)/content/browser/gpu/software_rendering_list.json $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.css $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.html $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.js $(LOCAL_PATH)/content/browser/resources/gpu/browser_bridge.js $(LOCAL_PATH)/content/browser/resources/gpu/gpu_internals.html $(LOCAL_PATH)/content/browser/resources/gpu/gpu_internals.js $(LOCAL_PATH)/content/browser/resources/gpu/info_view.css $(LOCAL_PATH)/content/browser/resources/gpu/info_view.html $(LOCAL_PATH)/content/browser/resources/gpu/info_view.js $(LOCAL_PATH)/content/browser/resources/indexed_db/indexeddb_internals.css $(LOCAL_PATH)/content/browser/resources/indexed_db/indexeddb_internals.html $(LOCAL_PATH)/content/browser/resources/indexed_db/indexeddb_internals.js $(LOCAL_PATH)/content/browser/resources/media/cache_entry.js $(LOCAL_PATH)/content/browser/resources/media/data_series.js $(LOCAL_PATH)/content/browser/resources/media/disjoint_range_set.js $(LOCAL_PATH)/content/browser/resources/media/dump_creator.js $(LOCAL_PATH)/content/browser/resources/media/event_list.js $(LOCAL_PATH)/content/browser/resources/media/item_store.js $(LOCAL_PATH)/content/browser/resources/media/media_internals.css $(LOCAL_PATH)/content/browser/resources/media/media_internals.html $(LOCAL_PATH)/content/browser/resources/media/media_internals.js $(LOCAL_PATH)/content/browser/resources/media/media_player.js $(LOCAL_PATH)/content/browser/resources/media/metrics.js $(LOCAL_PATH)/content/browser/resources/media/peer_connection_update_table.js $(LOCAL_PATH)/content/browser/resources/media/ssrc_info_manager.js $(LOCAL_PATH)/content/browser/resources/media/stats_graph_helper.js $(LOCAL_PATH)/content/browser/resources/media/stats_table.js $(LOCAL_PATH)/content/browser/resources/media/timeline_graph_view.js $(LOCAL_PATH)/content/browser/resources/media/util.js $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.css $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.html $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.js $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+ @echo "Gyp action: Generating resources from content_resources.grd ($@)"
+ $(hide)cd $(gyp_local_path)/content; mkdir -p $(gyp_shared_intermediate_dir)/content/grit $(gyp_shared_intermediate_dir)/content; python ../tools/grit/grit.py -i content_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/content" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses
+
+$(gyp_shared_intermediate_dir)/content/content_resources.pak: $(gyp_shared_intermediate_dir)/content/grit/content_resources.h ;
+$(gyp_shared_intermediate_dir)/content/content_resources.rc: $(gyp_shared_intermediate_dir)/content/grit/content_resources.h ;
+
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/content/grit/content_resources.h \
+ $(gyp_shared_intermediate_dir)/content/content_resources.pak \
+ $(gyp_shared_intermediate_dir)/content/content_resources.rc
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_generate_content_resources_gyp
+
+# Alias gyp target name.
+.PHONY: generate_content_resources
+generate_content_resources: content_generate_content_resources_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/generate_content_resources.target.darwin-x86.mk b/content/generate_content_resources.target.darwin-x86.mk
new file mode 100644
index 0000000..4f77a75
--- /dev/null
+++ b/content/generate_content_resources.target.darwin-x86.mk
@@ -0,0 +1,54 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_generate_content_resources_gyp
+LOCAL_MODULE_STEM := generate_content_resources
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+### Rules for action "content_resources":
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/content/content_resources.grd $(LOCAL_PATH)/content/browser/gpu/gpu_driver_bug_list.json $(LOCAL_PATH)/content/browser/gpu/gpu_switching_list.json $(LOCAL_PATH)/content/browser/gpu/software_rendering_list.json $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.css $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.html $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.js $(LOCAL_PATH)/content/browser/resources/gpu/browser_bridge.js $(LOCAL_PATH)/content/browser/resources/gpu/gpu_internals.html $(LOCAL_PATH)/content/browser/resources/gpu/gpu_internals.js $(LOCAL_PATH)/content/browser/resources/gpu/info_view.css $(LOCAL_PATH)/content/browser/resources/gpu/info_view.html $(LOCAL_PATH)/content/browser/resources/gpu/info_view.js $(LOCAL_PATH)/content/browser/resources/indexed_db/indexeddb_internals.css $(LOCAL_PATH)/content/browser/resources/indexed_db/indexeddb_internals.html $(LOCAL_PATH)/content/browser/resources/indexed_db/indexeddb_internals.js $(LOCAL_PATH)/content/browser/resources/media/cache_entry.js $(LOCAL_PATH)/content/browser/resources/media/data_series.js $(LOCAL_PATH)/content/browser/resources/media/disjoint_range_set.js $(LOCAL_PATH)/content/browser/resources/media/dump_creator.js $(LOCAL_PATH)/content/browser/resources/media/event_list.js $(LOCAL_PATH)/content/browser/resources/media/item_store.js $(LOCAL_PATH)/content/browser/resources/media/media_internals.css $(LOCAL_PATH)/content/browser/resources/media/media_internals.html $(LOCAL_PATH)/content/browser/resources/media/media_internals.js $(LOCAL_PATH)/content/browser/resources/media/media_player.js $(LOCAL_PATH)/content/browser/resources/media/metrics.js $(LOCAL_PATH)/content/browser/resources/media/peer_connection_update_table.js $(LOCAL_PATH)/content/browser/resources/media/ssrc_info_manager.js $(LOCAL_PATH)/content/browser/resources/media/stats_graph_helper.js $(LOCAL_PATH)/content/browser/resources/media/stats_table.js $(LOCAL_PATH)/content/browser/resources/media/timeline_graph_view.js $(LOCAL_PATH)/content/browser/resources/media/util.js $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.css $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.html $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.js $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+ @echo "Gyp action: Generating resources from content_resources.grd ($@)"
+ $(hide)cd $(gyp_local_path)/content; mkdir -p $(gyp_shared_intermediate_dir)/content/grit $(gyp_shared_intermediate_dir)/content; python ../tools/grit/grit.py -i content_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/content" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses
+
+$(gyp_shared_intermediate_dir)/content/content_resources.pak: $(gyp_shared_intermediate_dir)/content/grit/content_resources.h ;
+$(gyp_shared_intermediate_dir)/content/content_resources.rc: $(gyp_shared_intermediate_dir)/content/grit/content_resources.h ;
+
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/content/grit/content_resources.h \
+ $(gyp_shared_intermediate_dir)/content/content_resources.pak \
+ $(gyp_shared_intermediate_dir)/content/content_resources.rc
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_generate_content_resources_gyp
+
+# Alias gyp target name.
+.PHONY: generate_content_resources
+generate_content_resources: content_generate_content_resources_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/generate_content_resources.target.linux-arm.mk b/content/generate_content_resources.target.linux-arm.mk
index 9b8e909..4f77a75 100644
--- a/content/generate_content_resources.target.linux-arm.mk
+++ b/content/generate_content_resources.target.linux-arm.mk
@@ -18,9 +18,9 @@
$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/content/content_resources.grd $(LOCAL_PATH)/content/browser/gpu/gpu_driver_bug_list.json $(LOCAL_PATH)/content/browser/gpu/gpu_switching_list.json $(LOCAL_PATH)/content/browser/gpu/software_rendering_list.json $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.css $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.html $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.js $(LOCAL_PATH)/content/browser/resources/gpu/browser_bridge.js $(LOCAL_PATH)/content/browser/resources/gpu/gpu_internals.html $(LOCAL_PATH)/content/browser/resources/gpu/gpu_internals.js $(LOCAL_PATH)/content/browser/resources/gpu/info_view.css $(LOCAL_PATH)/content/browser/resources/gpu/info_view.html $(LOCAL_PATH)/content/browser/resources/gpu/info_view.js $(LOCAL_PATH)/content/browser/resources/media/cache_entry.js $(LOCAL_PATH)/content/browser/resources/media/data_series.js $(LOCAL_PATH)/content/browser/resources/media/disjoint_range_set.js $(LOCAL_PATH)/content/browser/resources/media/event_list.js $(LOCAL_PATH)/content/browser/resources/media/item_store.js $(LOCAL_PATH)/content/browser/resources/media/media_internals.css $(LOCAL_PATH)/content/browser/resources/media/media_internals.html $(LOCAL_PATH)/content/browser/resources/media/media_internals.js $(LOCAL_PATH)/content/browser/resources/media/media_player.js $(LOCAL_PATH)/content/browser/resources/media/metrics.js $(LOCAL_PATH)/content/browser/resources/media/stats_graph_helper.js $(LOCAL_PATH)/content/browser/resources/media/timeline_graph_view.js $(LOCAL_PATH)/content/browser/resources/media/util.js $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.css $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.html $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.js $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/content/content_resources.grd $(LOCAL_PATH)/content/browser/gpu/gpu_driver_bug_list.json $(LOCAL_PATH)/content/browser/gpu/gpu_switching_list.json $(LOCAL_PATH)/content/browser/gpu/software_rendering_list.json $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.css $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.html $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.js $(LOCAL_PATH)/content/browser/resources/gpu/browser_bridge.js $(LOCAL_PATH)/content/browser/resources/gpu/gpu_internals.html $(LOCAL_PATH)/content/browser/resources/gpu/gpu_internals.js $(LOCAL_PATH)/content/browser/resources/gpu/info_view.css $(LOCAL_PATH)/content/browser/resources/gpu/info_view.html $(LOCAL_PATH)/content/browser/resources/gpu/info_view.js $(LOCAL_PATH)/content/browser/resources/indexed_db/indexeddb_internals.css $(LOCAL_PATH)/content/browser/resources/indexed_db/indexeddb_internals.html $(LOCAL_PATH)/content/browser/resources/indexed_db/indexeddb_internals.js $(LOCAL_PATH)/content/browser/resources/media/cache_entry.js $(LOCAL_PATH)/content/browser/resources/media/data_series.js $(LOCAL_PATH)/content/browser/resources/media/disjoint_range_set.js $(LOCAL_PATH)/content/browser/resources/media/dump_creator.js $(LOCAL_PATH)/content/browser/resources/media/event_list.js $(LOCAL_PATH)/content/browser/resources/media/item_store.js $(LOCAL_PATH)/content/browser/resources/media/media_internals.css $(LOCAL_PATH)/content/browser/resources/media/media_internals.html $(LOCAL_PATH)/content/browser/resources/media/media_internals.js $(LOCAL_PATH)/content/browser/resources/media/media_player.js $(LOCAL_PATH)/content/browser/resources/media/metrics.js $(LOCAL_PATH)/content/browser/resources/media/peer_connection_update_table.js $(LOCAL_PATH)/content/browser/resources/media/ssrc_info_manager.js $(LOCAL_PATH)/content/browser/resources/media/stats_graph_helper.js $(LOCAL_PATH)/content/browser/resources/media/stats_table.js $(LOCAL_PATH)/content/browser/resources/media/timeline_graph_view.js $(LOCAL_PATH)/content/browser/resources/media/util.js $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.css $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.html $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.js $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from content_resources.grd ($@)"
- $(hide)cd $(gyp_local_path)/content; mkdir -p $(gyp_shared_intermediate_dir)/content/grit $(gyp_shared_intermediate_dir)/content; python ../tools/grit/grit.py -i content_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/content" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android
+ $(hide)cd $(gyp_local_path)/content; mkdir -p $(gyp_shared_intermediate_dir)/content/grit $(gyp_shared_intermediate_dir)/content; python ../tools/grit/grit.py -i content_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/content" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses
$(gyp_shared_intermediate_dir)/content/content_resources.pak: $(gyp_shared_intermediate_dir)/content/grit/content_resources.h ;
$(gyp_shared_intermediate_dir)/content/content_resources.rc: $(gyp_shared_intermediate_dir)/content/grit/content_resources.h ;
diff --git a/content/generate_content_resources.target.linux-x86.mk b/content/generate_content_resources.target.linux-x86.mk
index 9b8e909..4f77a75 100644
--- a/content/generate_content_resources.target.linux-x86.mk
+++ b/content/generate_content_resources.target.linux-x86.mk
@@ -18,9 +18,9 @@
$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/content/content_resources.grd $(LOCAL_PATH)/content/browser/gpu/gpu_driver_bug_list.json $(LOCAL_PATH)/content/browser/gpu/gpu_switching_list.json $(LOCAL_PATH)/content/browser/gpu/software_rendering_list.json $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.css $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.html $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.js $(LOCAL_PATH)/content/browser/resources/gpu/browser_bridge.js $(LOCAL_PATH)/content/browser/resources/gpu/gpu_internals.html $(LOCAL_PATH)/content/browser/resources/gpu/gpu_internals.js $(LOCAL_PATH)/content/browser/resources/gpu/info_view.css $(LOCAL_PATH)/content/browser/resources/gpu/info_view.html $(LOCAL_PATH)/content/browser/resources/gpu/info_view.js $(LOCAL_PATH)/content/browser/resources/media/cache_entry.js $(LOCAL_PATH)/content/browser/resources/media/data_series.js $(LOCAL_PATH)/content/browser/resources/media/disjoint_range_set.js $(LOCAL_PATH)/content/browser/resources/media/event_list.js $(LOCAL_PATH)/content/browser/resources/media/item_store.js $(LOCAL_PATH)/content/browser/resources/media/media_internals.css $(LOCAL_PATH)/content/browser/resources/media/media_internals.html $(LOCAL_PATH)/content/browser/resources/media/media_internals.js $(LOCAL_PATH)/content/browser/resources/media/media_player.js $(LOCAL_PATH)/content/browser/resources/media/metrics.js $(LOCAL_PATH)/content/browser/resources/media/stats_graph_helper.js $(LOCAL_PATH)/content/browser/resources/media/timeline_graph_view.js $(LOCAL_PATH)/content/browser/resources/media/util.js $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.css $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.html $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.js $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/content/content_resources.grd $(LOCAL_PATH)/content/browser/gpu/gpu_driver_bug_list.json $(LOCAL_PATH)/content/browser/gpu/gpu_switching_list.json $(LOCAL_PATH)/content/browser/gpu/software_rendering_list.json $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.css $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.html $(LOCAL_PATH)/content/browser/resources/accessibility/accessibility.js $(LOCAL_PATH)/content/browser/resources/gpu/browser_bridge.js $(LOCAL_PATH)/content/browser/resources/gpu/gpu_internals.html $(LOCAL_PATH)/content/browser/resources/gpu/gpu_internals.js $(LOCAL_PATH)/content/browser/resources/gpu/info_view.css $(LOCAL_PATH)/content/browser/resources/gpu/info_view.html $(LOCAL_PATH)/content/browser/resources/gpu/info_view.js $(LOCAL_PATH)/content/browser/resources/indexed_db/indexeddb_internals.css $(LOCAL_PATH)/content/browser/resources/indexed_db/indexeddb_internals.html $(LOCAL_PATH)/content/browser/resources/indexed_db/indexeddb_internals.js $(LOCAL_PATH)/content/browser/resources/media/cache_entry.js $(LOCAL_PATH)/content/browser/resources/media/data_series.js $(LOCAL_PATH)/content/browser/resources/media/disjoint_range_set.js $(LOCAL_PATH)/content/browser/resources/media/dump_creator.js $(LOCAL_PATH)/content/browser/resources/media/event_list.js $(LOCAL_PATH)/content/browser/resources/media/item_store.js $(LOCAL_PATH)/content/browser/resources/media/media_internals.css $(LOCAL_PATH)/content/browser/resources/media/media_internals.html $(LOCAL_PATH)/content/browser/resources/media/media_internals.js $(LOCAL_PATH)/content/browser/resources/media/media_player.js $(LOCAL_PATH)/content/browser/resources/media/metrics.js $(LOCAL_PATH)/content/browser/resources/media/peer_connection_update_table.js $(LOCAL_PATH)/content/browser/resources/media/ssrc_info_manager.js $(LOCAL_PATH)/content/browser/resources/media/stats_graph_helper.js $(LOCAL_PATH)/content/browser/resources/media/stats_table.js $(LOCAL_PATH)/content/browser/resources/media/timeline_graph_view.js $(LOCAL_PATH)/content/browser/resources/media/util.js $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.css $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.html $(LOCAL_PATH)/content/browser/resources/media/webrtc_internals.js $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from content_resources.grd ($@)"
- $(hide)cd $(gyp_local_path)/content; mkdir -p $(gyp_shared_intermediate_dir)/content/grit $(gyp_shared_intermediate_dir)/content; python ../tools/grit/grit.py -i content_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/content" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android
+ $(hide)cd $(gyp_local_path)/content; mkdir -p $(gyp_shared_intermediate_dir)/content/grit $(gyp_shared_intermediate_dir)/content; python ../tools/grit/grit.py -i content_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/content" -D _chromium -E "CHROMIUM_BUILD=chromium" -D android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses
$(gyp_shared_intermediate_dir)/content/content_resources.pak: $(gyp_shared_intermediate_dir)/content/grit/content_resources.h ;
$(gyp_shared_intermediate_dir)/content/content_resources.rc: $(gyp_shared_intermediate_dir)/content/grit/content_resources.h ;
diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc
index b8ce0a9..a4bc0ff 100644
--- a/content/gpu/gpu_child_thread.cc
+++ b/content/gpu/gpu_child_thread.cc
@@ -38,7 +38,7 @@
// If we are not on main thread in child process, send through
// the sync_message_filter; otherwise send directly.
- if (MessageLoop::current() !=
+ if (base::MessageLoop::current() !=
ChildProcess::current()->main_thread()->message_loop()) {
ChildProcess::current()->main_thread()->sync_message_filter()->Send(
new GpuHostMsg_OnLogMessage(severity, header, message));
@@ -82,6 +82,9 @@
}
GpuChildThread::~GpuChildThread() {
+}
+
+void GpuChildThread::Shutdown() {
logging::SetLogMessageHandler(NULL);
}
@@ -124,7 +127,7 @@
if (dead_on_arrival_) {
VLOG(1) << "Exiting GPU process due to errors during initialization";
- MessageLoop::current()->Quit();
+ base::MessageLoop::current()->Quit();
return;
}
@@ -159,7 +162,7 @@
}
void GpuChildThread::StopWatchdog() {
- if (watchdog_thread_.get()) {
+ if (watchdog_thread_) {
watchdog_thread_->Stop();
}
}
@@ -190,14 +193,14 @@
#if defined(OS_WIN)
if (!in_browser_process_) {
// The unsandboxed GPU process fulfilled its duty. Rest in peace.
- MessageLoop::current()->Quit();
+ base::MessageLoop::current()->Quit();
}
#endif // OS_WIN
}
void GpuChildThread::OnGetVideoMemoryUsageStats() {
GPUVideoMemoryUsageStats video_memory_usage_stats;
- if (gpu_channel_manager_.get())
+ if (gpu_channel_manager_)
gpu_channel_manager_->gpu_memory_manager()->GetVideoMemoryUsageStats(
&video_memory_usage_stats);
Send(new GpuHostMsg_VideoMemoryUsageStats(video_memory_usage_stats));
@@ -205,7 +208,7 @@
void GpuChildThread::OnClean() {
VLOG(1) << "GPU: Removing all contexts";
- if (gpu_channel_manager_.get())
+ if (gpu_channel_manager_)
gpu_channel_manager_->LoseAllContexts();
}
@@ -226,7 +229,7 @@
void GpuChildThread::OnDisableWatchdog() {
VLOG(1) << "GPU: Disabling watchdog thread";
- if (watchdog_thread_.get()) {
+ if (watchdog_thread_) {
// Disarm the watchdog before shutting down the message loop. This prevents
// the future posting of tasks to the message loop.
if (watchdog_thread_->message_loop())
diff --git a/content/gpu/gpu_child_thread.h b/content/gpu/gpu_child_thread.h
index 58c6c10..0d4baeb 100644
--- a/content/gpu/gpu_child_thread.h
+++ b/content/gpu/gpu_child_thread.h
@@ -43,6 +43,8 @@
virtual ~GpuChildThread();
+ virtual void Shutdown() OVERRIDE;
+
void Init(const base::Time& process_start_time);
void StopWatchdog();
diff --git a/content/gpu/gpu_info_collector.cc b/content/gpu/gpu_info_collector.cc
index 86fb0c5..0d51b69 100644
--- a/content/gpu/gpu_info_collector.cc
+++ b/content/gpu/gpu_info_collector.cc
@@ -7,10 +7,11 @@
#include <string>
#include <vector>
+#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/string_number_conversions.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
@@ -21,7 +22,7 @@
scoped_refptr<gfx::GLSurface> InitializeGLSurface() {
scoped_refptr<gfx::GLSurface> surface(
gfx::GLSurface::CreateOffscreenGLSurface(false, gfx::Size(1, 1)));
- if (!surface.get()) {
+ if (!surface) {
LOG(ERROR) << "gfx::GLContext::CreateOffscreenGLSurface failed";
return NULL;
}
@@ -35,7 +36,7 @@
gfx::GLContext::CreateGLContext(NULL,
surface,
gfx::PreferIntegratedGpu));
- if (!context.get()) {
+ if (!context) {
LOG(ERROR) << "gfx::GLContext::CreateGLContext failed";
return NULL;
}
@@ -53,7 +54,7 @@
reinterpret_cast<const char*>(glGetString(pname));
if (gl_string)
return std::string(gl_string);
- return "";
+ return std::string();
}
// Return a version string in the format of "major.minor".
@@ -71,7 +72,7 @@
if (pieces.size() >= 2)
return pieces[0] + "." + pieces[1];
}
- return "";
+ return std::string();
}
} // namespace anonymous
@@ -79,17 +80,18 @@
namespace gpu_info_collector {
bool CollectGraphicsInfoGL(content::GPUInfo* gpu_info) {
+ TRACE_EVENT0("startup", "gpu_info_collector::CollectGraphicsInfoGL");
if (!gfx::GLSurface::InitializeOneOff()) {
LOG(ERROR) << "gfx::GLSurface::InitializeOneOff() failed";
return false;
}
scoped_refptr<gfx::GLSurface> surface(InitializeGLSurface());
- if (!surface.get())
+ if (!surface)
return false;
scoped_refptr<gfx::GLContext> context(InitializeGLContext(surface.get()));
- if (!context.get())
+ if (!context)
return false;
gpu_info->gl_renderer = GetGLString(GL_RENDERER);
diff --git a/content/gpu/gpu_info_collector_android.cc b/content/gpu/gpu_info_collector_android.cc
index 157e5b6..a190c9d 100644
--- a/content/gpu/gpu_info_collector_android.cc
+++ b/content/gpu/gpu_info_collector_android.cc
@@ -8,8 +8,8 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "base/string_number_conversions.h"
-#include "base/string_piece.h"
#include "base/string_util.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "cc/base/switches.h"
#include "content/public/common/content_switches.h"
@@ -74,6 +74,8 @@
bool is_arm = vendor.find("arm") != std::string::npos;
bool is_qualcomm = vendor.find("qualcomm") != std::string::npos;
bool is_mali_t604 = is_arm && renderer.find("mali-t604") != std::string::npos;
+ bool is_vivante = vendor.find("vivante") != std::string::npos;
+ is_vivante |= vendor.find("hisilicon") != std::string::npos;
base::android::BuildInfo* build_info =
base::android::BuildInfo::GetInstance();
@@ -82,10 +84,17 @@
bool is_nexus7 = model.find("nexus 7") != std::string::npos;
bool is_nexus10 = model.find("nexus 10") != std::string::npos;
+ // Virtual contexts crash when switching surfaces, but only on SDK 16,
+ // so we us full context switching for now. If virtual contexts can
+ // avoid some of it's extra surface switches, or Qualcomm gives us
+ // a more directed work-around, we can remove this.
+ int sdk_int = base::android::BuildInfo::GetInstance()->sdk_int();
+
// IMG: avoid context switching perf problems, crashes with share groups
// Mali-T604: http://crbug.com/154715
// QualComm, NVIDIA: Crashes with share groups
- if (is_img || is_mali_t604 || is_qualcomm || is_nexus7) {
+ if (is_vivante || is_img || is_mali_t604 || is_nexus7
+ || (is_qualcomm && sdk_int != 16)) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableVirtualGLContexts);
}
diff --git a/content/gpu/gpu_info_collector_mac.mm b/content/gpu/gpu_info_collector_mac.mm
index f8aefe1..b3ded51 100644
--- a/content/gpu/gpu_info_collector_mac.mm
+++ b/content/gpu/gpu_info_collector_mac.mm
@@ -12,9 +12,9 @@
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/scoped_ptr.h"
#include "base/string_number_conversions.h"
-#include "base/string_piece.h"
#include "base/string_util.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/sys_string_conversions.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_implementation.h"
diff --git a/content/gpu/gpu_info_collector_win.cc b/content/gpu/gpu_info_collector_win.cc
index 462459b..402a4b1 100644
--- a/content/gpu/gpu_info_collector_win.cc
+++ b/content/gpu/gpu_info_collector_win.cc
@@ -189,15 +189,13 @@
bool IsLenovoDCuteInstalled() {
base::win::RegKey key;
- if (FAILED(key.Open(
- HKEY_LOCAL_MACHINE, L"SOFTWARE", KEY_READ | KEY_WOW64_64KEY))) {
- return false;
- }
-
- if (FAILED(key.OpenKey(L"Lenovo", KEY_READ | KEY_WOW64_64KEY)))
+ if (key.Open(HKEY_LOCAL_MACHINE, L"SOFTWARE", KEY_READ | KEY_WOW64_64KEY))
return false;
- if (FAILED(key.OpenKey(L"Lenovo dCute", KEY_READ | KEY_WOW64_64KEY)))
+ if (key.OpenKey(L"Lenovo", KEY_READ | KEY_WOW64_64KEY))
+ return false;
+
+ if (key.OpenKey(L"Lenovo dCute", KEY_READ | KEY_WOW64_64KEY))
return false;
return true;
@@ -375,7 +373,7 @@
#if !defined(GOOGLE_CHROME_BUILD)
AMDVideoCardType GetAMDVideocardType() {
- return UNKNOWN;
+ return STANDALONE;
}
#else
// This function has a real implementation for official builds that can
@@ -606,7 +604,7 @@
// Collect basic information about supported D3D11 features. Delay for 45
// seconds so as not to regress performance tests.
if (D3D11ShouldWork(*gpu_info)) {
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&CollectD3D11Support),
base::TimeDelta::FromSeconds(45));
diff --git a/content/gpu/gpu_info_collector_linux.cc b/content/gpu/gpu_info_collector_x11.cc
similarity index 86%
rename from content/gpu/gpu_info_collector_linux.cc
rename to content/gpu/gpu_info_collector_x11.cc
index 56b3800..2d43167 100644
--- a/content/gpu/gpu_info_collector_linux.cc
+++ b/content/gpu/gpu_info_collector_x11.cc
@@ -13,8 +13,8 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
-#include "base/string_piece.h"
#include "base/string_util.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_tokenizer.h"
#include "library_loaders/libpci.h"
@@ -130,34 +130,6 @@
gpu.vendor_id = device->vendor_id;
gpu.device_id = device->device_id;
- const int buffer_size = 255;
- scoped_array<char> buffer(new char[buffer_size]);
- // The current implementation of pci_lookup_name returns the same pointer
- // as the passed in upon success, and a different one (NULL or a pointer
- // to an error message) upon failure.
- if ((libpci_loader.pci_lookup_name)(access,
- buffer.get(),
- buffer_size,
- 1,
- device->vendor_id) == buffer.get()) {
- gpu.vendor_string = buffer.get();
- }
- if ((libpci_loader.pci_lookup_name)(access,
- buffer.get(),
- buffer_size,
- 2,
- device->vendor_id,
- device->device_id) == buffer.get()) {
- std::string device_string = buffer.get();
- size_t begin = device_string.find_first_of('[');
- size_t end = device_string.find_last_of(']');
- if (begin != std::string::npos && end != std::string::npos &&
- begin < end) {
- device_string = device_string.substr(begin + 1, end - begin - 1);
- }
- gpu.device_string = device_string;
- }
-
if (!primary_gpu_identified) {
primary_gpu_identified = true;
gpu_info->gpu = gpu;
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
index 44d00dd..6c1045f 100644
--- a/content/gpu/gpu_main.cc
+++ b/content/gpu/gpu_main.cc
@@ -16,6 +16,7 @@
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
#include "content/common/gpu/gpu_config.h"
+#include "content/common/sandbox_linux.h"
#include "content/gpu/gpu_child_thread.h"
#include "content/gpu/gpu_info_collector.h"
#include "content/gpu/gpu_process.h"
@@ -53,7 +54,12 @@
namespace content {
namespace {
-void WarmUpSandbox(const GPUInfo&, bool);
+void WarmUpSandbox();
+#if defined(OS_LINUX)
+bool StartSandboxLinux(const GPUInfo&, GpuWatchdogThread*, bool);
+#elif defined(OS_WIN)
+bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo*);
+#endif
}
// Main function for starting the Gpu process.
@@ -101,7 +107,7 @@
// GpuMsg_Initialize message from the browser.
bool dead_on_arrival = false;
- MessageLoop::Type message_loop_type = MessageLoop::TYPE_IO;
+ base::MessageLoop::Type message_loop_type = base::MessageLoop::TYPE_IO;
#if defined(OS_WIN)
// Unless we're running on desktop GL, we don't need a UI message
// loop, so avoid its use to work around apparent problems with some
@@ -109,13 +115,13 @@
if (command_line.HasSwitch(switches::kUseGL) &&
command_line.GetSwitchValueASCII(switches::kUseGL) ==
gfx::kGLImplementationDesktopName) {
- message_loop_type = MessageLoop::TYPE_UI;
+ message_loop_type = base::MessageLoop::TYPE_UI;
}
#elif defined(OS_LINUX)
- message_loop_type = MessageLoop::TYPE_DEFAULT;
+ message_loop_type = base::MessageLoop::TYPE_DEFAULT;
#endif
- MessageLoop main_message_loop(message_loop_type);
+ base::MessageLoop main_message_loop(message_loop_type);
base::PlatformThread::SetName("CrGpuMain");
// In addition to disabling the watchdog if the command line switch is
@@ -169,18 +175,39 @@
command_line.GetSwitchValueASCII(switches::kGpuDriverVersion);
GetContentClient()->SetGpuInfo(gpu_info);
- // We need to track that information for the WarmUpSandbox function.
+ // Warm up resources that don't need access to GPUInfo.
+ WarmUpSandbox();
+
+#if defined(OS_LINUX)
+ bool initialized_sandbox = false;
bool initialized_gl_context = false;
+ bool should_initialize_gl_context = false;
+#if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL)
+ // On Chrome OS ARM, GPU driver userspace creates threads when initializing
+ // a GL context, so start the sandbox early.
+ gpu_info.sandboxed = StartSandboxLinux(gpu_info, watchdog_thread.get(),
+ should_initialize_gl_context);
+ initialized_sandbox = true;
+#endif
+#endif // defined(OS_LINUX)
+
// Load and initialize the GL implementation and locate the GL entry points.
if (gfx::GLSurface::InitializeOneOff()) {
+ // We need to collect GL strings (VENDOR, RENDERER) for blacklisting
+ // purposes. However, on Mac we don't actually use them. As documented in
+ // crbug.com/222934, due to some driver issues, glGetString could take
+ // multiple seconds to finish, which in turn cause the GPU process to crash.
+ // By skipping the following code on Mac, we don't really lose anything,
+ // because the basic GPU information is passed down from browser process
+ // and we already registered them through SetGpuInfo() above.
+#if !defined(OS_MACOSX)
if (!gpu_info_collector::CollectContextGraphicsInfo(&gpu_info))
VLOG(1) << "gpu_info_collector::CollectGraphicsInfo failed";
GetContentClient()->SetGpuInfo(gpu_info);
- // We know that CollectGraphicsInfo will initialize a GLContext.
+#if defined(OS_LINUX)
initialized_gl_context = true;
-
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#if !defined(OS_CHROMEOS)
if (gpu_info.gpu.vendor_id == 0x10de && // NVIDIA
gpu_info.driver_vendor == "NVIDIA") {
base::ThreadRestrictions::AssertIOAllowed();
@@ -190,7 +217,9 @@
dead_on_arrival = true;
}
}
-#endif // OS_CHROMEOS
+#endif // !defined(OS_CHROMEOS)
+#endif // defined(OS_LINUX)
+#endif // !defined(OS_MACOSX)
} else {
VLOG(1) << "gfx::GLSurface::InitializeOneOff failed";
gpu_info.gpu_accessible = false;
@@ -212,47 +241,15 @@
watchdog_thread = NULL;
}
- {
- const bool should_initialize_gl_context = !initialized_gl_context &&
- !dead_on_arrival;
- // Warm up the current process before enabling the sandbox.
- WarmUpSandbox(gpu_info, should_initialize_gl_context);
- }
-
#if defined(OS_LINUX)
- {
- TRACE_EVENT0("gpu", "Initialize sandbox");
- bool do_init_sandbox = true;
+ should_initialize_gl_context = !initialized_gl_context &&
+ !dead_on_arrival;
-#if defined(OS_CHROMEOS) && defined(NDEBUG)
- // On Chrome OS and when not on a debug build, initialize
- // the GPU process' sandbox only for Intel GPUs.
- do_init_sandbox = gpu_info.gpu.vendor_id == 0x8086; // Intel GPU.
-#endif
-
- if (do_init_sandbox) {
- if (watchdog_thread.get())
- watchdog_thread->Stop();
- gpu_info.sandboxed = InitializeSandbox();
- if (watchdog_thread.get())
- watchdog_thread->Start();
- }
- }
-#endif
-
-#if defined(OS_WIN)
- {
- TRACE_EVENT0("gpu", "Lower token");
- // For windows, if the target_services interface is not zero, the process
- // is sandboxed and we must call LowerToken() before rendering untrusted
- // content.
- sandbox::TargetServices* target_services =
- parameters.sandbox_info->target_services;
- if (target_services) {
- target_services->LowerToken();
- gpu_info.sandboxed = true;
- }
- }
+ if (!initialized_sandbox)
+ gpu_info.sandboxed = StartSandboxLinux(gpu_info, watchdog_thread.get(),
+ should_initialize_gl_context);
+#elif defined(OS_WIN)
+ gpu_info.sandboxed = StartSandboxWindows(parameters.sandbox_info);
#endif
GpuProcess gpu_process;
@@ -280,7 +277,7 @@
void CreateDummyGlContext() {
scoped_refptr<gfx::GLSurface> surface(
gfx::GLSurface::CreateOffscreenGLSurface(false, gfx::Size(1, 1)));
- if (!surface.get()) {
+ if (!surface) {
VLOG(1) << "gfx::GLSurface::CreateOffscreenGLSurface failed";
return;
}
@@ -291,7 +288,7 @@
gfx::GLContext::CreateGLContext(NULL,
surface,
gfx::PreferDiscreteGpu));
- if (!context.get()) {
+ if (!context) {
VLOG(1) << "gfx::GLContext::CreateGLContext failed";
return;
}
@@ -305,8 +302,7 @@
}
#endif
-void WarmUpSandbox(const GPUInfo& gpu_info,
- bool should_initialize_gl_context) {
+void WarmUpSandbox() {
{
TRACE_EVENT0("gpu", "Warm up rand");
// Warm up the random subsystem, which needs to be done pre-sandbox on all
@@ -332,24 +328,8 @@
VaapiVideoDecodeAccelerator::PreSandboxInitialization();
#endif
-#if defined(OS_LINUX)
- // We special case Optimus since the vendor_id we see may not be Nvidia.
- bool uses_nvidia_driver = (gpu_info.gpu.vendor_id == 0x10de && // NVIDIA.
- gpu_info.driver_vendor == "NVIDIA") ||
- gpu_info.optimus;
- if (uses_nvidia_driver && should_initialize_gl_context) {
- // We need this on Nvidia to pre-open /dev/nvidiactl and /dev/nvidia0.
- CreateDummyGlContext();
- }
-#endif
-
#if defined(OS_WIN)
{
- TRACE_EVENT0("gpu", "Initialize COM");
- base::win::ScopedCOMInitializer com_initializer;
- }
-
- {
TRACE_EVENT0("gpu", "Preload setupapi.dll");
// Preload this DLL because the sandbox prevents it from loading.
LoadLibrary(L"setupapi.dll");
@@ -363,6 +343,57 @@
#endif
}
+#if defined(OS_LINUX)
+void WarmUpSandboxNvidia(const GPUInfo& gpu_info,
+ bool should_initialize_gl_context) {
+ // We special case Optimus since the vendor_id we see may not be Nvidia.
+ bool uses_nvidia_driver = (gpu_info.gpu.vendor_id == 0x10de && // NVIDIA.
+ gpu_info.driver_vendor == "NVIDIA") ||
+ gpu_info.optimus;
+ if (uses_nvidia_driver && should_initialize_gl_context) {
+ // We need this on Nvidia to pre-open /dev/nvidiactl and /dev/nvidia0.
+ CreateDummyGlContext();
+ }
+}
+
+bool StartSandboxLinux(const GPUInfo& gpu_info,
+ GpuWatchdogThread* watchdog_thread,
+ bool should_initialize_gl_context) {
+ TRACE_EVENT0("gpu", "Initialize sandbox");
+
+ bool res = false;
+
+ WarmUpSandboxNvidia(gpu_info, should_initialize_gl_context);
+
+ if (watchdog_thread)
+ watchdog_thread->Stop();
+ // LinuxSandbox::InitializeSandbox() must always be called
+ // with only one thread.
+ res = LinuxSandbox::InitializeSandbox();
+ if (watchdog_thread)
+ watchdog_thread->Start();
+
+ return res;
+}
+#endif // defined(OS_LINUX)
+
+#if defined(OS_WIN)
+bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo* sandbox_info) {
+ TRACE_EVENT0("gpu", "Lower token");
+
+ // For Windows, if the target_services interface is not zero, the process
+ // is sandboxed and we must call LowerToken() before rendering untrusted
+ // content.
+ sandbox::TargetServices* target_services = sandbox_info->target_services;
+ if (target_services) {
+ target_services->LowerToken();
+ return true;
+ }
+
+ return false;
+}
+#endif // defined(OS_WIN)
+
} // namespace.
} // namespace content
diff --git a/content/gpu/gpu_watchdog_thread.cc b/content/gpu/gpu_watchdog_thread.cc
index 5557571..09e710e 100644
--- a/content/gpu/gpu_watchdog_thread.cc
+++ b/content/gpu/gpu_watchdog_thread.cc
@@ -25,15 +25,15 @@
GpuWatchdogThread::GpuWatchdogThread(int timeout)
: base::Thread("Watchdog"),
- watched_message_loop_(MessageLoop::current()),
+ watched_message_loop_(base::MessageLoop::current()),
timeout_(base::TimeDelta::FromMilliseconds(timeout)),
armed_(false),
#if defined(OS_WIN)
watched_thread_handle_(0),
arm_cpu_time_(),
#endif
- ALLOW_THIS_IN_INITIALIZER_LIST(task_observer_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ task_observer_(this),
+ weak_factory_(this) {
DCHECK(timeout >= 0);
#if defined(OS_WIN)
diff --git a/content/gpu/gpu_watchdog_thread.h b/content/gpu/gpu_watchdog_thread.h
index 49c6236..22cc887 100644
--- a/content/gpu/gpu_watchdog_thread.h
+++ b/content/gpu/gpu_watchdog_thread.h
@@ -38,7 +38,7 @@
// An object of this type intercepts the reception and completion of all tasks
// on the watched thread and checks whether the watchdog is armed.
- class GpuWatchdogTaskObserver : public MessageLoop::TaskObserver {
+ class GpuWatchdogTaskObserver : public base::MessageLoop::TaskObserver {
public:
explicit GpuWatchdogTaskObserver(GpuWatchdogThread* watchdog);
virtual ~GpuWatchdogTaskObserver();
@@ -62,7 +62,7 @@
base::TimeDelta GetWatchedThreadTime();
#endif
- MessageLoop* watched_message_loop_;
+ base::MessageLoop* watched_message_loop_;
base::TimeDelta timeout_;
volatile bool armed_;
GpuWatchdogTaskObserver task_observer_;
diff --git a/content/surface_jni_headers.target.linux-arm.mk b/content/java_set_jni_headers.target.darwin-arm.mk
similarity index 79%
rename from content/surface_jni_headers.target.linux-arm.mk
rename to content/java_set_jni_headers.target.darwin-arm.mk
index 6376b54..6c3483c 100644
--- a/content/surface_jni_headers.target.linux-arm.mk
+++ b/content/java_set_jni_headers.target.darwin-arm.mk
@@ -3,8 +3,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE_CLASS := GYP
-LOCAL_MODULE := content_surface_jni_headers_gyp
-LOCAL_MODULE_STEM := surface_jni_headers
+LOCAL_MODULE := content_java_set_jni_headers_gyp
+LOCAL_MODULE_STEM := java_set_jni_headers
LOCAL_MODULE_SUFFIX := .stamp
LOCAL_MODULE_TAGS := optional
gyp_intermediate_dir := $(call local-intermediates-dir)
@@ -14,24 +14,24 @@
GYP_TARGET_DEPENDENCIES :=
### Rules for action "generate_jni_headers_from_jar_file":
-$(gyp_shared_intermediate_dir)/content/jni/Surface_jni.h: gyp_local_path := $(LOCAL_PATH)
-$(gyp_shared_intermediate_dir)/content/jni/Surface_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/Surface_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/Surface_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/content/jni/Surface_jni.h: $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar $(GYP_TARGET_DEPENDENCIES)
- @echo "Gyp action: Generating JNI bindings from $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar/android/view/Surface.class ($@)"
- $(hide)cd $(gyp_local_path)/content; mkdir -p $(gyp_shared_intermediate_dir)/content/jni; ../base/android/jni_generator/jni_generator.py -j "$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar" --input_file android/view/Surface.class --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar $(GYP_TARGET_DEPENDENCIES)
+ @echo "Gyp action: Generating JNI bindings from $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar/java/util/HashSet.class ($@)"
+ $(hide)cd $(gyp_local_path)/content; mkdir -p $(gyp_shared_intermediate_dir)/content/jni; ../base/android/jni_generator/jni_generator.py -j "$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar" --input_file java/util/HashSet.class --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
GYP_GENERATED_OUTPUTS := \
- $(gyp_shared_intermediate_dir)/content/jni/Surface_jni.h
+ $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
LOCAL_GENERATED_SOURCES := \
- $(gyp_shared_intermediate_dir)/content/jni/Surface_jni.h
+ $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
@@ -75,7 +75,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -83,7 +82,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -123,11 +121,11 @@
### Rules for final target.
# Add target alias to "gyp_all_modules" target.
.PHONY: gyp_all_modules
-gyp_all_modules: content_surface_jni_headers_gyp
+gyp_all_modules: content_java_set_jni_headers_gyp
# Alias gyp target name.
-.PHONY: surface_jni_headers
-surface_jni_headers: content_surface_jni_headers_gyp
+.PHONY: java_set_jni_headers
+java_set_jni_headers: content_java_set_jni_headers_gyp
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
LOCAL_UNINSTALLABLE_MODULE := true
diff --git a/content/surface_jni_headers.target.linux-x86.mk b/content/java_set_jni_headers.target.darwin-x86.mk
similarity index 78%
rename from content/surface_jni_headers.target.linux-x86.mk
rename to content/java_set_jni_headers.target.darwin-x86.mk
index 9ce34f2..502136f 100644
--- a/content/surface_jni_headers.target.linux-x86.mk
+++ b/content/java_set_jni_headers.target.darwin-x86.mk
@@ -3,8 +3,8 @@
include $(CLEAR_VARS)
LOCAL_MODULE_CLASS := GYP
-LOCAL_MODULE := content_surface_jni_headers_gyp
-LOCAL_MODULE_STEM := surface_jni_headers
+LOCAL_MODULE := content_java_set_jni_headers_gyp
+LOCAL_MODULE_STEM := java_set_jni_headers
LOCAL_MODULE_SUFFIX := .stamp
LOCAL_MODULE_TAGS := optional
gyp_intermediate_dir := $(call local-intermediates-dir)
@@ -14,24 +14,24 @@
GYP_TARGET_DEPENDENCIES :=
### Rules for action "generate_jni_headers_from_jar_file":
-$(gyp_shared_intermediate_dir)/content/jni/Surface_jni.h: gyp_local_path := $(LOCAL_PATH)
-$(gyp_shared_intermediate_dir)/content/jni/Surface_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/Surface_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/Surface_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/content/jni/Surface_jni.h: $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar $(GYP_TARGET_DEPENDENCIES)
- @echo "Gyp action: Generating JNI bindings from $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar/android/view/Surface.class ($@)"
- $(hide)cd $(gyp_local_path)/content; mkdir -p $(gyp_shared_intermediate_dir)/content/jni; ../base/android/jni_generator/jni_generator.py -j "$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar" --input_file android/view/Surface.class --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar $(GYP_TARGET_DEPENDENCIES)
+ @echo "Gyp action: Generating JNI bindings from $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar/java/util/HashSet.class ($@)"
+ $(hide)cd $(gyp_local_path)/content; mkdir -p $(gyp_shared_intermediate_dir)/content/jni; ../base/android/jni_generator/jni_generator.py -j "$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar" --input_file java/util/HashSet.class --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
GYP_GENERATED_OUTPUTS := \
- $(gyp_shared_intermediate_dir)/content/jni/Surface_jni.h
+ $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
LOCAL_GENERATED_SOURCES := \
- $(gyp_shared_intermediate_dir)/content/jni/Surface_jni.h
+ $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
@@ -55,6 +55,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -76,7 +77,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -84,7 +84,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
@@ -123,11 +122,11 @@
### Rules for final target.
# Add target alias to "gyp_all_modules" target.
.PHONY: gyp_all_modules
-gyp_all_modules: content_surface_jni_headers_gyp
+gyp_all_modules: content_java_set_jni_headers_gyp
# Alias gyp target name.
-.PHONY: surface_jni_headers
-surface_jni_headers: content_surface_jni_headers_gyp
+.PHONY: java_set_jni_headers
+java_set_jni_headers: content_java_set_jni_headers_gyp
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
LOCAL_UNINSTALLABLE_MODULE := true
diff --git a/content/java_set_jni_headers.target.linux-arm.mk b/content/java_set_jni_headers.target.linux-arm.mk
index 1123ac9..6c3483c 100644
--- a/content/java_set_jni_headers.target.linux-arm.mk
+++ b/content/java_set_jni_headers.target.linux-arm.mk
@@ -75,7 +75,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -83,7 +82,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
diff --git a/content/java_set_jni_headers.target.linux-x86.mk b/content/java_set_jni_headers.target.linux-x86.mk
index bf53480..502136f 100644
--- a/content/java_set_jni_headers.target.linux-x86.mk
+++ b/content/java_set_jni_headers.target.linux-x86.mk
@@ -55,6 +55,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -76,7 +77,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -84,7 +84,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
diff --git a/content/page_transition_types_java.target.darwin-arm.mk b/content/page_transition_types_java.target.darwin-arm.mk
new file mode 100644
index 0000000..739f25a
--- /dev/null
+++ b/content/page_transition_types_java.target.darwin-arm.mk
@@ -0,0 +1,142 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_page_transition_types_java_gyp
+LOCAL_MODULE_STEM := page_transition_types_java
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+
+### Generated for rule "content_content_gyp_page_transition_types_java_target_generate_java_constants":
+# "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/gcc_preprocess.py $(LOCAL_PATH)/content/public/common/page_transition_types_list.h $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser; cd $(gyp_local_path)/content; python ../build/android/gyp/gcc_preprocess.py "--include-path=.." "--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java" "--template=public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template"
+
+.PHONY: content_page_transition_types_java_gyp_rule_trigger
+content_page_transition_types_java_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES := \
+ content_page_transition_types_java_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_page_transition_types_java_gyp
+
+# Alias gyp target name.
+.PHONY: page_transition_types_java
+page_transition_types_java: content_page_transition_types_java_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/page_transition_types_java.target.darwin-x86.mk b/content/page_transition_types_java.target.darwin-x86.mk
new file mode 100644
index 0000000..cf3edd3
--- /dev/null
+++ b/content/page_transition_types_java.target.darwin-x86.mk
@@ -0,0 +1,143 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_page_transition_types_java_gyp
+LOCAL_MODULE_STEM := page_transition_types_java
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+
+### Generated for rule "content_content_gyp_page_transition_types_java_target_generate_java_constants":
+# "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/gcc_preprocess.py $(LOCAL_PATH)/content/public/common/page_transition_types_list.h $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser; cd $(gyp_local_path)/content; python ../build/android/gyp/gcc_preprocess.py "--include-path=.." "--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java" "--template=public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template"
+
+.PHONY: content_page_transition_types_java_gyp_rule_trigger
+content_page_transition_types_java_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES := \
+ content_page_transition_types_java_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_page_transition_types_java_gyp
+
+# Alias gyp target name.
+.PHONY: page_transition_types_java
+page_transition_types_java: content_page_transition_types_java_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/page_transition_types_java.target.linux-arm.mk b/content/page_transition_types_java.target.linux-arm.mk
index 831a616..739f25a 100644
--- a/content/page_transition_types_java.target.linux-arm.mk
+++ b/content/page_transition_types_java.target.linux-arm.mk
@@ -15,13 +15,13 @@
### Generated for rule "content_content_gyp_page_transition_types_java_target_generate_java_constants":
-# "{'inputs': ['public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['gcc', '-E', '-D', 'ANDROID', '-x', 'c-header', '-P', '-I', '..', '-o', '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
+# "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template $(LOCAL_PATH)/content/public/common/page_transition_types_list.h $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser; cd $(gyp_local_path)/content; gcc -E -D ANDROID -x c-header -P -I .. -o "$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java" public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/gcc_preprocess.py $(LOCAL_PATH)/content/public/common/page_transition_types_list.h $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser; cd $(gyp_local_path)/content; python ../build/android/gyp/gcc_preprocess.py "--include-path=.." "--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java" "--template=public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template"
.PHONY: content_page_transition_types_java_gyp_rule_trigger
content_page_transition_types_java_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java
@@ -79,7 +79,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -87,7 +86,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
diff --git a/content/page_transition_types_java.target.linux-x86.mk b/content/page_transition_types_java.target.linux-x86.mk
index 8b82a3e..cf3edd3 100644
--- a/content/page_transition_types_java.target.linux-x86.mk
+++ b/content/page_transition_types_java.target.linux-x86.mk
@@ -15,13 +15,13 @@
### Generated for rule "content_content_gyp_page_transition_types_java_target_generate_java_constants":
-# "{'inputs': ['public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['gcc', '-E', '-D', 'ANDROID', '-x', 'c-header', '-P', '-I', '..', '-o', '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
+# "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template $(LOCAL_PATH)/content/public/common/page_transition_types_list.h $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser; cd $(gyp_local_path)/content; gcc -E -D ANDROID -x c-header -P -I .. -o "$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java" public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/gcc_preprocess.py $(LOCAL_PATH)/content/public/common/page_transition_types_list.h $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser; cd $(gyp_local_path)/content; python ../build/android/gyp/gcc_preprocess.py "--include-path=.." "--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java" "--template=public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template"
.PHONY: content_page_transition_types_java_gyp_rule_trigger
content_page_transition_types_java_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java
@@ -59,6 +59,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -80,7 +81,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -88,7 +88,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
diff --git a/content/plugin/plugin_channel.cc b/content/plugin/plugin_channel.cc
index 8569a3d..781ca00 100644
--- a/content/plugin/plugin_channel.cc
+++ b/content/plugin/plugin_channel.cc
@@ -67,7 +67,7 @@
return;
// Delete the event when the stack unwinds as it could be in use now.
- MessageLoop::current()->DeleteSoon(
+ base::MessageLoop::current()->DeleteSoon(
FROM_HERE, modal_dialog_event_map_[render_view_id].event);
modal_dialog_event_map_.erase(render_view_id);
}
@@ -200,7 +200,7 @@
}
PluginChannel::~PluginChannel() {
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&PluginReleaseCallback),
base::TimeDelta::FromMinutes(kPluginReleaseTimeMinutes));
@@ -280,9 +280,11 @@
// Don't release the modal dialog event right away, but do it after the
// stack unwinds since the plugin can be destroyed later if it's in use
// right now.
- MessageLoop::current()->PostNonNestableTask(FROM_HERE, base::Bind(
- &MessageFilter::ReleaseModalDialogEvent, filter.get(),
- render_view_id));
+ base::MessageLoop::current()->PostNonNestableTask(
+ FROM_HERE,
+ base::Bind(&MessageFilter::ReleaseModalDialogEvent,
+ filter.get(),
+ render_view_id));
return;
}
}
@@ -302,7 +304,7 @@
base::FilePath path = command_line->GetSwitchValuePath(switches::kPluginPath);
scoped_refptr<webkit::npapi::PluginLib> plugin_lib(
webkit::npapi::PluginLib::CreatePluginLib(path));
- if (plugin_lib.get()) {
+ if (plugin_lib) {
NPError err = plugin_lib->NP_Initialize();
if (err == NPERR_NO_ERROR) {
const char* site_str = site.empty() ? NULL : site.c_str();
diff --git a/content/plugin/plugin_main.cc b/content/plugin/plugin_main.cc
index 971e308..298fbd4 100644
--- a/content/plugin/plugin_main.cc
+++ b/content/plugin/plugin_main.cc
@@ -13,7 +13,7 @@
#include "base/hi_res_timer_manager.h"
#include "base/message_loop.h"
#include "base/string_util.h"
-#include "base/system_monitor/system_monitor.h"
+#include "base/power_monitor/power_monitor.h"
#include "base/threading/platform_thread.h"
#include "content/common/child_process.h"
#include "content/plugin/plugin_thread.h"
@@ -52,10 +52,10 @@
#endif
InitializeChromeApplication();
#endif
- MessageLoop main_message_loop(MessageLoop::TYPE_UI);
+ base::MessageLoop main_message_loop(base::MessageLoop::TYPE_UI);
base::PlatformThread::SetName("CrPluginMain");
- base::SystemMonitor system_monitor;
+ base::PowerMonitor power_monitor;
HighResolutionTimerManager high_resolution_timer_manager;
const CommandLine& parsed_command_line = parameters.command_line;
@@ -77,7 +77,7 @@
{
ChildProcess plugin_process;
plugin_process.set_main_thread(new PluginThread());
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
}
return 0;
diff --git a/content/plugin/plugin_thread.cc b/content/plugin/plugin_thread.cc
index ea0cbc1..8256ef6 100644
--- a/content/plugin/plugin_thread.cc
+++ b/content/plugin/plugin_thread.cc
@@ -58,7 +58,7 @@
// Ensure that we don't wait indefinitely for the plugin to shutdown.
// as the browser does not terminate plugin processes on shutdown.
// We achieve this by posting an exit process task on the IO thread.
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&EnsureTerminateMessageFilter::Terminate, this),
kPluginProcessTerminateTimeout);
@@ -117,7 +117,7 @@
scoped_refptr<webkit::npapi::PluginLib> plugin(
webkit::npapi::PluginLib::CreatePluginLib(plugin_path));
- if (plugin.get()) {
+ if (plugin) {
plugin->NP_Initialize();
// For OOP plugins the plugin dll will be unloaded during process shutdown
// time.
@@ -137,6 +137,9 @@
}
PluginThread::~PluginThread() {
+}
+
+void PluginThread::Shutdown() {
if (preloaded_plugin_module_) {
base::UnloadNativeLibrary(preloaded_plugin_module_);
preloaded_plugin_module_ = NULL;
@@ -170,7 +173,7 @@
scoped_refptr<PluginChannel> channel(PluginChannel::GetPluginChannel(
renderer_id, ChildProcess::current()->io_message_loop_proxy()));
IPC::ChannelHandle channel_handle;
- if (channel.get()) {
+ if (channel) {
channel_handle.name = channel->channel_handle().name;
#if defined(OS_POSIX)
// On POSIX, pass the renderer-side FD.
diff --git a/content/plugin/plugin_thread.h b/content/plugin/plugin_thread.h
index f967126..86c9b2d 100644
--- a/content/plugin/plugin_thread.h
+++ b/content/plugin/plugin_thread.h
@@ -25,6 +25,7 @@
public:
PluginThread();
virtual ~PluginThread();
+ virtual void Shutdown() OVERRIDE;
// Returns the one plugin thread.
static PluginThread* current();
diff --git a/content/plugin/webplugin_delegate_stub.cc b/content/plugin/webplugin_delegate_stub.cc
index 0adb0f9..5c25961 100644
--- a/content/plugin/webplugin_delegate_stub.cc
+++ b/content/plugin/webplugin_delegate_stub.cc
@@ -38,7 +38,7 @@
WebPlugin* webplugin) {
// The plugin may not expect us to try to release the scriptable object
// after calling NPP_Destroy on the instance, so delete the stub now.
- if (scriptable_object.get())
+ if (scriptable_object)
scriptable_object->DeleteSoon();
// WebPlugin must outlive WebPluginDelegate.
if (delegate)
@@ -65,9 +65,12 @@
if (channel_->in_send()) {
// The delegate or an npobject is in the callstack, so don't delete it
// right away.
- MessageLoop::current()->PostNonNestableTask(FROM_HERE,
- base::Bind(&DestroyWebPluginAndDelegate, plugin_scriptable_object_,
- delegate_, webplugin_));
+ base::MessageLoop::current()->PostNonNestableTask(
+ FROM_HERE,
+ base::Bind(&DestroyWebPluginAndDelegate,
+ plugin_scriptable_object_,
+ delegate_,
+ webplugin_));
} else {
// Safe to delete right away.
DestroyWebPluginAndDelegate(
diff --git a/content/plugin/webplugin_proxy.cc b/content/plugin/webplugin_proxy.cc
index 5ac898d..43e177c 100644
--- a/content/plugin/webplugin_proxy.cc
+++ b/content/plugin/webplugin_proxy.cc
@@ -69,7 +69,7 @@
page_url_(page_url),
windowless_buffer_index_(0),
host_render_view_routing_id_(host_render_view_routing_id),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ weak_factory_(this) {
#if defined(USE_X11)
windowless_shm_pixmaps_[0] = None;
windowless_shm_pixmaps_[1] = None;
@@ -102,7 +102,7 @@
#if defined(OS_MACOSX)
// Destroy the surface early, since it may send messages during cleanup.
- if (accelerated_surface_.get())
+ if (accelerated_surface_)
accelerated_surface_.reset();
#endif
@@ -199,9 +199,11 @@
waiting_for_paint_ = true;
// Invalidates caused by calls to NPN_InvalidateRect/NPN_InvalidateRgn
// need to be painted asynchronously as per the NPAPI spec.
- MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&WebPluginProxy::OnPaint, weak_factory_.GetWeakPtr(),
- damaged_rect_));
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&WebPluginProxy::OnPaint,
+ weak_factory_.GetWeakPtr(),
+ damaged_rect_));
damaged_rect_ = gfx::Rect();
}
}
@@ -275,7 +277,7 @@
}
int WebPluginProxy::GetRendererId() {
- if (channel_.get())
+ if (channel_)
return channel_->renderer_id();
return -1;
}
@@ -629,7 +631,7 @@
WebPluginAcceleratedSurface* WebPluginProxy::GetAcceleratedSurface(
gfx::GpuPreference gpu_preference) {
- if (!accelerated_surface_.get())
+ if (!accelerated_surface_)
accelerated_surface_.reset(
WebPluginAcceleratedSurfaceProxy::Create(this, gpu_preference));
return accelerated_surface_.get();
diff --git a/content/port/browser/render_view_host_delegate_view.h b/content/port/browser/render_view_host_delegate_view.h
index 85ef3da..9eced8c 100644
--- a/content/port/browser/render_view_host_delegate_view.h
+++ b/content/port/browser/render_view_host_delegate_view.h
@@ -50,7 +50,9 @@
// The user started dragging content of the specified type within the
// RenderView. Contextual information about the dragged content is supplied
- // by WebDropData.
+ // by WebDropData. If the delegate's view cannot start the drag for /any/
+ // reason, it must inform the renderer that the drag has ended; otherwise,
+ // this results in bugs like http://crbug.com/157134.
virtual void StartDragging(const WebDropData& drop_data,
WebKit::WebDragOperationsMask allowed_ops,
const gfx::ImageSkia& image,
diff --git a/content/port/browser/render_widget_host_view_frame_subscriber.h b/content/port/browser/render_widget_host_view_frame_subscriber.h
index de1ee089..fb88860 100644
--- a/content/port/browser/render_widget_host_view_frame_subscriber.h
+++ b/content/port/browser/render_widget_host_view_frame_subscriber.h
@@ -44,8 +44,9 @@
base::Time /* timestamp */,
bool /* frame_captured */)> DeliverFrameCallback;
- // Called when a new frame is going to be presented. Implementation can
- // decide whether the current frame should be captured or not.
+ // Called when a new frame is going to be presented at time
+ // |present_time|. Implementation can decide whether the current frame should
+ // be captured or not.
//
// Return true if the current frame should be captured. If so, |storage|
// should will be set to hold an appropriately sized and allocated buffer
@@ -61,6 +62,7 @@
//
// Return false if the current frame should not be captured.
virtual bool ShouldCaptureFrame(
+ base::Time present_time,
scoped_refptr<media::VideoFrame>* storage,
DeliverFrameCallback* callback) = 0;
};
diff --git a/content/port/browser/render_widget_host_view_port.h b/content/port/browser/render_widget_host_view_port.h
index 397d71d..46a96c2 100644
--- a/content/port/browser/render_widget_host_view_port.h
+++ b/content/port/browser/render_widget_host_view_port.h
@@ -280,6 +280,8 @@
virtual InputEventAckState FilterInputEvent(
const WebKit::WebInputEvent& input_event) = 0;
+ virtual void GestureEventAck(int gesture_event_type) = 0;
+
virtual void SetPopupType(WebKit::WebPopupType popup_type) = 0;
virtual WebKit::WebPopupType GetPopupType() = 0;
@@ -303,13 +305,6 @@
#if defined(OS_ANDROID)
virtual void ShowDisambiguationPopup(const gfx::Rect& target_rect,
const SkBitmap& zoomed_bitmap) = 0;
- virtual void UpdateFrameInfo(const gfx::Vector2dF& scroll_offset,
- float page_scale_factor,
- const gfx::Vector2dF& page_scale_factor_limits,
- const gfx::SizeF& content_size,
- const gfx::SizeF& viewport_size,
- const gfx::Vector2dF& controls_offset,
- const gfx::Vector2dF& content_offset) = 0;
virtual void HasTouchEventHandlers(bool need_touch_events) = 0;
#endif
diff --git a/content/ppapi_plugin/broker_process_dispatcher.cc b/content/ppapi_plugin/broker_process_dispatcher.cc
index d9dd974..68b6746 100644
--- a/content/ppapi_plugin/broker_process_dispatcher.cc
+++ b/content/ppapi_plugin/broker_process_dispatcher.cc
@@ -105,7 +105,7 @@
// plugin. This is the case for common plugins where they may be used on a
// source and destination page of a navigation. We don't want to tear down
// and re-start processes each time in these cases.
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&ChildProcess::ReleaseProcess,
base::Unretained(ChildProcess::current())),
@@ -304,7 +304,7 @@
return true;
std::string data_str = ConvertPluginDataPath(plugin_data_path);
- scoped_array<PP_Flash_BrowserOperations_SiteSetting> site_array(
+ scoped_ptr<PP_Flash_BrowserOperations_SiteSetting[]> site_array(
new PP_Flash_BrowserOperations_SiteSetting[sites.size()]);
for (size_t i = 0; i < sites.size(); ++i) {
diff --git a/content/ppapi_plugin/plugin_process_dispatcher.cc b/content/ppapi_plugin/plugin_process_dispatcher.cc
index 34d46ab..12fe91b 100644
--- a/content/ppapi_plugin/plugin_process_dispatcher.cc
+++ b/content/ppapi_plugin/plugin_process_dispatcher.cc
@@ -32,7 +32,7 @@
// plugin. This is the case for common plugins where they may be used on a
// source and destination page of a navigation. We don't want to tear down
// and re-start processes each time in these cases.
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&ChildProcess::ReleaseProcess,
base::Unretained(ChildProcess::current())),
diff --git a/content/ppapi_plugin/ppapi_broker_main.cc b/content/ppapi_plugin/ppapi_broker_main.cc
index 04315f5..e2c6097 100644
--- a/content/ppapi_plugin/ppapi_broker_main.cc
+++ b/content/ppapi_plugin/ppapi_broker_main.cc
@@ -19,7 +19,7 @@
ChildProcess::WaitForDebugger("PpapiBroker");
}
- MessageLoop main_message_loop(MessageLoop::TYPE_DEFAULT);
+ base::MessageLoop main_message_loop(base::MessageLoop::TYPE_DEFAULT);
base::PlatformThread::SetName("CrPPAPIBrokerMain");
ChildProcess ppapi_broker_process;
diff --git a/content/ppapi_plugin/ppapi_plugin_main.cc b/content/ppapi_plugin/ppapi_plugin_main.cc
index 9db7f2f..25ea26e 100644
--- a/content/ppapi_plugin/ppapi_plugin_main.cc
+++ b/content/ppapi_plugin/ppapi_plugin_main.cc
@@ -9,6 +9,7 @@
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
#include "content/common/child_process.h"
+#include "content/common/sandbox_linux.h"
#include "content/ppapi_plugin/ppapi_thread.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
@@ -78,7 +79,7 @@
#endif
}
- MessageLoop main_message_loop;
+ base::MessageLoop main_message_loop;
base::PlatformThread::SetName("CrPPAPIMain");
#if defined(OS_LINUX) && defined(USE_NSS)
@@ -93,7 +94,7 @@
GetContentClient()->plugin()->PreSandboxInitialization();
#if defined(OS_LINUX)
- InitializeSandbox();
+ LinuxSandbox::InitializeSandbox();
#endif
ChildProcess ppapi_process;
diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc
index e0bfb78..4f4be32 100644
--- a/content/ppapi_plugin/ppapi_thread.cc
+++ b/content/ppapi_plugin/ppapi_thread.cc
@@ -9,6 +9,7 @@
#include "base/command_line.h"
#include "base/debug/crash_logging.h"
#include "base/logging.h"
+#include "base/metrics/histogram.h"
#include "base/process_util.h"
#include "base/rand_util.h"
#include "base/stringprintf.h"
@@ -88,13 +89,11 @@
local_pp_module_(
base::RandInt(0, std::numeric_limits<PP_Module>::max())),
next_plugin_dispatcher_id_(1),
- ALLOW_THIS_IN_INITIALIZER_LIST(dispatcher_message_listener_(this)) {
+ dispatcher_message_listener_(this) {
ppapi::proxy::PluginGlobals* globals = ppapi::proxy::PluginGlobals::Get();
globals->set_plugin_proxy_delegate(this);
globals->set_command_line(
command_line.GetSwitchValueASCII(switches::kPpapiFlashArgs));
- globals->set_enable_threading(
- !command_line.HasSwitch(switches::kDisablePepperThreading));
webkit_platform_support_.reset(new PpapiWebKitPlatformSupportImpl);
WebKit::initialize(webkit_platform_support_.get());
@@ -114,6 +113,9 @@
}
PpapiThread::~PpapiThread() {
+}
+
+void PpapiThread::Shutdown() {
ppapi::proxy::PluginGlobals::Get()->set_plugin_proxy_delegate(NULL);
if (plugin_entry_points_.shutdown_module)
plugin_entry_points_.shutdown_module();
@@ -127,7 +129,7 @@
bool PpapiThread::Send(IPC::Message* msg) {
// Allow access from multiple threads.
- if (MessageLoop::current() == message_loop())
+ if (base::MessageLoop::current() == message_loop())
return ChildThread::Send(msg);
return sync_message_filter()->Send(msg);
@@ -261,6 +263,7 @@
if (!library.is_valid()) {
LOG(ERROR) << "Failed to load Pepper module from "
<< path.value() << " (error: " << error << ")";
+ ReportLoadResult(path, LOAD_FAILED);
return;
}
@@ -270,6 +273,7 @@
library.GetFunctionPointer("PPP_GetInterface"));
if (!plugin_entry_points_.get_interface) {
LOG(WARNING) << "No PPP_GetInterface in plugin library";
+ ReportLoadResult(path, ENTRY_POINT_MISSING);
return;
}
@@ -288,6 +292,7 @@
library.GetFunctionPointer("PPP_InitializeModule"));
if (!plugin_entry_points_.initialize_module) {
LOG(WARNING) << "No PPP_InitializeModule in plugin library";
+ ReportLoadResult(path, ENTRY_POINT_MISSING);
return;
}
}
@@ -325,16 +330,19 @@
library.GetFunctionPointer("PPP_InitializeBroker"));
if (!init_broker) {
LOG(WARNING) << "No PPP_InitializeBroker in plugin library";
+ ReportLoadResult(path, ENTRY_POINT_MISSING);
return;
}
int32_t init_error = init_broker(&connect_instance_func_);
if (init_error != PP_OK) {
LOG(WARNING) << "InitBroker failed with error " << init_error;
+ ReportLoadResult(path, INIT_FAILED);
return;
}
if (!connect_instance_func_) {
LOG(WARNING) << "InitBroker did not provide PP_ConnectInstance_Func";
+ ReportLoadResult(path, INIT_FAILED);
return;
}
} else {
@@ -350,12 +358,15 @@
&ppapi::proxy::PluginDispatcher::GetBrowserInterface);
if (init_error != PP_OK) {
LOG(WARNING) << "InitModule failed with error " << init_error;
+ ReportLoadResult(path, INIT_FAILED);
return;
}
}
// Initialization succeeded, so keep the plugin DLL loaded.
library_.Reset(library.Release());
+
+ ReportLoadResult(path, LOAD_SUCCESS);
}
void PpapiThread::OnCreateChannel(base::ProcessId renderer_pid,
@@ -461,7 +472,7 @@
ppapi::proxy::PluginGlobals::Get()->set_plugin_name(
path.BaseName().AsUTF8Unsafe());
- // plugin() is NULL when in-process. Which is fine, because this is
+ // plugin() is NULL when in-process, which is fine, because this is
// just a hook for setting the process name.
if (GetContentClient()->plugin()) {
GetContentClient()->plugin()->PluginProcessStarted(
@@ -469,4 +480,24 @@
}
}
+void PpapiThread::ReportLoadResult(const base::FilePath& path,
+ LoadResult result) {
+ DCHECK_LT(result, LOAD_RESULT_MAX);
+
+ std::ostringstream histogram_name;
+ histogram_name << "Plugin.Ppapi" << (is_broker_ ? "Broker" : "Plugin")
+ << "LoadResult_" << path.BaseName().MaybeAsASCII();
+
+ // Note: This leaks memory, which is expected behavior.
+ base::HistogramBase* histogram =
+ base::LinearHistogram::FactoryGet(
+ histogram_name.str(),
+ 1,
+ LOAD_RESULT_MAX,
+ LOAD_RESULT_MAX + 1,
+ base::HistogramBase::kUmaTargetedHistogramFlag);
+
+ histogram->Add(result);
+}
+
} // namespace content
diff --git a/content/ppapi_plugin/ppapi_thread.h b/content/ppapi_plugin/ppapi_thread.h
index 0e21d56..7faff6b 100644
--- a/content/ppapi_plugin/ppapi_thread.h
+++ b/content/ppapi_plugin/ppapi_thread.h
@@ -47,8 +47,20 @@
public:
PpapiThread(const CommandLine& command_line, bool is_broker);
virtual ~PpapiThread();
+ virtual void Shutdown() OVERRIDE;
private:
+ // Make sure the enum list in tools/histogram/histograms.xml is updated with
+ // any change in this list.
+ enum LoadResult {
+ LOAD_SUCCESS,
+ LOAD_FAILED,
+ ENTRY_POINT_MISSING,
+ INIT_FAILED,
+ // NOTE: Add new values only immediately above this line.
+ LOAD_RESULT_MAX // Boundary value for UMA_HISTOGRAM_ENUMERATION.
+ };
+
// This class finds the target PluginDispatcher for each message it receives
// and forwards the message.
class DispatcherMessageListener : public IPC::Listener {
@@ -113,6 +125,8 @@
// Sets up the name of the plugin for logging using the given path.
void SavePluginName(const base::FilePath& path);
+ void ReportLoadResult(const base::FilePath& path, LoadResult result);
+
// True if running in a broker process rather than a normal plugin process.
bool is_broker_;
diff --git a/content/public/android/java/res/values/official-command-line.xml b/content/public/android/java/res/values/official-command-line.xml
deleted file mode 100644
index 4589501..0000000
--- a/content/public/android/java/res/values/official-command-line.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<resources>
- <string-array name="official_command_line">
- <!-- Note: this value will be overridden by the identically named resource (if
- one exists) in the apk that is being built. -->
- <!-- Format: double-dashed command-line flags within <item></item> blocks. -->
- </string-array>
-</resources>
diff --git a/content/public/android/java/resource_map/org/chromium/content/R.java b/content/public/android/java/resource_map/org/chromium/content/R.java
index 47653c2..daa8a77 100644
--- a/content/public/android/java/resource_map/org/chromium/content/R.java
+++ b/content/public/android/java/resource_map/org/chromium/content/R.java
@@ -16,9 +16,6 @@
* com.android.internal.R.
*/
public final class R {
- public static final class array {
- public static int official_command_line;
- }
public static final class dimen {
public static int link_preview_overlay_radius;
}
diff --git a/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java b/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java
index 240cf5b..3d85310 100644
--- a/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java
+++ b/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java
@@ -46,7 +46,6 @@
// This is the native "Main" thread for the renderer / utility process.
private Thread mMainThread;
// Parameters received via IPC, only accessed while holding the mMainThread monitor.
- private String mNativeLibraryName; // Must be passed in via the bind command.
private String[] mCommandLineParams;
private int mCpuCount;
private long mCpuFeatures;
@@ -113,12 +112,6 @@
@Override
public void run() {
try {
- synchronized (mMainThread) {
- while (mNativeLibraryName == null) {
- mMainThread.wait();
- }
- }
- LibraryLoader.setLibraryToLoad(mNativeLibraryName);
try {
LibraryLoader.loadNow();
} catch (ProcessInitException e) {
@@ -193,8 +186,6 @@
stopSelf();
synchronized (mMainThread) {
- mNativeLibraryName = intent.getStringExtra(
- ChildProcessConnection.EXTRA_NATIVE_LIBRARY_NAME);
mCommandLineParams = intent.getStringArrayExtra(
ChildProcessConnection.EXTRA_COMMAND_LINE);
mMainThread.notifyAll();
diff --git a/content/public/android/java/src/org/chromium/content/app/LibraryLoader.java b/content/public/android/java/src/org/chromium/content/app/LibraryLoader.java
index abd1ef1..38cd2df 100644
--- a/content/public/android/java/src/org/chromium/content/app/LibraryLoader.java
+++ b/content/public/android/java/src/org/chromium/content/app/LibraryLoader.java
@@ -14,17 +14,15 @@
import org.chromium.content.common.TraceEvent;
/**
- * This class provides functionality to load and register the native library.
- * Callers are allowed to separate loading the library from initializing it.
- * This may be an advantage for Android Webview, where the library can be loaded
+ * This class provides functionality to load and register the native libraries.
+ * Callers are allowed to separate loading the libraries from initializing them.
+ * This may be an advantage for Android Webview, where the libraries can be loaded
* by the zygote process, but then needs per process initialization after the
* application processes are forked from the zygote process.
*
- * The library may be loaded and initialized from any thread. Synchronization
+ * The libraries may be loaded and initialized from any thread. Synchronization
* primitives are used to ensure that overlapping requests from different
- * threads are handled sequentially; however, care must still be taken to
- * ensure that {@link #setLibraryToLoad(String)} is called prior to invoking
- * {@link #loadNow()} or {@link #ensureInitialized()}.
+ * threads are handled sequentially.
*
* See also content/app/android/library_loader_hooks.cc, which contains
* the native counterpart to this class.
@@ -33,45 +31,23 @@
public class LibraryLoader {
private static final String TAG = "LibraryLoader";
- // The name of the library that will be loaded. Ideally this is a
- // write-once, read-many value, but for the sake of unit tests
- // we allow it to be mutated arbitrarily.
- private static String sLibrary = null;
-
- // Guards all access to the library
+ // Guards all access to the libraries
private static final Object sLock = new Object();
- // One-way switch becomes true when the library is loaded.
+ // One-way switch becomes true when the libraries are loaded.
private static boolean sLoaded = false;
- // One-way switch becomes true when the library is initialized (
+ // One-way switch becomes true when the libraries are initialized (
// by calling nativeLibraryLoaded, which forwards to LibraryLoaded(...) in
// library_loader_hooks.cc).
private static boolean sInitialized = false;
-
+ // TODO(cjhopman): Remove this once it's unused.
/**
- * Sets the library name that is to be loaded. This must be called prior to the library being
- * loaded the first time. Outside of testing, this should only be called once.
- *
- * @param library The name of the library to be loaded (without the lib prefix).
+ * Doesn't do anything.
*/
+ @Deprecated
public static void setLibraryToLoad(String library) {
- synchronized(sLock) {
- if (TextUtils.equals(sLibrary, library)) return;
-
- assert !sLoaded : "Setting the library must happen before load is called.";
- sLibrary = library;
- }
- }
-
- /**
- * @return The name of the native library set to be loaded.
- */
- public static String getLibraryToLoad() {
- synchronized(sLock) {
- return sLibrary;
- }
}
/**
@@ -121,15 +97,14 @@
// Invoke System.loadLibrary(...), triggering JNI_OnLoad in native code
private static void loadAlreadyLocked() throws ProcessInitException {
- if (sLibrary == null) {
- assert false : "No library specified to load. Call setLibraryToLoad before first.";
- }
try {
if (!sLoaded) {
assert !sInitialized;
- Log.i(TAG, "loading: " + sLibrary);
- System.loadLibrary(sLibrary);
- Log.i(TAG, "loaded: " + sLibrary);
+ for (String sLibrary : NativeLibraries.libraries) {
+ Log.i(TAG, "loading: " + sLibrary);
+ System.loadLibrary(sLibrary);
+ Log.i(TAG, "loaded: " + sLibrary);
+ }
sLoaded = true;
}
} catch (UnsatisfiedLinkError e) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnection.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnection.java
index ce9a164..cfd5f54 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnection.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnection.java
@@ -36,8 +36,6 @@
// Names of items placed in the bind intent or connection bundle.
public static final String EXTRA_COMMAND_LINE =
"com.google.android.apps.chrome.extra.command_line";
- public static final String EXTRA_NATIVE_LIBRARY_NAME =
- "com.google.android.apps.chrome.extra.native_library_name";
// Note the FDs may only be passed in the connection bundle.
public static final String EXTRA_FILES_PREFIX =
"com.google.android.apps.chrome.extra.extraFile_";
@@ -128,19 +126,16 @@
* to setup the connection parameters. (These methods are separated to allow the client
* to pass whatever parameters they have available here, and complete the remainder
* later while reducing the connection setup latency).
- * @param nativeLibraryName The name of the shared native library to be loaded for the
- * child process.
* @param commandLine (Optional) Command line for the child process. If omitted, then
* the command line parameters must instead be passed to setupConnection().
*/
- void bind(String nativeLibraryName, String[] commandLine) {
+ void bind(String[] commandLine) {
synchronized(mUiThreadLock) {
TraceEvent.begin();
assert !ThreadUtils.runningOnUiThread();
final Intent intent = createServiceBindIntent();
- intent.putExtra(EXTRA_NATIVE_LIBRARY_NAME, nativeLibraryName);
if (commandLine != null) {
intent.putExtra(EXTRA_COMMAND_LINE, commandLine);
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java
index 5ddc008..92669a6 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java
@@ -18,7 +18,6 @@
import org.chromium.content.app.ChildProcessService;
import org.chromium.content.app.PrivilegedProcessService;
import org.chromium.content.app.SandboxedProcessService;
-import org.chromium.content.app.LibraryLoader;
import org.chromium.content.common.IChildProcessCallback;
import org.chromium.content.common.IChildProcessService;
@@ -155,10 +154,7 @@
String[] commandLine, boolean inSandbox) {
ChildProcessConnection connection = allocateConnection(context, inSandbox);
if (connection != null) {
- String libraryName = LibraryLoader.getLibraryToLoad();
- assert libraryName != null : "Attempting to launch a child process without first "
- + "calling LibraryLoader.setLibraryToLoad";
- connection.bind(libraryName, commandLine);
+ connection.bind(commandLine);
}
return connection;
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContainerViewDelegate.java b/content/public/android/java/src/org/chromium/content/browser/ContainerViewDelegate.java
deleted file mode 100644
index 8417345..0000000
--- a/content/public/android/java/src/org/chromium/content/browser/ContainerViewDelegate.java
+++ /dev/null
@@ -1,25 +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.
-
-package org.chromium.content.browser;
-
-import android.view.View;
-
-/**
- * Interface to add and remove views from the implementing view.
- */
-public interface ContainerViewDelegate {
-
- /**
- * Add the view.
- * @param view The view to be added.
- */
- public void addViewToContainerView(View view);
-
- /**
- * Remove the view if it is present, otherwise do nothing.
- * @param view The view to be removed.
- */
- public void removeViewFromContainerView(View view);
-}
\ No newline at end of file
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentSettings.java b/content/public/android/java/src/org/chromium/content/browser/ContentSettings.java
index 5f3e8d3..df03f00 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentSettings.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentSettings.java
@@ -7,13 +7,13 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.webkit.WebSettings.PluginState;
-import android.webkit.WebView;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.base.ThreadUtils;
+import java.util.concurrent.Callable;
+
/**
* Manages settings state for a ContentView. A ContentSettings instance is obtained
* from ContentView.getContentSettings(). If ContentView is used in the
@@ -22,14 +22,6 @@
*/
@JNINamespace("content")
public class ContentSettings {
- // This enum corresponds to WebSettings.LayoutAlgorithm. We use our own to be
- // able to extend it.
- public enum LayoutAlgorithm {
- NORMAL,
- SINGLE_COLUMN,
- NARROW_COLUMNS,
- TEXT_AUTOSIZING,
- }
private static final String TAG = "ContentSettings";
@@ -43,164 +35,40 @@
private ContentViewCore mContentViewCore;
- // When ContentView is used in PERSONALITY_CHROME mode, settings can't
- // be modified through the ContentSettings instance.
- private boolean mCanModifySettings;
-
- // A flag to avoid sending superfluous synchronization messages.
- private boolean mIsSyncMessagePending = false;
// Custom handler that queues messages to call native code on the UI thread.
private final EventHandler mEventHandler;
// Protects access to settings fields.
private final Object mContentSettingsLock = new Object();
- private static final int MINIMUM_FONT_SIZE = 1;
- private static final int MAXIMUM_FONT_SIZE = 72;
-
- // Private settings so we don't have to go into native code to
- // retrieve the values. After setXXX, mEventHandler.syncSettingsLocked() needs to be called.
- //
- // TODO(mnaganov): populate with the complete set of legacy WebView settings.
- // Note: If adding a new setting to this class, make sure to add it to the initFrom()
- // method defined below.
-
- private LayoutAlgorithm mLayoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS;
- private int mTextSizePercent = 100;
- private String mStandardFontFamily = "sans-serif";
- private String mFixedFontFamily = "monospace";
- private String mSansSerifFontFamily = "sans-serif";
- private String mSerifFontFamily = "serif";
- private String mCursiveFontFamily = "cursive";
- private String mFantasyFontFamily = "fantasy";
- // FIXME: Should be obtained from Android. Problem: it is hidden.
- private String mDefaultTextEncoding = "Latin-1";
- private String mUserAgent;
- private int mMinimumFontSize = 8;
- private int mMinimumLogicalFontSize = 8;
- private int mDefaultFontSize = 16;
- private int mDefaultFixedFontSize = 13;
- private boolean mLoadsImagesAutomatically = true;
- private boolean mImagesEnabled = true;
- private boolean mJavaScriptEnabled = false;
- private boolean mAllowUniversalAccessFromFileURLs = false;
- private boolean mAllowFileAccessFromFileURLs = false;
- private boolean mJavaScriptCanOpenWindowsAutomatically = false;
- private boolean mSupportMultipleWindows = false;
- private PluginState mPluginState = PluginState.OFF;
- private boolean mAppCacheEnabled = false;
- private boolean mDomStorageEnabled = false;
- private boolean mDatabaseEnabled = false;
- private boolean mUseWideViewport = false;
- private boolean mLoadWithOverviewMode = false;
- private boolean mMediaPlaybackRequiresUserGesture = true;
- private String mDefaultVideoPosterURL;
-
- // Not accessed by the native side.
private boolean mSupportZoom = true;
private boolean mBuiltInZoomControls = false;
private boolean mDisplayZoomControls = true;
- static class LazyDefaultUserAgent {
- // Lazy Holder pattern
- private static final String sInstance = nativeGetDefaultUserAgent();
- }
-
- // Protects access to settings global fields.
- private static final Object sGlobalContentSettingsLock = new Object();
- // For compatibility with the legacy WebView, we can only enable AppCache when the path is
- // provided. However, we don't use the path, so we just check if we have received it from the
- // client.
- private static boolean sAppCachePathIsSet = false;
// Class to handle messages to be processed on the UI thread.
private class EventHandler {
- // Message id for syncing
- private static final int SYNC = 0;
- // Message id for updating user agent in the view
- private static final int UPDATE_UA = 1;
// Message id for updating multi-touch zoom state in the view
private static final int UPDATE_MULTI_TOUCH = 2;
// Actual UI thread handler
private Handler mHandler;
EventHandler() {
- mHandler = mContentViewCore.isPersonalityView() ?
- new Handler(Looper.getMainLooper()) {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case SYNC:
- synchronized (mContentSettingsLock) {
- syncToNativeOnUiThread();
- mIsSyncMessagePending = false;
- mContentSettingsLock.notifyAll();
- }
- break;
- case UPDATE_UA:
- if (mContentViewCore.isAlive()) {
- mContentViewCore.setAllUserAgentOverridesInHistory();
- }
- break;
- case UPDATE_MULTI_TOUCH:
- if (mContentViewCore.isAlive()) {
- mContentViewCore.updateMultiTouchZoomSupport();
- }
- break;
- }
- }
- } :
- new Handler(Looper.getMainLooper()) {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case SYNC:
- synchronized (mContentSettingsLock) {
- syncFromNativeOnUiThread();
- mIsSyncMessagePending = false;
- }
- break;
- }
- }
- };
- }
-
- private void syncSettingsLocked() {
- assert Thread.holdsLock(mContentSettingsLock);
- if (mNativeContentSettings == 0) return;
if (mContentViewCore.isPersonalityView()) {
- if (Looper.myLooper() == mHandler.getLooper()) {
- syncToNativeOnUiThread();
- } else {
- // We're being called on a background thread, so post a message.
- if (mIsSyncMessagePending) {
- return;
- }
- mIsSyncMessagePending = true;
- mHandler.sendMessage(Message.obtain(null, SYNC));
- // When used in PERSONALITY_VIEW mode, we must block
- // until the settings have been sync'd to native to
- // ensure that they have taken effect.
- try {
- while (mIsSyncMessagePending) {
- mContentSettingsLock.wait();
+ mHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case UPDATE_MULTI_TOUCH:
+ if (mContentViewCore.isAlive()) {
+ mContentViewCore.updateMultiTouchZoomSupport();
+ }
+ break;
}
- } catch (InterruptedException e) {}
- }
- } else {
- if (mIsSyncMessagePending) {
- return;
- }
- mIsSyncMessagePending = true;
- mHandler.sendMessage(Message.obtain(null, SYNC));
+ }
+ };
}
}
- private void sendUpdateUaMessageLocked() {
- assert Thread.holdsLock(mContentSettingsLock);
- if (mNativeContentSettings == 0) return;
- mHandler.sendMessage(Message.obtain(null, UPDATE_UA));
- }
-
private void sendUpdateMultiTouchMessageLocked() {
assert Thread.holdsLock(mContentSettingsLock);
if (mNativeContentSettings == 0) return;
@@ -212,31 +80,16 @@
* Package constructor to prevent clients from creating a new settings
* instance. Must be called on the UI thread.
*/
- ContentSettings(ContentViewCore contentViewCore, int nativeContentView,
- boolean isAccessFromFileURLsGrantedByDefault) {
+ ContentSettings(ContentViewCore contentViewCore, int nativeContentView) {
ThreadUtils.assertOnUiThread();
mContentViewCore = contentViewCore;
- mCanModifySettings = mContentViewCore.isPersonalityView();
- mNativeContentSettings = nativeInit(nativeContentView, mCanModifySettings);
+ mNativeContentSettings = nativeInit(nativeContentView);
assert mNativeContentSettings != 0;
- if (isAccessFromFileURLsGrantedByDefault) {
- mAllowUniversalAccessFromFileURLs = true;
- mAllowFileAccessFromFileURLs = true;
- }
-
mEventHandler = new EventHandler();
- if (mCanModifySettings) {
- // PERSONALITY_VIEW
- mUserAgent = LazyDefaultUserAgent.sInstance;
- syncToNativeOnUiThread();
- } else {
- // PERSONALITY_CHROME
- // Chrome has zooming enabled by default. These settings are not
- // set by the native code.
+ if (!mContentViewCore.isPersonalityView()) {
mBuiltInZoomControls = true;
mDisplayZoomControls = false;
- syncFromNativeOnUiThread();
}
}
@@ -251,43 +104,6 @@
}
/**
- * @returns the default User-Agent used by each ContentViewCore instance, i.e. unless
- * overridden by {@link #setUserAgentString()}
- */
- public static String getDefaultUserAgent() {
- return LazyDefaultUserAgent.sInstance;
- }
-
- /**
- * Set the WebView's user-agent string. If the string "ua" is null or empty,
- * it will use the system default user-agent string.
- */
- public void setUserAgentString(String ua) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- final String oldUserAgent = mUserAgent;
- if (ua == null || ua.length() == 0) {
- mUserAgent = LazyDefaultUserAgent.sInstance;
- } else {
- mUserAgent = ua;
- }
- if (!oldUserAgent.equals(mUserAgent)) {
- mEventHandler.sendUpdateUaMessageLocked();
- }
- }
- }
-
- /**
- * Gets the WebView's user-agent string.
- */
- public String getUserAgentString() {
- // TODO(mnaganov): Doesn't reflect changes made by ChromeNativePreferences.
- synchronized (mContentSettingsLock) {
- return mUserAgent;
- }
- }
-
- /**
* Sets whether the WebView should support zooming using its on-screen zoom
* controls and gestures. The particular zoom mechanisms that should be used
* can be set with {@link #setBuiltInZoomControls}. This setting does not
@@ -379,874 +195,22 @@
return supportsMultiTouchZoom() && mDisplayZoomControls;
}
- public void setLoadWithOverviewMode(boolean overview) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mLoadWithOverviewMode != overview) {
- mLoadWithOverviewMode = overview;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- public boolean getLoadWithOverviewMode() {
- synchronized (mContentSettingsLock) {
- return mLoadWithOverviewMode;
- }
- }
-
/**
- * Sets the text zoom of the page in percent. Default is 100.
- *
- * @param textZoom the percent value for increasing or decreasing the text
- */
- public void setTextZoom(int textZoom) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mTextSizePercent != textZoom) {
- mTextSizePercent = textZoom;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Gets the text zoom of the page in percent.
- *
- * @return a percent value describing the text zoom
- * @see #setTextSizeZoom
- */
- public int getTextZoom() {
- synchronized (mContentSettingsLock) {
- return mTextSizePercent;
- }
- }
-
- /**
- * Set the standard font family name.
- * @param font A font family name.
- */
- public void setStandardFontFamily(String font) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (font != null && !mStandardFontFamily.equals(font)) {
- mStandardFontFamily = font;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Get the standard font family name. The default is "sans-serif".
- * @return The standard font family name as a string.
- */
- public String getStandardFontFamily() {
- synchronized (mContentSettingsLock) {
- return mStandardFontFamily;
- }
- }
-
- /**
- * Set the fixed font family name.
- * @param font A font family name.
- */
- public void setFixedFontFamily(String font) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (font != null && !mFixedFontFamily.equals(font)) {
- mFixedFontFamily = font;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Get the fixed font family name. The default is "monospace".
- * @return The fixed font family name as a string.
- */
- public String getFixedFontFamily() {
- synchronized (mContentSettingsLock) {
- return mFixedFontFamily;
- }
- }
-
- /**
- * Set the sans-serif font family name.
- * @param font A font family name.
- */
- public void setSansSerifFontFamily(String font) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (font != null && !mSansSerifFontFamily.equals(font)) {
- mSansSerifFontFamily = font;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Get the sans-serif font family name.
- * @return The sans-serif font family name as a string.
- */
- public String getSansSerifFontFamily() {
- synchronized (mContentSettingsLock) {
- return mSansSerifFontFamily;
- }
- }
-
- /**
- * Set the serif font family name. The default is "sans-serif".
- * @param font A font family name.
- */
- public void setSerifFontFamily(String font) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (font != null && !mSerifFontFamily.equals(font)) {
- mSerifFontFamily = font;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Get the serif font family name. The default is "serif".
- * @return The serif font family name as a string.
- */
- public String getSerifFontFamily() {
- synchronized (mContentSettingsLock) {
- return mSerifFontFamily;
- }
- }
-
- /**
- * Set the cursive font family name.
- * @param font A font family name.
- */
- public void setCursiveFontFamily(String font) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (font != null && !mCursiveFontFamily.equals(font)) {
- mCursiveFontFamily = font;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Get the cursive font family name. The default is "cursive".
- * @return The cursive font family name as a string.
- */
- public String getCursiveFontFamily() {
- synchronized (mContentSettingsLock) {
- return mCursiveFontFamily;
- }
- }
-
- /**
- * Set the fantasy font family name.
- * @param font A font family name.
- */
- public void setFantasyFontFamily(String font) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (font != null && !mFantasyFontFamily.equals(font)) {
- mFantasyFontFamily = font;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Get the fantasy font family name. The default is "fantasy".
- * @return The fantasy font family name as a string.
- */
- public String getFantasyFontFamily() {
- synchronized (mContentSettingsLock) {
- return mFantasyFontFamily;
- }
- }
-
- /**
- * Set the minimum font size.
- * @param size A non-negative integer between 1 and 72.
- * Any number outside the specified range will be pinned.
- */
- public void setMinimumFontSize(int size) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- size = clipFontSize(size);
- if (mMinimumFontSize != size) {
- mMinimumFontSize = size;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Get the minimum font size. The default is 8.
- * @return A non-negative integer between 1 and 72.
- */
- public int getMinimumFontSize() {
- synchronized (mContentSettingsLock) {
- return mMinimumFontSize;
- }
- }
-
- /**
- * Set the minimum logical font size.
- * @param size A non-negative integer between 1 and 72.
- * Any number outside the specified range will be pinned.
- */
- public void setMinimumLogicalFontSize(int size) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- size = clipFontSize(size);
- if (mMinimumLogicalFontSize != size) {
- mMinimumLogicalFontSize = size;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Get the minimum logical font size. The default is 8.
- * @return A non-negative integer between 1 and 72.
- */
- public int getMinimumLogicalFontSize() {
- synchronized (mContentSettingsLock) {
- return mMinimumLogicalFontSize;
- }
- }
-
- /**
- * Set the default font size.
- * @param size A non-negative integer between 1 and 72.
- * Any number outside the specified range will be pinned.
- */
- public void setDefaultFontSize(int size) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- size = clipFontSize(size);
- if (mDefaultFontSize != size) {
- mDefaultFontSize = size;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Get the default font size. The default is 16.
- * @return A non-negative integer between 1 and 72.
- */
- public int getDefaultFontSize() {
- synchronized (mContentSettingsLock) {
- return mDefaultFontSize;
- }
- }
-
- /**
- * Set the default fixed font size.
- * @param size A non-negative integer between 1 and 72.
- * Any number outside the specified range will be pinned.
- */
- public void setDefaultFixedFontSize(int size) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- size = clipFontSize(size);
- if (mDefaultFixedFontSize != size) {
- mDefaultFixedFontSize = size;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Get the default fixed font size. The default is 16.
- * @return A non-negative integer between 1 and 72.
- */
- public int getDefaultFixedFontSize() {
- synchronized (mContentSettingsLock) {
- return mDefaultFixedFontSize;
- }
- }
-
- /**
- * Tell the WebView to enable JavaScript execution.
- *
- * @param flag True if the WebView should execute JavaScript.
- */
- public void setJavaScriptEnabled(boolean flag) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mJavaScriptEnabled != flag) {
- mJavaScriptEnabled = flag;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Sets whether JavaScript running in the context of a file scheme URL
- * should be allowed to access content from any origin. This includes
- * access to content from other file scheme URLs. See
- * {@link #setAllowFileAccessFromFileURLs}. To enable the most restrictive,
- * and therefore secure policy, this setting should be disabled.
- * <p>
- * The default value is true for API level
- * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1} and below,
- * and false for API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN}
- * and above.
- *
- * @param flag whether JavaScript running in the context of a file scheme
- * URL should be allowed to access content from any origin
- */
- public void setAllowUniversalAccessFromFileURLs(boolean flag) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mAllowUniversalAccessFromFileURLs != flag) {
- mAllowUniversalAccessFromFileURLs = flag;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Sets whether JavaScript running in the context of a file scheme URL
- * should be allowed to access content from other file scheme URLs. To
- * enable the most restrictive, and therefore secure policy, this setting
- * should be disabled. Note that the value of this setting is ignored if
- * the value of {@link #getAllowUniversalAccessFromFileURLs} is true.
- * <p>
- * The default value is true for API level
- * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1} and below,
- * and false for API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN}
- * and above.
- *
- * @param flag whether JavaScript running in the context of a file scheme
- * URL should be allowed to access content from other file
- * scheme URLs
- */
- public void setAllowFileAccessFromFileURLs(boolean flag) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mAllowFileAccessFromFileURLs != flag) {
- mAllowFileAccessFromFileURLs = flag;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Tell the WebView to load image resources automatically.
- * Note that setting this flag to false this does not block image loads
- * from WebCore cache.
- * @param flag True if the WebView should load images automatically.
- */
- public void setLoadsImagesAutomatically(boolean flag) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mLoadsImagesAutomatically != flag) {
- mLoadsImagesAutomatically = flag;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Return true if the WebView will load image resources automatically.
- * The default is true.
- * @return True if the WebView loads images automatically.
- */
- public boolean getLoadsImagesAutomatically() {
- synchronized (mContentSettingsLock) {
- return mLoadsImagesAutomatically;
- }
- }
-
- /**
- * Sets whether images are enabled for this WebView. Setting this from
- * false to true will reload the blocked images in place.
- * Note that unlike {@link #setLoadsImagesAutomatically}, setting this
- * flag to false this will block image loads from WebCore cache as well.
- * The default is true.
- * @param flag whether the WebView should enable images.
- */
- public void setImagesEnabled(boolean flag) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mImagesEnabled != flag) {
- mImagesEnabled = flag;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Gets whether images are enabled for this WebView.
- * @return true if the WebView has images eanbled
- */
- public boolean getImagesEnabled() {
- synchronized (mContentSettingsLock) {
- return mImagesEnabled;
- }
- }
-
- /**
- * Return true if JavaScript is enabled. <b>Note: The default is false.</b>
+ * Return true if JavaScript is enabled.
*
* @return True if JavaScript is enabled.
*/
public boolean getJavaScriptEnabled() {
- synchronized (mContentSettingsLock) {
- return mJavaScriptEnabled;
- }
- }
-
- /**
- * Gets whether JavaScript running in the context of a file scheme URL can
- * access content from any origin. This includes access to content from
- * other file scheme URLs.
- *
- * @return whether JavaScript running in the context of a file scheme URL
- * can access content from any origin
- * @see #setAllowUniversalAccessFromFileURLs
- */
- public boolean getAllowUniversalAccessFromFileURLs() {
- synchronized (mContentSettingsLock) {
- return mAllowUniversalAccessFromFileURLs;
- }
- }
-
- /**
- * Gets whether JavaScript running in the context of a file scheme URL can
- * access content from other file scheme URLs.
- *
- * @return whether JavaScript running in the context of a file scheme URL
- * can access content from other file scheme URLs
- * @see #setAllowFileAccessFromFileURLs
- */
- public boolean getAllowFileAccessFromFileURLs() {
- synchronized (mContentSettingsLock) {
- return mAllowFileAccessFromFileURLs;
- }
- }
-
- /**
- * Tell the WebView to enable plugins.
- * @param flag True if the WebView should load plugins.
- * @deprecated This method has been deprecated in favor of
- * {@link #setPluginState}
- */
- @Deprecated
- public void setPluginsEnabled(boolean flag) {
- assert mCanModifySettings;
- setPluginState(flag ? PluginState.ON : PluginState.OFF);
- }
-
- /**
- * Tell the WebView to enable, disable, or have plugins on demand. On
- * demand mode means that if a plugin exists that can handle the embedded
- * content, a placeholder icon will be shown instead of the plugin. When
- * the placeholder is clicked, the plugin will be enabled.
- * @param state One of the PluginState values.
- */
- public void setPluginState(PluginState state) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mPluginState != state) {
- mPluginState = state;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Return true if plugins are enabled.
- * @return True if plugins are enabled.
- * @deprecated This method has been replaced by {@link #getPluginState}
- */
- @Deprecated
- public boolean getPluginsEnabled() {
- synchronized (mContentSettingsLock) {
- return mPluginState == PluginState.ON;
- }
- }
-
- /**
- * Return true if plugins are disabled.
- * @return True if plugins are disabled.
- * @hide
- */
- @CalledByNative
- private boolean getPluginsDisabled() {
- // This should only be called from SyncToNative, which is called
- // either from the constructor, or with mContentSettingsLock being held.
- return mPluginState == PluginState.OFF;
- }
-
- /**
- * Sets if plugins are disabled.
- * @return True if plugins are disabled.
- * @hide
- */
- @CalledByNative
- private void setPluginsDisabled(boolean disabled) {
- // This should only be called from SyncFromToNative, which is called
- // either from the constructor, or with mContentSettingsLock being held.
- mPluginState = disabled ? PluginState.OFF : PluginState.ON;
- }
-
- /**
- * Return the current plugin state.
- * @return A value corresponding to the enum PluginState.
- */
- public PluginState getPluginState() {
- synchronized (mContentSettingsLock) {
- return mPluginState;
- }
- }
-
-
- /**
- * Tell javascript to open windows automatically. This applies to the
- * javascript function window.open().
- * @param flag True if javascript can open windows automatically.
- */
- public void setJavaScriptCanOpenWindowsAutomatically(boolean flag) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mJavaScriptCanOpenWindowsAutomatically != flag) {
- mJavaScriptCanOpenWindowsAutomatically = flag;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Return true if javascript can open windows automatically. The default
- * is false.
- * @return True if javascript can open windows automatically during
- * window.open().
- */
- public boolean getJavaScriptCanOpenWindowsAutomatically() {
- synchronized (mContentSettingsLock) {
- return mJavaScriptCanOpenWindowsAutomatically;
- }
- }
-
- /**
- * Sets the underlying layout algorithm. The default is
- * {@link LayoutAlgorithm#NARROW_COLUMNS}.
- *
- * @param l the layout algorithm to use, as a {@link LayoutAlgorithm} value
- */
- public void setLayoutAlgorithm(LayoutAlgorithm l) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mLayoutAlgorithm != l) {
- mLayoutAlgorithm = l;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Gets the current layout algorithm.
- *
- * @return the layout algorithm in use, as a {@link LayoutAlgorithm} value
- * @see #setLayoutAlgorithm
- */
- public LayoutAlgorithm getLayoutAlgorithm() {
- synchronized (mContentSettingsLock) {
- return mLayoutAlgorithm;
- }
- }
-
- /**
- * Sets whether Text Auto-sizing layout algorithm is enabled.
- *
- * @param enabled whether Text Auto-sizing layout algorithm is enabled
- * @hide
- */
- @CalledByNative
- private void setTextAutosizingEnabled(boolean enabled) {
- // This should only be called from SyncFromNative, which is called
- // either from the constructor, or with mContentSettingsLock being held.
- mLayoutAlgorithm = enabled ?
- LayoutAlgorithm.TEXT_AUTOSIZING : LayoutAlgorithm.NARROW_COLUMNS;
- }
-
- /**
- * Gets whether Text Auto-sizing layout algorithm is enabled.
- *
- * @return true if Text Auto-sizing layout algorithm is enabled
- * @hide
- */
- @CalledByNative
- private boolean getTextAutosizingEnabled() {
- return mLayoutAlgorithm == LayoutAlgorithm.TEXT_AUTOSIZING;
- }
-
- /**
- * Tells the WebView whether it supports multiple windows. True means
- * that {@link WebChromeClient#onCreateWindow(WebView, boolean,
- * boolean, Message)} is implemented by the host application.
- */
- public void setSupportMultipleWindows(boolean support) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mSupportMultipleWindows != support) {
- mSupportMultipleWindows = support;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Gets whether the WebView is supporting multiple windows.
- *
- * @return true if the WebView is supporting multiple windows. This means
- * that {@link WebChromeClient#onCreateWindow(WebView, boolean,
- * boolean, Message)} is implemented by the host application.
- */
- public boolean supportMultipleWindows() {
- synchronized (mContentSettingsLock) {
- return mSupportMultipleWindows;
- }
- }
-
- /**
- * Sets whether the WebView should enable support for the "viewport"
- * HTML meta tag or should use a wide viewport.
- * When the value of the setting is false, the layout width is always set to the
- * width of the WebView control in device-independent (CSS) pixels.
- * When the value is true and the page contains the viewport meta tag, the value
- * of the width specified in the tag is used. If the page does not contain the tag or
- * does not provide a width, then a wide viewport will be used.
- *
- * @param use whether to enable support for the viewport meta tag
- */
- public void setUseWideViewPort(boolean use) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mUseWideViewport != use) {
- mUseWideViewport = use;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Gets whether the WebView supports the "viewport"
- * HTML meta tag or will use a wide viewport.
- *
- * @return true if the WebView supports the viewport meta tag
- * @see #setUseWideViewPort
- */
- public boolean getUseWideViewPort() {
- synchronized (mContentSettingsLock) {
- return mUseWideViewport;
- }
- }
-
- /**
- * Sets whether the Application Caches API should be enabled. The default
- * is false. Note that in order for the Application Caches API to be
- * enabled, a non-empty database path must also be supplied to
- * {@link #setAppCachePath} (this is done for compatibility with the
- * legacy implementation).
- *
- * @param flag true if the WebView should enable Application Caches
- */
- public void setAppCacheEnabled(boolean flag) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mAppCacheEnabled != flag) {
- mAppCacheEnabled = flag;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Sets the path to the Application Caches files. In order for the
- * Application Caches API to be enabled, this method must be called with a
- * non-empty path. This method should only be called once: repeated calls
- * are ignored.
- *
- * @param path a non empty-string
- */
- public void setAppCachePath(String path) {
- assert mCanModifySettings;
- boolean needToSync = false;
- synchronized (sGlobalContentSettingsLock) {
- // AppCachePath can only be set once.
- if (!sAppCachePathIsSet && path != null && !path.isEmpty()) {
- sAppCachePathIsSet = true;
- needToSync = true;
- }
- }
- // The obvious problem here is that other WebViews will not be updated,
- // until they execute synchronization from Java to the native side.
- // But this is the same behaviour as it was in the legacy WebView.
- if (needToSync) {
- synchronized (mContentSettingsLock) {
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Gets whether Application Cache is enabled.
- *
- * @return true if Application Cache is enabled
- * @hide
- */
- @CalledByNative
- private boolean getAppCacheEnabled() {
- // This should only be called from SyncToNative, which is called
- // either from the constructor, or with mContentSettingsLock being held.
- if (!mAppCacheEnabled) {
- return false;
- }
- synchronized (sGlobalContentSettingsLock) {
- return sAppCachePathIsSet;
- }
- }
-
- /**
- * Sets whether the DOM storage API is enabled. The default value is false.
- *
- * @param flag true if the ContentView should use the DOM storage API
- */
- public void setDomStorageEnabled(boolean flag) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mDomStorageEnabled != flag) {
- mDomStorageEnabled = flag;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Gets whether the DOM Storage APIs are enabled.
- *
- * @return true if the DOM Storage APIs are enabled
- * @see #setDomStorageEnabled
- */
- public boolean getDomStorageEnabled() {
- synchronized (mContentSettingsLock) {
- return mDomStorageEnabled;
- }
- }
-
- /**
- * Sets whether the WebSQL storage API is enabled. The default value is false.
- *
- * @param flag true if the ContentView should use the WebSQL storage API
- */
- public void setDatabaseEnabled(boolean flag) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mDatabaseEnabled != flag) {
- mDatabaseEnabled = flag;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Gets whether the WebSQL Storage APIs are enabled.
- *
- * @return true if the WebSQL Storage APIs are enabled
- * @see #setDatabaseEnabled
- */
- public boolean getDatabaseEnabled() {
- synchronized (mContentSettingsLock) {
- return mDatabaseEnabled;
- }
- }
-
- /**
- * Set the default text encoding name to use when decoding html pages.
- * @param encoding The text encoding name.
- */
- public void setDefaultTextEncodingName(String encoding) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (encoding != null && !mDefaultTextEncoding.equals(encoding)) {
- mDefaultTextEncoding = encoding;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Get the default text encoding name. The default is "Latin-1".
- * @return The default text encoding name as a string.
- */
- public String getDefaultTextEncodingName() {
- synchronized (mContentSettingsLock) {
- return mDefaultTextEncoding;
- }
- }
-
- /**
- * Set whether the user gesture is required for media playback.
- * @param require true if the user gesture is required.
- */
- public void setMediaPlaybackRequiresUserGesture(boolean require) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mMediaPlaybackRequiresUserGesture != require) {
- mMediaPlaybackRequiresUserGesture = require;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Get whether the user gesture is required for Media Playback.
- * @return true if the user gesture is required.
- */
- public boolean getMediaPlaybackRequiresUserGesture() {
- synchronized (mContentSettingsLock) {
- return mMediaPlaybackRequiresUserGesture;
- }
- }
-
- /**
- * Set the default video poster URL.
- * @param url The url of default video poster.
- */
- public void setDefaultVideoPosterURL(String url) {
- assert mCanModifySettings;
- synchronized (mContentSettingsLock) {
- if (mDefaultVideoPosterURL != null && !mDefaultVideoPosterURL.equals(url) ||
- mDefaultVideoPosterURL == null && url != null) {
- mDefaultVideoPosterURL = url;
- mEventHandler.syncSettingsLocked();
- }
- }
- }
-
- /**
- * Get the default video poster URL.
- */
- public String getDefaultVideoPosterURL() {
- synchronized (mContentSettingsLock) {
- return mDefaultVideoPosterURL;
- }
- }
-
- private int clipFontSize(int size) {
- if (size < MINIMUM_FONT_SIZE) {
- return MINIMUM_FONT_SIZE;
- } else if (size > MAXIMUM_FONT_SIZE) {
- return MAXIMUM_FONT_SIZE;
- }
- return size;
+ return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Boolean>() {
+ @Override
+ public Boolean call() {
+ if (mNativeContentSettings != 0) {
+ return nativeGetJavaScriptEnabled(mNativeContentSettings);
+ } else {
+ return false;
+ }
+ }
+ });
}
/**
@@ -1257,69 +221,13 @@
* windows in an already created WebView)
*/
public void initFrom(ContentSettings settings) {
- setLayoutAlgorithm(settings.getLayoutAlgorithm());
- setLoadWithOverviewMode(settings.getLoadWithOverviewMode());
- setTextZoom(settings.getTextZoom());
- setStandardFontFamily(settings.getStandardFontFamily());
- setFixedFontFamily(settings.getFixedFontFamily());
- setSansSerifFontFamily(settings.getSansSerifFontFamily());
- setSerifFontFamily(settings.getSerifFontFamily());
- setCursiveFontFamily(settings.getCursiveFontFamily());
- setFantasyFontFamily(settings.getFantasyFontFamily());
- setDefaultTextEncodingName(settings.getDefaultTextEncodingName());
- setUserAgentString(settings.getUserAgentString());
- setMinimumFontSize(settings.getMinimumFontSize());
- setMinimumLogicalFontSize(settings.getMinimumLogicalFontSize());
- setDefaultFontSize(settings.getDefaultFontSize());
- setDefaultFixedFontSize(settings.getDefaultFixedFontSize());
- setLoadsImagesAutomatically(settings.getLoadsImagesAutomatically());
- setImagesEnabled(settings.getImagesEnabled());
- setJavaScriptEnabled(settings.getJavaScriptEnabled());
- setAllowUniversalAccessFromFileURLs(settings.getAllowUniversalAccessFromFileURLs());
- setAllowFileAccessFromFileURLs(settings.getAllowFileAccessFromFileURLs());
- setJavaScriptCanOpenWindowsAutomatically(
- settings.getJavaScriptCanOpenWindowsAutomatically());
- setSupportMultipleWindows(settings.supportMultipleWindows());
- setPluginState(settings.getPluginState());
- setAppCacheEnabled(settings.mAppCacheEnabled);
- setDomStorageEnabled(settings.getDomStorageEnabled());
- setDatabaseEnabled(settings.getDatabaseEnabled());
setSupportZoom(settings.supportZoom());
setBuiltInZoomControls(settings.getBuiltInZoomControls());
setDisplayZoomControls(settings.getDisplayZoomControls());
- setMediaPlaybackRequiresUserGesture(settings.getMediaPlaybackRequiresUserGesture());
- setDefaultVideoPosterURL(settings.getDefaultVideoPosterURL());
- }
-
- /**
- * Synchronize java side and native side settings. When ContentView
- * is running in PERSONALITY_VIEW mode, this needs to be done after
- * any java side setting is changed to sync them to native. In
- * PERSONALITY_CHROME mode, this needs to be called whenever native
- * settings are changed to sync them to java.
- */
- void syncSettings() {
- synchronized (mContentSettingsLock) {
- mEventHandler.syncSettingsLocked();
- }
- }
-
- void syncToNativeOnUiThread() {
- if (mNativeContentSettings != 0) nativeSyncToNative(mNativeContentSettings);
- }
-
- void syncFromNativeOnUiThread() {
- if (mNativeContentSettings != 0) nativeSyncFromNative(mNativeContentSettings);
}
// Initialize the ContentSettings native side.
- private native int nativeInit(int contentViewPtr, boolean isMasterMode);
+ private native int nativeInit(int contentViewPtr);
- private static native String nativeGetDefaultUserAgent();
-
- // Synchronize Java settings from native settings.
- private native void nativeSyncFromNative(int nativeContentSettings);
-
- // Synchronize native settings from Java settings.
- private native void nativeSyncToNative(int nativeContentSettings);
+ private native boolean nativeGetJavaScriptEnabled(int nativeContentSettings);
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentView.java b/content/public/android/java/src/org/chromium/content/browser/ContentView.java
index fa5cea7..9ea4fb4 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentView.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentView.java
@@ -23,11 +23,8 @@
import com.google.common.annotations.VisibleForTesting;
-import org.chromium.content.common.ProcessInitException;
import org.chromium.content.common.TraceEvent;
-import org.chromium.ui.gfx.NativeWindow;
-
-import java.util.ArrayList;
+import org.chromium.ui.WindowAndroid;
/**
* The containing view for {@link ContentViewCore} that exists in the Android UI hierarchy and
@@ -36,26 +33,30 @@
* TODO(joth): Remove any methods overrides from this class that were added for WebView
* compatibility.
*/
-public class ContentView extends FrameLayout implements ContentViewCore.InternalAccessDelegate {
+public class ContentView extends FrameLayout
+ implements ContentViewCore.InternalAccessDelegate, PageInfo {
// Used when ContentView implements a standalone View.
public static final int PERSONALITY_VIEW = ContentViewCore.PERSONALITY_VIEW;
// Used for Chrome.
public static final int PERSONALITY_CHROME = ContentViewCore.PERSONALITY_CHROME;
- private ContentViewCore mContentViewCore;
+ private final ContentViewCore mContentViewCore;
+
+ private float mCurrentTouchOffsetX;
+ private float mCurrentTouchOffsetY;
/**
* Creates an instance of a ContentView.
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* @param nativeWebContents A pointer to the native web contents.
- * @param nativeWindow An instance of the NativeWindow.
+ * @param windowAndroid An instance of the WindowAndroid.
* @param personality One of {@link #PERSONALITY_CHROME} or {@link #PERSONALITY_VIEW}.
* @return A ContentView instance.
*/
public static ContentView newInstance(Context context, int nativeWebContents,
- NativeWindow nativeWindow, int personality) {
- return newInstance(context, nativeWebContents, nativeWindow, null,
+ WindowAndroid windowAndroid, int personality) {
+ return newInstance(context, nativeWebContents, windowAndroid, null,
android.R.attr.webViewStyle, personality);
}
@@ -64,15 +65,15 @@
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* @param nativeWebContents A pointer to the native web contents.
- * @param nativeWindow An instance of the NativeWindow.
+ * @param windowAndroid An instance of the WindowAndroid.
* @param attrs The attributes of the XML tag that is inflating the view.
* @return A ContentView instance.
*/
public static ContentView newInstance(Context context, int nativeWebContents,
- NativeWindow nativeWindow, AttributeSet attrs) {
+ WindowAndroid windowAndroid, AttributeSet attrs) {
// TODO(klobag): use the WebViewStyle as the default style for now. It enables scrollbar.
// When ContentView is moved to framework, we can define its own style in the res.
- return newInstance(context, nativeWebContents, nativeWindow, attrs,
+ return newInstance(context, nativeWebContents, windowAndroid, attrs,
android.R.attr.webViewStyle);
}
@@ -81,34 +82,71 @@
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* @param nativeWebContents A pointer to the native web contents.
- * @param nativeWindow An instance of the NativeWindow.
+ * @param windowAndroid An instance of the WindowAndroid.
* @param attrs The attributes of the XML tag that is inflating the view.
* @param defStyle The default style to apply to this view.
* @return A ContentView instance.
*/
public static ContentView newInstance(Context context, int nativeWebContents,
- NativeWindow nativeWindow, AttributeSet attrs, int defStyle) {
- return newInstance(context, nativeWebContents, nativeWindow, attrs, defStyle,
+ WindowAndroid windowAndroid, AttributeSet attrs, int defStyle) {
+ return newInstance(context, nativeWebContents, windowAndroid, attrs, defStyle,
PERSONALITY_VIEW);
}
private static ContentView newInstance(Context context, int nativeWebContents,
- NativeWindow nativeWindow, AttributeSet attrs, int defStyle, int personality) {
+ WindowAndroid windowAndroid, AttributeSet attrs, int defStyle, int personality) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
- return new ContentView(context, nativeWebContents, nativeWindow, attrs, defStyle,
+ return new ContentView(context, nativeWebContents, windowAndroid, attrs, defStyle,
personality);
} else {
- return new JellyBeanContentView(context, nativeWebContents, nativeWindow, attrs,
+ return new JellyBeanContentView(context, nativeWebContents, windowAndroid, attrs,
defStyle, personality);
}
}
- protected ContentView(Context context, int nativeWebContents, NativeWindow nativeWindow,
+ protected ContentView(Context context, int nativeWebContents, WindowAndroid windowAndroid,
AttributeSet attrs, int defStyle, int personality) {
super(context, attrs, defStyle);
mContentViewCore = new ContentViewCore(context, personality);
- mContentViewCore.initialize(this, this, nativeWebContents, nativeWindow, false);
+ mContentViewCore.initialize(this, this, nativeWebContents, windowAndroid);
+ }
+
+ // PageInfo implementation.
+
+ @Override
+ public String getUrl() {
+ return mContentViewCore.getUrl();
+ }
+
+ @Override
+ public String getTitle() {
+ return mContentViewCore.getTitle();
+ }
+
+ @Override
+ public boolean isReadyForSnapshot() {
+ return !isCrashed() && isReady();
+ }
+
+ @Override
+ public Bitmap getBitmap() {
+ return getBitmap(getWidth(), getHeight());
+ }
+
+ @Override
+ public Bitmap getBitmap(int width, int height) {
+ return mContentViewCore.getBitmap(width, height);
+ }
+
+ @Override
+ public int getBackgroundColor() {
+ return mContentViewCore.getBackgroundColor();
+ }
+
+ @Override
+ public View getView() {
+ return this;
}
/**
@@ -180,25 +218,17 @@
return mContentViewCore.getContentViewClient();
}
- public int getBackgroundColor() {
- return mContentViewCore.getBackgroundColor();
- }
-
/**
* Load url without fixing up the url string. Consumers of ContentView are responsible for
* ensuring the URL passed in is properly formatted (i.e. the scheme has been added if left
* off during user input).
*
- * @param pararms Parameters for this load.
+ * @param params Parameters for this load.
*/
public void loadUrl(LoadUrlParams params) {
mContentViewCore.loadUrl(params);
}
- void setAllUserAgentOverridesInHistory() {
- mContentViewCore.setAllUserAgentOverridesInHistory();
- }
-
/**
* Stops loading the current web contents.
*/
@@ -207,41 +237,6 @@
}
/**
- * Get the URL of the current page.
- *
- * @return The URL of the current page.
- */
- public String getUrl() {
- return mContentViewCore.getUrl();
- }
-
- /**
- * Get the title of the current page.
- *
- * @return The title of the current page.
- */
- public String getTitle() {
- return mContentViewCore.getTitle();
- }
-
- public Bitmap getBitmap() {
- return getBitmap(getWidth(), getHeight());
- }
-
- public Bitmap getBitmap(int width, int height) {
- return mContentViewCore.getBitmap(width, height);
- }
-
- /**
- * @return Whether the ContentView is covered by an overlay that is more than half
- * of it's surface. This is used to determine if we need to do a slow bitmap capture or
- * to show the ContentView without them.
- */
- public boolean hasLargeOverlay() {
- return mContentViewCore.hasLargeOverlay();
- }
-
- /**
* @return Whether the current WebContents has a previous navigation entry.
*/
public boolean canGoBack() {
@@ -486,12 +481,19 @@
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- return mContentViewCore.dispatchKeyEvent(event);
+ if (isFocused()) {
+ return mContentViewCore.dispatchKeyEvent(event);
+ } else {
+ return super.dispatchKeyEvent(event);
+ }
}
@Override
public boolean onTouchEvent(MotionEvent event) {
- return mContentViewCore.onTouchEvent(event);
+ MotionEvent offset = createOffsetMotionEvent(event);
+ boolean consumed = mContentViewCore.onTouchEvent(offset);
+ offset.recycle();
+ return consumed;
}
/**
@@ -509,6 +511,23 @@
return mContentViewCore.onGenericMotionEvent(event);
}
+ /**
+ * Sets the current amount to offset incoming touch events by. This is used to handle content
+ * moving and not lining up properly with the android input system.
+ * @param dx The X offset in pixels to shift touch events.
+ * @param dy The Y offset in pixels to shift touch events.
+ */
+ public void setCurrentMotionEventOffsets(float dx, float dy) {
+ mCurrentTouchOffsetX = dx;
+ mCurrentTouchOffsetY = dy;
+ }
+
+ private MotionEvent createOffsetMotionEvent(MotionEvent src) {
+ MotionEvent dst = MotionEvent.obtain(src);
+ dst.offsetLocation(mCurrentTouchOffsetX, mCurrentTouchOffsetY);
+ return dst;
+ }
+
@Override
protected void onConfigurationChanged(Configuration newConfig) {
mContentViewCore.onConfigurationChanged(newConfig);
@@ -753,13 +772,6 @@
}
/**
- * @return Whether or not the texture view is available or not.
- */
- public boolean isAvailable() {
- return mContentViewCore.isAvailable();
- }
-
- /**
* Returns whether or not accessibility injection is being used.
*/
public boolean isInjectingAccessibilityScript() {
@@ -787,6 +799,24 @@
mContentViewCore.exitFullscreen();
}
+ /**
+ * Return content scroll y.
+ *
+ * @return The vertical scroll position in pixels.
+ */
+ public int getContentScrollY() {
+ return mContentViewCore.computeVerticalScrollOffset();
+ }
+
+ /**
+ * Return content height.
+ *
+ * @return The height of the content in pixels.
+ */
+ public int getContentHeight() {
+ return mContentViewCore.computeVerticalScrollRange();
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////////
// Start Implementation of ContentViewCore.InternalAccessDelegate //
///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java
index 9d765a3..3176ecc 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java
@@ -42,14 +42,6 @@
}
/**
- * Notifies that the content size has changed.
- * @param widthCss The width of the content in CSS pixels.
- * @param heightCss The height of the content in CSS pixels.
- */
- public void onContentSizeChanged(float widthCss, float heightCss) {
- }
-
- /**
* Lets client listen on the scaling changes on delayed, throttled
* and best-effort basis. Used for WebView.onScaleChanged.
*/
@@ -60,9 +52,10 @@
* Notifies the client that the position of the top controls has changed.
* @param topControlsOffsetYPix The Y offset of the top controls in physical pixels.
* @param contentOffsetYPix The Y offset of the content in physical pixels.
+ * @param overdrawBottomHeightPix The overdraw height.
*/
public void onOffsetsForFullscreenChanged(
- float topControlsOffsetYPix, float contentOffsetYPix) {
+ float topControlsOffsetYPix, float contentOffsetYPix, float overdrawBottomHeightPix) {
}
public void onTabCrash() {
@@ -173,4 +166,7 @@
public void onExternalVideoSurfaceRequested(int playerId) {
}
+
+ public void onGeometryChanged(int playerId, float x, float y, float height, float width) {
+ }
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index 731166d..20b30d8 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -34,6 +34,7 @@
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
+import android.widget.FrameLayout;
import com.google.common.annotations.VisibleForTesting;
@@ -42,10 +43,19 @@
import org.chromium.base.WeakContext;
import org.chromium.content.R;
import org.chromium.content.browser.ContentViewGestureHandler.MotionEventDelegate;
-import org.chromium.content.browser.ImeAdapter.AdapterInputConnectionFactory;
import org.chromium.content.browser.accessibility.AccessibilityInjector;
+import org.chromium.content.browser.input.AdapterInputConnection;
+import org.chromium.content.browser.input.HandleView;
+import org.chromium.content.browser.input.ImeAdapter;
+import org.chromium.content.browser.input.ImeAdapter.AdapterInputConnectionFactory;
+import org.chromium.content.browser.input.InsertionHandleController;
+import org.chromium.content.browser.input.SelectPopupDialog;
+import org.chromium.content.browser.input.SelectionHandleController;
import org.chromium.content.common.TraceEvent;
-import org.chromium.ui.gfx.NativeWindow;
+import org.chromium.ui.ViewAndroid;
+import org.chromium.ui.ViewAndroidDelegate;
+import org.chromium.ui.WindowAndroid;
+import org.chromium.ui.gfx.DeviceDisplayInfo;
import java.lang.annotation.Annotation;
import java.util.HashMap;
@@ -157,21 +167,102 @@
}
/**
- * Interface for subscribing to content size changes.
+ * An interface that allows the embedder to be notified when the pinch gesture starts and
+ * stops.
*/
- public static interface ContentSizeChangeListener {
+ public static interface PinchGestureStateListener {
/**
- * Called when the content size changes.
- * The containing view may want to adjust its size to match the content.
+ * Called when the pinch gesture starts.
*/
- void onContentSizeChanged(int contentWidthPix, int contentHeightPix);
+ void onPinchGestureStart();
+ /**
+ * Called when the pinch gesture ends.
+ */
+ void onPinchGestureEnd();
+ }
+
+ private VSyncManager.Provider mVSyncProvider;
+ private VSyncManager.Listener mVSyncListener;
+ private int mVSyncSubscriberCount;
+ private boolean mVSyncListenerRegistered;
+
+ // To avoid IPC delay we use input events to directly trigger a vsync signal in the renderer.
+ // When we do this, we also need to avoid sending the real vsync signal for the current
+ // frame to avoid double-ticking. This flag is used to inhibit the next vsync notification.
+ private boolean mDidSignalVSyncUsingInputEvent;
+
+ public VSyncManager.Listener getVSyncListener(VSyncManager.Provider vsyncProvider) {
+ if (mVSyncProvider != null && mVSyncListenerRegistered) {
+ mVSyncProvider.unregisterVSyncListener(mVSyncListener);
+ mVSyncListenerRegistered = false;
+ }
+
+ mVSyncProvider = vsyncProvider;
+ mVSyncListener = new VSyncManager.Listener() {
+ @Override
+ public void updateVSync(long tickTimeMicros, long intervalMicros) {
+ if (mNativeContentViewCore != 0) {
+ nativeUpdateVSyncParameters(mNativeContentViewCore, tickTimeMicros,
+ intervalMicros);
+ }
+ }
+
+ @Override
+ public void onVSync(long frameTimeMicros) {
+ if (mDidSignalVSyncUsingInputEvent) {
+ TraceEvent.instant("ContentViewCore::onVSync ignored");
+ mDidSignalVSyncUsingInputEvent = false;
+ return;
+ }
+ if (mNativeContentViewCore != 0) {
+ nativeOnVSync(mNativeContentViewCore, frameTimeMicros);
+ }
+ }
+ };
+
+ if (mVSyncSubscriberCount > 0) {
+ // setVSyncNotificationEnabled(true) is called before getVSyncListener.
+ vsyncProvider.registerVSyncListener(mVSyncListener);
+ mVSyncListenerRegistered = true;
+ }
+
+ return mVSyncListener;
+ }
+
+ @CalledByNative
+ void setVSyncNotificationEnabled(boolean enabled) {
+ if (!isVSyncNotificationEnabled() && enabled) {
+ mDidSignalVSyncUsingInputEvent = false;
+ }
+ if (mVSyncProvider != null) {
+ if (!mVSyncListenerRegistered && enabled) {
+ mVSyncProvider.registerVSyncListener(mVSyncListener);
+ mVSyncListenerRegistered = true;
+ } else if (mVSyncSubscriberCount == 1 && !enabled) {
+ assert mVSyncListenerRegistered;
+ mVSyncProvider.unregisterVSyncListener(mVSyncListener);
+ mVSyncListenerRegistered = false;
+ }
+ }
+ mVSyncSubscriberCount += enabled ? 1 : -1;
+ assert mVSyncSubscriberCount >= 0;
+ }
+
+ @CalledByNative
+ private void resetVSyncNotification() {
+ while (isVSyncNotificationEnabled()) setVSyncNotificationEnabled(false);
+ mVSyncSubscriberCount = 0;
+ mVSyncListenerRegistered = false;
+ }
+
+ private boolean isVSyncNotificationEnabled() {
+ return mVSyncProvider != null && mVSyncListenerRegistered;
}
private final Context mContext;
private ViewGroup mContainerView;
private InternalAccessDelegate mContainerViewInternals;
private WebContentsObserverAndroid mWebContentsObserver;
- private ContentSizeChangeListener mContentSizeChangeListener;
private ContentViewClient mContentViewClient;
@@ -183,6 +274,7 @@
private boolean mAttachedToWindow = false;
private ContentViewGestureHandler mContentViewGestureHandler;
+ private PinchGestureStateListener mPinchGestureStateListener;
private ZoomManager mZoomManager;
private PopupZoomer mPopupZoomer;
@@ -192,7 +284,7 @@
// Only valid when focused on a text / password field.
private ImeAdapter mImeAdapter;
private ImeAdapter.AdapterInputConnectionFactory mAdapterInputConnectionFactory;
- private ImeAdapter.AdapterInputConnection mInputConnection;
+ private AdapterInputConnection mInputConnection;
private SelectionHandleController mSelectionHandleController;
private InsertionHandleController mInsertionHandleController;
@@ -205,6 +297,8 @@
private int mPhysicalBackingWidthPix;
private int mPhysicalBackingHeightPix;
private int mOverdrawBottomHeightPix;
+ private int mViewportSizeOffsetWidthPix;
+ private int mViewportSizeOffsetHeightPix;
// Cached copy of all positions and scales as reported by the renderer.
private final RenderCoordinates mRenderCoordinates;
@@ -240,6 +334,11 @@
// Whether we use hardware-accelerated drawing.
private boolean mHardwareAccelerated = false;
+ // Whether we received a new frame since consumePendingRendererFrame() was last called.
+ private boolean mPendingRendererFrame = false;
+
+ private ViewAndroid mViewAndroid;
+
/**
* Constructs a new ContentViewCore. Embedders must call initialize() after constructing
* a ContentViewCore and before using it.
@@ -278,6 +377,21 @@
}
/**
+ * Specifies how much smaller the WebKit layout size should be relative to the size of this
+ * view.
+ * @param offsetXPix The X amount in pixels to shrink the viewport by.
+ * @param offsetYPix The Y amount in pixels to shrink the viewport by.
+ */
+ public void setViewportSizeOffset(int offsetXPix, int offsetYPix) {
+ if (offsetXPix != mViewportSizeOffsetWidthPix ||
+ offsetYPix != mViewportSizeOffsetHeightPix) {
+ mViewportSizeOffsetWidthPix = offsetXPix;
+ mViewportSizeOffsetHeightPix = offsetYPix;
+ if (mNativeContentViewCore != 0) nativeWasResized(mNativeContentViewCore);
+ }
+ }
+
+ /**
* Returns a delegate that can be used to add and remove views from the ContainerView.
*
* NOTE: Use with care, as not all ContentViewCore users setup their ContainerView in the same
@@ -286,35 +400,58 @@
* compatibility breaks with existing applications. If in doubt, contact the
* android_webview/OWNERS
*
- * @return A ContainerViewDelegate that can be used to add and remove views.
+ * @return A ViewAndroidDelegate that can be used to add and remove views.
*/
- @CalledByNative
- public ContainerViewDelegate getContainerViewDelegate() {
- return new ContainerViewDelegate() {
+ @VisibleForTesting
+ public ViewAndroidDelegate getViewAndroidDelegate() {
+ return new ViewAndroidDelegate() {
@Override
- public void addViewToContainerView(View view) {
- mContainerView.addView(view);
+ public View acquireAnchorView() {
+ View anchorView = new View(getContext());
+ mContainerView.addView(anchorView);
+ return anchorView;
}
@Override
- public void removeViewFromContainerView(View view) {
- mContainerView.removeView(view);
+ public void setAnchorViewPosition(
+ View view, float x, float y, float width, float height) {
+ assert(view.getParent() == mContainerView);
+ float scale = (float) DeviceDisplayInfo.create(getContext()).getDIPScale();
+
+ // The anchor view should not go outside the bounds of the ContainerView.
+ int scaledX = Math.round(x * scale);
+ int scaledWidth = Math.round(width * scale);
+ if (scaledWidth + scaledX > mContainerView.getWidth()) {
+ scaledWidth = mContainerView.getWidth() - scaledX;
+ }
+
+ FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
+ scaledWidth, Math.round(height * scale));
+ lp.leftMargin = scaledX;
+ lp.topMargin = (int) mRenderCoordinates.getContentOffsetYPix() +
+ Math.round(y * scale);
+ view.setLayoutParams(lp);
+ }
+
+ @Override
+ public void releaseAnchorView(View anchorView) {
+ mContainerView.removeView(anchorView);
}
};
}
@VisibleForTesting
- protected ImeAdapter getImeAdapterForTest() {
+ public ImeAdapter getImeAdapterForTest() {
return mImeAdapter;
}
@VisibleForTesting
- protected void setAdapterInputConnectionFactory(AdapterInputConnectionFactory factory) {
+ public void setAdapterInputConnectionFactory(AdapterInputConnectionFactory factory) {
mAdapterInputConnectionFactory = factory;
}
@VisibleForTesting
- protected ImeAdapter.AdapterInputConnection getInputConnectionForTest() {
+ public AdapterInputConnection getInputConnectionForTest() {
return mInputConnection;
}
@@ -423,8 +560,7 @@
* @param internalDispatcher Handles dispatching all hidden or super methods to the
* containerView.
* @param nativeWebContents A pointer to the native web contents.
- * @param nativeWindow An instance of the NativeWindow.
- * @param isAccessFromFileURLsGrantedByDefault Default WebSettings configuration.
+ * @param windowAndroid An instance of the WindowAndroid.
*/
// Perform important post-construction set up of the ContentViewCore.
// We do not require the containing view in the constructor to allow embedders to create a
@@ -436,8 +572,7 @@
// Note that the caller remains the owner of the nativeWebContents and is responsible for
// deleting it after destroying the ContentViewCore.
public void initialize(ViewGroup containerView, InternalAccessDelegate internalDispatcher,
- int nativeWebContents, NativeWindow nativeWindow,
- boolean isAccessFromFileURLsGrantedByDefault) {
+ int nativeWebContents, WindowAndroid windowAndroid) {
// Check whether to use hardware acceleration. This is a bit hacky, and
// only works if the Context is actually an Activity (as it is in the
// Chrome application).
@@ -453,20 +588,21 @@
// HW support directly.
mHardwareAccelerated = hasHardwareAcceleration(mContext);
- // Input events are delivered at vsync time on JB+.
- boolean inputEventsDeliveredAtVSync =
- (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN);
-
mContainerView = containerView;
- mNativeContentViewCore = nativeInit(mHardwareAccelerated, inputEventsDeliveredAtVSync,
- nativeWebContents, nativeWindow.getNativePointer());
- mContentSettings = new ContentSettings(
- this, mNativeContentViewCore, isAccessFromFileURLsGrantedByDefault);
- initializeContainerView(internalDispatcher);
- if (mPersonality == PERSONALITY_VIEW) {
- setAllUserAgentOverridesInHistory();
+
+ int windowNativePointer = windowAndroid != null ? windowAndroid.getNativePointer() : 0;
+
+ int viewAndroidNativePointer = 0;
+ if (windowNativePointer != 0) {
+ mViewAndroid = new ViewAndroid(windowAndroid, getViewAndroidDelegate());
+ viewAndroidNativePointer = mViewAndroid.getNativePointer();
}
+ mNativeContentViewCore = nativeInit(mHardwareAccelerated,
+ nativeWebContents, viewAndroidNativePointer, windowNativePointer);
+ mContentSettings = new ContentSettings(this, mNativeContentViewCore);
+ initializeContainerView(internalDispatcher);
+
mAccessibilityInjector = AccessibilityInjector.newInstance(this);
mAccessibilityInjector.addOrRemoveAccessibilityApisIfNecessary();
@@ -611,6 +747,9 @@
if (mNativeContentViewCore != 0) {
nativeOnJavaContentViewCoreDestroyed(mNativeContentViewCore);
}
+ resetVSyncNotification();
+ mVSyncProvider = null;
+ if (mViewAndroid != null) mViewAndroid.destroy();
mNativeContentViewCore = 0;
mContentSettings = null;
mJavaScriptInterfaces.clear();
@@ -665,10 +804,6 @@
return mContentViewClient;
}
- public void setContentSizeChangeListener(ContentSizeChangeListener listener) {
- mContentSizeChangeListener = listener;
- }
-
public int getBackgroundColor() {
if (mNativeContentViewCore != 0) {
return nativeGetBackgroundColor(mNativeContentViewCore);
@@ -692,7 +827,7 @@
* ensuring the URL passed in is properly formatted (i.e. the scheme has been added if left
* off during user input).
*
- * @param pararms Parameters for this load.
+ * @param params Parameters for this load.
*/
public void loadUrl(LoadUrlParams params) {
if (mNativeContentViewCore == 0) return;
@@ -714,11 +849,6 @@
params.mCanLoadLocalResources);
}
- void setAllUserAgentOverridesInHistory() {
- nativeSetAllUserAgentOverridesInHistory(mNativeContentViewCore,
- mContentSettings.getUserAgentString());
- }
-
/**
* Stops loading the current web contents.
*/
@@ -768,13 +898,14 @@
}
/**
- * Indicate that the browser compositor has consumed a pending renderer frame.
+ * Mark any new frames that have arrived since this function was last called as non-pending.
*
- * @return Whether there was a pending renderer frame.
+ * @return Whether there was a pending frame from the renderer.
*/
public boolean consumePendingRendererFrame() {
- return mNativeContentViewCore == 0 ?
- false : nativeConsumePendingRendererFrame(mNativeContentViewCore);
+ boolean hadPendingFrame = mPendingRendererFrame;
+ mPendingRendererFrame = false;
+ return hadPendingFrame;
}
/**
@@ -808,6 +939,18 @@
public int getOverdrawBottomHeightPix() { return mOverdrawBottomHeightPix; }
/**
+ * @return The amount to shrink the viewport relative to {@link #getViewportWidthPix()}.
+ */
+ @CalledByNative
+ public int getViewportSizeOffsetWidthPix() { return mViewportSizeOffsetWidthPix; }
+
+ /**
+ * @return The amount to shrink the viewport relative to {@link #getViewportHeightPix()}.
+ */
+ @CalledByNative
+ public int getViewportSizeOffsetHeightPix() { return mViewportSizeOffsetHeightPix; }
+
+ /**
* @see android.webkit.WebView#getContentHeight()
*/
public float getContentHeightCss() {
@@ -874,16 +1017,6 @@
}
/**
- * @return Whether the ContentView is covered by an overlay that is more than half
- * of it's surface. This is used to determine if we need to do a slow bitmap capture or
- * to show the ContentView without them.
- */
- public boolean hasLargeOverlay() {
- // TODO(nileshagrawal): Implement this.
- return false;
- }
-
- /**
* @return Whether the current WebContents has a previous navigation entry.
*/
public boolean canGoBack() {
@@ -1017,9 +1150,16 @@
}
@Override
- public boolean sendGesture(int type, long timeMs, int x, int y, Bundle b) {
+ public boolean sendGesture(int type, long timeMs, int x, int y, boolean lastInputEventForVSync,
+ Bundle b) {
if (mNativeContentViewCore == 0) return false;
updateTextHandlesForGesture(type);
+ updatePinchGestureStateListener(type);
+ if (lastInputEventForVSync && isVSyncNotificationEnabled()) {
+ assert type == ContentViewGestureHandler.GESTURE_SCROLL_BY ||
+ type == ContentViewGestureHandler.GESTURE_PINCH_BY;
+ mDidSignalVSyncUsingInputEvent = true;
+ }
switch (type) {
case ContentViewGestureHandler.GESTURE_SHOW_PRESSED_STATE:
nativeShowPressState(mNativeContentViewCore, timeMs, x, y);
@@ -1049,7 +1189,8 @@
case ContentViewGestureHandler.GESTURE_SCROLL_BY: {
int dx = b.getInt(ContentViewGestureHandler.DISTANCE_X);
int dy = b.getInt(ContentViewGestureHandler.DISTANCE_Y);
- nativeScrollBy(mNativeContentViewCore, timeMs, x, y, dx, dy);
+ nativeScrollBy(mNativeContentViewCore, timeMs, x, y, dx, dy,
+ lastInputEventForVSync);
return true;
}
case ContentViewGestureHandler.GESTURE_SCROLL_END:
@@ -1068,7 +1209,8 @@
return true;
case ContentViewGestureHandler.GESTURE_PINCH_BY:
nativePinchBy(mNativeContentViewCore, timeMs, x, y,
- b.getFloat(ContentViewGestureHandler.DELTA, 0));
+ b.getFloat(ContentViewGestureHandler.DELTA, 0),
+ lastInputEventForVSync);
return true;
case ContentViewGestureHandler.GESTURE_PINCH_END:
nativePinchEnd(mNativeContentViewCore, timeMs);
@@ -1078,6 +1220,25 @@
}
}
+ public void setPinchGestureStateListener(PinchGestureStateListener pinchGestureStateListener) {
+ mPinchGestureStateListener = pinchGestureStateListener;
+ }
+
+ void updatePinchGestureStateListener(int gestureType) {
+ if (mPinchGestureStateListener == null) return;
+
+ switch (gestureType) {
+ case ContentViewGestureHandler.GESTURE_PINCH_BEGIN:
+ mPinchGestureStateListener.onPinchGestureStart();
+ break;
+ case ContentViewGestureHandler.GESTURE_PINCH_END:
+ mPinchGestureStateListener.onPinchGestureEnd();
+ break;
+ default:
+ break;
+ }
+ }
+
public interface JavaScriptCallback {
void handleJavaScriptResult(String jsonResult);
}
@@ -1088,10 +1249,10 @@
* Used in automation tests.
*
* @param script The Javascript to execute.
- * @param message The callback to be fired off when a result is ready. The script's
- * result will be json encoded and passed as the parameter, and the call
- * will be made on the main thread.
- * If no result is required, pass null.
+ * @param callback The callback to be fired off when a result is ready. The script's
+ * result will be json encoded and passed as the parameter, and the call
+ * will be made on the main thread.
+ * If no result is required, pass null.
* @throws IllegalStateException If the ContentView has been destroyed.
*/
public void evaluateJavaScript(
@@ -1206,6 +1367,9 @@
}
setAccessibilityState(false);
hidePopupDialog();
+ if (mContentSettings != null && mContentSettings.supportZoom()) {
+ mZoomManager.dismissZoomPicker();
+ }
}
/**
@@ -1219,11 +1383,6 @@
}
}
- @CalledByNative
- private void onWebPreferencesUpdated() {
- mContentSettings.syncSettings();
- }
-
/**
* @see View#onCreateInputConnection(EditorInfo)
*/
@@ -1259,7 +1418,9 @@
if (newConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
mImeAdapter.attach(nativeGetNativeImeAdapter(mNativeContentViewCore),
- ImeAdapter.sTextInputTypeNone);
+ ImeAdapter.getTextInputTypeNone(),
+ AdapterInputConnection.INVALID_SELECTION,
+ AdapterInputConnection.INVALID_SELECTION);
InputMethodManager manager = (InputMethodManager)
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
manager.restartInput(mContainerView);
@@ -1486,7 +1647,7 @@
public void scrollBy(int xPix, int yPix) {
if (mNativeContentViewCore != 0) {
nativeScrollBy(mNativeContentViewCore,
- System.currentTimeMillis(), 0, 0, xPix, yPix);
+ System.currentTimeMillis(), 0, 0, xPix, yPix, false);
}
}
@@ -1502,7 +1663,8 @@
if (dxPix != 0 || dyPix != 0) {
long time = System.currentTimeMillis();
nativeScrollBegin(mNativeContentViewCore, time, xCurrentPix, yCurrentPix);
- nativeScrollBy(mNativeContentViewCore, time, xCurrentPix, yCurrentPix, dxPix, dyPix);
+ nativeScrollBy(mNativeContentViewCore,
+ time, xCurrentPix, yCurrentPix, dxPix, dyPix, false);
nativeScrollEnd(mNativeContentViewCore, time);
}
}
@@ -1627,7 +1789,7 @@
return mZoomManager.isMultiTouchZoomSupported();
}
- void selectPopupMenuItems(int[] indices) {
+ public void selectPopupMenuItems(int[] indices) {
if (mNativeContentViewCore != 0) {
nativeSelectPopupMenuItems(mNativeContentViewCore, indices);
}
@@ -1689,7 +1851,9 @@
@Override
public void selectBetweenCoordinates(int x1, int y1, int x2, int y2) {
if (mNativeContentViewCore != 0 && !(x1 == x2 && y1 == y2)) {
- nativeSelectBetweenCoordinates(mNativeContentViewCore, x1, y1, x2, y2);
+ nativeSelectBetweenCoordinates(mNativeContentViewCore,
+ x1, y1 - mRenderCoordinates.getContentOffsetYPix(),
+ x2, y2 - mRenderCoordinates.getContentOffsetYPix());
}
}
@@ -1715,7 +1879,8 @@
@Override
public void setCursorPosition(int x, int y) {
if (mNativeContentViewCore != 0) {
- nativeMoveCaret(mNativeContentViewCore, x, y);
+ nativeMoveCaret(mNativeContentViewCore,
+ x, y - mRenderCoordinates.getContentOffsetYPix());
}
}
@@ -1816,9 +1981,13 @@
getContentViewClient().onContextualActionBarHidden();
}
};
- mActionMode = mContainerView.startActionMode(
- getContentViewClient().getSelectActionModeCallback(getContext(), actionHandler,
- nativeIsIncognito(mNativeContentViewCore)));
+ mActionMode = null;
+ // On ICS, startActionMode throws an NPE when getParent() is null.
+ if (mContainerView.getParent() != null) {
+ mActionMode = mContainerView.startActionMode(
+ getContentViewClient().getSelectActionModeCallback(getContext(), actionHandler,
+ nativeIsIncognito(mNativeContentViewCore)));
+ }
mUnselectAllOnActionModeDismiss = true;
if (mActionMode == null) {
// There is no ActionMode, so remove the selection.
@@ -1934,8 +2103,9 @@
float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor,
float contentWidth, float contentHeight,
float viewportWidth, float viewportHeight,
- float controlsOffsetYCss, float contentOffsetYCss) {
-
+ float controlsOffsetYCss, float contentOffsetYCss,
+ float overdrawBottomHeightCss) {
+ TraceEvent.instant("ContentViewCore:updateFrameInfo");
// Adjust contentWidth/Height to be always at least as big as
// the actual viewport (as set by onSizeChanged).
contentWidth = Math.max(contentWidth,
@@ -1943,6 +2113,8 @@
contentHeight = Math.max(contentHeight,
mRenderCoordinates.fromPixToLocalCss(mViewportHeightPix));
+ final float contentOffsetYPix = mRenderCoordinates.fromDipToPix(contentOffsetYCss);
+
final boolean contentSizeChanged =
contentWidth != mRenderCoordinates.getContentWidthCss()
|| contentHeight != mRenderCoordinates.getContentHeightCss();
@@ -1955,6 +2127,9 @@
pageScaleChanged
|| scrollOffsetX != mRenderCoordinates.getScrollX()
|| scrollOffsetY != mRenderCoordinates.getScrollY();
+ final boolean contentOffsetChanged =
+ contentOffsetYPix != mRenderCoordinates.getContentOffsetYPix();
+
final boolean needHidePopupZoomer = contentSizeChanged || scrollChanged;
final boolean needUpdateZoomControls = scaleLimitsChanged || scrollChanged;
final boolean needTemporarilyHideHandles = scrollChanged;
@@ -1981,27 +2156,21 @@
scrollOffsetX, scrollOffsetY,
contentWidth, contentHeight,
viewportWidth, viewportHeight,
- pageScaleFactor, minPageScaleFactor, maxPageScaleFactor);
-
- if (contentSizeChanged) {
- getContentViewClient().onContentSizeChanged(
- mRenderCoordinates.getContentWidthCss(),
- mRenderCoordinates.getContentHeightCss());
- if (mContentSizeChangeListener != null) {
- mContentSizeChangeListener.onContentSizeChanged(
- mRenderCoordinates.getContentWidthPixInt(),
- mRenderCoordinates.getContentHeightPixInt());
- }
- }
+ pageScaleFactor, minPageScaleFactor, maxPageScaleFactor,
+ contentOffsetYPix);
if (needTemporarilyHideHandles) temporarilyHideTextHandles();
if (needUpdateZoomControls) mZoomManager.updateZoomControls();
+ if (contentOffsetChanged) updateHandleScreenPositions();
// Update offsets for fullscreen.
final float deviceScale = mRenderCoordinates.getDeviceScaleFactor();
final float controlsOffsetPix = controlsOffsetYCss * deviceScale;
- final float contentOffsetYPix = contentOffsetYCss * deviceScale;
- getContentViewClient().onOffsetsForFullscreenChanged(controlsOffsetPix, contentOffsetYPix);
+ final float overdrawBottomHeightPix = overdrawBottomHeightCss * deviceScale;
+ getContentViewClient().onOffsetsForFullscreenChanged(
+ controlsOffsetPix, contentOffsetYPix, overdrawBottomHeightPix);
+
+ mPendingRendererFrame = true;
}
@SuppressWarnings("unused")
@@ -2010,24 +2179,14 @@
String text, int selectionStart, int selectionEnd,
int compositionStart, int compositionEnd, boolean showImeIfNeeded) {
TraceEvent.begin();
-
- // Non-breaking spaces can cause the IME to get confused. Replace with normal spaces.
- text = text.replace('\u00A0', ' ');
-
- mSelectionEditable = (textInputType != ImeAdapter.sTextInputTypeNone);
+ mSelectionEditable = (textInputType != ImeAdapter.getTextInputTypeNone());
if (mActionMode != null) mActionMode.invalidate();
mImeAdapter.attachAndShowIfNeeded(nativeImeAdapterAndroid, textInputType,
- text, showImeIfNeeded);
+ selectionStart, selectionEnd, showImeIfNeeded);
if (mInputConnection != null) {
- // In WebKit if there's a composition then the selection will usually be the
- // same as the composition, whereas Android IMEs expect the selection to be
- // just a caret at the end of the composition.
- if (selectionStart == compositionStart && selectionEnd == compositionEnd) {
- selectionStart = selectionEnd;
- }
mInputConnection.setEditableText(text, selectionStart, selectionEnd,
compositionStart, compositionEnd);
}
@@ -2170,6 +2329,14 @@
}
}
+ @SuppressWarnings("unused")
+ @CalledByNative
+ private void onWebContentsSwapped() {
+ if (mImeAdapter != null && mNativeContentViewCore != 0) {
+ mImeAdapter.attach(nativeGetNativeImeAdapter(mNativeContentViewCore));
+ }
+ }
+
/**
* @return Whether a reload happens when this ContentView is activated.
*/
@@ -2382,14 +2549,6 @@
return nativeIsRenderWidgetHostViewReady(mNativeContentViewCore);
}
- /**
- * @return Whether or not the texture view is available or not.
- */
- public boolean isAvailable() {
- // TODO(nileshagrawal): Implement this.
- return false;
- }
-
@CalledByNative
private void startContentIntent(String contentUrl) {
getContentViewClient().onStartContentIntent(getContext(), contentUrl);
@@ -2484,10 +2643,13 @@
/**
* Changes whether hiding the top controls is enabled.
*
- * @param enable Whether hiding the top controls should be enabled.
+ * @param enableHiding Whether hiding the top controls should be enabled or not.
+ * @param enableShowing Whether showing the top controls should be enabled or not.
+ * @param animate Whether the transition should be animated or not.
*/
- public void enableHidingTopControls(boolean enable) {
- nativeEnableHidingTopControls(mNativeContentViewCore, enable);
+ public void updateTopControlsState(boolean enableHiding, boolean enableShowing,
+ boolean animate) {
+ nativeUpdateTopControlsState(mNativeContentViewCore, enableHiding, enableShowing, animate);
}
/**
@@ -2556,14 +2718,11 @@
}
/**
- * Update of the latest vsync parameters.
- * @param tickTimeMicros The latest vsync tick time in microseconds.
- * @param intervalMicros The vsync interval in microseconds.
+ * @return The original request URL for the current navigation entry, or null if there is no
+ * current entry.
*/
- public void updateVSync(long tickTimeMicros, long intervalMicros) {
- if (mNativeContentViewCore != 0) {
- nativeUpdateVSyncParameters(mNativeContentViewCore, tickTimeMicros, intervalMicros);
- }
+ public String getOriginalUrlForActiveNavigationEntry() {
+ return nativeGetOriginalUrlForActiveNavigationEntry(mNativeContentViewCore);
}
/**
@@ -2595,8 +2754,23 @@
getContentViewClient().onExternalVideoSurfaceRequested(playerId);
}
- private native int nativeInit(boolean hardwareAccelerated, boolean inputEventsDeliveredAtVSync,
- int webContentsPtr, int windowAndroidPtr);
+ @CalledByNative
+ private void notifyGeometryChange(int playerId, float x, float y, float width, float height) {
+ RenderCoordinates.NormalizedPoint topLeft = mRenderCoordinates.createNormalizedPoint();
+ RenderCoordinates.NormalizedPoint bottomRight = mRenderCoordinates.createNormalizedPoint();
+ topLeft.setLocalDip(x * getScale(), y * getScale());
+ bottomRight.setLocalDip((x + width) * getScale(), (y + height) * getScale());
+
+ getContentViewClient().onGeometryChanged(
+ playerId,
+ topLeft.getXPix(),
+ topLeft.getYPix(),
+ bottomRight.getXPix() - topLeft.getXPix(),
+ bottomRight.getYPix() - topLeft.getYPix());
+ }
+
+ private native int nativeInit(boolean hardwareAccelerated, int webContentsPtr,
+ int viewAndroidPtr, int windowAndroidPtr);
private native void nativeOnJavaContentViewCoreDestroyed(int nativeContentViewCoreImpl);
@@ -2612,9 +2786,6 @@
String virtualUrlForDataUrl,
boolean canLoadLocalResources);
- private native void nativeSetAllUserAgentOverridesInHistory(int nativeContentViewCoreImpl,
- String userAgentOverride);
-
private native String nativeGetURL(int nativeContentViewCoreImpl);
private native String nativeGetTitle(int nativeContentViewCoreImpl);
@@ -2623,8 +2794,6 @@
int nativeContentViewCoreImpl, String url, int nativeInterstitialPageDelegateAndroid);
private native boolean nativeIsShowingInterstitialPage(int nativeContentViewCoreImpl);
- private native boolean nativeConsumePendingRendererFrame(int nativeContentViewCoreImpl);
-
private native boolean nativeIsIncognito(int nativeContentViewCoreImpl);
// Returns true if the native side crashed so that java side can draw a sad tab.
@@ -2651,8 +2820,8 @@
private native void nativeScrollEnd(int nativeContentViewCoreImpl, long timeMs);
private native void nativeScrollBy(
- int nativeContentViewCoreImpl, long timeMs,
- float x, float y, float deltaX, float deltaY);
+ int nativeContentViewCoreImpl, long timeMs, float x, float y,
+ float deltaX, float deltaY, boolean lastInputEventForVSync);
private native void nativeFlingStart(
int nativeContentViewCoreImpl, long timeMs, float x, float y, float vx, float vy);
@@ -2683,7 +2852,7 @@
private native void nativePinchEnd(int nativeContentViewCoreImpl, long timeMs);
private native void nativePinchBy(int nativeContentViewCoreImpl, long timeMs,
- float anchorX, float anchorY, float deltaScale);
+ float anchorX, float anchorY, float deltaScale, boolean lastInputEventForVSync);
private native void nativeSelectBetweenCoordinates(
int nativeContentViewCoreImpl, float x1, float y1, float x2, float y2);
@@ -2742,10 +2911,14 @@
private native int nativeGetNavigationHistory(int nativeContentViewCoreImpl, Object context);
private native void nativeGetDirectedNavigationHistory(int nativeContentViewCoreImpl,
Object context, boolean isForward, int maxEntries);
+ private native String nativeGetOriginalUrlForActiveNavigationEntry(
+ int nativeContentViewCoreImpl);
private native void nativeUpdateVSyncParameters(int nativeContentViewCoreImpl,
long timebaseMicros, long intervalMicros);
+ private native void nativeOnVSync(int nativeContentViewCoreImpl, long frameTimeMicros);
+
private native boolean nativePopulateBitmapFromCompositor(int nativeContentViewCoreImpl,
Bitmap bitmap);
@@ -2754,8 +2927,8 @@
private native boolean nativeIsRenderWidgetHostViewReady(int nativeContentViewCoreImpl);
private native void nativeExitFullscreen(int nativeContentViewCoreImpl);
- private native void nativeEnableHidingTopControls(
- int nativeContentViewCoreImpl, boolean enable);
+ private native void nativeUpdateTopControlsState(int nativeContentViewCoreImpl,
+ boolean enableHiding, boolean enableShowing, boolean animate);
private native void nativeShowImeIfNeeded(int nativeContentViewCoreImpl);
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewDownloadDelegate.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewDownloadDelegate.java
index 9c056dd..46c3e97 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewDownloadDelegate.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewDownloadDelegate.java
@@ -24,18 +24,26 @@
String mimetype, String cookie, String referer, long contentLength);
/**
- * Notify the host application that a POST download is started.
+ * Notify the host application that a download is started.
*/
- void onHttpPostDownloadStarted();
+ void onDownloadStarted();
/**
- * Notify the host application that a POST download is finished.
+ * Notify the host application that a download is finished.
* @param url The full url to the content that was downloaded.
* @param mimetype The mimetype of downloaded file.
* @param path Path of the downloaded file.
* @param contentLength The file size of the downloaded file (in bytes).
* @param successful Whether the download succeeded
*/
- void onHttpPostDownloadCompleted(String url, String mimetype, String path,
+ void onDownloadCompleted(String url, String mimetype, String path,
long contentLength, boolean successful);
+
+ /**
+ * Notify the host application that a download has an extension indicating
+ * a dangerous file type.
+ * @param filename File name of the downloaded file.
+ * @param downloadId The download id.
+ */
+ void onDangerousDownload(String filename, int downloadId);
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java
index 2a73c01..7ce32da 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java
@@ -5,6 +5,7 @@
package org.chromium.content.browser;
import android.content.Context;
+import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
@@ -60,12 +61,8 @@
private MotionEvent mCurrentDownEvent;
private final MotionEventDelegate mMotionEventDelegate;
- // Queue of motion events. If the boolean value is true, it means
- // that the event has been offered to the native side but not yet acknowledged. If the
- // value is false, it means the touch event has not been offered
- // to the native side and can be immediately processed.
- private final Deque<MotionEvent> mPendingMotionEvents =
- new ArrayDeque<MotionEvent>();
+ // Queue of motion events.
+ private final Deque<MotionEvent> mPendingMotionEvents = new ArrayDeque<MotionEvent>();
// Has WebKit told us the current page requires touch events.
private boolean mHasTouchHandlers = false;
@@ -90,9 +87,8 @@
private boolean mIgnoreSingleTap;
// Does native think we are scrolling? True from right before we
- // send the first scroll event until the last finger is raised, or
- // until after the follow-up fling has finished. Call
- // nativeScrollBegin() when setting this to true, and use
+ // send the first scroll event until the last finger is raised.
+ // Call nativeScrollBegin() when setting this to true, and use
// tellNativeScrollingHasEnded() to set it to false.
private boolean mNativeScrolling;
@@ -104,6 +100,9 @@
// into scrolling or pinching mode.
private boolean mTouchCancelEventSent = false;
+ // Last cancelled touch event as a result of scrolling or pinching.
+ private MotionEvent mLastCancelledEvent = null;
+
private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();
//On single tap this will store the x, y coordinates of the touch.
@@ -118,7 +117,7 @@
// Cache of square of the scaled touch slop so we don't have to calculate it on every touch.
private int mScaledTouchSlopSquare;
- // Object that keeps trqack of and updates scroll snapping behavior.
+ // Object that keeps track of and updates scroll snapping behavior.
private SnapScrollController mSnapScrollController;
// Used to track the accumulated scroll error over time. This is used to remove the
@@ -126,6 +125,9 @@
private float mAccumulatedScrollErrorX = 0;
private float mAccumulatedScrollErrorY = 0;
+ // Whether input events are delivered right before vsync.
+ private boolean mInputEventsDeliveredAtVSync = false;
+
static final int GESTURE_SHOW_PRESSED_STATE = 0;
static final int GESTURE_DOUBLE_TAP = 1;
static final int GESTURE_SINGLE_TAP_UP = 2;
@@ -148,6 +150,11 @@
static final int INPUT_EVENT_ACK_STATE_NOT_CONSUMED = 2;
static final int INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS = 3;
+ // Return values of sendTouchEventToNative();
+ static final int EVENT_FORWARDED_TO_NATIVE = 0;
+ static final int EVENT_CONVERTED_TO_CANCEL = 1;
+ static final int EVENT_NOT_FORWARDED = 2;
+
/**
* This is an interface to handle MotionEvent related communication with the native side also
* access some ContentView specific parameters.
@@ -168,12 +175,15 @@
* @param timeMs The time the gesture event occurred at.
* @param x The x location for the gesture event.
* @param y The y location for the gesture event.
+ * @param lastInputEventForVSync Indicates that this gesture event is the last input
+ * to be event sent during the current vsync interval.
* @param extraParams A bundle that holds specific extra parameters for certain gestures.
* Refer to gesture type definition for more information.
* @return Whether the gesture was sent successfully.
*/
boolean sendGesture(
- int type, long timeMs, int x, int y, Bundle extraParams);
+ int type, long timeMs, int x, int y, boolean lastInputEventForVSync,
+ Bundle extraParams);
/**
* Gives the UI the chance to override each scroll event.
@@ -200,7 +210,11 @@
mLongPressDetector = new LongPressDetector(context, this);
mMotionEventDelegate = delegate;
mZoomManager = zoomManager;
- mSnapScrollController = new SnapScrollController(mZoomManager);
+ mSnapScrollController = new SnapScrollController(context, mZoomManager);
+
+ // Input events are delivered at vsync time on JB+.
+ mInputEventsDeliveredAtVSync = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN);
+
initGestureDetectors(context);
}
@@ -220,7 +234,7 @@
}
private void initGestureDetectors(final Context context) {
- int scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+ final int scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mScaledTouchSlopSquare = scaledTouchSlop * scaledTouchSlop;
try {
TraceEvent.begin();
@@ -244,6 +258,19 @@
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
+ if (!mSeenFirstScrollEvent) {
+ // Remove the touch slop region from the first scroll event to avoid a
+ // jump.
+ mSeenFirstScrollEvent = true;
+ double distance = Math.sqrt(
+ distanceX * distanceX + distanceY * distanceY);
+ double epsilon = 1e-3;
+ if (distance > epsilon) {
+ double ratio = Math.max(0, distance - scaledTouchSlop) / distance;
+ distanceX *= ratio;
+ distanceY *= ratio;
+ }
+ }
mSnapScrollController.updateSnapScrollMode(distanceX, distanceY);
if (mSnapScrollController.isSnappingScrolls()) {
if (mSnapScrollController.isSnapHorizontal()) {
@@ -253,12 +280,6 @@
}
}
- if (!mSeenFirstScrollEvent) {
- // Ignore the first scroll delta to avoid a visible jump.
- mSeenFirstScrollEvent = true;
- return true;
- }
-
boolean didUIStealScroll = mMotionEventDelegate.didUIStealScroll(
e2.getRawX() - mLastRawX, e2.getRawY() - mLastRawY);
@@ -267,9 +288,7 @@
if (didUIStealScroll) return true;
if (!mNativeScrolling) {
sendShowPressCancelIfNecessary(e1);
- if (mMotionEventDelegate.sendGesture(
- GESTURE_SCROLL_START, e1.getEventTime(),
- (int) e1.getX(), (int) e1.getY(), null)) {
+ if (sendMotionEventAsGesture(GESTURE_SCROLL_START, e1, null)) {
mNativeScrolling = true;
}
}
@@ -288,7 +307,7 @@
mExtraParamBundle.putInt(DISTANCE_X, dx);
mExtraParamBundle.putInt(DISTANCE_Y, dy);
if ((dx | dy) != 0) {
- mMotionEventDelegate.sendGesture(GESTURE_SCROLL_BY,
+ sendLastGestureForVSync(GESTURE_SCROLL_BY,
e2.getEventTime(), x, y, mExtraParamBundle);
}
@@ -316,8 +335,7 @@
@Override
public void onShowPress(MotionEvent e) {
mShowPressIsCalled = true;
- mMotionEventDelegate.sendGesture(GESTURE_SHOW_PRESSED_STATE,
- e.getEventTime(), (int) e.getX(), (int) e.getY(), null);
+ sendMotionEventAsGesture(GESTURE_SHOW_PRESSED_STATE, e, null);
}
@Override
@@ -336,8 +354,7 @@
if (e.getEventTime() - e.getDownTime() > DOUBLE_TAP_TIMEOUT) {
float x = e.getX();
float y = e.getY();
- if (mMotionEventDelegate.sendGesture(GESTURE_SINGLE_TAP_UP,
- e.getEventTime(), (int) x, (int) y, null)) {
+ if (sendMotionEventAsGesture(GESTURE_SINGLE_TAP_UP, e, null)) {
mIgnoreSingleTap = true;
}
setClickXAndY((int) x, (int) y);
@@ -349,8 +366,8 @@
float y = e.getY();
mExtraParamBundle.clear();
mExtraParamBundle.putBoolean(SHOW_PRESS, mShowPressIsCalled);
- if (mMotionEventDelegate.sendGesture(GESTURE_SINGLE_TAP_CONFIRMED,
- e.getEventTime(), (int) x, (int) y, mExtraParamBundle)) {
+ if (sendMotionEventAsGesture(GESTURE_SINGLE_TAP_CONFIRMED, e,
+ mExtraParamBundle)) {
mIgnoreSingleTap = true;
}
setClickXAndY((int) x, (int) y);
@@ -372,8 +389,8 @@
int y = (int) e.getY();
mExtraParamBundle.clear();
mExtraParamBundle.putBoolean(SHOW_PRESS, mShowPressIsCalled);
- mMotionEventDelegate.sendGesture(GESTURE_SINGLE_TAP_CONFIRMED,
- e.getEventTime(), x, y, mExtraParamBundle);
+ sendMotionEventAsGesture(GESTURE_SINGLE_TAP_CONFIRMED, e,
+ mExtraParamBundle);
setClickXAndY(x, y);
return true;
}
@@ -381,8 +398,7 @@
@Override
public boolean onDoubleTap(MotionEvent e) {
sendShowPressCancelIfNecessary(e);
- mMotionEventDelegate.sendGesture(GESTURE_DOUBLE_TAP,
- e.getEventTime(), (int) e.getX(), (int) e.getY(), null);
+ sendMotionEventAsGesture(GESTURE_DOUBLE_TAP, e, null);
return true;
}
@@ -390,8 +406,7 @@
public void onLongPress(MotionEvent e) {
if (!mZoomManager.isScaleGestureDetectionInProgress()) {
sendShowPressCancelIfNecessary(e);
- mMotionEventDelegate.sendGesture(GESTURE_LONG_PRESS,
- e.getEventTime(), (int) e.getX(), (int) e.getY(), null);
+ sendMotionEventAsGesture(GESTURE_LONG_PRESS, e, null);
}
}
@@ -452,12 +467,17 @@
* @param velocityY Initial velocity of the fling (Y) measured in pixels per second.
*/
void fling(long timeMs, int x, int y, int velocityX, int velocityY) {
+ if (!mNativeScrolling) {
+ // The native side needs a GESTURE_SCROLL_BEGIN before GESTURE_FLING_START
+ // to send the fling to the correct target. Send if it has not sent.
+ sendGesture(GESTURE_SCROLL_START, timeMs, x, y, null);
+ }
+
endFling(timeMs);
mExtraParamBundle.clear();
mExtraParamBundle.putInt(VELOCITY_X, velocityX);
mExtraParamBundle.putInt(VELOCITY_Y, velocityY);
- mMotionEventDelegate.sendGesture(GESTURE_FLING_START,
- timeMs, x, y, mExtraParamBundle);
+ sendGesture(GESTURE_FLING_START, timeMs, x, y, mExtraParamBundle);
}
/**
@@ -465,16 +485,18 @@
* @param timeMs The time in ms for the event initiating this gesture.
*/
void endFling(long timeMs) {
- mMotionEventDelegate.sendGesture(GESTURE_FLING_CANCEL, timeMs, 0, 0, null);
- tellNativeScrollingHasEnded(timeMs);
+ sendGesture(GESTURE_FLING_CANCEL, timeMs, 0, 0, null);
+ tellNativeScrollingHasEnded(timeMs, false);
}
// If native thinks scrolling (or fling-scrolling) is going on, tell native
// it has ended.
- private void tellNativeScrollingHasEnded(long timeMs) {
+ private void tellNativeScrollingHasEnded(long timeMs, boolean sendScrollEndEvent) {
if (mNativeScrolling) {
mNativeScrolling = false;
- mMotionEventDelegate.sendGesture(GESTURE_SCROLL_END, timeMs, 0, 0, null);
+ if (sendScrollEndEvent) {
+ sendGesture(GESTURE_SCROLL_END, timeMs, 0, 0, null);
+ }
}
}
@@ -501,7 +523,7 @@
* @param y The x coordinate for the event initiating this gesture.
*/
void pinchBegin(long timeMs, int x, int y) {
- mMotionEventDelegate.sendGesture(GESTURE_PINCH_BEGIN, timeMs, x, y, null);
+ sendGesture(GESTURE_PINCH_BEGIN, timeMs, x, y, null);
}
/**
@@ -514,8 +536,7 @@
void pinchBy(long timeMs, int anchorX, int anchorY, float delta) {
mExtraParamBundle.clear();
mExtraParamBundle.putFloat(DELTA, delta);
- mMotionEventDelegate.sendGesture(GESTURE_PINCH_BY,
- timeMs, anchorX, anchorY, mExtraParamBundle);
+ sendLastGestureForVSync(GESTURE_PINCH_BY, timeMs, anchorX, anchorY, mExtraParamBundle);
mPinchInProgress = true;
}
@@ -524,7 +545,7 @@
* @param timeMs The time in ms for the event initiating this gesture.
*/
void pinchEnd(long timeMs) {
- mMotionEventDelegate.sendGesture(GESTURE_PINCH_END, timeMs, 0, 0, null);
+ sendGesture(GESTURE_PINCH_END, timeMs, 0, 0, null);
mPinchInProgress = false;
}
@@ -649,7 +670,7 @@
&& previousEvent.getActionMasked() == MotionEvent.ACTION_MOVE
&& previousEvent.getPointerCount() == event.getPointerCount()) {
MotionEvent.PointerCoords[] coords =
- new MotionEvent.PointerCoords[event.getPointerCount()];
+ new MotionEvent.PointerCoords[event.getPointerCount()];
for (int i = 0; i < coords.length; ++i) {
coords[i] = new MotionEvent.PointerCoords();
event.getPointerCoords(i, coords[i]);
@@ -658,27 +679,42 @@
return true;
}
}
- if (!mPendingMotionEvents.isEmpty() || sendTouchEventToNative(event)) {
+ int forward = EVENT_NOT_FORWARDED;
+ if (mPendingMotionEvents.isEmpty()) {
+ forward = sendTouchEventToNative(event);
+ }
+ if (!mPendingMotionEvents.isEmpty() || forward != EVENT_NOT_FORWARDED) {
// Copy the event, as the original may get mutated after this method returns.
- mPendingMotionEvents.add(MotionEvent.obtain(event));
+ MotionEvent clone = MotionEvent.obtain(event);
+ mPendingMotionEvents.add(clone);
+ // If touch cancel was sent, remember the event.
+ if (forward == EVENT_CONVERTED_TO_CANCEL) {
+ mLastCancelledEvent = clone;
+ }
return true;
}
return false;
}
- private boolean sendTouchEventToNative(MotionEvent event) {
+ private int sendTouchEventToNative(MotionEvent event) {
TouchPoint[] pts = new TouchPoint[event.getPointerCount()];
int type = TouchPoint.createTouchPoints(event, pts);
- boolean forwarded = false;
- if (type != TouchPoint.CONVERSION_ERROR && !mNativeScrolling && !mPinchInProgress) {
- forwarded = mMotionEventDelegate.sendTouchEvent(event.getEventTime(), type, pts);
- mTouchCancelEventSent = false;
- } else if (!mTouchCancelEventSent) {
- mMotionEventDelegate.sendTouchEvent(event.getEventTime(),
- TouchPoint.TOUCH_EVENT_TYPE_CANCEL, pts);
- mTouchCancelEventSent = true;
+
+ if (type != TouchPoint.CONVERSION_ERROR) {
+ if (!mNativeScrolling && !mPinchInProgress) {
+ mTouchCancelEventSent = false;
+ if (mMotionEventDelegate.sendTouchEvent(event.getEventTime(), type, pts)) {
+ return EVENT_FORWARDED_TO_NATIVE;
+ }
+ } else if (!mTouchCancelEventSent) {
+ mTouchCancelEventSent = true;
+ if (mMotionEventDelegate.sendTouchEvent(event.getEventTime(),
+ TouchPoint.TOUCH_EVENT_TYPE_CANCEL, pts)) {
+ return EVENT_CONVERTED_TO_CANCEL;
+ }
+ }
}
- return forwarded;
+ return EVENT_NOT_FORWARDED;
}
private boolean processTouchEvent(MotionEvent event) {
@@ -712,7 +748,7 @@
handled |= mZoomManager.processTouchEvent(event);
if (possiblyEndMovement && !handled) {
- tellNativeScrollingHasEnded(event.getEventTime());
+ tellNativeScrollingHasEnded(event.getEventTime(), true);
}
return handled;
@@ -729,7 +765,11 @@
}
TraceEvent.begin();
MotionEvent ackedEvent = mPendingMotionEvents.removeFirst();
- MotionEvent nextEvent = mPendingMotionEvents.peekFirst();
+ if (ackedEvent.equals(mLastCancelledEvent)) {
+ // The event is canceled, just drain all the pending events until next
+ // touch down.
+ ackResult = INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
+ }
switch (ackResult) {
case INPUT_EVENT_ACK_STATE_UNKNOWN:
// This should never get sent.
@@ -738,11 +778,15 @@
case INPUT_EVENT_ACK_STATE_CONSUMED:
mJavaScriptIsConsumingGesture = true;
mZoomManager.passTouchEventThrough(ackedEvent);
- trySendNextEventToNative(nextEvent);
+ if (!mPendingMotionEvents.isEmpty()) {
+ trySendNextEventToNative(mPendingMotionEvents.peekFirst());
+ }
break;
case INPUT_EVENT_ACK_STATE_NOT_CONSUMED:
if (!mJavaScriptIsConsumingGesture) processTouchEvent(ackedEvent);
- trySendNextEventToNative(nextEvent);
+ if (!mPendingMotionEvents.isEmpty()) {
+ trySendNextEventToNative(mPendingMotionEvents.peekFirst());
+ }
break;
case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS:
mNoTouchHandlerForGesture = true;
@@ -760,16 +804,20 @@
}
private void trySendNextEventToNative(MotionEvent nextEvent) {
- if (nextEvent == null) return;
+ assert(nextEvent != null);
- if (!sendTouchEventToNative(nextEvent)) {
+ int forward = sendTouchEventToNative(nextEvent);
+ if (forward == EVENT_NOT_FORWARDED) {
if (!mJavaScriptIsConsumingGesture) processTouchEvent(nextEvent);
mPendingMotionEvents.removeFirst();
- nextEvent = mPendingMotionEvents.peekFirst();
- // Event though we missed sending one event to native, as long as we haven't
+ // Even though we missed sending one event to native, as long as we haven't
// received INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, we should keep sending
// events on the queue to native.
- trySendNextEventToNative(nextEvent);
+ if (!mPendingMotionEvents.isEmpty()) {
+ trySendNextEventToNative(mPendingMotionEvents.peekFirst());
+ }
+ } else if (forward == EVENT_CONVERTED_TO_CANCEL) {
+ mLastCancelledEvent = mPendingMotionEvents.peekFirst();
}
}
@@ -786,15 +834,30 @@
if (nextEvent == null) return;
mNoTouchHandlerForGesture = false;
- MotionEvent newDownEvent = mPendingMotionEvents.peekFirst();
- trySendNextEventToNative(newDownEvent);
+ trySendNextEventToNative(nextEvent);
+ }
+
+ private boolean sendMotionEventAsGesture(
+ int type, MotionEvent event, Bundle extraParams) {
+ return mMotionEventDelegate.sendGesture(type, event.getEventTime(),
+ (int) event.getX(), (int) event.getY(), false, extraParams);
+ }
+
+ private boolean sendGesture(
+ int type, long timeMs, int x, int y, Bundle extraParams) {
+ return mMotionEventDelegate.sendGesture(type, timeMs, x, y, false, extraParams);
+ }
+
+ private boolean sendLastGestureForVSync(
+ int type, long timeMs, int x, int y, Bundle extraParams) {
+ return mMotionEventDelegate.sendGesture(
+ type, timeMs, x, y, mInputEventsDeliveredAtVSync, extraParams);
}
void sendShowPressCancelIfNecessary(MotionEvent e) {
if (!mShowPressIsCalled) return;
- if (mMotionEventDelegate.sendGesture(GESTURE_SHOW_PRESS_CANCEL,
- e.getEventTime(), (int) e.getX(), (int) e.getY(), null)) {
+ if (sendMotionEventAsGesture(GESTURE_SHOW_PRESS_CANCEL, e, null)) {
mShowPressIsCalled = false;
}
}
@@ -816,8 +879,7 @@
if (mLongPressDetector.isInLongPress() && ev.getAction() == MotionEvent.ACTION_UP &&
!mZoomManager.isScaleGestureDetectionInProgress()) {
sendShowPressCancelIfNecessary(ev);
- mMotionEventDelegate.sendGesture(GESTURE_LONG_TAP,
- ev.getEventTime(), (int) ev.getX(), (int) ev.getY(), null);
+ sendMotionEventAsGesture(GESTURE_LONG_TAP, ev, null);
return true;
}
return false;
@@ -827,15 +889,23 @@
* This is for testing only.
* @return The first motion event on the pending motion events queue.
*/
- MotionEvent peekFirstInPendingMotionEvents() {
+ MotionEvent peekFirstInPendingMotionEventsForTesting() {
return mPendingMotionEvents.peekFirst();
}
/**
* This is for testing only.
+ * @return Whether the motion event is cancelled.
+ */
+ boolean isEventCancelledForTesting(MotionEvent event) {
+ return event != null && event.equals(mLastCancelledEvent);
+ }
+
+ /**
+ * This is for testing only.
* @return The number of motion events on the pending motion events queue.
*/
- int getNumberOfPendingMotionEvents() {
+ int getNumberOfPendingMotionEventsForTesting() {
return mPendingMotionEvents.size();
}
@@ -844,7 +914,7 @@
* Sends a show pressed state gesture through mListener. This should always be called after
* a down event;
*/
- void sendShowPressedStateGestureForTest() {
+ void sendShowPressedStateGestureForTesting() {
if (mCurrentDownEvent == null) return;
mListener.onShowPress(mCurrentDownEvent);
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java
index 781899d..ddd6b28 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java
@@ -25,17 +25,10 @@
private int mNativeContentViewRenderView = 0;
private SurfaceView mSurfaceView;
+ private VSyncAdapter mVSyncAdapter;
private ContentView mCurrentContentView;
- private final VSyncMonitor mVSyncMonitor;
-
- // The VSyncMonitor gives the timebase for the actual vsync, but we don't want render until
- // we have had a chance for input events to propagate to the compositor thread. This takes
- // 3 ms typically, so we adjust the vsync timestamps forward by a bit to give input events a
- // chance to arrive.
- private static final long INPUT_EVENT_LAG_FROM_VSYNC_MICROSECONDS = 3200;
-
/**
* Constructs a new ContentViewRenderView that should be can to a view hierarchy.
* Native code should add/remove the layers to be rendered through the ContentViewLayerRenderer.
@@ -47,7 +40,7 @@
mNativeContentViewRenderView = nativeInit();
assert mNativeContentViewRenderView != 0;
- mSurfaceView = new SurfaceView(getContext());
+ mSurfaceView = createSurfaceView(getContext());
mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
@@ -70,24 +63,60 @@
}
});
- mVSyncMonitor = new VSyncMonitor(getContext(), new VSyncMonitor.Listener() {
- @Override
- public void onVSync(VSyncMonitor monitor, long vsyncTimeMicros) {
- if (mCurrentContentView == null) return;
+ mVSyncAdapter = new VSyncAdapter(getContext());
+ addView(mSurfaceView,
+ new FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.MATCH_PARENT));
+ }
+
+ private static class VSyncAdapter implements VSyncManager.Provider, VSyncMonitor.Listener {
+ private final VSyncMonitor mVSyncMonitor;
+ private boolean mVSyncNotificationEnabled;
+ private VSyncManager.Listener mVSyncListener;
+
+ // The VSyncMonitor gives the timebase for the actual vsync, but we don't want render until
+ // we have had a chance for input events to propagate to the compositor thread. This takes
+ // 3 ms typically, so we adjust the vsync timestamps forward by a bit to give input events a
+ // chance to arrive.
+ private static final long INPUT_EVENT_LAG_FROM_VSYNC_MICROSECONDS = 3200;
+
+ VSyncAdapter(Context context) {
+ mVSyncMonitor = new VSyncMonitor(context, this);
+ }
+
+ @Override
+ public void onVSync(VSyncMonitor monitor, long vsyncTimeMicros) {
+ if (mVSyncListener == null) return;
+ if (mVSyncNotificationEnabled) {
+ mVSyncListener.onVSync(vsyncTimeMicros);
+ mVSyncMonitor.requestUpdate();
+ } else {
// Compensate for input event lag. Input events are delivered immediately on
// pre-JB releases, so this adjustment is only done for later versions.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
vsyncTimeMicros += INPUT_EVENT_LAG_FROM_VSYNC_MICROSECONDS;
}
- mCurrentContentView.getContentViewCore().updateVSync(vsyncTimeMicros,
+ mVSyncListener.updateVSync(vsyncTimeMicros,
mVSyncMonitor.getVSyncPeriodInMicroseconds());
}
- });
+ }
- addView(mSurfaceView,
- new FrameLayout.LayoutParams(
- FrameLayout.LayoutParams.MATCH_PARENT,
- FrameLayout.LayoutParams.MATCH_PARENT));
+ @Override
+ public void registerVSyncListener(VSyncManager.Listener listener) {
+ if (!mVSyncNotificationEnabled) mVSyncMonitor.requestUpdate();
+ mVSyncNotificationEnabled = true;
+ }
+
+ @Override
+ public void unregisterVSyncListener(VSyncManager.Listener listener) {
+ mVSyncNotificationEnabled = false;
+ }
+
+ void setVSyncListener(VSyncManager.Listener listener) {
+ mVSyncListener = listener;
+ if (mVSyncListener != null) mVSyncMonitor.requestUpdate();
+ }
}
/**
@@ -102,13 +131,13 @@
* Makes the passed ContentView the one displayed by this ContentViewRenderView.
*/
public void setCurrentContentView(ContentView contentView) {
+ ContentViewCore contentViewCore = contentView.getContentViewCore();
nativeSetCurrentContentView(mNativeContentViewRenderView,
- contentView.getContentViewCore().getNativeContentViewCore());
+ contentViewCore.getNativeContentViewCore());
mCurrentContentView = contentView;
- mCurrentContentView.getContentViewCore().onPhysicalBackingSizeChanged(
- getWidth(), getHeight());
- mVSyncMonitor.requestUpdate();
+ contentViewCore.onPhysicalBackingSizeChanged(getWidth(), getHeight());
+ mVSyncAdapter.setVSyncListener(contentViewCore.getVSyncListener(mVSyncAdapter));
}
/**
@@ -119,6 +148,16 @@
}
/**
+ * This method could be subclassed optionally to provide a custom SurfaceView object to
+ * this ContentViewRenderView.
+ * @param context The context used to create the SurfaceView object.
+ * @return The created SurfaceView object.
+ */
+ protected SurfaceView createSurfaceView(Context context) {
+ return new SurfaceView(context);
+ }
+
+ /**
* @return whether the surface view is initialized and ready to render.
*/
public boolean isInitialized() {
diff --git a/content/public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java b/content/public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java
new file mode 100644
index 0000000..ecb9d62
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/DeviceMotionAndOrientation.java
@@ -0,0 +1,451 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.util.Log;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+import org.chromium.base.WeakContext;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Android implementation of the device motion and orientation APIs.
+ */
+@JNINamespace("content")
+class DeviceMotionAndOrientation implements SensorEventListener {
+
+ private static final String TAG = "DeviceMotionAndOrientation";
+
+ // These fields are lazily initialized by getHandler().
+ private Thread mThread;
+ private Handler mHandler;
+
+ // The lock to access the mHandler.
+ private Object mHandlerLock = new Object();
+
+ // Non-zero if and only if we're listening for events.
+ // To avoid race conditions on the C++ side, access must be synchronized.
+ private int mNativePtr;
+
+ // The lock to access the mNativePtr.
+ private Object mNativePtrLock = new Object();
+
+ // The acceleration vector including gravity expressed in the body frame.
+ private float[] mAccelerationVector;
+
+ // The geomagnetic vector expressed in the body frame.
+ private float[] mMagneticFieldVector;
+
+ // Lazily initialized when registering for notifications.
+ private SensorManagerProxy mSensorManagerProxy;
+
+ // The only instance of that class and its associated lock.
+ private static DeviceMotionAndOrientation sSingleton;
+ private static Object sSingletonLock = new Object();
+
+ /**
+ * constants for using in JNI calls, also see
+ * content/browser/device_orientation/data_fetcher_impl_android.cc
+ */
+ static final int DEVICE_ORIENTATION = 0;
+ static final int DEVICE_MOTION = 1;
+
+ static final ImmutableSet<Integer> DEVICE_ORIENTATION_SENSORS = ImmutableSet.of(
+ Sensor.TYPE_ACCELEROMETER,
+ Sensor.TYPE_MAGNETIC_FIELD);
+
+ static final ImmutableSet<Integer> DEVICE_MOTION_SENSORS = ImmutableSet.of(
+ Sensor.TYPE_ACCELEROMETER,
+ Sensor.TYPE_LINEAR_ACCELERATION,
+ Sensor.TYPE_GYROSCOPE);
+
+ @VisibleForTesting
+ final Set<Integer> mActiveSensors = Sets.newHashSet();
+ boolean mDeviceMotionIsActive = false;
+ boolean mDeviceOrientationIsActive = false;
+
+ protected DeviceMotionAndOrientation() {
+ }
+
+ /**
+ * Start listening for sensor events. If this object is already listening
+ * for events, the old callback is unregistered first.
+ *
+ * @param nativePtr Value to pass to nativeGotOrientation() for each event.
+ * @param rateInMilliseconds Requested callback rate in milliseconds. The
+ * actual rate may be higher. Unwanted events should be ignored.
+ * @param eventType Type of event to listen to, can be either DEVICE_ORIENTATION or
+ * DEVICE_MOTION.
+ * @return True on success.
+ */
+ @CalledByNative
+ public boolean start(int nativePtr, int eventType, int rateInMilliseconds) {
+ boolean success = false;
+ synchronized (mNativePtrLock) {
+ switch (eventType) {
+ case DEVICE_ORIENTATION:
+ success = registerSensors(DEVICE_ORIENTATION_SENSORS, rateInMilliseconds,
+ true);
+ break;
+ case DEVICE_MOTION:
+ // note: device motion spec does not require all sensors to be available
+ success = registerSensors(DEVICE_MOTION_SENSORS, rateInMilliseconds, false);
+ break;
+ default:
+ Log.e(TAG, "Unknown event type: " + eventType);
+ return false;
+ }
+ if (success) {
+ mNativePtr = nativePtr;
+ setEventTypeActive(eventType, true);
+ }
+ return success;
+ }
+ }
+
+ /**
+ * Stop listening to sensors for a given event type. Ensures that sensors are not disabled
+ * if they are still in use by a different event type.
+ *
+ * @param eventType Type of event to listen to, can be either DEVICE_ORIENTATION or
+ * DEVICE_MOTION.
+ * We strictly guarantee that the corresponding native*() methods will not be called
+ * after this method returns.
+ */
+ @CalledByNative
+ public void stop(int eventType) {
+ Set<Integer> sensorsToRemainActive = Sets.newHashSet();
+ synchronized (mNativePtrLock) {
+ switch (eventType) {
+ case DEVICE_ORIENTATION:
+ if (mDeviceMotionIsActive) {
+ sensorsToRemainActive.addAll(DEVICE_MOTION_SENSORS);
+ }
+ break;
+ case DEVICE_MOTION:
+ if (mDeviceOrientationIsActive) {
+ sensorsToRemainActive.addAll(DEVICE_ORIENTATION_SENSORS);
+ }
+ break;
+ default:
+ Log.e(TAG, "Unknown event type: " + eventType);
+ return;
+ }
+
+ Set<Integer> sensorsToDeactivate = Sets.newHashSet(mActiveSensors);
+ sensorsToDeactivate.removeAll(sensorsToRemainActive);
+ unregisterSensors(sensorsToDeactivate);
+ setEventTypeActive(eventType, false);
+ if (mActiveSensors.isEmpty()) {
+ mNativePtr = 0;
+ }
+ }
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ // Nothing
+ }
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ sensorChanged(event.sensor.getType(), event.values);
+ }
+
+ @VisibleForTesting
+ void sensorChanged(int type, float[] values) {
+
+ switch (type) {
+ case Sensor.TYPE_ACCELEROMETER:
+ if (mAccelerationVector == null) {
+ mAccelerationVector = new float[3];
+ }
+ System.arraycopy(values, 0, mAccelerationVector, 0,
+ mAccelerationVector.length);
+ if (mDeviceMotionIsActive) {
+ gotAccelerationIncludingGravity(mAccelerationVector[0], mAccelerationVector[1],
+ mAccelerationVector[2]);
+ }
+ break;
+ case Sensor.TYPE_LINEAR_ACCELERATION:
+ if (mDeviceMotionIsActive) {
+ gotAcceleration(values[0], values[1], values[2]);
+ }
+ break;
+ case Sensor.TYPE_GYROSCOPE:
+ if (mDeviceMotionIsActive) {
+ gotRotationRate(values[0], values[1], values[2]);
+ }
+ break;
+ case Sensor.TYPE_MAGNETIC_FIELD:
+ if (mMagneticFieldVector == null) {
+ mMagneticFieldVector = new float[3];
+ }
+ System.arraycopy(values, 0, mMagneticFieldVector, 0,
+ mMagneticFieldVector.length);
+ break;
+ default:
+ // Unexpected
+ return;
+ }
+
+ if (mDeviceOrientationIsActive) {
+ getOrientationUsingGetRotationMatrix();
+ }
+ }
+
+ private void getOrientationUsingGetRotationMatrix() {
+ if (mAccelerationVector == null || mMagneticFieldVector == null) {
+ return;
+ }
+
+ // Get the rotation matrix.
+ // The rotation matrix that transforms from the body frame to the earth
+ // frame.
+ float[] deviceRotationMatrix = new float[9];
+ if (!SensorManager.getRotationMatrix(deviceRotationMatrix, null, mAccelerationVector,
+ mMagneticFieldVector)) {
+ return;
+ }
+
+ // Convert rotation matrix to rotation angles.
+ // Assuming that the rotations are appied in the order listed at
+ // http://developer.android.com/reference/android/hardware/SensorEvent.html#values
+ // the rotations are applied about the same axes and in the same order as required by the
+ // API. The only conversions are sign changes as follows. The angles are in radians
+
+ float[] rotationAngles = new float[3];
+ SensorManager.getOrientation(deviceRotationMatrix, rotationAngles);
+
+ double alpha = Math.toDegrees(-rotationAngles[0]);
+ while (alpha < 0.0) {
+ alpha += 360.0; // [0, 360)
+ }
+
+ double beta = Math.toDegrees(-rotationAngles[1]);
+ while (beta < -180.0) {
+ beta += 360.0; // [-180, 180)
+ }
+
+ double gamma = Math.toDegrees(rotationAngles[2]);
+ while (gamma < -90.0) {
+ gamma += 360.0; // [-90, 90)
+ }
+
+ gotOrientation(alpha, beta, gamma);
+ }
+
+ private SensorManagerProxy getSensorManagerProxy() {
+ if (mSensorManagerProxy != null) {
+ return mSensorManagerProxy;
+ }
+ SensorManager sensorManager = (SensorManager)WeakContext.getSystemService(
+ Context.SENSOR_SERVICE);
+ if (sensorManager != null) {
+ mSensorManagerProxy = new SensorManagerProxyImpl(sensorManager);
+ }
+ return mSensorManagerProxy;
+ }
+
+ @VisibleForTesting
+ void setSensorManagerProxy(SensorManagerProxy sensorManagerProxy) {
+ mSensorManagerProxy = sensorManagerProxy;
+ }
+
+ private void setEventTypeActive(int eventType, boolean value) {
+ switch (eventType) {
+ case DEVICE_ORIENTATION:
+ mDeviceOrientationIsActive = value;
+ return;
+ case DEVICE_MOTION:
+ mDeviceMotionIsActive = value;
+ return;
+ }
+ }
+
+ /**
+ * @param sensorTypes List of sensors to activate.
+ * @param rateInMilliseconds Intended delay (in milliseconds) between sensor readings.
+ * @param failOnMissingSensor If true the method returns true only if all sensors could be
+ * activated. When false the method return true if at least one
+ * sensor in sensorTypes could be activated.
+ */
+ private boolean registerSensors(Iterable<Integer> sensorTypes, int rateInMilliseconds,
+ boolean failOnMissingSensor) {
+ Set<Integer> sensorsToActivate = Sets.newHashSet(sensorTypes);
+ sensorsToActivate.removeAll(mActiveSensors);
+ boolean success = false;
+
+ for (Integer sensorType : sensorsToActivate) {
+ boolean result = registerForSensorType(sensorType, rateInMilliseconds);
+ if (!result && failOnMissingSensor) {
+ // restore the previous state upon failure
+ unregisterSensors(sensorsToActivate);
+ return false;
+ }
+ if (result) {
+ mActiveSensors.add(sensorType);
+ success = true;
+ }
+ }
+ return success;
+ }
+
+ private void unregisterSensors(Iterable<Integer> sensorTypes) {
+ for (Integer sensorType : sensorTypes) {
+ if (mActiveSensors.contains(sensorType)) {
+ getSensorManagerProxy().unregisterListener(this, sensorType);
+ mActiveSensors.remove(sensorType);
+ }
+ }
+ }
+
+ private boolean registerForSensorType(int type, int rateInMilliseconds) {
+ SensorManagerProxy sensorManager = getSensorManagerProxy();
+ if (sensorManager == null) {
+ return false;
+ }
+ final int rateInMicroseconds = 1000 * rateInMilliseconds;
+ return sensorManager.registerListener(this, type, rateInMicroseconds, getHandler());
+ }
+
+ protected void gotOrientation(double alpha, double beta, double gamma) {
+ synchronized (mNativePtrLock) {
+ if (mNativePtr != 0) {
+ nativeGotOrientation(mNativePtr, alpha, beta, gamma);
+ }
+ }
+ }
+
+ protected void gotAcceleration(double x, double y, double z) {
+ synchronized (mNativePtrLock) {
+ if (mNativePtr != 0) {
+ nativeGotAcceleration(mNativePtr, x, y, z);
+ }
+ }
+ }
+
+ protected void gotAccelerationIncludingGravity(double x, double y, double z) {
+ synchronized (mNativePtrLock) {
+ if (mNativePtr != 0) {
+ nativeGotAccelerationIncludingGravity(mNativePtr, x, y, z);
+ }
+ }
+ }
+
+ protected void gotRotationRate(double alpha, double beta, double gamma) {
+ synchronized (mNativePtrLock) {
+ if (mNativePtr != 0) {
+ nativeGotRotationRate(mNativePtr, alpha, beta, gamma);
+ }
+ }
+ }
+
+ private Handler getHandler() {
+ // TODO(timvolodine): Remove the mHandlerLock when sure that getHandler is not called
+ // from multiple threads. This will be the case when device motion and device orientation
+ // use the same polling thread (also see crbug/234282).
+ synchronized (mHandlerLock) {
+ if (mHandler == null) {
+ HandlerThread thread = new HandlerThread("DeviceMotionAndOrientation");
+ thread.start();
+ mHandler = new Handler(thread.getLooper()); // blocks on thread start
+ }
+ return mHandler;
+ }
+ }
+
+ @CalledByNative
+ static DeviceMotionAndOrientation getInstance() {
+ synchronized (sSingletonLock) {
+ if (sSingleton == null) {
+ sSingleton = new DeviceMotionAndOrientation();
+ }
+ return sSingleton;
+ }
+ }
+
+ /**
+ * Native JNI calls,
+ * see content/browser/device_orientation/data_fetcher_impl_android.cc
+ */
+
+ /**
+ * Orientation of the device with respect to its reference frame.
+ */
+ private native void nativeGotOrientation(
+ int nativeDataFetcherImplAndroid,
+ double alpha, double beta, double gamma);
+
+ /**
+ * Linear acceleration without gravity of the device with respect to its body frame.
+ */
+ private native void nativeGotAcceleration(
+ int nativeDataFetcherImplAndroid,
+ double x, double y, double z);
+
+ /**
+ * Acceleration including gravity of the device with respect to its body frame.
+ */
+ private native void nativeGotAccelerationIncludingGravity(
+ int nativeDataFetcherImplAndroid,
+ double x, double y, double z);
+
+ /**
+ * Rotation rate of the device with respect to its body frame.
+ */
+ private native void nativeGotRotationRate(
+ int nativeDataFetcherImplAndroid,
+ double alpha, double beta, double gamma);
+
+ /**
+ * Need the an interface for SensorManager for testing.
+ */
+ interface SensorManagerProxy {
+ public boolean registerListener(SensorEventListener listener, int sensorType, int rate,
+ Handler handler);
+ public void unregisterListener(SensorEventListener listener, int sensorType);
+ }
+
+ static class SensorManagerProxyImpl implements SensorManagerProxy {
+ private final SensorManager mSensorManager;
+
+ SensorManagerProxyImpl(SensorManager sensorManager) {
+ mSensorManager = sensorManager;
+ }
+
+ public boolean registerListener(SensorEventListener listener, int sensorType, int rate,
+ Handler handler) {
+ List<Sensor> sensors = mSensorManager.getSensorList(sensorType);
+ if (sensors.isEmpty()) {
+ return false;
+ }
+ return mSensorManager.registerListener(listener, sensors.get(0), rate, handler);
+ }
+
+ public void unregisterListener(SensorEventListener listener, int sensorType) {
+ List<Sensor> sensors = mSensorManager.getSensorList(sensorType);
+ if (!sensors.isEmpty()) {
+ mSensorManager.unregisterListener(listener, sensors.get(0));
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/content/public/android/java/src/org/chromium/content/browser/DeviceOrientation.java b/content/public/android/java/src/org/chromium/content/browser/DeviceOrientation.java
deleted file mode 100644
index a77cd28..0000000
--- a/content/public/android/java/src/org/chromium/content/browser/DeviceOrientation.java
+++ /dev/null
@@ -1,269 +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.
-
-package org.chromium.content.browser;
-
-import android.content.Context;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-import android.os.Handler;
-import android.os.Looper;
-
-import org.chromium.base.CalledByNative;
-import org.chromium.base.JNINamespace;
-import org.chromium.base.WeakContext;
-
-import java.util.List;
-
-/**
- * Android implementation of the DeviceOrientation API.
- */
-@JNINamespace("content")
-class DeviceOrientation implements SensorEventListener {
-
- // These fields are lazily initialized by getHandler().
- private Thread mThread;
- private Handler mHandler;
-
- // The lock to access the mHandler.
- private Object mHandlerLock = new Object();
-
- // Non-zero if and only if we're listening for events.
- // To avoid race conditions on the C++ side, access must be synchronized.
- private int mNativePtr;
-
- // The lock to access the mNativePtr.
- private Object mNativePtrLock = new Object();
-
- // The gravity vector expressed in the body frame.
- private float[] mGravityVector;
-
- // The geomagnetic vector expressed in the body frame.
- private float[] mMagneticFieldVector;
-
- // Lazily initialized when registering for notifications.
- private SensorManager mSensorManager;
-
- // The only instance of that class and its associated lock.
- private static DeviceOrientation sSingleton;
- private static Object sSingletonLock = new Object();
-
- private DeviceOrientation() {
- }
-
- /**
- * Start listening for sensor events. If this object is already listening
- * for events, the old callback is unregistered first.
- *
- * @param nativePtr Value to pass to nativeGotOrientation() for each event.
- * @param rateInMilliseconds Requested callback rate in milliseconds. The
- * actual rate may be higher. Unwanted events should be ignored.
- * @return True on success.
- */
- @CalledByNative
- public boolean start(int nativePtr, int rateInMilliseconds) {
- synchronized (mNativePtrLock) {
- stop();
- if (registerForSensors(rateInMilliseconds)) {
- mNativePtr = nativePtr;
- return true;
- }
- return false;
- }
- }
-
- /**
- * Stop listening for sensor events. Always succeeds.
- *
- * We strictly guarantee that nativeGotOrientation() will not be called
- * after this method returns.
- */
- @CalledByNative
- public void stop() {
- synchronized (mNativePtrLock) {
- if (mNativePtr != 0) {
- mNativePtr = 0;
- unregisterForSensors();
- }
- }
- }
-
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- // Nothing
- }
-
- @Override
- public void onSensorChanged(SensorEvent event) {
- switch (event.sensor.getType()) {
- case Sensor.TYPE_ACCELEROMETER:
- if (mGravityVector == null) {
- mGravityVector = new float[3];
- }
- System.arraycopy(event.values, 0, mGravityVector, 0, mGravityVector.length);
- break;
-
- case Sensor.TYPE_MAGNETIC_FIELD:
- if (mMagneticFieldVector == null) {
- mMagneticFieldVector = new float[3];
- }
- System.arraycopy(event.values, 0, mMagneticFieldVector, 0,
- mMagneticFieldVector.length);
- break;
-
- default:
- // Unexpected
- return;
- }
-
- getOrientationUsingGetRotationMatrix();
- }
-
- void getOrientationUsingGetRotationMatrix() {
- if (mGravityVector == null || mMagneticFieldVector == null) {
- return;
- }
-
- // Get the rotation matrix.
- // The rotation matrix that transforms from the body frame to the earth
- // frame.
- float[] deviceRotationMatrix = new float[9];
- if (!SensorManager.getRotationMatrix(deviceRotationMatrix, null, mGravityVector,
- mMagneticFieldVector)) {
- return;
- }
-
- // Convert rotation matrix to rotation angles.
- // Assuming that the rotations are appied in the order listed at
- // http://developer.android.com/reference/android/hardware/SensorEvent.html#values
- // the rotations are applied about the same axes and in the same order as required by the
- // API. The only conversions are sign changes as follows. The angles are in radians
-
- float[] rotationAngles = new float[3];
- SensorManager.getOrientation(deviceRotationMatrix, rotationAngles);
-
- double alpha = Math.toDegrees(-rotationAngles[0]);
- while (alpha < 0.0) {
- alpha += 360.0; // [0, 360)
- }
-
- double beta = Math.toDegrees(-rotationAngles[1]);
- while (beta < -180.0) {
- beta += 360.0; // [-180, 180)
- }
-
- double gamma = Math.toDegrees(rotationAngles[2]);
- while (gamma < -90.0) {
- gamma += 360.0; // [-90, 90)
- }
-
- gotOrientation(alpha, beta, gamma);
- }
-
- boolean registerForSensors(int rateInMilliseconds) {
- if (registerForSensorType(Sensor.TYPE_ACCELEROMETER, rateInMilliseconds)
- && registerForSensorType(Sensor.TYPE_MAGNETIC_FIELD, rateInMilliseconds)) {
- return true;
- }
- unregisterForSensors();
- return false;
- }
-
- private SensorManager getSensorManager() {
- if (mSensorManager != null) {
- return mSensorManager;
- }
- mSensorManager = (SensorManager)WeakContext.getSystemService(Context.SENSOR_SERVICE);
- return mSensorManager;
- }
-
- void unregisterForSensors() {
- SensorManager sensorManager = getSensorManager();
- if (sensorManager == null) {
- return;
- }
- sensorManager.unregisterListener(this);
- }
-
- boolean registerForSensorType(int type, int rateInMilliseconds) {
- SensorManager sensorManager = getSensorManager();
- if (sensorManager == null) {
- return false;
- }
- List<Sensor> sensors = sensorManager.getSensorList(type);
- if (sensors.isEmpty()) {
- return false;
- }
-
- final int rateInMicroseconds = 1000 * rateInMilliseconds;
- // We want to err on the side of getting more events than we need.
- final int requestedRate = rateInMicroseconds / 2;
-
- // TODO(steveblock): Consider handling multiple sensors.
- return sensorManager.registerListener(this, sensors.get(0), requestedRate, getHandler());
- }
-
- void gotOrientation(double alpha, double beta, double gamma) {
- synchronized (mNativePtrLock) {
- if (mNativePtr != 0) {
- nativeGotOrientation(mNativePtr, alpha, beta, gamma);
- }
- }
- }
-
- private Handler getHandler() {
- synchronized (mHandlerLock) {
- // If we don't have a background thread, start it now.
- if (mThread == null) {
- mThread = new Thread(new Runnable() {
- @Override
- public void run() {
- Looper.prepare();
- // Our Handler doesn't actually have to do anything, because
- // SensorManager posts directly to the underlying Looper.
- setHandler(new Handler());
- Looper.loop();
- }
- });
- mThread.start();
- }
- // Wait for the background thread to spin up.
- while (mHandler == null) {
- try {
- mHandlerLock.wait();
- } catch (InterruptedException e) {
- // Somebody doesn't want us to wait! That's okay, SensorManager accepts null.
- return null;
- }
- }
- return mHandler;
- }
- }
-
- private void setHandler(Handler handler) {
- synchronized (mHandlerLock) {
- mHandler = handler;
- mHandlerLock.notify();
- }
- }
-
- @CalledByNative
- private static DeviceOrientation getInstance() {
- synchronized (sSingletonLock) {
- if (sSingleton == null) {
- sSingleton = new DeviceOrientation();
- }
- return sSingleton;
- }
- }
-
- /**
- * See chrome/browser/device_orientation/data_fetcher_impl_android.cc
- */
- private native void nativeGotOrientation(
- int nativeDataFetcherImplAndroid,
- double alpha, double beta, double gamma);
-}
diff --git a/content/public/android/java/src/org/chromium/content/browser/DeviceUtils.java b/content/public/android/java/src/org/chromium/content/browser/DeviceUtils.java
index 04ebb45..30bb418 100644
--- a/content/public/android/java/src/org/chromium/content/browser/DeviceUtils.java
+++ b/content/public/android/java/src/org/chromium/content/browser/DeviceUtils.java
@@ -24,6 +24,9 @@
* @return Whether the app is should treat the device as a tablet for layout.
*/
public static boolean isTablet(Context context) {
+ if (isTv(context)) {
+ return true;
+ }
int minimumScreenWidthDp = context.getResources().getConfiguration().smallestScreenWidthDp;
return minimumScreenWidthDp >= MINIMUM_TABLET_WIDTH_DP;
}
@@ -49,7 +52,7 @@
* @param context The context for the caller activity.
*/
public static void addDeviceSpecificUserAgentSwitch(Context context) {
- if (isTv(context) || isTablet(context)) {
+ if (isTablet(context)) {
CommandLine.getInstance().appendSwitch(CommandLine.TABLET_UI);
} else {
CommandLine.getInstance().appendSwitch(CommandLine.USE_MOBILE_UA);
diff --git a/content/public/android/java/src/org/chromium/content/browser/DownloadController.java b/content/public/android/java/src/org/chromium/content/browser/DownloadController.java
index 77936fc..9577ba1 100644
--- a/content/public/android/java/src/org/chromium/content/browser/DownloadController.java
+++ b/content/public/android/java/src/org/chromium/content/browser/DownloadController.java
@@ -52,33 +52,46 @@
}
/**
- * Notifies the download delegate that a new POST download has started.
+ * Notifies the download delegate that a new download has started. This can
+ * be either a POST download or a GET download with authentication.
*/
@CalledByNative
- public void onHttpPostDownloadStarted(ContentViewCore view) {
+ public void onDownloadStarted(ContentViewCore view) {
ContentViewDownloadDelegate downloadDelagate = downloadDelegateFromView(view);
if (downloadDelagate != null) {
- downloadDelagate.onHttpPostDownloadStarted();
+ downloadDelagate.onDownloadStarted();
}
}
/**
- * Notifies the download delegate that a POST download completed and passes along info about the
- * download.
+ * Notifies the download delegate that a download completed and passes along info about the
+ * download. This can be either a POST download or a GET download with authentication.
*/
@CalledByNative
- public void onHttpPostDownloadCompleted(ContentViewCore view, String url,
+ public void onDownloadCompleted(ContentViewCore view, String url,
String contentDisposition, String mimetype, String path,
long contentLength, boolean successful) {
ContentViewDownloadDelegate downloadDelagate = downloadDelegateFromView(view);
if (downloadDelagate != null) {
- downloadDelagate.onHttpPostDownloadCompleted(
+ downloadDelagate.onDownloadCompleted(
url, mimetype, path, contentLength, successful);
}
}
+ /**
+ * Notifies the download delegate that a dangerous download started.
+ */
+ @CalledByNative
+ public void onDangerousDownload(ContentViewCore view, String filename,
+ int downloadId) {
+ ContentViewDownloadDelegate downloadDelagate = downloadDelegateFromView(view);
+ if (downloadDelagate != null) {
+ downloadDelagate.onDangerousDownload(filename, downloadId);
+ }
+ }
+
// native methods
private native void nativeInit();
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/ImeAdapter.java b/content/public/android/java/src/org/chromium/content/browser/ImeAdapter.java
deleted file mode 100644
index 4b312fd..0000000
--- a/content/public/android/java/src/org/chromium/content/browser/ImeAdapter.java
+++ /dev/null
@@ -1,842 +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.
-
-package org.chromium.content.browser;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.ResultReceiver;
-import android.text.Editable;
-import android.text.InputType;
-import android.text.Selection;
-import android.util.Log;
-import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.inputmethod.BaseInputConnection;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.ExtractedText;
-import android.view.inputmethod.ExtractedTextRequest;
-
-import com.google.common.annotations.VisibleForTesting;
-
-import org.chromium.base.CalledByNative;
-import org.chromium.base.JNINamespace;
-
-/**
- * Adapts and plumbs android IME service onto the chrome text input API.
- * ImeAdapter provides an interface in both ways native <-> java:
- * 1. InputConnectionAdapter notifies native code of text composition state and
- * dispatch key events from java -> WebKit.
- * 2. Native ImeAdapter notifies java side to clear composition text.
- *
- * The basic flow is:
- * 1. When InputConnectionAdapter gets called with composition or result text:
- * If we receive a composition text or a result text, then we just need to
- * dispatch a synthetic key event with special keycode 229, and then dispatch
- * the composition or result text.
- * 2. Intercept dispatchKeyEvent() method for key events not handled by IME, we
- * need to dispatch them to webkit and check webkit's reply. Then inject a
- * new key event for further processing if webkit didn't handle it.
- *
- * Note that the native peer object does not take any strong reference onto the
- * instance of this java object, hence it is up to the client of this class (e.g.
- * the ViewEmbedder implementor) to hold a strong reference to it for the required
- * lifetime of the object.
- */
-@JNINamespace("content")
-class ImeAdapter {
- interface ViewEmbedder {
- /**
- * @param isFinish whether the event is occurring because input is finished.
- */
- public void onImeEvent(boolean isFinish);
- public void onSetFieldValue();
- public void onDismissInput();
- public View getAttachedView();
- public ResultReceiver getNewShowKeyboardReceiver();
- }
-
- static final int COMPOSITION_KEY_CODE = 229;
-
- static int sEventTypeRawKeyDown;
- static int sEventTypeKeyUp;
- static int sEventTypeChar;
- static int sTextInputTypeNone;
- static int sTextInputTypeText;
- static int sTextInputTypeTextArea;
- static int sTextInputTypePassword;
- static int sTextInputTypeSearch;
- static int sTextInputTypeUrl;
- static int sTextInputTypeEmail;
- static int sTextInputTypeTel;
- static int sTextInputTypeNumber;
- static int sTextInputTypeWeek;
- static int sTextInputTypeContentEditable;
- static int sModifierShift;
- static int sModifierAlt;
- static int sModifierCtrl;
- static int sModifierCapsLockOn;
- static int sModifierNumLockOn;
-
- @CalledByNative
- static void initializeWebInputEvents(int eventTypeRawKeyDown, int eventTypeKeyUp,
- int eventTypeChar, int modifierShift, int modifierAlt, int modifierCtrl,
- int modifierCapsLockOn, int modifierNumLockOn) {
- sEventTypeRawKeyDown = eventTypeRawKeyDown;
- sEventTypeKeyUp = eventTypeKeyUp;
- sEventTypeChar = eventTypeChar;
- sModifierShift = modifierShift;
- sModifierAlt = modifierAlt;
- sModifierCtrl = modifierCtrl;
- sModifierCapsLockOn = modifierCapsLockOn;
- sModifierNumLockOn = modifierNumLockOn;
- }
-
- @CalledByNative
- static void initializeTextInputTypes(int textInputTypeNone, int textInputTypeText,
- int textInputTypeTextArea, int textInputTypePassword, int textInputTypeSearch,
- int textInputTypeUrl, int textInputTypeEmail, int textInputTypeTel,
- int textInputTypeNumber, int textInputTypeDate, int textInputTypeDateTime,
- int textInputTypeDateTimeLocal, int textInputTypeMonth, int textInputTypeTime,
- int textInputTypeWeek, int textInputTypeContentEditable) {
- sTextInputTypeNone = textInputTypeNone;
- sTextInputTypeText = textInputTypeText;
- sTextInputTypeTextArea = textInputTypeTextArea;
- sTextInputTypePassword = textInputTypePassword;
- sTextInputTypeSearch = textInputTypeSearch;
- sTextInputTypeUrl = textInputTypeUrl;
- sTextInputTypeEmail = textInputTypeEmail;
- sTextInputTypeTel = textInputTypeTel;
- sTextInputTypeNumber = textInputTypeNumber;
- sTextInputTypeWeek = textInputTypeWeek;
- sTextInputTypeContentEditable = textInputTypeContentEditable;
- }
-
- private int mNativeImeAdapterAndroid;
- private int mTextInputType;
-
- private final Context mContext;
- private InputMethodManagerWrapper mInputMethodManagerWrapper;
- private final SelectionHandleController mSelectionHandleController;
- private final InsertionHandleController mInsertionHandleController;
- private AdapterInputConnection mInputConnection;
- private final ViewEmbedder mViewEmbedder;
- private final Handler mHandler;
-
- private class DelayedDismissInput implements Runnable {
- private final int mNativeImeAdapter;
-
- DelayedDismissInput(int nativeImeAdapter) {
- mNativeImeAdapter = nativeImeAdapter;
- }
-
- @Override
- public void run() {
- attach(mNativeImeAdapter, sTextInputTypeNone);
- dismissInput(true);
- }
- }
-
- private DelayedDismissInput mDismissInput = null;
-
- @VisibleForTesting
- protected boolean mIsShowWithoutHideOutstanding = false;
-
- // Delay introduced to avoid hiding the keyboard if new show requests are received.
- // The time required by the unfocus-focus events triggered by tab has been measured in soju:
- // Mean: 18.633 ms, Standard deviation: 7.9837 ms.
- // The value here should be higher enough to cover these cases, but not too high to avoid
- // letting the user perceiving important delays.
- private static final int INPUT_DISMISS_DELAY = 150;
-
- ImeAdapter(Context context, SelectionHandleController selectionHandleController,
- InsertionHandleController insertionHandleController, ViewEmbedder embedder) {
- mContext = context;
- mInputMethodManagerWrapper = new InputMethodManagerWrapper(context);
- mSelectionHandleController = selectionHandleController;
- mInsertionHandleController = insertionHandleController;
- mViewEmbedder = embedder;
- mHandler = new Handler();
- }
-
- boolean isFor(int nativeImeAdapter, int textInputType) {
- return mNativeImeAdapterAndroid == nativeImeAdapter &&
- mTextInputType == textInputType;
- }
-
- @VisibleForTesting
- protected void setInputMethodManagerWrapper(InputMethodManagerWrapper immw) {
- mInputMethodManagerWrapper = immw;
- }
-
- private InputMethodManagerWrapper getInputMethodManagerWrapper() {
- return mInputMethodManagerWrapper;
- }
-
- void attachAndShowIfNeeded(int nativeImeAdapter, int textInputType,
- String text, boolean showIfNeeded) {
- mHandler.removeCallbacks(mDismissInput);
-
- // If current input type is none and showIfNeeded is false, IME should not be shown
- // and input type should remain as none.
- if (mTextInputType == sTextInputTypeNone && !showIfNeeded) {
- return;
- }
-
- if (!isFor(nativeImeAdapter, textInputType)) {
- // Set a delayed task to perform unfocus. This avoids hiding the keyboard when tabbing
- // through text inputs or when JS rapidly changes focus to another text element.
- if (textInputType == sTextInputTypeNone) {
- mDismissInput = new DelayedDismissInput(nativeImeAdapter);
- mHandler.postDelayed(mDismissInput, INPUT_DISMISS_DELAY);
- return;
- }
-
- int previousType = mTextInputType;
- attach(nativeImeAdapter, textInputType);
-
- mInputMethodManagerWrapper.restartInput(mViewEmbedder.getAttachedView());
- if (showIfNeeded) {
- showKeyboard();
- }
- } else if (hasInputType() && showIfNeeded) {
- showKeyboard();
- }
- }
-
- void attach(int nativeImeAdapter, int textInputType) {
- mNativeImeAdapterAndroid = nativeImeAdapter;
- mTextInputType = textInputType;
- nativeAttachImeAdapter(mNativeImeAdapterAndroid);
- }
-
- /**
- * Attaches the imeAdapter to its native counterpart. This is needed to start forwarding
- * keyboard events to WebKit.
- * @param nativeImeAdapter The pointer to the native ImeAdapter object.
- */
- void attach(int nativeImeAdapter) {
- mNativeImeAdapterAndroid = nativeImeAdapter;
- if (nativeImeAdapter != 0) {
- nativeAttachImeAdapter(mNativeImeAdapterAndroid);
- }
- }
-
- /**
- * Used to check whether the native counterpart of the ImeAdapter has been attached yet.
- * @return Whether native ImeAdapter has been attached and its pointer is currently nonzero.
- */
- boolean isNativeImeAdapterAttached() {
- return mNativeImeAdapterAndroid != 0;
- }
-
- private void showKeyboard() {
- mIsShowWithoutHideOutstanding = true;
- mInputMethodManagerWrapper.showSoftInput(mViewEmbedder.getAttachedView(), 0,
- mViewEmbedder.getNewShowKeyboardReceiver());
- }
-
- private void dismissInput(boolean unzoomIfNeeded) {
- hideKeyboard(unzoomIfNeeded);
- mViewEmbedder.onDismissInput();
- }
-
- private void hideKeyboard(boolean unzoomIfNeeded) {
- mIsShowWithoutHideOutstanding = false;
- View view = mViewEmbedder.getAttachedView();
- if (mInputMethodManagerWrapper.isActive(view)) {
- mInputMethodManagerWrapper.hideSoftInputFromWindow(view.getWindowToken(), 0,
- unzoomIfNeeded ? mViewEmbedder.getNewShowKeyboardReceiver() : null);
- }
- }
-
- @CalledByNative
- void detach() {
- mNativeImeAdapterAndroid = 0;
- mTextInputType = 0;
- }
-
- boolean hasInputType() {
- return mTextInputType != sTextInputTypeNone;
- }
-
- static boolean isTextInputType(int type) {
- return type != sTextInputTypeNone && !InputDialogContainer.isDialogInputType(type);
- }
-
- boolean hasTextInputType() {
- return isTextInputType(mTextInputType);
- }
-
- boolean dispatchKeyEvent(KeyEvent event) {
- return translateAndSendNativeEvents(event);
- }
-
- void commitText() {
- cancelComposition();
- if (mNativeImeAdapterAndroid != 0) {
- nativeCommitText(mNativeImeAdapterAndroid, "");
- }
- }
-
- @SuppressWarnings("unused")
- @CalledByNative
- private void cancelComposition() {
- if (mInputConnection != null) {
- mInputConnection.restartInput();
- }
- }
-
- @VisibleForTesting
- boolean checkCompositionQueueAndCallNative(String text, int newCursorPosition,
- boolean isCommit) {
- if (mNativeImeAdapterAndroid == 0) return false;
-
-
- // Committing an empty string finishes the current composition.
- boolean isFinish = text.isEmpty();
- if (!isFinish) {
- mSelectionHandleController.hideAndDisallowAutomaticShowing();
- mInsertionHandleController.hideAndDisallowAutomaticShowing();
- }
- mViewEmbedder.onImeEvent(isFinish);
- int keyCode = shouldSendKeyEventWithKeyCode(text);
- long timeStampMs = System.currentTimeMillis();
-
- if (keyCode != COMPOSITION_KEY_CODE) {
- sendKeyEventWithKeyCode(keyCode,
- KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE);
- } else {
- nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeRawKeyDown,
- timeStampMs, keyCode, 0);
- if (isCommit) {
- nativeCommitText(mNativeImeAdapterAndroid, text);
- } else {
- nativeSetComposingText(mNativeImeAdapterAndroid, text, newCursorPosition);
- }
- nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeKeyUp,
- timeStampMs, keyCode, 0);
- }
-
- return true;
- }
-
- private int shouldSendKeyEventWithKeyCode(String text) {
- if (text.length() != 1) return COMPOSITION_KEY_CODE;
-
- if (text.equals("\n")) return KeyEvent.KEYCODE_ENTER;
- else if (text.equals("\t")) return KeyEvent.KEYCODE_TAB;
- else return COMPOSITION_KEY_CODE;
- }
-
- private void sendKeyEventWithKeyCode(int keyCode, int flags) {
- long eventTime = System.currentTimeMillis();
- translateAndSendNativeEvents(new KeyEvent(eventTime, eventTime,
- KeyEvent.ACTION_DOWN, keyCode, 0, 0,
- KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
- flags));
- translateAndSendNativeEvents(new KeyEvent(System.currentTimeMillis(), eventTime,
- KeyEvent.ACTION_UP, keyCode, 0, 0,
- KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
- flags));
- }
-
- private boolean translateAndSendNativeEvents(KeyEvent event) {
- if (mNativeImeAdapterAndroid == 0) return false;
-
- int action = event.getAction();
- if (action != KeyEvent.ACTION_DOWN &&
- action != KeyEvent.ACTION_UP) {
- // action == KeyEvent.ACTION_MULTIPLE
- // TODO(bulach): confirm the actual behavior. Apparently:
- // If event.getKeyCode() == KEYCODE_UNKNOWN, we can send a
- // composition key down (229) followed by a commit text with the
- // string from event.getUnicodeChars().
- // Otherwise, we'd need to send an event with a
- // WebInputEvent::IsAutoRepeat modifier. We also need to verify when
- // we receive ACTION_MULTIPLE: we may receive it after an ACTION_DOWN,
- // and if that's the case, we'll need to review when to send the Char
- // event.
- return false;
- }
- mViewEmbedder.onImeEvent(false);
- return nativeSendKeyEvent(mNativeImeAdapterAndroid, event, event.getAction(),
- getModifiers(event.getMetaState()), event.getEventTime(), event.getKeyCode(),
- event.isSystem(), event.getUnicodeChar());
- }
-
- private void setInputConnection(AdapterInputConnection inputConnection) {
- mInputConnection = inputConnection;
- }
-
- private static int getModifiers(int metaState) {
- int modifiers = 0;
- if ((metaState & KeyEvent.META_SHIFT_ON) != 0) {
- modifiers |= sModifierShift;
- }
- if ((metaState & KeyEvent.META_ALT_ON) != 0) {
- modifiers |= sModifierAlt;
- }
- if ((metaState & KeyEvent.META_CTRL_ON) != 0) {
- modifiers |= sModifierCtrl;
- }
- if ((metaState & KeyEvent.META_CAPS_LOCK_ON) != 0) {
- modifiers |= sModifierCapsLockOn;
- }
- if ((metaState & KeyEvent.META_NUM_LOCK_ON) != 0) {
- modifiers |= sModifierNumLockOn;
- }
- return modifiers;
- }
-
- boolean isActive() {
- return mInputConnection != null && mInputConnection.isActive();
- }
-
- private boolean sendSyntheticKeyEvent(
- int eventType, long timestampMs, int keyCode, int unicodeChar) {
- if (mNativeImeAdapterAndroid == 0) return false;
-
- nativeSendSyntheticKeyEvent(
- mNativeImeAdapterAndroid, eventType, timestampMs, keyCode, unicodeChar);
- return true;
- }
-
- private boolean deleteSurroundingText(int leftLength, int rightLength) {
- if (mNativeImeAdapterAndroid == 0) return false;
-
- nativeDeleteSurroundingText(mNativeImeAdapterAndroid, leftLength, rightLength);
- return true;
- }
-
- @VisibleForTesting
- protected boolean setEditableSelectionOffsets(int start, int end) {
- if (mNativeImeAdapterAndroid == 0) return false;
-
- nativeSetEditableSelectionOffsets(mNativeImeAdapterAndroid, start, end);
- return true;
- }
-
- private void batchStateChanged(boolean isBegin) {
- if (mNativeImeAdapterAndroid == 0) return;
- nativeImeBatchStateChanged(mNativeImeAdapterAndroid, isBegin);
- }
-
- private boolean setComposingRegion(int start, int end) {
- if (mNativeImeAdapterAndroid == 0) return false;
-
- nativeSetComposingRegion(mNativeImeAdapterAndroid, start, end);
- return true;
- }
-
- boolean unselect() {
- if (mNativeImeAdapterAndroid == 0) return false;
-
- nativeUnselect(mNativeImeAdapterAndroid);
- return true;
- }
-
- boolean selectAll() {
- if (mNativeImeAdapterAndroid == 0) return false;
-
- nativeSelectAll(mNativeImeAdapterAndroid);
- return true;
- }
-
- boolean cut() {
- if (mNativeImeAdapterAndroid == 0) return false;
-
- nativeCut(mNativeImeAdapterAndroid);
- return true;
- }
-
- boolean copy() {
- if (mNativeImeAdapterAndroid == 0) return false;
-
- nativeCopy(mNativeImeAdapterAndroid);
- return true;
- }
-
- boolean paste() {
- if (mNativeImeAdapterAndroid == 0) return false;
-
- nativePaste(mNativeImeAdapterAndroid);
- return true;
- }
-
- public static class AdapterInputConnectionFactory {
- public AdapterInputConnection get(View view, ImeAdapter imeAdapter,
- EditorInfo outAttrs) {
- return new AdapterInputConnection(view, imeAdapter, outAttrs);
- }
- }
-
- // This InputConnection is created by ContentView.onCreateInputConnection.
- // It then adapts android's IME to chrome's RenderWidgetHostView using the
- // native ImeAdapterAndroid via the outer class ImeAdapter.
- public static class AdapterInputConnection extends BaseInputConnection {
- private static final String TAG =
- "org.chromium.content.browser.ImeAdapter$AdapterInputConnection";
- private static final boolean DEBUG = false;
- private final View mInternalView;
- private final ImeAdapter mImeAdapter;
-
- private boolean mSingleLine;
- private int mNumNestedBatchEdits = 0;
- private boolean mIgnoreTextInputStateUpdates = false;
-
- /**
- * Updates the AdapterInputConnection's internal representation of the text
- * being edited and its selection and composition properties. The resulting
- * Editable is accessible through the getEditable() method.
- * If the text has not changed, this also calls updateSelection on the InputMethodManager.
- * @param text The String contents of the field being edited
- * @param selectionStart The character offset of the selection start, or the caret
- * position if there is no selection
- * @param selectionEnd The character offset of the selection end, or the caret
- * position if there is no selection
- * @param compositionStart The character offset of the composition start, or -1
- * if there is no composition
- * @param compositionEnd The character offset of the composition end, or -1
- * if there is no selection
- */
- public void setEditableText(String text, int selectionStart, int selectionEnd,
- int compositionStart, int compositionEnd) {
- if (DEBUG) {
- Log.w(TAG, "setEditableText [" + text + "] [" + selectionStart + " " + selectionEnd
- + "] [" + compositionStart + " " + compositionEnd + "]");
- }
- Editable editable = getEditable();
-
- int prevSelectionStart = Selection.getSelectionStart(editable);
- int prevSelectionEnd = Selection.getSelectionEnd(editable);
- int prevCompositionStart = getComposingSpanStart(editable);
- int prevCompositionEnd = getComposingSpanEnd(editable);
- String prevText = editable.toString();
-
- selectionStart = Math.min(selectionStart, text.length());
- selectionEnd = Math.min(selectionEnd, text.length());
- compositionStart = Math.min(compositionStart, text.length());
- compositionEnd = Math.min(compositionEnd, text.length());
-
- boolean textUnchanged = prevText.equals(text);
-
- if (!textUnchanged) {
- editable.replace(0, editable.length(), text);
- }
-
- if (prevSelectionStart == selectionStart && prevSelectionEnd == selectionEnd
- && prevCompositionStart == compositionStart
- && prevCompositionEnd == compositionEnd) {
- // Nothing has changed; don't need to do anything
- return;
- }
-
- Selection.setSelection(editable, selectionStart, selectionEnd);
- super.setComposingRegion(compositionStart, compositionEnd);
-
- if (mIgnoreTextInputStateUpdates) return;
- updateSelection(selectionStart, selectionEnd, compositionStart, compositionEnd);
- }
-
- @VisibleForTesting
- protected void updateSelection(
- int selectionStart, int selectionEnd,
- int compositionStart, int compositionEnd) {
- if (DEBUG) {
- Log.w(TAG, "updateSelection [" + selectionStart + " " + selectionEnd + "] ["
- + compositionStart + " " + compositionEnd + "]");
- }
- // updateSelection should
- // be called every time the selection or composition changes if it happens not
- // within a batch edit, or at the end of each top level batch edit.
- getInputMethodManagerWrapper().updateSelection(mInternalView,
- selectionStart, selectionEnd, compositionStart, compositionEnd);
- }
-
- @Override
- public boolean setComposingText(CharSequence text, int newCursorPosition) {
- if (DEBUG) Log.w(TAG, "setComposingText [" + text + "] [" + newCursorPosition + "]");
- super.setComposingText(text, newCursorPosition);
- return mImeAdapter.checkCompositionQueueAndCallNative(text.toString(),
- newCursorPosition, false);
- }
-
- @Override
- public boolean commitText(CharSequence text, int newCursorPosition) {
- if (DEBUG) Log.w(TAG, "commitText [" + text + "] [" + newCursorPosition + "]");
- super.commitText(text, newCursorPosition);
- return mImeAdapter.checkCompositionQueueAndCallNative(text.toString(),
- newCursorPosition, text.length() > 0);
- }
-
- @Override
- public boolean performEditorAction(int actionCode) {
- if (DEBUG) Log.w(TAG, "performEditorAction [" + actionCode + "]");
- if (actionCode == EditorInfo.IME_ACTION_NEXT) {
- restartInput();
- // Send TAB key event
- long timeStampMs = System.currentTimeMillis();
- mImeAdapter.sendSyntheticKeyEvent(
- sEventTypeRawKeyDown, timeStampMs, KeyEvent.KEYCODE_TAB, 0);
- } else {
- mImeAdapter.sendKeyEventWithKeyCode(KeyEvent.KEYCODE_ENTER,
- KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE
- | KeyEvent.FLAG_EDITOR_ACTION);
- }
- return true;
- }
-
- @Override
- public boolean performContextMenuAction(int id) {
- if (DEBUG) Log.w(TAG, "performContextMenuAction [" + id + "]");
- switch (id) {
- case android.R.id.selectAll:
- return mImeAdapter.selectAll();
- case android.R.id.cut:
- return mImeAdapter.cut();
- case android.R.id.copy:
- return mImeAdapter.copy();
- case android.R.id.paste:
- return mImeAdapter.paste();
- default:
- return false;
- }
- }
-
- @Override
- public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
- if (DEBUG) Log.w(TAG, "getExtractedText");
- ExtractedText et = new ExtractedText();
- Editable editable = getEditable();
- et.text = editable.toString();
- et.partialEndOffset = editable.length();
- et.selectionStart = Selection.getSelectionStart(editable);
- et.selectionEnd = Selection.getSelectionEnd(editable);
- et.flags = mSingleLine ? ExtractedText.FLAG_SINGLE_LINE : 0;
- return et;
- }
-
- @Override
- public boolean beginBatchEdit() {
- if (DEBUG) Log.w(TAG, "beginBatchEdit [" + (mNumNestedBatchEdits == 0) + "]");
- if (mNumNestedBatchEdits == 0) mImeAdapter.batchStateChanged(true);
-
- mNumNestedBatchEdits++;
- return false;
- }
-
- @Override
- public boolean endBatchEdit() {
- if (mNumNestedBatchEdits == 0) return false;
-
- --mNumNestedBatchEdits;
- if (DEBUG) Log.w(TAG, "endBatchEdit [" + (mNumNestedBatchEdits == 0) + "]");
- if (mNumNestedBatchEdits == 0) mImeAdapter.batchStateChanged(false);
- return false;
- }
-
- @Override
- public boolean deleteSurroundingText(int leftLength, int rightLength) {
- if (DEBUG) {
- Log.w(TAG, "deleteSurroundingText [" + leftLength + " " + rightLength + "]");
- }
- if (!super.deleteSurroundingText(leftLength, rightLength)) {
- return false;
- }
- return mImeAdapter.deleteSurroundingText(leftLength, rightLength);
- }
-
- @Override
- public boolean sendKeyEvent(KeyEvent event) {
- if (DEBUG) Log.w(TAG, "sendKeyEvent [" + event.getAction() + "]");
- mImeAdapter.mSelectionHandleController.hideAndDisallowAutomaticShowing();
- mImeAdapter.mInsertionHandleController.hideAndDisallowAutomaticShowing();
-
- // If this is a key-up, and backspace/del or if the key has a character representation,
- // need to update the underlying Editable (i.e. the local representation of the text
- // being edited).
- if (event.getAction() == KeyEvent.ACTION_UP) {
- if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
- super.deleteSurroundingText(1, 0);
- } else if (event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL) {
- super.deleteSurroundingText(0, 1);
- } else {
- int unicodeChar = event.getUnicodeChar();
- if (unicodeChar != 0) {
- Editable editable = getEditable();
- int selectionStart = Selection.getSelectionStart(editable);
- int selectionEnd = Selection.getSelectionEnd(editable);
- if (selectionStart > selectionEnd) {
- int temp = selectionStart;
- selectionStart = selectionEnd;
- selectionEnd = temp;
- }
- editable.replace(selectionStart, selectionEnd,
- Character.toString((char)unicodeChar));
- }
- }
- }
- mImeAdapter.translateAndSendNativeEvents(event);
- return true;
- }
-
- @Override
- public boolean finishComposingText() {
- if (DEBUG) Log.w(TAG, "finishComposingText");
- Editable editable = getEditable();
- if (getComposingSpanStart(editable) == getComposingSpanEnd(editable)) {
- return true;
- }
- super.finishComposingText();
- return mImeAdapter.checkCompositionQueueAndCallNative("", 0, true);
- }
-
- @Override
- public boolean setSelection(int start, int end) {
- if (DEBUG) Log.w(TAG, "setSelection");
- if (start < 0 || end < 0) return true;
- super.setSelection(start, end);
- return mImeAdapter.setEditableSelectionOffsets(start, end);
- }
-
- /**
- * Informs the InputMethodManager and InputMethodSession (i.e. the IME) that the text
- * state is no longer what the IME has and that it needs to be updated.
- */
- void restartInput() {
- if (DEBUG) Log.w(TAG, "restartInput");
- getInputMethodManagerWrapper().restartInput(mInternalView);
- mIgnoreTextInputStateUpdates = false;
- mNumNestedBatchEdits = 0;
- }
-
- @Override
- public boolean setComposingRegion(int start, int end) {
- if (DEBUG) Log.w(TAG, "setComposingRegion [" + start + " " + end + "]");
- int a = Math.min(start, end);
- int b = Math.max(start, end);
- super.setComposingRegion(a, b);
- return mImeAdapter.setComposingRegion(a, b);
- }
-
- boolean isActive() {
- return getInputMethodManagerWrapper().isActive(mInternalView);
- }
-
- void setIgnoreTextInputStateUpdates(boolean shouldIgnore) {
- mIgnoreTextInputStateUpdates = shouldIgnore;
- if (shouldIgnore) return;
-
- Editable editable = getEditable();
- updateSelection(Selection.getSelectionStart(editable),
- Selection.getSelectionEnd(editable),
- getComposingSpanStart(editable),
- getComposingSpanEnd(editable));
- }
-
- @VisibleForTesting
- protected boolean isIgnoringTextInputStateUpdates() {
- return mIgnoreTextInputStateUpdates;
- }
-
- private InputMethodManagerWrapper getInputMethodManagerWrapper() {
- return mImeAdapter.getInputMethodManagerWrapper();
- }
-
- @VisibleForTesting
- protected AdapterInputConnection(View view, ImeAdapter imeAdapter, EditorInfo outAttrs) {
- super(view, true);
- mInternalView = view;
- mImeAdapter = imeAdapter;
- mImeAdapter.setInputConnection(this);
- mSingleLine = true;
- outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN;
- outAttrs.inputType = EditorInfo.TYPE_CLASS_TEXT
- | EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT;
- if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeText) {
- // Normal text field
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO;
- } else if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeTextArea ||
- imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeContentEditable) {
- // TextArea or contenteditable.
- outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
- | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES
- | EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT;
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_NONE;
- mSingleLine = false;
- } else if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypePassword) {
- // Password
- outAttrs.inputType = InputType.TYPE_CLASS_TEXT
- | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD;
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO;
- } else if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeSearch) {
- // Search
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_SEARCH;
- } else if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeUrl) {
- // Url
- // TYPE_TEXT_VARIATION_URI prevents Tab key from showing, so
- // exclude it for now.
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO;
- } else if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeEmail) {
- // Email
- outAttrs.inputType = InputType.TYPE_CLASS_TEXT
- | InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO;
- } else if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeTel) {
- // Telephone
- // Number and telephone do not have both a Tab key and an
- // action in default OSK, so set the action to NEXT
- outAttrs.inputType = InputType.TYPE_CLASS_PHONE;
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT;
- } else if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeNumber) {
- // Number
- outAttrs.inputType = InputType.TYPE_CLASS_NUMBER
- | InputType.TYPE_NUMBER_VARIATION_NORMAL;
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT;
- }
-
- Editable editable = getEditable();
- int selectionStart = Selection.getSelectionStart(editable);
- int selectionEnd = Selection.getSelectionEnd(editable);
- if (selectionStart < 0 || selectionEnd < 0) {
- selectionStart = editable.length();
- selectionEnd = selectionStart;
- }
- outAttrs.initialSelStart = selectionStart;
- outAttrs.initialSelEnd = selectionEnd;
- }
- }
-
- private native boolean nativeSendSyntheticKeyEvent(int nativeImeAdapterAndroid,
- int eventType, long timestampMs, int keyCode, int unicodeChar);
-
- private native boolean nativeSendKeyEvent(int nativeImeAdapterAndroid, KeyEvent event,
- int action, int modifiers, long timestampMs, int keyCode, boolean isSystemKey,
- int unicodeChar);
-
- private native void nativeSetComposingText(int nativeImeAdapterAndroid, String text,
- int newCursorPosition);
-
- private native void nativeCommitText(int nativeImeAdapterAndroid, String text);
-
- private native void nativeAttachImeAdapter(int nativeImeAdapterAndroid);
-
- private native void nativeSetEditableSelectionOffsets(int nativeImeAdapterAndroid,
- int start, int end);
-
- private native void nativeSetComposingRegion(int nativeImeAdapterAndroid, int start, int end);
-
- private native void nativeDeleteSurroundingText(int nativeImeAdapterAndroid,
- int before, int after);
-
- private native void nativeImeBatchStateChanged(int nativeImeAdapterAndroid, boolean isBegin);
-
- private native void nativeUnselect(int nativeImeAdapterAndroid);
- private native void nativeSelectAll(int nativeImeAdapterAndroid);
- private native void nativeCut(int nativeImeAdapterAndroid);
- private native void nativeCopy(int nativeImeAdapterAndroid);
- private native void nativePaste(int nativeImeAdapterAndroid);
-}
diff --git a/content/public/android/java/src/org/chromium/content/browser/JellyBeanContentView.java b/content/public/android/java/src/org/chromium/content/browser/JellyBeanContentView.java
index 1bc2fae..80b8ccf 100644
--- a/content/public/android/java/src/org/chromium/content/browser/JellyBeanContentView.java
+++ b/content/public/android/java/src/org/chromium/content/browser/JellyBeanContentView.java
@@ -10,15 +10,15 @@
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
-import org.chromium.ui.gfx.NativeWindow;
+import org.chromium.ui.WindowAndroid;
/**
* A version of {@link ContentView} that supports JellyBean features.
*/
class JellyBeanContentView extends ContentView {
- JellyBeanContentView(Context context, int nativeWebContents, NativeWindow nativeWindow,
+ JellyBeanContentView(Context context, int nativeWebContents, WindowAndroid windowAndroid,
AttributeSet attrs, int defStyle, int personality) {
- super(context, nativeWebContents, nativeWindow, attrs, defStyle, personality);
+ super(context, nativeWebContents, windowAndroid, attrs, defStyle, personality);
}
@Override
diff --git a/content/public/android/java/src/org/chromium/content/browser/LongPressDetector.java b/content/public/android/java/src/org/chromium/content/browser/LongPressDetector.java
index 5bd73ad..d46d485 100644
--- a/content/public/android/java/src/org/chromium/content/browser/LongPressDetector.java
+++ b/content/public/android/java/src/org/chromium/content/browser/LongPressDetector.java
@@ -7,7 +7,6 @@
import android.content.Context;
import android.os.Handler;
import android.os.Message;
-import android.util.Pair;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
diff --git a/content/public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java b/content/public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java
new file mode 100644
index 0000000..5d0de5a
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java
@@ -0,0 +1,117 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser;
+
+import android.content.Context;
+import android.media.MediaMetadataRetriever;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+import org.chromium.base.PathUtils;
+
+import java.io.File;
+import java.util.HashMap;
+
+/**
+ * Java counterpart of android MediaResourceGetter.
+ */
+@JNINamespace("content")
+class MediaResourceGetter {
+
+ private static final String TAG = "MediaResourceGetter";
+
+ private static class MediaMetadata {
+ private final int mDurationInMilliseconds;
+ private final int mWidth;
+ private final int mHeight;
+ private final boolean mSuccess;
+
+ private MediaMetadata(int durationInMilliseconds, int width, int height, boolean success) {
+ mDurationInMilliseconds = durationInMilliseconds;
+ mWidth = width;
+ mHeight = height;
+ mSuccess = success;
+ }
+
+ @CalledByNative("MediaMetadata")
+ private int getDurationInMilliseconds() { return mDurationInMilliseconds; }
+
+ @CalledByNative("MediaMetadata")
+ private int getWidth() { return mWidth; }
+
+ @CalledByNative("MediaMetadata")
+ private int getHeight() { return mHeight; }
+
+ @CalledByNative("MediaMetadata")
+ private boolean isSuccess() { return mSuccess; }
+ }
+
+ @CalledByNative
+ private static MediaMetadata extractMediaMetadata(Context context, String url, String cookies) {
+ int durationInMilliseconds = 0;
+ int width = 0;
+ int height = 0;
+ boolean success = false;
+ // TODO(qinmin): use ConnectionTypeObserver to listen to the network type change.
+ ConnectivityManager mConnectivityManager =
+ (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (mConnectivityManager != null) {
+ NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
+ if (info == null) {
+ return new MediaMetadata(durationInMilliseconds, width, height, success);
+ }
+ switch (info.getType()) {
+ case ConnectivityManager.TYPE_ETHERNET:
+ case ConnectivityManager.TYPE_WIFI:
+ break;
+ case ConnectivityManager.TYPE_WIMAX:
+ case ConnectivityManager.TYPE_MOBILE:
+ default:
+ return new MediaMetadata(durationInMilliseconds, width, height, success);
+ }
+ }
+
+ MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+ try {
+ Uri uri = Uri.parse(url);
+ String scheme = uri.getScheme();
+ if (scheme == null || scheme.equals("file")) {
+ File file = new File(uri.getPath());
+ String path = file.getAbsolutePath();
+ if (file.exists() && (path.startsWith("/mnt/sdcard/") ||
+ path.startsWith("/sdcard/") ||
+ path.startsWith(PathUtils.getExternalStorageDirectory()))) {
+ retriever.setDataSource(path);
+ } else {
+ Log.e(TAG, "Unable to read file: " + url);
+ return new MediaMetadata(durationInMilliseconds, width, height, success);
+ }
+ } else {
+ HashMap<String, String> headersMap = new HashMap<String, String>();
+ if (!TextUtils.isEmpty(cookies)) {
+ headersMap.put("Cookie", cookies);
+ }
+ retriever.setDataSource(url, headersMap);
+ }
+ durationInMilliseconds = Integer.parseInt(
+ retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
+ width = Integer.parseInt(
+ retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
+ height = Integer.parseInt(
+ retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
+ success = true;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Invalid url: " + e);
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Invalid url: " + e);
+ }
+ return new MediaMetadata(durationInMilliseconds, width, height, success);
+ }
+}
diff --git a/content/public/android/java/src/org/chromium/content/browser/PageInfo.java b/content/public/android/java/src/org/chromium/content/browser/PageInfo.java
new file mode 100644
index 0000000..1a80b20
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/PageInfo.java
@@ -0,0 +1,50 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser;
+
+import android.graphics.Bitmap;
+import android.view.View;
+
+/**
+ * A minimal interface for a View to implement to be shown in a Tab. The main implementation of
+ * this is ContentView but other Views can also implement this, enabling them to be shown in a Tab
+ * as well.
+ */
+public interface PageInfo {
+ /**
+ * @return The URL of the page.
+ */
+ String getUrl();
+
+ /**
+ * @return The title of the page.
+ */
+ String getTitle();
+
+ /**
+ * @return True, if the view is in a suitable state for a snapshot.
+ */
+ boolean isReadyForSnapshot();
+
+ /**
+ * @return An unscaled screenshot of the page.
+ */
+ Bitmap getBitmap();
+
+ /**
+ * @return A screenshot of the page scaled to the specified size.
+ */
+ Bitmap getBitmap(int width, int height);
+
+ /**
+ * @return The background color of the page.
+ */
+ int getBackgroundColor();
+
+ /**
+ * @return The View to display the page. This is always non-null.
+ */
+ View getView();
+}
diff --git a/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java b/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java
index 1506fab..be362fb 100644
--- a/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java
+++ b/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java
@@ -33,6 +33,8 @@
// Cached device density.
private float mDeviceScaleFactor;
+ private float mContentOffsetYPix;
+
// Internally-visible set of update methods (used by ContentViewCore).
void reset() {
mScrollXCss = mScrollYCss = 0;
@@ -52,12 +54,14 @@
float scrollXCss, float scrollYCss,
float contentWidthCss, float contentHeightCss,
float viewportWidthCss, float viewportHeightCss,
- float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor) {
+ float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor,
+ float contentOffsetYPix) {
mScrollXCss = scrollXCss;
mScrollYCss = scrollYCss;
mPageScaleFactor = pageScaleFactor;
mMinPageScaleFactor = minPageScaleFactor;
mMaxPageScaleFactor = maxPageScaleFactor;
+ mContentOffsetYPix = contentOffsetYPix;
updateContentSizeCss(contentWidthCss, contentHeightCss);
mLastFrameViewportWidthCss = viewportWidthCss;
@@ -102,7 +106,7 @@
/**
* @return Physical (screen) Y coordinate of the point.
*/
- public float getYPix() { return getYLocalDip() * mDeviceScaleFactor; }
+ public float getYPix() { return getYLocalDip() * mDeviceScaleFactor + mContentOffsetYPix; }
/**
* Sets the point to the given absolute CSS (document) coordinates.
@@ -127,7 +131,7 @@
public void setScreen(float xPix, float yPix) {
setLocalDip(xPix / mDeviceScaleFactor, yPix / mDeviceScaleFactor);
}
-}
+ }
/**
* @return A helper to convert a point between between absolute CSS and local DIP spaces.
@@ -235,6 +239,13 @@
}
/**
+ * @return The Physical on-screen Y offset amount below the top controls.
+ */
+ public float getContentOffsetYPix() {
+ return mContentOffsetYPix;
+ }
+
+ /**
* @return Current page scale factor (maps CSS pixels to DIP pixels).
*/
public float getPageScaleFactor() { return mPageScaleFactor; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ResourceExtractor.java b/content/public/android/java/src/org/chromium/content/browser/ResourceExtractor.java
index c9f3c31..2b650ce 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ResourceExtractor.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ResourceExtractor.java
@@ -13,8 +13,8 @@
import android.preference.PreferenceManager;
import android.util.Log;
-import org.chromium.base.LocaleUtils;
import org.chromium.base.PathUtils;
+import org.chromium.ui.LocalizationUtils;
import java.io.File;
import java.io.FileOutputStream;
@@ -70,7 +70,7 @@
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
HashSet<String> filenames = (HashSet<String>) prefs.getStringSet(
PAK_FILENAMES, new HashSet<String>());
- String currentLocale = LocaleUtils.getDefaultLocale();
+ String currentLocale = LocalizationUtils.getDefaultLocale();
String currentLanguage = currentLocale.split("-", 2)[0];
if (prefs.getString(LAST_LANGUAGE, "").equals(currentLanguage)
diff --git a/content/public/android/java/src/org/chromium/content/browser/SnapScrollController.java b/content/public/android/java/src/org/chromium/content/browser/SnapScrollController.java
index 68e1873..b457bef 100644
--- a/content/public/android/java/src/org/chromium/content/browser/SnapScrollController.java
+++ b/content/public/android/java/src/org/chromium/content/browser/SnapScrollController.java
@@ -4,6 +4,8 @@
package org.chromium.content.browser;
+import android.content.Context;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
@@ -16,8 +18,8 @@
private static final int SNAP_HORIZ = 1;
private static final int SNAP_VERT = 2;
private static final int SNAP_BOUND = 16;
- private static float CHANNEL_DISTANCE = 16f;
+ private float mChannelDistance = 16f;
private int mSnapScrollMode = SNAP_NONE;
private int mFirstTouchX = -1;
private int mFirstTouchY = -1;
@@ -25,7 +27,8 @@
private float mDistanceY = 0;
private ZoomManager mZoomManager;
- SnapScrollController(ZoomManager zoomManager) {
+ SnapScrollController(Context context, ZoomManager zoomManager) {
+ calculateChannelDistance(context);
mZoomManager = zoomManager;
}
@@ -40,16 +43,16 @@
mDistanceX += Math.abs(distanceX);
mDistanceY += Math.abs(distanceY);
if (mSnapScrollMode == SNAP_HORIZ) {
- if (mDistanceY > CHANNEL_DISTANCE) {
+ if (mDistanceY > mChannelDistance) {
mSnapScrollMode = SNAP_NONE;
- } else if (mDistanceX > CHANNEL_DISTANCE) {
+ } else if (mDistanceX > mChannelDistance) {
mDistanceX = 0;
mDistanceY = 0;
}
} else {
- if (mDistanceX > CHANNEL_DISTANCE) {
+ if (mDistanceX > mChannelDistance) {
mSnapScrollMode = SNAP_NONE;
- } else if (mDistanceY > CHANNEL_DISTANCE) {
+ } else if (mDistanceY > mChannelDistance) {
mDistanceX = 0;
mDistanceY = 0;
}
@@ -98,6 +101,24 @@
}
}
+ private void calculateChannelDistance(Context context) {
+ // The channel distance is adjusted for density and screen size.
+ final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+ final double screenSize = Math.hypot((double) metrics.widthPixels / metrics.densityDpi,
+ (double) metrics.heightPixels / metrics.densityDpi);
+ if (screenSize < 3.0) {
+ mChannelDistance = 16f;
+ } else if (screenSize < 5.0) {
+ mChannelDistance = 22f;
+ } else if (screenSize < 7.0) {
+ mChannelDistance = 28f;
+ } else {
+ mChannelDistance = 34f;
+ }
+ mChannelDistance = mChannelDistance * metrics.density;
+ if (mChannelDistance < 16f) mChannelDistance = 16f;
+ }
+
/**
* Resets the snap scroll mode to default.
*/
diff --git a/content/public/android/java/src/org/chromium/content/browser/VSyncManager.java b/content/public/android/java/src/org/chromium/content/browser/VSyncManager.java
new file mode 100644
index 0000000..438d7c7
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/VSyncManager.java
@@ -0,0 +1,36 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser;
+
+public abstract class VSyncManager {
+ /**
+ * Interface for requesting notification of the display vsync signal. The provider will call
+ * Listener.onVSync() to notify about vsync. The number of registrations and unregistrations of
+ * a given listener must be balanced.
+ */
+ public static interface Provider {
+ void registerVSyncListener(Listener listener);
+ void unregisterVSyncListener(Listener listener);
+ }
+
+ /**
+ * Interface for receiving vsync notifications and information about the display refresh
+ * interval.
+ */
+ public static interface Listener {
+ /**
+ * Notification of a vsync event.
+ * @param frameTimeMicros The latest vsync frame time in microseconds.
+ */
+ void onVSync(long frameTimeMicros);
+
+ /**
+ * Update with the latest vsync parameters.
+ * @param tickTimeMicros The latest vsync tick time in microseconds.
+ * @param intervalMicros The vsync interval in microseconds.
+ */
+ void updateVSync(long tickTimeMicros, long intervalMicros);
+ }
+}
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityInjector.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityInjector.java
index d877798..db4b4d1 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityInjector.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityInjector.java
@@ -171,16 +171,23 @@
* Checks whether or not touch to explore is enabled on the system.
*/
public boolean accessibilityIsAvailable() {
- // Need to make sure we actually have a service running that requires injecting
- // this script.
- List<AccessibilityServiceInfo> services =
- getAccessibilityManager().getEnabledAccessibilityServiceList(
- FEEDBACK_BRAILLE | AccessibilityServiceInfo.FEEDBACK_SPOKEN);
+ if (!getAccessibilityManager().isEnabled() ||
+ mContentViewCore.getContentSettings() == null ||
+ !mContentViewCore.getContentSettings().getJavaScriptEnabled()) {
+ return false;
+ }
- return getAccessibilityManager().isEnabled() &&
- mContentViewCore.getContentSettings() != null &&
- mContentViewCore.getContentSettings().getJavaScriptEnabled() &&
- services.size() > 0;
+ try {
+ // Check that there is actually a service running that requires injecting this script.
+ List<AccessibilityServiceInfo> services =
+ getAccessibilityManager().getEnabledAccessibilityServiceList(
+ FEEDBACK_BRAILLE | AccessibilityServiceInfo.FEEDBACK_SPOKEN);
+ return services.size() > 0;
+ } catch (NullPointerException e) {
+ // getEnabledAccessibilityServiceList() can throw an NPE due to a bad
+ // AccessibilityService.
+ return false;
+ }
}
/**
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java
index 0df4a20..4dc2736 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java
@@ -149,7 +149,15 @@
private static class CallbackHandler {
private static final String JAVASCRIPT_ACTION_TEMPLATE =
- "(function() { %s.onResult(%d, %s); })()";
+ "(function() {" +
+ " retVal = false;" +
+ " try {" +
+ " retVal = %s;" +
+ " } catch (e) {" +
+ " retVal = false;" +
+ " }" +
+ " %s.onResult(%d, retVal);" +
+ "})()";
// Time in milliseconds to wait for a result before failing.
private static final long RESULT_TIMEOUT = 5000;
@@ -174,8 +182,8 @@
*/
private boolean performAction(ContentViewCore contentView, String code) {
final int resultId = mResultIdCounter.getAndIncrement();
- final String js = String.format(JAVASCRIPT_ACTION_TEMPLATE, mInterfaceName, resultId,
- code);
+ final String js = String.format(JAVASCRIPT_ACTION_TEMPLATE, code, mInterfaceName,
+ resultId);
contentView.evaluateJavaScript(js, null);
return getResultAndClear(resultId);
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/AdapterInputConnection.java b/content/public/android/java/src/org/chromium/content/browser/input/AdapterInputConnection.java
new file mode 100644
index 0000000..48cc4fe
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/input/AdapterInputConnection.java
@@ -0,0 +1,429 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.input;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import android.text.Editable;
+import android.text.InputType;
+import android.text.Selection;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.inputmethod.BaseInputConnection;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.ExtractedText;
+import android.view.inputmethod.ExtractedTextRequest;
+
+/**
+ * InputConnection is created by ContentView.onCreateInputConnection.
+ * It then adapts android's IME to chrome's RenderWidgetHostView using the
+ * native ImeAdapterAndroid via the class ImeAdapter.
+ */
+public class AdapterInputConnection extends BaseInputConnection {
+ private static final String TAG =
+ "org.chromium.content.browser.input.AdapterInputConnection";
+ private static final boolean DEBUG = false;
+ /**
+ * Selection value should be -1 if not known. See EditorInfo.java for details.
+ */
+ public static final int INVALID_SELECTION = -1;
+ public static final int INVALID_COMPOSITION = -1;
+
+ private final View mInternalView;
+ private final ImeAdapter mImeAdapter;
+
+ private boolean mSingleLine;
+ private int mNumNestedBatchEdits = 0;
+ private boolean mIgnoreTextInputStateUpdates = false;
+
+ private int mLastUpdateSelectionStart = INVALID_SELECTION;
+ private int mLastUpdateSelectionEnd = INVALID_SELECTION;
+ private int mLastUpdateCompositionStart = INVALID_COMPOSITION;
+ private int mLastUpdateCompositionEnd = INVALID_COMPOSITION;
+
+ @VisibleForTesting
+ AdapterInputConnection(View view, ImeAdapter imeAdapter, EditorInfo outAttrs) {
+ super(view, true);
+ mInternalView = view;
+ mImeAdapter = imeAdapter;
+ mImeAdapter.setInputConnection(this);
+ mSingleLine = true;
+ outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN;
+ outAttrs.inputType = EditorInfo.TYPE_CLASS_TEXT
+ | EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT;
+
+ if (imeAdapter.getTextInputType() == ImeAdapter.sTextInputTypeText) {
+ // Normal text field
+ outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO;
+ } else if (imeAdapter.getTextInputType() == ImeAdapter.sTextInputTypeTextArea ||
+ imeAdapter.getTextInputType() == ImeAdapter.sTextInputTypeContentEditable) {
+ // TextArea or contenteditable.
+ outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
+ | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES
+ | EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT;
+ outAttrs.imeOptions |= EditorInfo.IME_ACTION_NONE;
+ mSingleLine = false;
+ } else if (imeAdapter.getTextInputType() == ImeAdapter.sTextInputTypePassword) {
+ // Password
+ outAttrs.inputType = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD;
+ outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO;
+ } else if (imeAdapter.getTextInputType() == ImeAdapter.sTextInputTypeSearch) {
+ // Search
+ outAttrs.imeOptions |= EditorInfo.IME_ACTION_SEARCH;
+ } else if (imeAdapter.getTextInputType() == ImeAdapter.sTextInputTypeUrl) {
+ // Url
+ // TYPE_TEXT_VARIATION_URI prevents Tab key from showing, so
+ // exclude it for now.
+ outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO;
+ } else if (imeAdapter.getTextInputType() == ImeAdapter.sTextInputTypeEmail) {
+ // Email
+ outAttrs.inputType = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
+ outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO;
+ } else if (imeAdapter.getTextInputType() == ImeAdapter.sTextInputTypeTel) {
+ // Telephone
+ // Number and telephone do not have both a Tab key and an
+ // action in default OSK, so set the action to NEXT
+ outAttrs.inputType = InputType.TYPE_CLASS_PHONE;
+ outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT;
+ } else if (imeAdapter.getTextInputType() == ImeAdapter.sTextInputTypeNumber) {
+ // Number
+ outAttrs.inputType = InputType.TYPE_CLASS_NUMBER
+ | InputType.TYPE_NUMBER_VARIATION_NORMAL;
+ outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT;
+ }
+ outAttrs.initialSelStart = imeAdapter.getInitialSelectionStart();
+ outAttrs.initialSelEnd = imeAdapter.getInitialSelectionStart();
+ }
+
+ /**
+ * Updates the AdapterInputConnection's internal representation of the text
+ * being edited and its selection and composition properties. The resulting
+ * Editable is accessible through the getEditable() method.
+ * If the text has not changed, this also calls updateSelection on the InputMethodManager.
+ * @param text The String contents of the field being edited
+ * @param selectionStart The character offset of the selection start, or the caret
+ * position if there is no selection
+ * @param selectionEnd The character offset of the selection end, or the caret
+ * position if there is no selection
+ * @param compositionStart The character offset of the composition start, or -1
+ * if there is no composition
+ * @param compositionEnd The character offset of the composition end, or -1
+ * if there is no selection
+ */
+ public void setEditableText(String text, int selectionStart, int selectionEnd,
+ int compositionStart, int compositionEnd) {
+ if (DEBUG) {
+ Log.w(TAG, "setEditableText [" + text + "] [" + selectionStart + " " + selectionEnd
+ + "] [" + compositionStart + " " + compositionEnd + "]");
+ }
+ // Non-breaking spaces can cause the IME to get confused. Replace with normal spaces.
+ text = text.replace('\u00A0', ' ');
+
+ Editable editable = getEditable();
+
+ int prevSelectionStart = Selection.getSelectionStart(editable);
+ int prevSelectionEnd = Selection.getSelectionEnd(editable);
+ int prevCompositionStart = getComposingSpanStart(editable);
+ int prevCompositionEnd = getComposingSpanEnd(editable);
+ String prevText = editable.toString();
+
+ selectionStart = Math.min(selectionStart, text.length());
+ selectionEnd = Math.min(selectionEnd, text.length());
+ compositionStart = Math.min(compositionStart, text.length());
+ compositionEnd = Math.min(compositionEnd, text.length());
+
+ boolean textUnchanged = prevText.equals(text);
+
+ if (!textUnchanged) {
+ editable.replace(0, editable.length(), text);
+ }
+
+ if (prevSelectionStart == selectionStart && prevSelectionEnd == selectionEnd
+ && prevCompositionStart == compositionStart
+ && prevCompositionEnd == compositionEnd) {
+ // Nothing has changed; don't need to do anything
+ return;
+ }
+
+ Selection.setSelection(editable, selectionStart, selectionEnd);
+
+ if (compositionStart == compositionEnd) {
+ removeComposingSpans(editable);
+ } else {
+ super.setComposingRegion(compositionStart, compositionEnd);
+ }
+
+ if (mIgnoreTextInputStateUpdates) return;
+ updateSelection(selectionStart, selectionEnd, compositionStart, compositionEnd);
+ }
+
+ @VisibleForTesting
+ protected void updateSelection(
+ int selectionStart, int selectionEnd,
+ int compositionStart, int compositionEnd) {
+ // Avoid sending update if we sent an exact update already previously.
+ if (mLastUpdateSelectionStart == selectionStart &&
+ mLastUpdateSelectionEnd == selectionEnd &&
+ mLastUpdateCompositionStart == compositionStart &&
+ mLastUpdateCompositionEnd == compositionEnd) {
+ return;
+ }
+ if (DEBUG) {
+ Log.w(TAG, "updateSelection [" + selectionStart + " " + selectionEnd + "] ["
+ + compositionStart + " " + compositionEnd + "]");
+ }
+ // updateSelection should be called every time the selection or composition changes
+ // if it happens not within a batch edit, or at the end of each top level batch edit.
+ getInputMethodManagerWrapper().updateSelection(mInternalView,
+ selectionStart, selectionEnd, compositionStart, compositionEnd);
+ mLastUpdateSelectionStart = selectionStart;
+ mLastUpdateSelectionEnd = selectionEnd;
+ mLastUpdateCompositionStart = compositionStart;
+ mLastUpdateCompositionEnd = compositionEnd;
+ }
+
+ /**
+ * @see BaseInputConnection#setComposingText(java.lang.CharSequence, int)
+ */
+ @Override
+ public boolean setComposingText(CharSequence text, int newCursorPosition) {
+ if (DEBUG) Log.w(TAG, "setComposingText [" + text + "] [" + newCursorPosition + "]");
+ super.setComposingText(text, newCursorPosition);
+ return mImeAdapter.checkCompositionQueueAndCallNative(text.toString(),
+ newCursorPosition, false);
+ }
+
+ /**
+ * @see BaseInputConnection#commitText(java.lang.CharSequence, int)
+ */
+ @Override
+ public boolean commitText(CharSequence text, int newCursorPosition) {
+ if (DEBUG) Log.w(TAG, "commitText [" + text + "] [" + newCursorPosition + "]");
+ super.commitText(text, newCursorPosition);
+ return mImeAdapter.checkCompositionQueueAndCallNative(text.toString(),
+ newCursorPosition, text.length() > 0);
+ }
+
+ /**
+ * @see BaseInputConnection#performEditorAction(int)
+ */
+ @Override
+ public boolean performEditorAction(int actionCode) {
+ if (DEBUG) Log.w(TAG, "performEditorAction [" + actionCode + "]");
+ if (actionCode == EditorInfo.IME_ACTION_NEXT) {
+ restartInput();
+ // Send TAB key event
+ long timeStampMs = System.currentTimeMillis();
+ mImeAdapter.sendSyntheticKeyEvent(
+ ImeAdapter.sEventTypeRawKeyDown, timeStampMs, KeyEvent.KEYCODE_TAB, 0);
+ } else {
+ mImeAdapter.sendKeyEventWithKeyCode(KeyEvent.KEYCODE_ENTER,
+ KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE
+ | KeyEvent.FLAG_EDITOR_ACTION);
+ }
+ return true;
+ }
+
+ /**
+ * @see BaseInputConnection#performContextMenuAction(int)
+ */
+ @Override
+ public boolean performContextMenuAction(int id) {
+ if (DEBUG) Log.w(TAG, "performContextMenuAction [" + id + "]");
+ switch (id) {
+ case android.R.id.selectAll:
+ return mImeAdapter.selectAll();
+ case android.R.id.cut:
+ return mImeAdapter.cut();
+ case android.R.id.copy:
+ return mImeAdapter.copy();
+ case android.R.id.paste:
+ return mImeAdapter.paste();
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * @see BaseInputConnection#getExtractedText(android.view.inputmethod.ExtractedTextRequest,
+ * int)
+ */
+ @Override
+ public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
+ if (DEBUG) Log.w(TAG, "getExtractedText");
+ ExtractedText et = new ExtractedText();
+ Editable editable = getEditable();
+ et.text = editable.toString();
+ et.partialEndOffset = editable.length();
+ et.selectionStart = Selection.getSelectionStart(editable);
+ et.selectionEnd = Selection.getSelectionEnd(editable);
+ et.flags = mSingleLine ? ExtractedText.FLAG_SINGLE_LINE : 0;
+ return et;
+ }
+
+ /**
+ * @see BaseInputConnection#beginBatchEdit()
+ */
+ @Override
+ public boolean beginBatchEdit() {
+ if (DEBUG) Log.w(TAG, "beginBatchEdit [" + (mNumNestedBatchEdits == 0) + "]");
+ if (mNumNestedBatchEdits == 0) mImeAdapter.batchStateChanged(true);
+
+ mNumNestedBatchEdits++;
+ return false;
+ }
+
+ /**
+ * @see BaseInputConnection#endBatchEdit()
+ */
+ @Override
+ public boolean endBatchEdit() {
+ if (mNumNestedBatchEdits == 0) return false;
+
+ --mNumNestedBatchEdits;
+ if (DEBUG) Log.w(TAG, "endBatchEdit [" + (mNumNestedBatchEdits == 0) + "]");
+ if (mNumNestedBatchEdits == 0) mImeAdapter.batchStateChanged(false);
+ return false;
+ }
+
+ /**
+ * @see BaseInputConnection#deleteSurroundingText(int, int)
+ */
+ @Override
+ public boolean deleteSurroundingText(int leftLength, int rightLength) {
+ if (DEBUG) {
+ Log.w(TAG, "deleteSurroundingText [" + leftLength + " " + rightLength + "]");
+ }
+ if (!super.deleteSurroundingText(leftLength, rightLength)) {
+ return false;
+ }
+ return mImeAdapter.deleteSurroundingText(leftLength, rightLength);
+ }
+
+ /**
+ * @see BaseInputConnection#sendKeyEvent(android.view.KeyEvent)
+ */
+ @Override
+ public boolean sendKeyEvent(KeyEvent event) {
+ if (DEBUG) Log.w(TAG, "sendKeyEvent [" + event.getAction() + "]");
+ mImeAdapter.hideSelectionAndInsertionHandleControllers();
+
+ // If this is a key-up, and backspace/del or if the key has a character representation,
+ // need to update the underlying Editable (i.e. the local representation of the text
+ // being edited).
+ if (event.getAction() == KeyEvent.ACTION_UP) {
+ if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
+ super.deleteSurroundingText(1, 0);
+ } else if (event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL) {
+ super.deleteSurroundingText(0, 1);
+ } else {
+ int unicodeChar = event.getUnicodeChar();
+ if (unicodeChar != 0) {
+ Editable editable = getEditable();
+ int selectionStart = Selection.getSelectionStart(editable);
+ int selectionEnd = Selection.getSelectionEnd(editable);
+ if (selectionStart > selectionEnd) {
+ int temp = selectionStart;
+ selectionStart = selectionEnd;
+ selectionEnd = temp;
+ }
+ editable.replace(selectionStart, selectionEnd,
+ Character.toString((char)unicodeChar));
+ }
+ }
+ }
+ mImeAdapter.translateAndSendNativeEvents(event);
+ return true;
+ }
+
+ /**
+ * @see BaseInputConnection#finishComposingText()
+ */
+ @Override
+ public boolean finishComposingText() {
+ if (DEBUG) Log.w(TAG, "finishComposingText");
+ Editable editable = getEditable();
+ if (getComposingSpanStart(editable) == getComposingSpanEnd(editable)) {
+ return true;
+ }
+ super.finishComposingText();
+
+ beginBatchEdit();
+ int selectionStart = Selection.getSelectionStart(editable);
+ int selectionEnd = Selection.getSelectionEnd(editable);
+ if (!mImeAdapter.checkCompositionQueueAndCallNative("", 0, true)) return false;
+ if (!mImeAdapter.setEditableSelectionOffsets(selectionStart, selectionEnd)) return false;
+ endBatchEdit();
+ return true;
+ }
+
+ /**
+ * @see BaseInputConnection#setSelection(int, int)
+ */
+ @Override
+ public boolean setSelection(int start, int end) {
+ if (DEBUG) Log.w(TAG, "setSelection");
+ if (start < 0 || end < 0) return true;
+ super.setSelection(start, end);
+ return mImeAdapter.setEditableSelectionOffsets(start, end);
+ }
+
+ /**
+ * Informs the InputMethodManager and InputMethodSession (i.e. the IME) that the text
+ * state is no longer what the IME has and that it needs to be updated.
+ */
+ void restartInput() {
+ if (DEBUG) Log.w(TAG, "restartInput");
+ getInputMethodManagerWrapper().restartInput(mInternalView);
+ mIgnoreTextInputStateUpdates = false;
+ mNumNestedBatchEdits = 0;
+ }
+
+ /**
+ * @see BaseInputConnection#setComposingRegion(int, int)
+ */
+ @Override
+ public boolean setComposingRegion(int start, int end) {
+ if (DEBUG) Log.w(TAG, "setComposingRegion [" + start + " " + end + "]");
+ int a = Math.min(start, end);
+ int b = Math.max(start, end);
+ if (a < 0) a = 0;
+ if (b < 0) b = 0;
+
+ if (a == b) {
+ removeComposingSpans(getEditable());
+ } else {
+ super.setComposingRegion(a, b);
+ }
+ return mImeAdapter.setComposingRegion(a, b);
+ }
+
+ boolean isActive() {
+ return getInputMethodManagerWrapper().isActive(mInternalView);
+ }
+
+ public void setIgnoreTextInputStateUpdates(boolean shouldIgnore) {
+ mIgnoreTextInputStateUpdates = shouldIgnore;
+ if (shouldIgnore) return;
+
+ Editable editable = getEditable();
+ updateSelection(Selection.getSelectionStart(editable),
+ Selection.getSelectionEnd(editable),
+ getComposingSpanStart(editable),
+ getComposingSpanEnd(editable));
+ }
+
+ @VisibleForTesting
+ protected boolean isIgnoringTextInputStateUpdates() {
+ return mIgnoreTextInputStateUpdates;
+ }
+
+ private InputMethodManagerWrapper getInputMethodManagerWrapper() {
+ return mImeAdapter.getInputMethodManagerWrapper();
+ }
+}
diff --git a/content/public/android/java/src/org/chromium/content/browser/CursorController.java b/content/public/android/java/src/org/chromium/content/browser/input/CursorController.java
similarity index 95%
rename from content/public/android/java/src/org/chromium/content/browser/CursorController.java
rename to content/public/android/java/src/org/chromium/content/browser/input/CursorController.java
index 6e572c8..10e3064 100644
--- a/content/public/android/java/src/org/chromium/content/browser/CursorController.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/CursorController.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.content.browser;
+package org.chromium.content.browser.input;
import android.view.ViewTreeObserver;
diff --git a/content/public/android/java/src/org/chromium/content/browser/DateTimeChooserAndroid.java b/content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java
similarity index 96%
rename from content/public/android/java/src/org/chromium/content/browser/DateTimeChooserAndroid.java
rename to content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java
index 7fc146b..f8fca54 100644
--- a/content/public/android/java/src/org/chromium/content/browser/DateTimeChooserAndroid.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java
@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.content.browser;
+package org.chromium.content.browser.input;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
+import org.chromium.content.browser.ContentViewCore;
import android.content.Context;
diff --git a/content/public/android/java/src/org/chromium/content/browser/DateTimePickerDialog.java b/content/public/android/java/src/org/chromium/content/browser/input/DateTimePickerDialog.java
similarity index 99%
rename from content/public/android/java/src/org/chromium/content/browser/DateTimePickerDialog.java
rename to content/public/android/java/src/org/chromium/content/browser/input/DateTimePickerDialog.java
index c122c29..29bca66 100644
--- a/content/public/android/java/src/org/chromium/content/browser/DateTimePickerDialog.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/DateTimePickerDialog.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.content.browser;
+package org.chromium.content.browser.input;
import android.app.AlertDialog;
import android.content.Context;
diff --git a/content/public/android/java/src/org/chromium/content/browser/HandleView.java b/content/public/android/java/src/org/chromium/content/browser/input/HandleView.java
similarity index 97%
rename from content/public/android/java/src/org/chromium/content/browser/HandleView.java
rename to content/public/android/java/src/org/chromium/content/browser/input/HandleView.java
index a772d5d..a220894 100644
--- a/content/public/android/java/src/org/chromium/content/browser/HandleView.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/HandleView.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.content.browser;
+package org.chromium.content.browser.input;
import android.content.Context;
import android.content.res.TypedArray;
@@ -27,7 +27,7 @@
/**
* View that displays a selection or insertion handle for text editing.
*/
-class HandleView extends View {
+public class HandleView extends View {
private static final float FADE_DURATION = 200.f;
private Drawable mDrawable;
@@ -113,7 +113,7 @@
}
mDrawable = mSelectHandleLeft;
handleWidth = mDrawable.getIntrinsicWidth();
- mHotspotX = (handleWidth * 3) / 4;
+ mHotspotX = (handleWidth * 3) / 4f;
break;
}
@@ -124,7 +124,7 @@
}
mDrawable = mSelectHandleRight;
handleWidth = mDrawable.getIntrinsicWidth();
- mHotspotX = handleWidth / 4;
+ mHotspotX = handleWidth / 4f;
break;
}
@@ -136,7 +136,7 @@
}
mDrawable = mSelectHandleCenter;
handleWidth = mDrawable.getIntrinsicWidth();
- mHotspotX = handleWidth / 2;
+ mHotspotX = handleWidth / 2f;
mIsInsertionHandle = true;
break;
}
@@ -306,6 +306,9 @@
case MotionEvent.ACTION_CANCEL:
mIsDragging = false;
break;
+
+ default:
+ return false;
}
return true;
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
new file mode 100644
index 0000000..354b242
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
@@ -0,0 +1,579 @@
+// 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.
+
+package org.chromium.content.browser.input;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.ResultReceiver;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+
+/**
+ * Adapts and plumbs android IME service onto the chrome text input API.
+ * ImeAdapter provides an interface in both ways native <-> java:
+ * 1. InputConnectionAdapter notifies native code of text composition state and
+ * dispatch key events from java -> WebKit.
+ * 2. Native ImeAdapter notifies java side to clear composition text.
+ *
+ * The basic flow is:
+ * 1. When InputConnectionAdapter gets called with composition or result text:
+ * If we receive a composition text or a result text, then we just need to
+ * dispatch a synthetic key event with special keycode 229, and then dispatch
+ * the composition or result text.
+ * 2. Intercept dispatchKeyEvent() method for key events not handled by IME, we
+ * need to dispatch them to webkit and check webkit's reply. Then inject a
+ * new key event for further processing if webkit didn't handle it.
+ *
+ * Note that the native peer object does not take any strong reference onto the
+ * instance of this java object, hence it is up to the client of this class (e.g.
+ * the ViewEmbedder implementor) to hold a strong reference to it for the required
+ * lifetime of the object.
+ */
+@JNINamespace("content")
+public class ImeAdapter {
+ public interface ViewEmbedder {
+ /**
+ * @param isFinish whether the event is occurring because input is finished.
+ */
+ void onImeEvent(boolean isFinish);
+ void onSetFieldValue();
+ void onDismissInput();
+ View getAttachedView();
+ ResultReceiver getNewShowKeyboardReceiver();
+ }
+
+ private class DelayedDismissInput implements Runnable {
+ private final int mNativeImeAdapter;
+
+ DelayedDismissInput(int nativeImeAdapter) {
+ mNativeImeAdapter = nativeImeAdapter;
+ }
+
+ @Override
+ public void run() {
+ attach(mNativeImeAdapter, sTextInputTypeNone, AdapterInputConnection.INVALID_SELECTION,
+ AdapterInputConnection.INVALID_SELECTION);
+ dismissInput(true);
+ }
+ }
+
+ private static final int COMPOSITION_KEY_CODE = 229;
+
+ // Delay introduced to avoid hiding the keyboard if new show requests are received.
+ // The time required by the unfocus-focus events triggered by tab has been measured in soju:
+ // Mean: 18.633 ms, Standard deviation: 7.9837 ms.
+ // The value here should be higher enough to cover these cases, but not too high to avoid
+ // letting the user perceiving important delays.
+ private static final int INPUT_DISMISS_DELAY = 150;
+
+ // All the constants that are retrieved from the C++ code.
+ // They get set through initializeWebInputEvents and initializeTextInputTypes calls.
+ static int sEventTypeRawKeyDown;
+ static int sEventTypeKeyUp;
+ static int sEventTypeChar;
+ static int sTextInputTypeNone;
+ static int sTextInputTypeText;
+ static int sTextInputTypeTextArea;
+ static int sTextInputTypePassword;
+ static int sTextInputTypeSearch;
+ static int sTextInputTypeUrl;
+ static int sTextInputTypeEmail;
+ static int sTextInputTypeTel;
+ static int sTextInputTypeNumber;
+ static int sTextInputTypeWeek;
+ static int sTextInputTypeContentEditable;
+ static int sModifierShift;
+ static int sModifierAlt;
+ static int sModifierCtrl;
+ static int sModifierCapsLockOn;
+ static int sModifierNumLockOn;
+
+ private int mNativeImeAdapterAndroid;
+ private final Context mContext;
+ private InputMethodManagerWrapper mInputMethodManagerWrapper;
+ private AdapterInputConnection mInputConnection;
+ private final ViewEmbedder mViewEmbedder;
+ private final Handler mHandler;
+ private DelayedDismissInput mDismissInput = null;
+ private final SelectionHandleController mSelectionHandleController;
+ private final InsertionHandleController mInsertionHandleController;
+ private int mTextInputType;
+ private int mInitialSelectionStart;
+ private int mInitialSelectionEnd;
+
+ @VisibleForTesting
+ boolean mIsShowWithoutHideOutstanding = false;
+
+ /**
+ * @param context View context.
+ * @param selectionHandleController The controller that handles selection.
+ * @param insertionHandleController The controller that handles insertion.
+ * @param embedder The view that is used for callbacks from ImeAdapter.
+ */
+ public ImeAdapter(Context context, SelectionHandleController selectionHandleController,
+ InsertionHandleController insertionHandleController, ViewEmbedder embedder) {
+ mContext = context;
+ mInputMethodManagerWrapper = new InputMethodManagerWrapper(context);
+ mSelectionHandleController = selectionHandleController;
+ mInsertionHandleController = insertionHandleController;
+ mViewEmbedder = embedder;
+ mHandler = new Handler();
+ }
+
+ public static class AdapterInputConnectionFactory {
+ public AdapterInputConnection get(View view, ImeAdapter imeAdapter,
+ EditorInfo outAttrs) {
+ return new AdapterInputConnection(view, imeAdapter, outAttrs);
+ }
+ }
+
+ @VisibleForTesting
+ protected void setInputMethodManagerWrapper(InputMethodManagerWrapper immw) {
+ mInputMethodManagerWrapper = immw;
+ }
+
+ /**
+ * Should be only used by AdapterInputConnection.
+ * @return InputMethodManagerWrapper that should receive all the calls directed to
+ * InputMethodManager.
+ */
+ InputMethodManagerWrapper getInputMethodManagerWrapper() {
+ return mInputMethodManagerWrapper;
+ }
+
+ /**
+ * Set the current active InputConnection when a new InputConnection is constructed.
+ * @param inputConnection The input connection that is currently used with IME.
+ */
+ void setInputConnection(AdapterInputConnection inputConnection) {
+ mInputConnection = inputConnection;
+ }
+
+ /**
+ * Should be only used by AdapterInputConnection.
+ * @return The input type of currently focused element.
+ */
+ int getTextInputType() {
+ return mTextInputType;
+ }
+
+ /**
+ * Should be only used by AdapterInputConnection.
+ * @return The starting index of the initial text selection.
+ */
+ int getInitialSelectionStart() {
+ return mInitialSelectionStart;
+ }
+
+ /**
+ * Should be only used by AdapterInputConnection.
+ * @return The ending index of the initial text selection.
+ */
+ int getInitialSelectionEnd() {
+ return mInitialSelectionEnd;
+ }
+
+ public static int getTextInputTypeNone() {
+ return sTextInputTypeNone;
+ }
+
+ private static int getModifiers(int metaState) {
+ int modifiers = 0;
+ if ((metaState & KeyEvent.META_SHIFT_ON) != 0) {
+ modifiers |= sModifierShift;
+ }
+ if ((metaState & KeyEvent.META_ALT_ON) != 0) {
+ modifiers |= sModifierAlt;
+ }
+ if ((metaState & KeyEvent.META_CTRL_ON) != 0) {
+ modifiers |= sModifierCtrl;
+ }
+ if ((metaState & KeyEvent.META_CAPS_LOCK_ON) != 0) {
+ modifiers |= sModifierCapsLockOn;
+ }
+ if ((metaState & KeyEvent.META_NUM_LOCK_ON) != 0) {
+ modifiers |= sModifierNumLockOn;
+ }
+ return modifiers;
+ }
+
+ void hideSelectionAndInsertionHandleControllers() {
+ mSelectionHandleController.hideAndDisallowAutomaticShowing();
+ mInsertionHandleController.hideAndDisallowAutomaticShowing();
+ }
+
+ public boolean isActive() {
+ return mInputConnection != null && mInputConnection.isActive();
+ }
+
+ private boolean isFor(int nativeImeAdapter, int textInputType) {
+ return mNativeImeAdapterAndroid == nativeImeAdapter &&
+ mTextInputType == textInputType;
+ }
+
+ public void attachAndShowIfNeeded(int nativeImeAdapter, int textInputType,
+ int selectionStart, int selectionEnd, boolean showIfNeeded) {
+ mHandler.removeCallbacks(mDismissInput);
+
+ // If current input type is none and showIfNeeded is false, IME should not be shown
+ // and input type should remain as none.
+ if (mTextInputType == sTextInputTypeNone && !showIfNeeded) {
+ return;
+ }
+
+ if (!isFor(nativeImeAdapter, textInputType)) {
+ // Set a delayed task to perform unfocus. This avoids hiding the keyboard when tabbing
+ // through text inputs or when JS rapidly changes focus to another text element.
+ if (textInputType == sTextInputTypeNone) {
+ mDismissInput = new DelayedDismissInput(nativeImeAdapter);
+ mHandler.postDelayed(mDismissInput, INPUT_DISMISS_DELAY);
+ return;
+ }
+
+ int previousType = mTextInputType;
+ attach(nativeImeAdapter, textInputType, selectionStart, selectionEnd);
+
+ mInputMethodManagerWrapper.restartInput(mViewEmbedder.getAttachedView());
+ if (showIfNeeded) {
+ showKeyboard();
+ }
+ } else if (hasInputType() && showIfNeeded) {
+ showKeyboard();
+ }
+ }
+
+ public void attach(int nativeImeAdapter, int textInputType, int selectionStart,
+ int selectionEnd) {
+ if (mNativeImeAdapterAndroid != 0) {
+ nativeResetImeAdapter(mNativeImeAdapterAndroid);
+ }
+ mNativeImeAdapterAndroid = nativeImeAdapter;
+ mTextInputType = textInputType;
+ mInitialSelectionStart = selectionStart;
+ mInitialSelectionEnd = selectionEnd;
+ nativeAttachImeAdapter(mNativeImeAdapterAndroid);
+ }
+
+ /**
+ * Attaches the imeAdapter to its native counterpart. This is needed to start forwarding
+ * keyboard events to WebKit.
+ * @param nativeImeAdapter The pointer to the native ImeAdapter object.
+ */
+ public void attach(int nativeImeAdapter) {
+ if (mNativeImeAdapterAndroid != 0) {
+ nativeResetImeAdapter(mNativeImeAdapterAndroid);
+ }
+ mNativeImeAdapterAndroid = nativeImeAdapter;
+ if (nativeImeAdapter != 0) {
+ nativeAttachImeAdapter(mNativeImeAdapterAndroid);
+ }
+ }
+
+ /**
+ * Used to check whether the native counterpart of the ImeAdapter has been attached yet.
+ * @return Whether native ImeAdapter has been attached and its pointer is currently nonzero.
+ */
+ public boolean isNativeImeAdapterAttached() {
+ return mNativeImeAdapterAndroid != 0;
+ }
+
+ private void showKeyboard() {
+ mIsShowWithoutHideOutstanding = true;
+ mInputMethodManagerWrapper.showSoftInput(mViewEmbedder.getAttachedView(), 0,
+ mViewEmbedder.getNewShowKeyboardReceiver());
+ }
+
+ private void dismissInput(boolean unzoomIfNeeded) {
+ hideKeyboard(unzoomIfNeeded);
+ mViewEmbedder.onDismissInput();
+ }
+
+ private void hideKeyboard(boolean unzoomIfNeeded) {
+ mIsShowWithoutHideOutstanding = false;
+ View view = mViewEmbedder.getAttachedView();
+ if (mInputMethodManagerWrapper.isActive(view)) {
+ mInputMethodManagerWrapper.hideSoftInputFromWindow(view.getWindowToken(), 0,
+ unzoomIfNeeded ? mViewEmbedder.getNewShowKeyboardReceiver() : null);
+ }
+ }
+
+ private boolean hasInputType() {
+ return mTextInputType != sTextInputTypeNone;
+ }
+
+ static boolean isTextInputType(int type) {
+ return type != sTextInputTypeNone && !InputDialogContainer.isDialogInputType(type);
+ }
+
+ public boolean hasTextInputType() {
+ return isTextInputType(mTextInputType);
+ }
+
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ return translateAndSendNativeEvents(event);
+ }
+
+ private int shouldSendKeyEventWithKeyCode(String text) {
+ if (text.length() != 1) return COMPOSITION_KEY_CODE;
+
+ if (text.equals("\n")) return KeyEvent.KEYCODE_ENTER;
+ else if (text.equals("\t")) return KeyEvent.KEYCODE_TAB;
+ else return COMPOSITION_KEY_CODE;
+ }
+
+ void sendKeyEventWithKeyCode(int keyCode, int flags) {
+ long eventTime = System.currentTimeMillis();
+ translateAndSendNativeEvents(new KeyEvent(eventTime, eventTime,
+ KeyEvent.ACTION_DOWN, keyCode, 0, 0,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
+ flags));
+ translateAndSendNativeEvents(new KeyEvent(System.currentTimeMillis(), eventTime,
+ KeyEvent.ACTION_UP, keyCode, 0, 0,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
+ flags));
+ }
+
+ // Calls from Java to C++
+
+ @VisibleForTesting
+ boolean checkCompositionQueueAndCallNative(String text, int newCursorPosition,
+ boolean isCommit) {
+ if (mNativeImeAdapterAndroid == 0) return false;
+
+ // Committing an empty string finishes the current composition.
+ boolean isFinish = text.isEmpty();
+ if (!isFinish) {
+ mSelectionHandleController.hideAndDisallowAutomaticShowing();
+ mInsertionHandleController.hideAndDisallowAutomaticShowing();
+ }
+ mViewEmbedder.onImeEvent(isFinish);
+ int keyCode = shouldSendKeyEventWithKeyCode(text);
+ long timeStampMs = System.currentTimeMillis();
+
+ if (keyCode != COMPOSITION_KEY_CODE) {
+ sendKeyEventWithKeyCode(keyCode,
+ KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE);
+ } else {
+ nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeRawKeyDown,
+ timeStampMs, keyCode, 0);
+ if (isCommit) {
+ nativeCommitText(mNativeImeAdapterAndroid, text);
+ } else {
+ nativeSetComposingText(mNativeImeAdapterAndroid, text, newCursorPosition);
+ }
+ nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeKeyUp,
+ timeStampMs, keyCode, 0);
+ }
+
+ return true;
+ }
+
+ boolean translateAndSendNativeEvents(KeyEvent event) {
+ if (mNativeImeAdapterAndroid == 0) return false;
+
+ int action = event.getAction();
+ if (action != KeyEvent.ACTION_DOWN &&
+ action != KeyEvent.ACTION_UP) {
+ // action == KeyEvent.ACTION_MULTIPLE
+ // TODO(bulach): confirm the actual behavior. Apparently:
+ // If event.getKeyCode() == KEYCODE_UNKNOWN, we can send a
+ // composition key down (229) followed by a commit text with the
+ // string from event.getUnicodeChars().
+ // Otherwise, we'd need to send an event with a
+ // WebInputEvent::IsAutoRepeat modifier. We also need to verify when
+ // we receive ACTION_MULTIPLE: we may receive it after an ACTION_DOWN,
+ // and if that's the case, we'll need to review when to send the Char
+ // event.
+ return false;
+ }
+ mViewEmbedder.onImeEvent(false);
+ return nativeSendKeyEvent(mNativeImeAdapterAndroid, event, event.getAction(),
+ getModifiers(event.getMetaState()), event.getEventTime(), event.getKeyCode(),
+ event.isSystem(), event.getUnicodeChar());
+ }
+
+ boolean sendSyntheticKeyEvent(
+ int eventType, long timestampMs, int keyCode, int unicodeChar) {
+ if (mNativeImeAdapterAndroid == 0) return false;
+
+ nativeSendSyntheticKeyEvent(
+ mNativeImeAdapterAndroid, eventType, timestampMs, keyCode, unicodeChar);
+ return true;
+ }
+
+ boolean deleteSurroundingText(int leftLength, int rightLength) {
+ if (mNativeImeAdapterAndroid == 0) return false;
+ nativeDeleteSurroundingText(mNativeImeAdapterAndroid, leftLength, rightLength);
+ return true;
+ }
+
+ @VisibleForTesting
+ protected boolean setEditableSelectionOffsets(int start, int end) {
+ if (mNativeImeAdapterAndroid == 0) return false;
+ nativeSetEditableSelectionOffsets(mNativeImeAdapterAndroid, start, end);
+ return true;
+ }
+
+ void batchStateChanged(boolean isBegin) {
+ if (mNativeImeAdapterAndroid == 0) return;
+ nativeImeBatchStateChanged(mNativeImeAdapterAndroid, isBegin);
+ }
+
+ void commitText() {
+ cancelComposition();
+ if (mNativeImeAdapterAndroid != 0) {
+ nativeCommitText(mNativeImeAdapterAndroid, "");
+ }
+ }
+
+ /**
+ * Send a request to the native counterpart to set compositing region to given indices.
+ * @param start The start of the composition.
+ * @param end The end of the composition.
+ * @return Whether the native counterpart of ImeAdapter received the call.
+ */
+ boolean setComposingRegion(int start, int end) {
+ if (mNativeImeAdapterAndroid == 0) return false;
+ nativeSetComposingRegion(mNativeImeAdapterAndroid, start, end);
+ return true;
+ }
+
+ /**
+ * Send a request to the native counterpart to unselect text.
+ * @return Whether the native counterpart of ImeAdapter received the call.
+ */
+ public boolean unselect() {
+ if (mNativeImeAdapterAndroid == 0) return false;
+ nativeUnselect(mNativeImeAdapterAndroid);
+ return true;
+ }
+
+ /**
+ * Send a request to the native counterpart of ImeAdapter to select all the text.
+ * @return Whether the native counterpart of ImeAdapter received the call.
+ */
+ public boolean selectAll() {
+ if (mNativeImeAdapterAndroid == 0) return false;
+ nativeSelectAll(mNativeImeAdapterAndroid);
+ return true;
+ }
+
+ /**
+ * Send a request to the native counterpart of ImeAdapter to cut the selected text.
+ * @return Whether the native counterpart of ImeAdapter received the call.
+ */
+ public boolean cut() {
+ if (mNativeImeAdapterAndroid == 0) return false;
+ nativeCut(mNativeImeAdapterAndroid);
+ return true;
+ }
+
+ /**
+ * Send a request to the native counterpart of ImeAdapter to copy the selected text.
+ * @return Whether the native counterpart of ImeAdapter received the call.
+ */
+ public boolean copy() {
+ if (mNativeImeAdapterAndroid == 0) return false;
+ nativeCopy(mNativeImeAdapterAndroid);
+ return true;
+ }
+
+ /**
+ * Send a request to the native counterpart of ImeAdapter to paste the text from the clipboard.
+ * @return Whether the native counterpart of ImeAdapter received the call.
+ */
+ public boolean paste() {
+ if (mNativeImeAdapterAndroid == 0) return false;
+ nativePaste(mNativeImeAdapterAndroid);
+ return true;
+ }
+
+ // Calls from C++ to Java
+
+ @CalledByNative
+ private static void initializeWebInputEvents(int eventTypeRawKeyDown, int eventTypeKeyUp,
+ int eventTypeChar, int modifierShift, int modifierAlt, int modifierCtrl,
+ int modifierCapsLockOn, int modifierNumLockOn) {
+ sEventTypeRawKeyDown = eventTypeRawKeyDown;
+ sEventTypeKeyUp = eventTypeKeyUp;
+ sEventTypeChar = eventTypeChar;
+ sModifierShift = modifierShift;
+ sModifierAlt = modifierAlt;
+ sModifierCtrl = modifierCtrl;
+ sModifierCapsLockOn = modifierCapsLockOn;
+ sModifierNumLockOn = modifierNumLockOn;
+ }
+
+ @CalledByNative
+ private static void initializeTextInputTypes(int textInputTypeNone, int textInputTypeText,
+ int textInputTypeTextArea, int textInputTypePassword, int textInputTypeSearch,
+ int textInputTypeUrl, int textInputTypeEmail, int textInputTypeTel,
+ int textInputTypeNumber, int textInputTypeDate, int textInputTypeDateTime,
+ int textInputTypeDateTimeLocal, int textInputTypeMonth, int textInputTypeTime,
+ int textInputTypeWeek, int textInputTypeContentEditable) {
+ sTextInputTypeNone = textInputTypeNone;
+ sTextInputTypeText = textInputTypeText;
+ sTextInputTypeTextArea = textInputTypeTextArea;
+ sTextInputTypePassword = textInputTypePassword;
+ sTextInputTypeSearch = textInputTypeSearch;
+ sTextInputTypeUrl = textInputTypeUrl;
+ sTextInputTypeEmail = textInputTypeEmail;
+ sTextInputTypeTel = textInputTypeTel;
+ sTextInputTypeNumber = textInputTypeNumber;
+ sTextInputTypeWeek = textInputTypeWeek;
+ sTextInputTypeContentEditable = textInputTypeContentEditable;
+ }
+
+ @CalledByNative
+ private void cancelComposition() {
+ if (mInputConnection != null) {
+ mInputConnection.restartInput();
+ }
+ }
+
+ @CalledByNative
+ void detach() {
+ mNativeImeAdapterAndroid = 0;
+ mTextInputType = 0;
+ }
+
+ private native boolean nativeSendSyntheticKeyEvent(int nativeImeAdapterAndroid,
+ int eventType, long timestampMs, int keyCode, int unicodeChar);
+
+ private native boolean nativeSendKeyEvent(int nativeImeAdapterAndroid, KeyEvent event,
+ int action, int modifiers, long timestampMs, int keyCode, boolean isSystemKey,
+ int unicodeChar);
+
+ private native void nativeSetComposingText(int nativeImeAdapterAndroid, String text,
+ int newCursorPosition);
+
+ private native void nativeCommitText(int nativeImeAdapterAndroid, String text);
+
+ private native void nativeAttachImeAdapter(int nativeImeAdapterAndroid);
+
+ private native void nativeSetEditableSelectionOffsets(int nativeImeAdapterAndroid,
+ int start, int end);
+
+ private native void nativeSetComposingRegion(int nativeImeAdapterAndroid, int start, int end);
+
+ private native void nativeDeleteSurroundingText(int nativeImeAdapterAndroid,
+ int before, int after);
+
+ private native void nativeImeBatchStateChanged(int nativeImeAdapterAndroid, boolean isBegin);
+
+ private native void nativeUnselect(int nativeImeAdapterAndroid);
+ private native void nativeSelectAll(int nativeImeAdapterAndroid);
+ private native void nativeCut(int nativeImeAdapterAndroid);
+ private native void nativeCopy(int nativeImeAdapterAndroid);
+ private native void nativePaste(int nativeImeAdapterAndroid);
+ private native void nativeResetImeAdapter(int nativeImeAdapterAndroid);
+}
diff --git a/content/public/android/java/src/org/chromium/content/browser/InputDialogContainer.java b/content/public/android/java/src/org/chromium/content/browser/input/InputDialogContainer.java
similarity index 97%
rename from content/public/android/java/src/org/chromium/content/browser/InputDialogContainer.java
rename to content/public/android/java/src/org/chromium/content/browser/input/InputDialogContainer.java
index 466665d..11189c5 100644
--- a/content/public/android/java/src/org/chromium/content/browser/InputDialogContainer.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/InputDialogContainer.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.content.browser;
+package org.chromium.content.browser.input;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
@@ -18,8 +18,8 @@
import android.widget.DatePicker;
import android.widget.TimePicker;
-import org.chromium.content.browser.DateTimePickerDialog.OnDateTimeSetListener;
-import org.chromium.content.browser.MonthPickerDialog.OnMonthSetListener;
+import org.chromium.content.browser.input.DateTimePickerDialog.OnDateTimeSetListener;
+import org.chromium.content.browser.input.MonthPickerDialog.OnMonthSetListener;
import org.chromium.content.R;
import java.text.ParseException;
@@ -27,7 +27,7 @@
import java.util.Calendar;
import java.util.Date;
-class InputDialogContainer {
+public class InputDialogContainer {
interface InputActionDelegate {
void cancelDateTimeDialog();
diff --git a/content/public/android/java/src/org/chromium/content/browser/InputMethodManagerWrapper.java b/content/public/android/java/src/org/chromium/content/browser/input/InputMethodManagerWrapper.java
similarity index 96%
rename from content/public/android/java/src/org/chromium/content/browser/InputMethodManagerWrapper.java
rename to content/public/android/java/src/org/chromium/content/browser/input/InputMethodManagerWrapper.java
index 572582e..34b8b4e 100644
--- a/content/public/android/java/src/org/chromium/content/browser/InputMethodManagerWrapper.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/InputMethodManagerWrapper.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.content.browser;
+package org.chromium.content.browser.input;
import android.content.Context;
import android.os.IBinder;
@@ -13,7 +13,7 @@
/**
* Wrapper around Android's InputMethodManager
*/
-public class InputMethodManagerWrapper {
+class InputMethodManagerWrapper {
private final Context mContext;
public InputMethodManagerWrapper(Context context) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/InsertionHandleController.java b/content/public/android/java/src/org/chromium/content/browser/input/InsertionHandleController.java
similarity index 93%
rename from content/public/android/java/src/org/chromium/content/browser/InsertionHandleController.java
rename to content/public/android/java/src/org/chromium/content/browser/input/InsertionHandleController.java
index 18fb7a4..e3ab838 100644
--- a/content/public/android/java/src/org/chromium/content/browser/InsertionHandleController.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/InsertionHandleController.java
@@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.content.browser;
+package org.chromium.content.browser.input;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
-import android.graphics.PointF;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@@ -20,7 +19,7 @@
/**
* CursorController for inserting text at the cursor position.
*/
-abstract class InsertionHandleController implements CursorController {
+public abstract class InsertionHandleController implements CursorController {
/** The handle view, lazily created when first shown */
private HandleView mHandle;
@@ -36,18 +35,18 @@
private Context mContext;
- InsertionHandleController(View parent) {
+ public InsertionHandleController(View parent) {
mParent = parent;
mContext = parent.getContext();
}
/** Allows the handle to be shown automatically when cursor position changes */
- void allowAutomaticShowing() {
+ public void allowAutomaticShowing() {
mAllowAutomaticShowing = true;
}
/** Disallows the handle from being shown automatically when cursor position changes */
- void hideAndDisallowAutomaticShowing() {
+ public void hideAndDisallowAutomaticShowing() {
hide();
mAllowAutomaticShowing = false;
}
@@ -55,7 +54,7 @@
/**
* Shows the handle.
*/
- void showHandle() {
+ public void showHandle() {
createHandleIfNeeded();
showHandleIfNeeded();
}
@@ -66,13 +65,13 @@
}
}
- void showHandleWithPastePopup() {
+ public void showHandleWithPastePopup() {
showHandle();
showPastePopup();
}
/** Shows the handle at the given coordinates, as long as automatic showing is allowed */
- void onCursorPositionChanged() {
+ public void onCursorPositionChanged() {
if (mAllowAutomaticShowing) {
showHandle();
}
@@ -83,25 +82,21 @@
* @param x Handle x in physical pixels.
* @param y Handle y in physical pixels.
*/
- void setHandlePosition(int x, int y) {
- mHandle.positionAt(x, y);
- }
-
- void setHandlePosition(float x, float y) {
- setHandlePosition((int) x, (int) y);
+ public void setHandlePosition(float x, float y) {
+ mHandle.positionAt((int) x, (int) y);
}
/**
* If the handle is not visible, sets its visibility to View.VISIBLE and begins fading it in.
*/
- void beginHandleFadeIn() {
+ public void beginHandleFadeIn() {
mHandle.beginFadeIn();
}
/**
* Sets the handle to the given visibility.
*/
- void setHandleVisibility(int visibility) {
+ public void setHandleVisibility(int visibility) {
mHandle.setVisibility(visibility);
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/MonthPicker.java b/content/public/android/java/src/org/chromium/content/browser/input/MonthPicker.java
similarity index 89%
rename from content/public/android/java/src/org/chromium/content/browser/MonthPicker.java
rename to content/public/android/java/src/org/chromium/content/browser/input/MonthPicker.java
index 75794ee..01e636e 100644
--- a/content/public/android/java/src/org/chromium/content/browser/MonthPicker.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/MonthPicker.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.content.browser;
+package org.chromium.content.browser.input;
import android.content.Context;
import android.content.res.Configuration;
@@ -15,10 +15,10 @@
import android.view.accessibility.AccessibilityEvent;
import android.widget.DatePicker;
import android.widget.FrameLayout;
-import android.widget.LinearLayout;
import android.widget.NumberPicker;
import android.widget.NumberPicker.OnValueChangeListener;
+import java.text.DateFormatSymbols;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Locale;
@@ -35,8 +35,6 @@
private static final boolean DEFAULT_ENABLED_STATE = true;
- private final LinearLayout mSpinners;
-
private final NumberPicker mMonthSpinner;
private final NumberPicker mYearSpinner;
@@ -49,8 +47,6 @@
private int mNumberOfMonths;
- private Calendar mTempDate;
-
private Calendar mMinDate;
private Calendar mMaxDate;
@@ -97,31 +93,33 @@
inflater.inflate(R.layout.month_picker, this, true);
OnValueChangeListener onChangeListener = new OnValueChangeListener() {
+ @Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
- mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
+ Calendar tempDate = getCalendarForLocale(null, mCurrentLocale);
+ tempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
+
// take care of wrapping of days and months to update greater fields
if (picker == mMonthSpinner) {
if (oldVal == 11 && newVal == 0) {
- mTempDate.add(Calendar.MONTH, 1);
+ tempDate.add(Calendar.MONTH, 1);
} else if (oldVal == 0 && newVal == 11) {
- mTempDate.add(Calendar.MONTH, -1);
+ tempDate.add(Calendar.MONTH, -1);
} else {
- mTempDate.add(Calendar.MONTH, newVal - oldVal);
+ tempDate.add(Calendar.MONTH, newVal - oldVal);
}
} else if (picker == mYearSpinner) {
- mTempDate.set(Calendar.YEAR, newVal);
+ tempDate.set(Calendar.YEAR, newVal);
} else {
throw new IllegalArgumentException();
}
+
// now set the date to the adjusted one
- setDate(mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH));
+ setDate(tempDate.get(Calendar.YEAR), tempDate.get(Calendar.MONTH));
updateSpinners();
notifyDateChanged();
}
};
- mSpinners = (LinearLayout) findViewById(R.id.pickers);
-
// month
mMonthSpinner = (NumberPicker) findViewById(R.id.month);
mMonthSpinner.setMinValue(0);
@@ -135,14 +133,12 @@
mYearSpinner.setOnLongPressUpdateInterval(100);
mYearSpinner.setOnValueChangedListener(onChangeListener);
- mTempDate.clear();
- mTempDate.set(startYear, 0, 1);
+ Calendar tempDate = getCalendarForLocale(null, mCurrentLocale);
+ tempDate.set(startYear, 0, 1);
- setMinDate(mTempDate.getTimeInMillis());
-
- mTempDate.clear();
- mTempDate.set(endYear, 11, 31);
- setMaxDate(mTempDate.getTimeInMillis());
+ setMinDate(tempDate.getTimeInMillis());
+ tempDate.set(endYear, 11, 31);
+ setMaxDate(tempDate.getTimeInMillis());
// initialize to current date
mCurrentDate.setTimeInMillis(System.currentTimeMillis());
@@ -171,9 +167,10 @@
* @param minDate The minimal supported date.
*/
public void setMinDate(long minDate) {
- mTempDate.setTimeInMillis(minDate);
- if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
- && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
+ Calendar tempDate = getCalendarForLocale(null, mCurrentLocale);
+ tempDate.setTimeInMillis(minDate);
+ if (tempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
+ && tempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
return;
}
mMinDate.setTimeInMillis(minDate);
@@ -205,9 +202,10 @@
* @param maxDate The maximal supported date.
*/
public void setMaxDate(long maxDate) {
- mTempDate.setTimeInMillis(maxDate);
- if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
- && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
+ Calendar tempDate = getCalendarForLocale(null, mCurrentLocale);
+ tempDate.setTimeInMillis(maxDate);
+ if (tempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
+ && tempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
return;
}
mMaxDate.setTimeInMillis(maxDate);
@@ -266,18 +264,13 @@
}
mCurrentLocale = locale;
-
- mTempDate = getCalendarForLocale(mTempDate, locale);
mMinDate = getCalendarForLocale(mMinDate, locale);
mMaxDate = getCalendarForLocale(mMaxDate, locale);
mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
- mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1;
- mShortMonths = new String[mNumberOfMonths];
- for (int i = 0; i < mNumberOfMonths; i++) {
- mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i,
- DateUtils.LENGTH_MEDIUM);
- }
+ mShortMonths =
+ DateFormatSymbols.getInstance(mCurrentLocale).getShortMonths();
+ mNumberOfMonths = mShortMonths.length;
}
/**
diff --git a/content/public/android/java/src/org/chromium/content/browser/MonthPickerDialog.java b/content/public/android/java/src/org/chromium/content/browser/input/MonthPickerDialog.java
similarity index 97%
rename from content/public/android/java/src/org/chromium/content/browser/MonthPickerDialog.java
rename to content/public/android/java/src/org/chromium/content/browser/input/MonthPickerDialog.java
index cf8c770..354810e 100644
--- a/content/public/android/java/src/org/chromium/content/browser/MonthPickerDialog.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/MonthPickerDialog.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.content.browser;
+package org.chromium.content.browser.input;
import android.app.AlertDialog;
import android.content.Context;
@@ -12,7 +12,7 @@
import android.os.Bundle;
import android.view.View;
-import org.chromium.content.browser.MonthPicker.OnMonthChangedListener;
+import org.chromium.content.browser.input.MonthPicker.OnMonthChangedListener;
import org.chromium.content.R;
public class MonthPickerDialog extends AlertDialog implements OnClickListener,
diff --git a/content/public/android/java/src/org/chromium/content/browser/SelectPopupDialog.java b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java
similarity index 97%
rename from content/public/android/java/src/org/chromium/content/browser/SelectPopupDialog.java
rename to content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java
index b5d00a5..d32266b 100644
--- a/content/public/android/java/src/org/chromium/content/browser/SelectPopupDialog.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java
@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.content.browser;
+package org.chromium.content.browser.input;
+
+import org.chromium.content.browser.ContentViewCore;
import android.app.AlertDialog;
import android.content.DialogInterface;
@@ -18,7 +20,7 @@
/**
* Handles the popup dialog for the <select> HTML tag support.
*/
-class SelectPopupDialog {
+public class SelectPopupDialog {
// The currently showing popup dialog, null if none is showing.
private static SelectPopupDialog sShownDialog;
@@ -211,7 +213,7 @@
}
// The methods below are used by tests.
- static SelectPopupDialog getCurrent() {
+ public static SelectPopupDialog getCurrent() {
return sShownDialog;
}
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/SelectionHandleController.java b/content/public/android/java/src/org/chromium/content/browser/input/SelectionHandleController.java
similarity index 81%
rename from content/public/android/java/src/org/chromium/content/browser/SelectionHandleController.java
rename to content/public/android/java/src/org/chromium/content/browser/input/SelectionHandleController.java
index 8c5a969..f65c6a5 100644
--- a/content/public/android/java/src/org/chromium/content/browser/SelectionHandleController.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/SelectionHandleController.java
@@ -2,15 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.content.browser;
+package org.chromium.content.browser.input;
-import android.graphics.PointF;
import android.view.View;
/**
* CursorController for selecting a range of text.
*/
-abstract class SelectionHandleController implements CursorController {
+public abstract class SelectionHandleController implements CursorController {
// The following constants match the ones in
// third_party/WebKit/Source/WebKit/chromium/public/WebTextDirection.h
@@ -32,17 +31,17 @@
private int mFixedHandleX;
private int mFixedHandleY;
- SelectionHandleController(View parent) {
+ public SelectionHandleController(View parent) {
mParent = parent;
}
/** Automatically show selection anchors when text is selected. */
- void allowAutomaticShowing() {
+ public void allowAutomaticShowing() {
mAllowAutomaticShowing = true;
}
/** Hide selection anchors, and don't automatically show them. */
- void hideAndDisallowAutomaticShowing() {
+ public void hideAndDisallowAutomaticShowing() {
hide();
mAllowAutomaticShowing = false;
}
@@ -101,7 +100,7 @@
/**
* @return true iff this controller is being used to drag either the selection start or end.
*/
- boolean isDragging() {
+ public boolean isDragging() {
return (mStartHandle != null && mStartHandle.isDragging()) ||
(mEndHandle != null && mEndHandle.isDragging());
}
@@ -121,17 +120,8 @@
* @param x The start handle position X in physical pixels.
* @param y The start handle position Y in physical pixels.
*/
- void setStartHandlePosition(int x, int y) {
- mStartHandle.positionAt(x, y);
- }
-
- /**
- * Moves the start handle so that it points at the given coordinates.
- * @param x The start handle position X in physical pixels.
- * @param y The start handle position Y in physical pixels.
- */
- void setStartHandlePosition(float x, float y) {
- setStartHandlePosition((int) x, (int) y);
+ public void setStartHandlePosition(float x, float y) {
+ mStartHandle.positionAt((int) x, (int) y);
}
/**
@@ -139,24 +129,15 @@
* @param x The end handle position X in physical pixels.
* @param y The end handle position Y in physical pixels.
*/
- void setEndHandlePosition(int x, int y) {
- mEndHandle.positionAt(x, y);
- }
-
- /**
- * Moves the end handle so that it points at the given coordinates.
- * @param x The end handle position X in physical pixels.
- * @param y The end handle position Y in physical pixels.
- */
- void setEndHandlePosition(float x, float y) {
- setEndHandlePosition((int) x, (int) y);
+ public void setEndHandlePosition(float x, float y) {
+ mEndHandle.positionAt((int) x, (int) y);
}
/**
* If the handles are not visible, sets their visibility to View.VISIBLE and begins fading them
* in.
*/
- void beginHandleFadeIn() {
+ public void beginHandleFadeIn() {
mStartHandle.beginFadeIn();
mEndHandle.beginFadeIn();
}
@@ -164,7 +145,7 @@
/**
* Sets the start and end handles to the given visibility.
*/
- void setHandleVisibility(int visibility) {
+ public void setHandleVisibility(int visibility) {
mStartHandle.setVisibility(visibility);
mEndHandle.setVisibility(visibility);
}
@@ -175,7 +156,7 @@
* @param startDir Direction (left/right) of start handle.
* @param endDir Direction (left/right) of end handle.
*/
- void onSelectionChanged(int startDir, int endDir) {
+ public void onSelectionChanged(int startDir, int endDir) {
if (mAllowAutomaticShowing) {
showHandles(startDir, endDir);
}
@@ -189,7 +170,7 @@
* @param startDir Direction (left/right) of start handle.
* @param endDir Direction (left/right) of end handle.
*/
- void showHandles(int startDir, int endDir) {
+ public void showHandles(int startDir, int endDir) {
createHandlesIfNeeded(startDir, endDir);
showHandlesIfNeeded();
}
diff --git a/content/public/android/java/src/org/chromium/content/common/CommandLine.java b/content/public/android/java/src/org/chromium/content/common/CommandLine.java
index 32ae2cd..83cb348 100644
--- a/content/public/android/java/src/org/chromium/content/common/CommandLine.java
+++ b/content/public/android/java/src/org/chromium/content/common/CommandLine.java
@@ -67,6 +67,9 @@
// How much of the top controls need to be hidden before they will auto hide.
public static final String TOP_CONTROLS_HIDE_THRESHOLD = "top-controls-hide-threshold";
+ // Native switch - chrome_switches::kEnableInstantExtendedAPI
+ public static final String ENABLE_INSTANT_EXTENDED_API = "enable-instant-extended-api";
+
// Public abstract interface, implemented in derived classes.
// All these methods reflect their native-side counterparts.
/**
diff --git a/content/public/android/java/src/org/chromium/content/common/PerfTraceEvent.java b/content/public/android/java/src/org/chromium/content/common/PerfTraceEvent.java
index 11e24b9..6516efa 100644
--- a/content/public/android/java/src/org/chromium/content/common/PerfTraceEvent.java
+++ b/content/public/android/java/src/org/chromium/content/common/PerfTraceEvent.java
@@ -48,7 +48,7 @@
INSTANT("I");
// The string understood by the trace scripts.
- private String mTypeStr;
+ private final String mTypeStr;
EventType(String typeStr) {
mTypeStr = typeStr;
@@ -82,7 +82,7 @@
*
* @param strings Event names we will record.
*/
- public static void setFilter(List<String> strings) {
+ public static synchronized void setFilter(List<String> strings) {
sFilter = new LinkedList<String>(strings);
}
@@ -143,7 +143,7 @@
* It is safe to call trace methods without checking if PerfTraceEvent
* is enabled.
*/
- public static boolean enabled() {
+ public static synchronized boolean enabled() {
return sEnabled;
}
@@ -333,7 +333,7 @@
* @param file Which file to append the performance data to. If {@code null}, the performance
* data will be sent to STDOUT.
*/
- public static void setOutputFile(File file) {
+ public static synchronized void setOutputFile(File file) {
sOutputFile = file;
}
diff --git a/content/public/android/java/src/org/chromium/content/common/SurfaceTextureListener.java b/content/public/android/java/src/org/chromium/content/common/SurfaceTextureListener.java
deleted file mode 100644
index d6ed16f..0000000
--- a/content/public/android/java/src/org/chromium/content/common/SurfaceTextureListener.java
+++ /dev/null
@@ -1,46 +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.
-
-package org.chromium.content.common;
-
-import android.graphics.SurfaceTexture;
-
-import org.chromium.base.CalledByNative;
-import org.chromium.base.JNINamespace;
-
-/**
- * Listener to an android SurfaceTexture object for frame availability.
- */
-@JNINamespace("content")
-class SurfaceTextureListener implements SurfaceTexture.OnFrameAvailableListener {
- // Used to determine the class instance to dispatch the native call to.
- private int mNativeSurfaceTextureListener = 0;
-
- private SurfaceTextureListener(int nativeSurfaceTextureListener) {
- assert nativeSurfaceTextureListener != 0;
- mNativeSurfaceTextureListener = nativeSurfaceTextureListener;
- }
-
- @Override
- public void onFrameAvailable(SurfaceTexture surfaceTexture) {
- nativeFrameAvailable(mNativeSurfaceTextureListener);
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- nativeDestroy(mNativeSurfaceTextureListener);
- } finally {
- super.finalize();
- }
- }
-
- @CalledByNative
- private static SurfaceTextureListener create(int nativeSurfaceTextureListener) {
- return new SurfaceTextureListener(nativeSurfaceTextureListener);
- }
-
- private native void nativeFrameAvailable(int nativeSurfaceTextureListener);
- private native void nativeDestroy(int nativeSurfaceTextureListener);
-}
diff --git a/content/public/android/java/src/org/chromium/content/common/TraceEvent.java b/content/public/android/java/src/org/chromium/content/common/TraceEvent.java
index ffd2528..2ee8114 100644
--- a/content/public/android/java/src/org/chromium/content/common/TraceEvent.java
+++ b/content/public/android/java/src/org/chromium/content/common/TraceEvent.java
@@ -74,16 +74,11 @@
try {
Class<?> traceClass = Class.forName("android.os.Trace");
long traceTagView = traceClass.getField("TRACE_TAG_VIEW").getLong(null);
- String propertyTraceTagEnableFlags = (String) traceClass.getField(
- "PROPERTY_TRACE_TAG_ENABLEFLAGS").get(null);
-
- Class<?> systemPropertiesClass = Class.forName("android.os.SystemProperties");
- Method systemPropertiesGetLongMethod = systemPropertiesClass.getDeclaredMethod(
- "getLong", String.class, Long.TYPE);
- long enabledFlags = (Long) systemPropertiesGetLongMethod.invoke(
- null, propertyTraceTagEnableFlags, 0);
- Log.d("TraceEvent", "New enabled flags: " + enabledFlags);
- if ((enabledFlags & traceTagView) != 0) {
+ Method isTagEnabledMethod = traceClass.getDeclaredMethod(
+ "isTagEnabled", Long.TYPE);
+ Boolean viewTagEnabled = (Boolean) isTagEnabledMethod.invoke(null, traceTagView);
+ Log.d("TraceEvent", "View tag enabled: " + viewTagEnabled.booleanValue());
+ if (viewTagEnabled.booleanValue()) {
nativeStartATrace();
enabled = true;
} else {
diff --git a/content/public/android/java/strings/android_content_strings.grd b/content/public/android/java/strings/android_content_strings.grd
index 26c801e..30b3853 100644
--- a/content/public/android/java/strings/android_content_strings.grd
+++ b/content/public/android/java/strings/android_content_strings.grd
@@ -56,6 +56,7 @@
</messages>
</release>
<translations>
+ <file lang="am" path="translations/android_content_strings_am.xtb" />
<file lang="ar" path="translations/android_content_strings_ar.xtb" />
<file lang="bg" path="translations/android_content_strings_bg.xtb" />
<file lang="ca" path="translations/android_content_strings_ca.xtb" />
@@ -91,6 +92,7 @@
<file lang="sl" path="translations/android_content_strings_sl.xtb" />
<file lang="sr" path="translations/android_content_strings_sr.xtb" />
<file lang="sv" path="translations/android_content_strings_sv.xtb" />
+ <file lang="sw" path="translations/android_content_strings_sw.xtb" />
<file lang="th" path="translations/android_content_strings_th.xtb" />
<file lang="tr" path="translations/android_content_strings_tr.xtb" />
<file lang="uk" path="translations/android_content_strings_uk.xtb" />
@@ -99,47 +101,49 @@
<file lang="zh-TW" path="translations/android_content_strings_zh-TW.xtb" />
</translations>
<outputs>
- <output filename="values-ar/strings.xml" lang="ar" type="android" />
- <output filename="values-bg/strings.xml" lang="bg" type="android" />
- <output filename="values-ca/strings.xml" lang="ca" type="android" />
- <output filename="values-cs/strings.xml" lang="cs" type="android" />
- <output filename="values-da/strings.xml" lang="da" type="android" />
- <output filename="values-de/strings.xml" lang="de" type="android" />
- <output filename="values-el/strings.xml" lang="el" type="android" />
- <output filename="values/strings.xml" lang="en" type="android" />
- <output filename="values-en-rGB/strings.xml" lang="en-GB" type="android" />
- <output filename="values-es/strings.xml" lang="es" type="android" />
- <output filename="values-es-rUS/strings.xml" lang="es-419" type="android" />
- <output filename="values-fa/strings.xml" lang="fa" type="android" />
- <output filename="values-fi/strings.xml" lang="fi" type="android" />
- <output filename="values-tl/strings.xml" lang="fil" type="android" />
- <output filename="values-fr/strings.xml" lang="fr" type="android" />
- <output filename="values-hi/strings.xml" lang="hi" type="android" />
- <output filename="values-hr/strings.xml" lang="hr" type="android" />
- <output filename="values-hu/strings.xml" lang="hu" type="android" />
- <output filename="values-in/strings.xml" lang="id" type="android" />
- <output filename="values-it/strings.xml" lang="it" type="android" />
- <output filename="values-iw/strings.xml" lang="iw" type="android" />
- <output filename="values-ja/strings.xml" lang="ja" type="android" />
- <output filename="values-ko/strings.xml" lang="ko" type="android" />
- <output filename="values-lt/strings.xml" lang="lt" type="android" />
- <output filename="values-lv/strings.xml" lang="lv" type="android" />
- <output filename="values-nl/strings.xml" lang="nl" type="android" />
- <output filename="values-nb/strings.xml" lang="no" type="android" />
- <output filename="values-pl/strings.xml" lang="pl" type="android" />
- <output filename="values-pt-rBR/strings.xml" lang="pt-BR" type="android" />
- <output filename="values-pt-rPT/strings.xml" lang="pt-PT" type="android" />
- <output filename="values-ro/strings.xml" lang="ro" type="android" />
- <output filename="values-ru/strings.xml" lang="ru" type="android" />
- <output filename="values-sk/strings.xml" lang="sk" type="android" />
- <output filename="values-sl/strings.xml" lang="sl" type="android" />
- <output filename="values-sr/strings.xml" lang="sr" type="android" />
- <output filename="values-sv/strings.xml" lang="sv" type="android" />
- <output filename="values-th/strings.xml" lang="th" type="android" />
- <output filename="values-tr/strings.xml" lang="tr" type="android" />
- <output filename="values-uk/strings.xml" lang="uk" type="android" />
- <output filename="values-vi/strings.xml" lang="vi" type="android" />
- <output filename="values-zh-rCN/strings.xml" lang="zh-CN" type="android" />
- <output filename="values-zh-rTW/strings.xml" lang="zh-TW" type="android" />
+ <output filename="values-am/android_content_strings.xml" lang="am" type="android" />
+ <output filename="values-ar/android_content_strings.xml" lang="ar" type="android" />
+ <output filename="values-bg/android_content_strings.xml" lang="bg" type="android" />
+ <output filename="values-ca/android_content_strings.xml" lang="ca" type="android" />
+ <output filename="values-cs/android_content_strings.xml" lang="cs" type="android" />
+ <output filename="values-da/android_content_strings.xml" lang="da" type="android" />
+ <output filename="values-de/android_content_strings.xml" lang="de" type="android" />
+ <output filename="values-el/android_content_strings.xml" lang="el" type="android" />
+ <output filename="values/android_content_strings.xml" lang="en" type="android" />
+ <output filename="values-en-rGB/android_content_strings.xml" lang="en-GB" type="android" />
+ <output filename="values-es/android_content_strings.xml" lang="es" type="android" />
+ <output filename="values-es-rUS/android_content_strings.xml" lang="es-419" type="android" />
+ <output filename="values-fa/android_content_strings.xml" lang="fa" type="android" />
+ <output filename="values-fi/android_content_strings.xml" lang="fi" type="android" />
+ <output filename="values-tl/android_content_strings.xml" lang="fil" type="android" />
+ <output filename="values-fr/android_content_strings.xml" lang="fr" type="android" />
+ <output filename="values-hi/android_content_strings.xml" lang="hi" type="android" />
+ <output filename="values-hr/android_content_strings.xml" lang="hr" type="android" />
+ <output filename="values-hu/android_content_strings.xml" lang="hu" type="android" />
+ <output filename="values-in/android_content_strings.xml" lang="id" type="android" />
+ <output filename="values-it/android_content_strings.xml" lang="it" type="android" />
+ <output filename="values-iw/android_content_strings.xml" lang="iw" type="android" />
+ <output filename="values-ja/android_content_strings.xml" lang="ja" type="android" />
+ <output filename="values-ko/android_content_strings.xml" lang="ko" type="android" />
+ <output filename="values-lt/android_content_strings.xml" lang="lt" type="android" />
+ <output filename="values-lv/android_content_strings.xml" lang="lv" type="android" />
+ <output filename="values-nl/android_content_strings.xml" lang="nl" type="android" />
+ <output filename="values-nb/android_content_strings.xml" lang="no" type="android" />
+ <output filename="values-pl/android_content_strings.xml" lang="pl" type="android" />
+ <output filename="values-pt-rBR/android_content_strings.xml" lang="pt-BR" type="android" />
+ <output filename="values-pt-rPT/android_content_strings.xml" lang="pt-PT" type="android" />
+ <output filename="values-ro/android_content_strings.xml" lang="ro" type="android" />
+ <output filename="values-ru/android_content_strings.xml" lang="ru" type="android" />
+ <output filename="values-sk/android_content_strings.xml" lang="sk" type="android" />
+ <output filename="values-sl/android_content_strings.xml" lang="sl" type="android" />
+ <output filename="values-sr/android_content_strings.xml" lang="sr" type="android" />
+ <output filename="values-sv/android_content_strings.xml" lang="sv" type="android" />
+ <output filename="values-sw/android_content_strings.xml" lang="sw" type="android" />
+ <output filename="values-th/android_content_strings.xml" lang="th" type="android" />
+ <output filename="values-tr/android_content_strings.xml" lang="tr" type="android" />
+ <output filename="values-uk/android_content_strings.xml" lang="uk" type="android" />
+ <output filename="values-vi/android_content_strings.xml" lang="vi" type="android" />
+ <output filename="values-zh-rCN/android_content_strings.xml" lang="zh-CN" type="android" />
+ <output filename="values-zh-rTW/android_content_strings.xml" lang="zh-TW" type="android" />
</outputs>
-</grit>
\ No newline at end of file
+</grit>
diff --git a/content/public/android/java/strings/translations/android_content_strings_am.xtb b/content/public/android/java/strings/translations/android_content_strings_am.xtb
new file mode 100644
index 0000000..cc8a0c3
--- /dev/null
+++ b/content/public/android/java/strings/translations/android_content_strings_am.xtb
@@ -0,0 +1,21 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="am">
+<translation id="6015796118275082299">ዓመት</translation>
+<translation id="1256337885411059545">ቪዲዮ ማጫወት አልተቻለም</translation>
+<translation id="7821540960913969614">ቀን ያዘጋጁ</translation>
+<translation id="4932733599132424254">ቀን</translation>
+<translation id="6727102863431372879">አዘጋጅ</translation>
+<translation id="273860350361291195">ይቅርታ፣ ይህ ቪዲዮ ወደዚህ መሣሪያ በዥረት ለመልቀቅ ልክ የሆነ አይደለም።</translation>
+<translation id="2410828433627930127">ይቅርታ፣ ይህ ቪዲዮ ሊጫወት አልቻለም።</translation>
+<translation id="8987927404178983737">ወር</translation>
+<translation id="2532336938189706096">የድር ዕይታ</translation>
+<translation id="7096034533295549981">ቪዲዮን በመጫን ላይ</translation>
+<translation id="1542044944667958430">የድር ፍለጋ</translation>
+<translation id="6527303717912515753">አጋራ</translation>
+<translation id="2841013758207633010">ሰዓት</translation>
+<translation id="6643016212128521049">አጽዳ</translation>
+<translation id="7781164152564914424">ወር ያዘጋጁ</translation>
+<translation id="6965382102122355670">ይሁን</translation>
+<translation id="6444070574980481588">ቀን እና ሰዓት ያዘጋጁ</translation>
+</translationbundle>
\ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_ar.xtb b/content/public/android/java/strings/translations/android_content_strings_ar.xtb
index 5c4cfce..e9615ba 100644
--- a/content/public/android/java/strings/translations/android_content_strings_ar.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_ar.xtb
@@ -1,14 +1,14 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ar">
-<translation id="6015796118275082299">عام</translation>
+<translation id="6015796118275082299">السنة</translation>
<translation id="1256337885411059545">لا يمكن تشغيل الفيديو</translation>
<translation id="7821540960913969614">تعيين التاريخ</translation>
<translation id="4932733599132424254">التاريخ</translation>
<translation id="6727102863431372879">تعيين</translation>
-<translation id="273860350361291195">عذرًا، هذا الفيديو غير صالح للبث على هذا الجهاز.</translation>
+<translation id="273860350361291195">عذرًا، هذا الفيديو غير صالح للبث إلى هذا الجهاز.</translation>
<translation id="2410828433627930127">عذرًا، لا يمكن تشغيل هذا الفيديو.</translation>
-<translation id="8987927404178983737">الشهر</translation>
+<translation id="8987927404178983737">شهر</translation>
<translation id="2532336938189706096">عرض الويب</translation>
<translation id="7096034533295549981">تحميل الفيديو</translation>
<translation id="1542044944667958430">بحث الويب</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_bg.xtb b/content/public/android/java/strings/translations/android_content_strings_bg.xtb
index 5815bb9..7f21d6e 100644
--- a/content/public/android/java/strings/translations/android_content_strings_bg.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_bg.xtb
@@ -6,8 +6,8 @@
<translation id="7821540960913969614">Задаване на датата</translation>
<translation id="4932733599132424254">Дата</translation>
<translation id="6727102863431372879">Задаване</translation>
-<translation id="273860350361291195">Клипът не е валиден за поточно предаване към у-вото.</translation>
-<translation id="2410828433627930127">Клипът не може да се пусне.</translation>
+<translation id="273860350361291195">За съжаление видеоклипът не е валиден за поточно предаване към устройството.</translation>
+<translation id="2410828433627930127">За съжаление видеоклипът не може да се пусне.</translation>
<translation id="8987927404178983737">Месец</translation>
<translation id="2532336938189706096">Изглед в мрежата</translation>
<translation id="7096034533295549981">Клип: Зарежда се</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_ca.xtb b/content/public/android/java/strings/translations/android_content_strings_ca.xtb
index 39923c4..10adc64 100644
--- a/content/public/android/java/strings/translations/android_content_strings_ca.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_ca.xtb
@@ -3,10 +3,10 @@
<translationbundle lang="ca">
<translation id="6015796118275082299">Any</translation>
<translation id="1256337885411059545">No es pot reproduir el vídeo</translation>
-<translation id="7821540960913969614">Establiment de la data</translation>
+<translation id="7821540960913969614">Definir la data</translation>
<translation id="4932733599132424254">Data</translation>
<translation id="6727102863431372879">Defineix</translation>
-<translation id="273860350361291195">Aquest vídeo no és vàlid per a la transmissió en aquest dispositiu.</translation>
+<translation id="273860350361291195">Aquest vídeo no és vàlid per a l'emissió en aquest dispositiu.</translation>
<translation id="2410828433627930127">No es pot reproduir aquest vídeo.</translation>
<translation id="8987927404178983737">Mes</translation>
<translation id="2532336938189706096">Visualització web</translation>
@@ -15,7 +15,7 @@
<translation id="6527303717912515753">Comparteix</translation>
<translation id="2841013758207633010">Hora</translation>
<translation id="6643016212128521049">Esborra</translation>
-<translation id="7781164152564914424">Establiment de mes</translation>
+<translation id="7781164152564914424">Definir el mes</translation>
<translation id="6965382102122355670">D'acord</translation>
-<translation id="6444070574980481588">Establiment de data i d'hora</translation>
+<translation id="6444070574980481588">Definir la data i l'hora</translation>
</translationbundle>
\ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_cs.xtb b/content/public/android/java/strings/translations/android_content_strings_cs.xtb
index b6f3407..489539f 100644
--- a/content/public/android/java/strings/translations/android_content_strings_cs.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_cs.xtb
@@ -6,9 +6,9 @@
<translation id="7821540960913969614">Nastavení data</translation>
<translation id="4932733599132424254">Datum</translation>
<translation id="6727102863431372879">Nastavit</translation>
-<translation id="273860350361291195">Video do zař. nelze streamovat.</translation>
+<translation id="273860350361291195">Video do zařizení nelze streamovat.</translation>
<translation id="2410828433627930127">Toto video nelze přehrát.</translation>
-<translation id="8987927404178983737">Měsíc</translation>
+<translation id="8987927404178983737">měsíc</translation>
<translation id="2532336938189706096">Webové zobrazení</translation>
<translation id="7096034533295549981">Načítání videa</translation>
<translation id="1542044944667958430">Vyhledávání na webu</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_da.xtb b/content/public/android/java/strings/translations/android_content_strings_da.xtb
index f6aaa2c..b4a8951 100644
--- a/content/public/android/java/strings/translations/android_content_strings_da.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_da.xtb
@@ -5,7 +5,7 @@
<translation id="1256337885411059545">Videoen kan ikke afspilles</translation>
<translation id="7821540960913969614">Indstil dato</translation>
<translation id="4932733599132424254">Dato</translation>
-<translation id="6727102863431372879">Angiv</translation>
+<translation id="6727102863431372879">Indstil</translation>
<translation id="273860350361291195">Denne video er ikke gyldig til streaming på denne enhed.</translation>
<translation id="2410828433627930127">Denne video kan ikke afspilles.</translation>
<translation id="8987927404178983737">Måned</translation>
@@ -13,7 +13,7 @@
<translation id="7096034533295549981">Indlæser video</translation>
<translation id="1542044944667958430">Websøgning</translation>
<translation id="6527303717912515753">Del</translation>
-<translation id="2841013758207633010">Tid</translation>
+<translation id="2841013758207633010">Tidspunkt</translation>
<translation id="6643016212128521049">Ryd</translation>
<translation id="7781164152564914424">Angiv måned</translation>
<translation id="6965382102122355670">OK</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_de.xtb b/content/public/android/java/strings/translations/android_content_strings_de.xtb
index f14eb37..d8f5250 100644
--- a/content/public/android/java/strings/translations/android_content_strings_de.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_de.xtb
@@ -5,7 +5,7 @@
<translation id="1256337885411059545">Videowiedergabe nicht möglich</translation>
<translation id="7821540960913969614">Datum festlegen</translation>
<translation id="4932733599132424254">Datum</translation>
-<translation id="6727102863431372879">Festlegen</translation>
+<translation id="6727102863431372879">Übernehmen</translation>
<translation id="273860350361291195">Dieses Video ist zum Streaming auf diesem Gerät ungültig.</translation>
<translation id="2410828433627930127">Videowiedergabe nicht möglich</translation>
<translation id="8987927404178983737">Monat</translation>
@@ -13,7 +13,7 @@
<translation id="7096034533295549981">Lädt Video...</translation>
<translation id="1542044944667958430">Websuche</translation>
<translation id="6527303717912515753">Teilen</translation>
-<translation id="2841013758207633010">Zeit</translation>
+<translation id="2841013758207633010">Uhrzeit</translation>
<translation id="6643016212128521049">Löschen</translation>
<translation id="7781164152564914424">Monat einstellen</translation>
<translation id="6965382102122355670">OK</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_es-419.xtb b/content/public/android/java/strings/translations/android_content_strings_es-419.xtb
index da571d8..f7b8849 100644
--- a/content/public/android/java/strings/translations/android_content_strings_es-419.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_es-419.xtb
@@ -5,8 +5,8 @@
<translation id="1256337885411059545">No se puede reproducir el video.</translation>
<translation id="7821540960913969614">Establecer una fecha</translation>
<translation id="4932733599132424254">Fecha</translation>
-<translation id="6727102863431372879">Configurar</translation>
-<translation id="273860350361291195">Error al transmitir video</translation>
+<translation id="6727102863431372879">Establecer</translation>
+<translation id="273860350361291195">El video no se puede transmitir a este dispositivo.</translation>
<translation id="2410828433627930127">El video no se puede reproducir.</translation>
<translation id="8987927404178983737">Mes</translation>
<translation id="2532336938189706096">Vista web</translation>
@@ -15,7 +15,7 @@
<translation id="6527303717912515753">Compartir</translation>
<translation id="2841013758207633010">Hora</translation>
<translation id="6643016212128521049">Borrar</translation>
-<translation id="7781164152564914424">Configurar el mes</translation>
+<translation id="7781164152564914424">Establecer el mes</translation>
<translation id="6965382102122355670">Aceptar</translation>
-<translation id="6444070574980481588">Configurar fecha y hora</translation>
+<translation id="6444070574980481588">Establecer fecha y hora</translation>
</translationbundle>
\ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_es.xtb b/content/public/android/java/strings/translations/android_content_strings_es.xtb
index ea53af9..afde6de 100644
--- a/content/public/android/java/strings/translations/android_content_strings_es.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_es.xtb
@@ -6,15 +6,15 @@
<translation id="7821540960913969614">Definir fecha</translation>
<translation id="4932733599132424254">Fecha</translation>
<translation id="6727102863431372879">Establecer</translation>
-<translation id="273860350361291195">Error al transmitir vídeo</translation>
-<translation id="2410828433627930127">El vídeo no se puede reproducir.</translation>
+<translation id="273860350361291195">Este vídeo no se puede reproducir en este dispositivo.</translation>
+<translation id="2410828433627930127">Este vídeo no se puede reproducir.</translation>
<translation id="8987927404178983737">Mes</translation>
<translation id="2532336938189706096">Vista web</translation>
<translation id="7096034533295549981">Cargando vídeo...</translation>
<translation id="1542044944667958430">Búsqueda web</translation>
<translation id="6527303717912515753">Compartir</translation>
-<translation id="2841013758207633010">Hora</translation>
-<translation id="6643016212128521049">Eliminar</translation>
+<translation id="2841013758207633010">Tiempo</translation>
+<translation id="6643016212128521049">Borrar</translation>
<translation id="7781164152564914424">Establecer mes</translation>
<translation id="6965382102122355670">Aceptar</translation>
<translation id="6444070574980481588">Establecer fecha y hora</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_fa.xtb b/content/public/android/java/strings/translations/android_content_strings_fa.xtb
index 2bf23c4..8266b88 100644
--- a/content/public/android/java/strings/translations/android_content_strings_fa.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_fa.xtb
@@ -2,17 +2,17 @@
<!DOCTYPE translationbundle>
<translationbundle lang="fa">
<translation id="6015796118275082299">سال</translation>
-<translation id="1256337885411059545">نمیتوان ویدئو پخش کرد</translation>
+<translation id="1256337885411059545">نمیتوان ویدیو پخش کرد</translation>
<translation id="7821540960913969614">تنظیم تاریخ</translation>
<translation id="4932733599132424254">تاریخ</translation>
<translation id="6727102863431372879">تنظیم</translation>
-<translation id="273860350361291195">متأسفیم، این ویدئو برای پخش جریانی بااین دستگاه معتبر نیست.</translation>
-<translation id="2410828433627930127">متأسفیم، این ویدئو پخش نمیشود.</translation>
+<translation id="273860350361291195">متأسفانه، این ویدیو برای پخش در این دستگاه معتبر نیست.</translation>
+<translation id="2410828433627930127">متأسفانه، این ویدیو قابل پخش نیست.</translation>
<translation id="8987927404178983737">ماه</translation>
<translation id="2532336938189706096">بازدید از وب</translation>
<translation id="7096034533295549981">بارگیری ویدیو</translation>
<translation id="1542044944667958430">جستجوی وب</translation>
-<translation id="6527303717912515753">اشتراکگذاری</translation>
+<translation id="6527303717912515753">اشتراکگذاری</translation>
<translation id="2841013758207633010">زمان</translation>
<translation id="6643016212128521049">پاک کردن</translation>
<translation id="7781164152564914424">تنظیم ماه</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_fil.xtb b/content/public/android/java/strings/translations/android_content_strings_fil.xtb
index 9d225c5..ffeb50a 100644
--- a/content/public/android/java/strings/translations/android_content_strings_fil.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_fil.xtb
@@ -6,8 +6,8 @@
<translation id="7821540960913969614">Magtakda ng petsa</translation>
<translation id="4932733599132424254">Petsa</translation>
<translation id="6727102863431372879">Itakda</translation>
-<translation id="273860350361291195">Paumnhn,d wsto strmng dvce vdeo.</translation>
-<translation id="2410828433627930127">Paumanhin, di ma-play video ito.</translation>
+<translation id="273860350361291195">Paumanhin, di-wasto ang video para sa pag-stream sa device na ito.</translation>
+<translation id="2410828433627930127">Paumanhin, hindi mape-play ang video na ito.</translation>
<translation id="8987927404178983737">Buwan</translation>
<translation id="2532336938189706096">View ng Web</translation>
<translation id="7096034533295549981">Nilo-load video</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_hi.xtb b/content/public/android/java/strings/translations/android_content_strings_hi.xtb
index 9df7a31..955e22f 100644
--- a/content/public/android/java/strings/translations/android_content_strings_hi.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_hi.xtb
@@ -6,8 +6,8 @@
<translation id="7821540960913969614">दिनांक सेट करें</translation>
<translation id="4932733599132424254">दिनांक</translation>
<translation id="6727102863431372879">सेट करें</translation>
-<translation id="273860350361291195">उपकरण पर वीडियो स्ट्रीम अमान्य.</translation>
-<translation id="2410828433627930127">यह वीडियो नहीं चलाया जा सकता.</translation>
+<translation id="273860350361291195">क्षमा करें, यह वीडियो इस उपकरण पर स्ट्रीम करने के लिए मान्य नहीं है.</translation>
+<translation id="2410828433627930127">क्षमा करें, यह वीडियो नहीं चलाया जा सकता.</translation>
<translation id="8987927404178983737">माह</translation>
<translation id="2532336938189706096">वेब दृश्य</translation>
<translation id="7096034533295549981">वीडियो लोड हो रहा है</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_hr.xtb b/content/public/android/java/strings/translations/android_content_strings_hr.xtb
index fbb6b66..027da65 100644
--- a/content/public/android/java/strings/translations/android_content_strings_hr.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_hr.xtb
@@ -6,8 +6,8 @@
<translation id="7821540960913969614">Postavite datum</translation>
<translation id="4932733599132424254">Datum</translation>
<translation id="6727102863431372879">Postavi</translation>
-<translation id="273860350361291195">Video nije valjan za str. na ur.</translation>
-<translation id="2410828433627930127">Videoz. nije moguće reproducir.</translation>
+<translation id="273860350361291195">Video nije valjan za strujanje na uređaj.</translation>
+<translation id="2410828433627930127">Nije moguće reproducirati taj videozapis.</translation>
<translation id="8987927404178983737">Mjesec</translation>
<translation id="2532336938189706096">Web-prikaz</translation>
<translation id="7096034533295549981">Učitavanje videa</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_id.xtb b/content/public/android/java/strings/translations/android_content_strings_id.xtb
index beda171..09ce365 100644
--- a/content/public/android/java/strings/translations/android_content_strings_id.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_id.xtb
@@ -12,7 +12,7 @@
<translation id="2532336938189706096">Tampilan Web</translation>
<translation id="7096034533295549981">Memuat video</translation>
<translation id="1542044944667958430">Penelusuran web</translation>
-<translation id="6527303717912515753">Bagikan</translation>
+<translation id="6527303717912515753">Berbagi</translation>
<translation id="2841013758207633010">Waktu</translation>
<translation id="6643016212128521049">Hapus</translation>
<translation id="7781164152564914424">Setel bulan</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_it.xtb b/content/public/android/java/strings/translations/android_content_strings_it.xtb
index b4854bb..086a3db 100644
--- a/content/public/android/java/strings/translations/android_content_strings_it.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_it.xtb
@@ -13,7 +13,7 @@
<translation id="7096034533295549981">Caricamento video</translation>
<translation id="1542044944667958430">Ricerca Google</translation>
<translation id="6527303717912515753">Condividi</translation>
-<translation id="2841013758207633010">Ora</translation>
+<translation id="2841013758207633010">Data/ora</translation>
<translation id="6643016212128521049">Cancella</translation>
<translation id="7781164152564914424">Imposta mese</translation>
<translation id="6965382102122355670">OK</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_ja.xtb b/content/public/android/java/strings/translations/android_content_strings_ja.xtb
index 8205ed0..48a2d03 100644
--- a/content/public/android/java/strings/translations/android_content_strings_ja.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_ja.xtb
@@ -6,15 +6,15 @@
<translation id="7821540960913969614">日付の設定</translation>
<translation id="4932733599132424254">日付</translation>
<translation id="6727102863431372879">設定</translation>
-<translation id="273860350361291195">この動画はご使用の端末ではストリーミングできません。</translation>
+<translation id="273860350361291195">この動画はご使用のデバイスではストリーミングできません。</translation>
<translation id="2410828433627930127">この動画は再生できません。</translation>
<translation id="8987927404178983737">月</translation>
<translation id="2532336938189706096">ウェブ表示</translation>
<translation id="7096034533295549981">動画を読み込み中</translation>
<translation id="1542044944667958430">ウェブ検索</translation>
<translation id="6527303717912515753">共有</translation>
-<translation id="2841013758207633010">時間</translation>
-<translation id="6643016212128521049">消去</translation>
+<translation id="2841013758207633010">時刻</translation>
+<translation id="6643016212128521049">クリア</translation>
<translation id="7781164152564914424">月の設定</translation>
<translation id="6965382102122355670">OK</translation>
<translation id="6444070574980481588">日時の設定</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_lt.xtb b/content/public/android/java/strings/translations/android_content_strings_lt.xtb
index eb559ab..06603f9 100644
--- a/content/public/android/java/strings/translations/android_content_strings_lt.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_lt.xtb
@@ -6,8 +6,8 @@
<translation id="7821540960913969614">Nustatykite datą</translation>
<translation id="4932733599132424254">Data</translation>
<translation id="6727102863431372879">Nustatyti</translation>
-<translation id="273860350361291195">Deja, šis vaizdo įrašas netinka perduoti srautu į šį įrenginį.</translation>
-<translation id="2410828433627930127">Vaizdo įrašo paleisti nepavyksta</translation>
+<translation id="273860350361291195">Apgailestaujame, šis vaizdo įrašas yra netinkamas perduoti srautu į šį įrenginį.</translation>
+<translation id="2410828433627930127">Apgailestaujame, šis vaizdo įrašas negali būti paleistas.</translation>
<translation id="8987927404178983737">Mėnuo</translation>
<translation id="2532336938189706096">Žiniatinklio rodinys</translation>
<translation id="7096034533295549981">Įkel. v. įrašas</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_lv.xtb b/content/public/android/java/strings/translations/android_content_strings_lv.xtb
index 49917d9..17b6175 100644
--- a/content/public/android/java/strings/translations/android_content_strings_lv.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_lv.xtb
@@ -2,12 +2,12 @@
<!DOCTYPE translationbundle>
<translationbundle lang="lv">
<translation id="6015796118275082299">Gads</translation>
-<translation id="1256337885411059545">Nevar demonstrēt videoklipu</translation>
+<translation id="1256337885411059545">Nevar demonstrēt videoklipu.</translation>
<translation id="7821540960913969614">Datuma iestatīšana</translation>
<translation id="4932733599132424254">Datums</translation>
<translation id="6727102863431372879">Iestatīt</translation>
-<translation id="273860350361291195">Šo video nevar straumēt ierīcē.</translation>
-<translation id="2410828433627930127">Šo video nevar demonstrēt.</translation>
+<translation id="273860350361291195">Diemžēl šo videoklipu nevar straumēt šajā ierīcē.</translation>
+<translation id="2410828433627930127">Diemžēl šo videoklipu nevar demonstrēt.</translation>
<translation id="8987927404178983737">Mēnesis</translation>
<translation id="2532336938189706096">Tīmekļa skatījums</translation>
<translation id="7096034533295549981">Video ielāde</translation>
@@ -15,7 +15,7 @@
<translation id="6527303717912515753">Kopīgot</translation>
<translation id="2841013758207633010">Laiks</translation>
<translation id="6643016212128521049">Notīrīt</translation>
-<translation id="7781164152564914424">Iestatīt mēnesi</translation>
+<translation id="7781164152564914424">Mēneša iestatīšana</translation>
<translation id="6965382102122355670">Labi</translation>
-<translation id="6444070574980481588">Iestatīt datumu un laiku</translation>
+<translation id="6444070574980481588">Datuma un laika iestatīšana</translation>
</translationbundle>
\ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_no.xtb b/content/public/android/java/strings/translations/android_content_strings_no.xtb
index 1847d96..c3efd81 100644
--- a/content/public/android/java/strings/translations/android_content_strings_no.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_no.xtb
@@ -6,7 +6,7 @@
<translation id="7821540960913969614">Angi dato</translation>
<translation id="4932733599132424254">Dato</translation>
<translation id="6727102863431372879">Angi</translation>
-<translation id="273860350361291195">Videoen er ikke gyldig for direkteavsp. på enheten.</translation>
+<translation id="273860350361291195">Videoen er ikke gyldig for direkteavspilling på enheten.</translation>
<translation id="2410828433627930127">Videoen kan ikke spilles av.</translation>
<translation id="8987927404178983737">Måned</translation>
<translation id="2532336938189706096">Nettvisning</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_pl.xtb b/content/public/android/java/strings/translations/android_content_strings_pl.xtb
index 2ad7806..04efc58 100644
--- a/content/public/android/java/strings/translations/android_content_strings_pl.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_pl.xtb
@@ -2,12 +2,12 @@
<!DOCTYPE translationbundle>
<translationbundle lang="pl">
<translation id="6015796118275082299">Rok</translation>
-<translation id="1256337885411059545">Nie można odtworzyć filmu.</translation>
+<translation id="1256337885411059545">Nie można odtworzyć filmu</translation>
<translation id="7821540960913969614">Ustaw datę</translation>
<translation id="4932733599132424254">Data</translation>
<translation id="6727102863431372879">Ustaw</translation>
-<translation id="273860350361291195">Przepraszamy, ten film nie nadaje się do strumieniowego przesyłania do tego urządzenia.</translation>
-<translation id="2410828433627930127">Niestety, nie można odtworzyć tego filmu.</translation>
+<translation id="273860350361291195">Ten film nie nadaje się do strumieniowego przesyłania do tego urządzenia.</translation>
+<translation id="2410828433627930127">Nie można odtworzyć tego filmu.</translation>
<translation id="8987927404178983737">Miesiąc</translation>
<translation id="2532336938189706096">Widok sieci</translation>
<translation id="7096034533295549981">Wczytuję film</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_pt-BR.xtb b/content/public/android/java/strings/translations/android_content_strings_pt-BR.xtb
index c7e5410..7643b5e 100644
--- a/content/public/android/java/strings/translations/android_content_strings_pt-BR.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_pt-BR.xtb
@@ -11,7 +11,7 @@
<translation id="8987927404178983737">Mês</translation>
<translation id="2532336938189706096">Visualização da Web</translation>
<translation id="7096034533295549981">Carregando vídeo</translation>
-<translation id="1542044944667958430">Pesquisa na web</translation>
+<translation id="1542044944667958430">Pesquisa na Web</translation>
<translation id="6527303717912515753">Compartilhar</translation>
<translation id="2841013758207633010">Tempo</translation>
<translation id="6643016212128521049">Limpar</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_pt-PT.xtb b/content/public/android/java/strings/translations/android_content_strings_pt-PT.xtb
index f8ed30b..0f8206b 100644
--- a/content/public/android/java/strings/translations/android_content_strings_pt-PT.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_pt-PT.xtb
@@ -6,14 +6,14 @@
<translation id="7821540960913969614">Definir data</translation>
<translation id="4932733599132424254">Data</translation>
<translation id="6727102863431372879">Definir</translation>
-<translation id="273860350361291195">Lamentamos, este vídeo não é válido para transmissão em fluxo contínuo neste aparelho.</translation>
-<translation id="2410828433627930127">Lamentamos, não é possível reproduzir este vídeo.</translation>
+<translation id="273860350361291195">Lamentamos, este vídeo não é válido para transmissão em fluxo contínuo neste dispositivo.</translation>
+<translation id="2410828433627930127">Lamentamos, mas não é possível reproduzir este vídeo.</translation>
<translation id="8987927404178983737">Mês</translation>
<translation id="2532336938189706096">Visualização na Web</translation>
<translation id="7096034533295549981">A carregar vídeo</translation>
<translation id="1542044944667958430">Pesquisa Web</translation>
<translation id="6527303717912515753">Partilhar</translation>
-<translation id="2841013758207633010">Tempo</translation>
+<translation id="2841013758207633010">Hora</translation>
<translation id="6643016212128521049">Limpar</translation>
<translation id="7781164152564914424">Definir mês</translation>
<translation id="6965382102122355670">OK</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_ro.xtb b/content/public/android/java/strings/translations/android_content_strings_ro.xtb
index db352c1..9329a5c 100644
--- a/content/public/android/java/strings/translations/android_content_strings_ro.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_ro.xtb
@@ -1,20 +1,20 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ro">
-<translation id="6015796118275082299">An</translation>
+<translation id="6015796118275082299">Anul</translation>
<translation id="1256337885411059545">Nu se poate reda videoclipul</translation>
<translation id="7821540960913969614">Setați data</translation>
-<translation id="4932733599132424254">Dată</translation>
+<translation id="4932733599132424254">Data</translation>
<translation id="6727102863431372879">Setați</translation>
-<translation id="273860350361291195">Video nevalid pt. flux dispoz.</translation>
-<translation id="2410828433627930127">Acest clip nu poate fi redat.</translation>
-<translation id="8987927404178983737">Lună</translation>
+<translation id="273860350361291195">Videoclipul nu este valid pentru fluxul către acest dispozitiv.</translation>
+<translation id="2410828433627930127">Ne pare rău, acest videoclip nu poate fi redat.</translation>
+<translation id="8987927404178983737">Luna</translation>
<translation id="2532336938189706096">Vizualizare pe web</translation>
<translation id="7096034533295549981">Încărcare video</translation>
<translation id="1542044944667958430">Căutare pe web</translation>
-<translation id="6527303717912515753">Distribuiți</translation>
-<translation id="2841013758207633010">Oră</translation>
-<translation id="6643016212128521049">Goliți</translation>
+<translation id="6527303717912515753">Trimiteți</translation>
+<translation id="2841013758207633010">Ora</translation>
+<translation id="6643016212128521049">Ștergeţi</translation>
<translation id="7781164152564914424">Setați luna</translation>
<translation id="6965382102122355670">OK</translation>
<translation id="6444070574980481588">Setați data și ora</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_ru.xtb b/content/public/android/java/strings/translations/android_content_strings_ru.xtb
index d4dd3f7..6027b0a 100644
--- a/content/public/android/java/strings/translations/android_content_strings_ru.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_ru.xtb
@@ -5,17 +5,17 @@
<translation id="1256337885411059545">Не удается воспроизвести видео</translation>
<translation id="7821540960913969614">Установка даты</translation>
<translation id="4932733599132424254">Дата</translation>
-<translation id="6727102863431372879">Применить</translation>
-<translation id="273860350361291195">Невозможно воспроизвести видео.</translation>
+<translation id="6727102863431372879">Установить</translation>
+<translation id="273860350361291195">Невозможно воспроизвести видео на этом устройстве.</translation>
<translation id="2410828433627930127">Невозможно воспроизвести видео.</translation>
<translation id="8987927404178983737">Месяц</translation>
<translation id="2532336938189706096">Веб-версия</translation>
<translation id="7096034533295549981">Загрузка видео…</translation>
-<translation id="1542044944667958430">Результаты веб-поиска</translation>
+<translation id="1542044944667958430">Веб-поиск</translation>
<translation id="6527303717912515753">Поделиться</translation>
<translation id="2841013758207633010">Время</translation>
<translation id="6643016212128521049">Очистить</translation>
-<translation id="7781164152564914424">Установите месяц</translation>
+<translation id="7781164152564914424">Установка месяца</translation>
<translation id="6965382102122355670">ОК</translation>
-<translation id="6444070574980481588">Установите дату и время</translation>
+<translation id="6444070574980481588">Установка даты и времени</translation>
</translationbundle>
\ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_sk.xtb b/content/public/android/java/strings/translations/android_content_strings_sk.xtb
index d9832ae..73ec836 100644
--- a/content/public/android/java/strings/translations/android_content_strings_sk.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_sk.xtb
@@ -2,12 +2,12 @@
<!DOCTYPE translationbundle>
<translationbundle lang="sk">
<translation id="6015796118275082299">Rok</translation>
-<translation id="1256337885411059545">Video sa nepodarilo prehrať</translation>
+<translation id="1256337885411059545">Video sa nedá prehrať</translation>
<translation id="7821540960913969614">Nastaviť dátum</translation>
<translation id="4932733599132424254">Dátum</translation>
<translation id="6727102863431372879">Nastaviť</translation>
-<translation id="273860350361291195">Video sa nedá stream. do zariad.</translation>
-<translation id="2410828433627930127">Toto video sa nedá prehrať.</translation>
+<translation id="273860350361291195">Je nám to ľúto, ale toto video sa nedá streamovať do tohto zariadenia.</translation>
+<translation id="2410828433627930127">Je nám to ľúto, ale toto video sa nedá prehrať.</translation>
<translation id="8987927404178983737">Mesiac</translation>
<translation id="2532336938189706096">Webové zobrazenie</translation>
<translation id="7096034533295549981">Načítanie videa</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_sl.xtb b/content/public/android/java/strings/translations/android_content_strings_sl.xtb
index 9279e5c..60747f2 100644
--- a/content/public/android/java/strings/translations/android_content_strings_sl.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_sl.xtb
@@ -5,17 +5,17 @@
<translation id="1256337885411059545">Videa ni mogoče predvajati</translation>
<translation id="7821540960913969614">Nastavitev datuma</translation>
<translation id="4932733599132424254">Datum</translation>
-<translation id="6727102863431372879">Nastavi</translation>
+<translation id="6727102863431372879">Nastavitev</translation>
<translation id="273860350361291195">Ta videoposnetek ni veljaven za pretakanje v to napravo.</translation>
-<translation id="2410828433627930127">Tega videa ni mogoče predvajati.</translation>
+<translation id="2410828433627930127">Tega videoposnetka ni mogoče predvajati.</translation>
<translation id="8987927404178983737">Mesec</translation>
<translation id="2532336938189706096">Spletni pogled</translation>
<translation id="7096034533295549981">Nalaganje videa</translation>
<translation id="1542044944667958430">Spletno iskanje</translation>
-<translation id="6527303717912515753">Deli</translation>
+<translation id="6527303717912515753">Deli z drugimi</translation>
<translation id="2841013758207633010">Čas</translation>
-<translation id="6643016212128521049">Izbriši</translation>
+<translation id="6643016212128521049">Počisti</translation>
<translation id="7781164152564914424">Nastavitev meseca</translation>
<translation id="6965382102122355670">V redu</translation>
-<translation id="6444070574980481588">Nastavitev datuma in ure</translation>
+<translation id="6444070574980481588">Nastavitev datuma in časa</translation>
</translationbundle>
\ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_sr.xtb b/content/public/android/java/strings/translations/android_content_strings_sr.xtb
index c668169..6d1aed7 100644
--- a/content/public/android/java/strings/translations/android_content_strings_sr.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_sr.xtb
@@ -6,7 +6,7 @@
<translation id="7821540960913969614">Подешавање датума</translation>
<translation id="4932733599132424254">Датум</translation>
<translation id="6727102863431372879">Подеси</translation>
-<translation id="273860350361291195">Жао нам је, овај видео није погодан за стрим. на овај уређ.</translation>
+<translation id="273860350361291195">Жао нам је, овај видео није погодан за стриминг на овом уређају.</translation>
<translation id="2410828433627930127">Жао нам је, овај видео не може да се пусти.</translation>
<translation id="8987927404178983737">Месец</translation>
<translation id="2532336938189706096">Веб-приказ</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_sv.xtb b/content/public/android/java/strings/translations/android_content_strings_sv.xtb
index 414f66b..bb46f23 100644
--- a/content/public/android/java/strings/translations/android_content_strings_sv.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_sv.xtb
@@ -5,16 +5,16 @@
<translation id="1256337885411059545">Det går inte att spela upp video</translation>
<translation id="7821540960913969614">Ange datum</translation>
<translation id="4932733599132424254">Datum</translation>
-<translation id="6727102863431372879">Spara</translation>
-<translation id="273860350361291195">Videon kan inte spelas upp.</translation>
-<translation id="2410828433627930127">Videon kan inte spelas upp.</translation>
+<translation id="6727102863431372879">Ange</translation>
+<translation id="273860350361291195">Det går tyvärr inte att spela upp videon direkt på den här enheten.</translation>
+<translation id="2410828433627930127">Det går tyvärr inte att spela upp den här videon.</translation>
<translation id="8987927404178983737">Månad</translation>
<translation id="2532336938189706096">Webbvy</translation>
<translation id="7096034533295549981">Videon läses in</translation>
<translation id="1542044944667958430">Webbsökning</translation>
<translation id="6527303717912515753">Dela</translation>
<translation id="2841013758207633010">Tid</translation>
-<translation id="6643016212128521049">Ta bort</translation>
+<translation id="6643016212128521049">Rensa</translation>
<translation id="7781164152564914424">Ange månad</translation>
<translation id="6965382102122355670">OK</translation>
<translation id="6444070574980481588">Ange datum och tid</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_sw.xtb b/content/public/android/java/strings/translations/android_content_strings_sw.xtb
new file mode 100644
index 0000000..7ec8346
--- /dev/null
+++ b/content/public/android/java/strings/translations/android_content_strings_sw.xtb
@@ -0,0 +1,21 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sw">
+<translation id="6015796118275082299">Mwaka</translation>
+<translation id="1256337885411059545">Haiwezi kucheza video</translation>
+<translation id="7821540960913969614">Weka tarehe</translation>
+<translation id="4932733599132424254">Tarehe</translation>
+<translation id="6727102863431372879">Weka</translation>
+<translation id="273860350361291195">Samahani, video hii si halali kwa mtiririko katika kifaa hiki.</translation>
+<translation id="2410828433627930127">Samahani, video hii haiwezi kuchezwa.</translation>
+<translation id="8987927404178983737">Mwezi</translation>
+<translation id="2532336938189706096">Mwonekano wa Wavuti</translation>
+<translation id="7096034533295549981">Inapakia video</translation>
+<translation id="1542044944667958430">Tafuta kwenye wavuti</translation>
+<translation id="6527303717912515753">Shiriki</translation>
+<translation id="2841013758207633010">Wakati</translation>
+<translation id="6643016212128521049">Futa</translation>
+<translation id="7781164152564914424">Weka mwezi</translation>
+<translation id="6965382102122355670">Sawa</translation>
+<translation id="6444070574980481588">Weka tarehe na muda</translation>
+</translationbundle>
\ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_th.xtb b/content/public/android/java/strings/translations/android_content_strings_th.xtb
index d880eb0..dc83adb 100644
--- a/content/public/android/java/strings/translations/android_content_strings_th.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_th.xtb
@@ -12,7 +12,7 @@
<translation id="2532336938189706096">มุมมองเว็บ</translation>
<translation id="7096034533295549981">กำลังโหลดวิดีโอ</translation>
<translation id="1542044944667958430">ค้นเว็บ</translation>
-<translation id="6527303717912515753">แบ่งปัน</translation>
+<translation id="6527303717912515753">แชร์</translation>
<translation id="2841013758207633010">เวลา</translation>
<translation id="6643016212128521049">ล้าง</translation>
<translation id="7781164152564914424">ตั้งเดือน</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_tr.xtb b/content/public/android/java/strings/translations/android_content_strings_tr.xtb
index 1c62641..1328328 100644
--- a/content/public/android/java/strings/translations/android_content_strings_tr.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_tr.xtb
@@ -6,7 +6,7 @@
<translation id="7821540960913969614">Tarih ayarla</translation>
<translation id="4932733599132424254">Tarih</translation>
<translation id="6727102863431372879">Ayarla</translation>
-<translation id="273860350361291195">Bu video cihaza akışla gönderilemez.</translation>
+<translation id="273860350361291195">Maalesef bu video bu cihaza akışla göndermek için uygun değil.</translation>
<translation id="2410828433627930127">Maalesef bu video oynatılamıyor.</translation>
<translation id="8987927404178983737">Ay</translation>
<translation id="2532336938189706096">Web Görüntüleme</translation>
@@ -14,7 +14,7 @@
<translation id="1542044944667958430">Web arama</translation>
<translation id="6527303717912515753">Paylaş</translation>
<translation id="2841013758207633010">Zaman</translation>
-<translation id="6643016212128521049">Temizle</translation>
+<translation id="6643016212128521049">Sil</translation>
<translation id="7781164152564914424">Ayı ayarla</translation>
<translation id="6965382102122355670">Tamam</translation>
<translation id="6444070574980481588">Tarih ve saati ayarla</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_uk.xtb b/content/public/android/java/strings/translations/android_content_strings_uk.xtb
index cff5d1b..7c0dc1e 100644
--- a/content/public/android/java/strings/translations/android_content_strings_uk.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_uk.xtb
@@ -6,13 +6,13 @@
<translation id="7821540960913969614">Установити дату</translation>
<translation id="4932733599132424254">Дата</translation>
<translation id="6727102863431372879">Установити</translation>
-<translation id="273860350361291195">Відео не можна передати на цей пристрій.</translation>
-<translation id="2410828433627930127">Це відео неможливо відтворити.</translation>
+<translation id="273860350361291195">На жаль, це відео неможливо потоково передати на цей пристрій.</translation>
+<translation id="2410828433627930127">На жаль, це відео неможливо відтворити.</translation>
<translation id="8987927404178983737">Місяць</translation>
<translation id="2532336938189706096">Веб-версія</translation>
<translation id="7096034533295549981">Завантаж. відео</translation>
<translation id="1542044944667958430">Веб-пошук</translation>
-<translation id="6527303717912515753">Поділитися</translation>
+<translation id="6527303717912515753">Надіслати</translation>
<translation id="2841013758207633010">Час</translation>
<translation id="6643016212128521049">Очистити</translation>
<translation id="7781164152564914424">Установити місяць</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_vi.xtb b/content/public/android/java/strings/translations/android_content_strings_vi.xtb
index 5f29428..55b152a 100644
--- a/content/public/android/java/strings/translations/android_content_strings_vi.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_vi.xtb
@@ -4,9 +4,9 @@
<translation id="6015796118275082299">Năm</translation>
<translation id="1256337885411059545">Không thể phát video</translation>
<translation id="7821540960913969614">Đặt ngày</translation>
-<translation id="4932733599132424254">Ngày</translation>
+<translation id="4932733599132424254">Ngày</translation>
<translation id="6727102863431372879">Đặt</translation>
-<translation id="273860350361291195">Rất tiếc, không thể phát video.</translation>
+<translation id="273860350361291195">Rất tiếc, video này không hợp lệ để phát trực tuyến sang thiết bị này.</translation>
<translation id="2410828433627930127">Rất tiếc, không thể phát video.</translation>
<translation id="8987927404178983737">Tháng</translation>
<translation id="2532336938189706096">Xem trên web</translation>
@@ -14,7 +14,7 @@
<translation id="1542044944667958430">Tìm kiếm trên web</translation>
<translation id="6527303717912515753">Chia sẻ</translation>
<translation id="2841013758207633010">Thời gian</translation>
-<translation id="6643016212128521049">Xóa</translation>
+<translation id="6643016212128521049">Xoá</translation>
<translation id="7781164152564914424">Đặt tháng</translation>
<translation id="6965382102122355670">OK</translation>
<translation id="6444070574980481588">Đặt ngày giờ</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_zh-CN.xtb b/content/public/android/java/strings/translations/android_content_strings_zh-CN.xtb
index 6d96e16..23770f9 100644
--- a/content/public/android/java/strings/translations/android_content_strings_zh-CN.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_zh-CN.xtb
@@ -1,14 +1,14 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="zh-CN">
-<translation id="6015796118275082299">年</translation>
+<translation id="6015796118275082299">年份</translation>
<translation id="1256337885411059545">无法播放视频</translation>
<translation id="7821540960913969614">设置日期</translation>
<translation id="4932733599132424254">日期</translation>
<translation id="6727102863431372879">设置</translation>
-<translation id="273860350361291195">抱歉,该视频不适合在此设备上播放。</translation>
-<translation id="2410828433627930127">很抱歉,无法播放此视频。</translation>
-<translation id="8987927404178983737">月</translation>
+<translation id="273860350361291195">抱歉,该视频无法流式传输到此设备。</translation>
+<translation id="2410828433627930127">抱歉,无法播放此视频。</translation>
+<translation id="8987927404178983737">月份</translation>
<translation id="2532336938189706096">网络视图</translation>
<translation id="7096034533295549981">正在加载视频</translation>
<translation id="1542044944667958430">网页搜索</translation>
diff --git a/content/public/android/java/strings/translations/android_content_strings_zh-TW.xtb b/content/public/android/java/strings/translations/android_content_strings_zh-TW.xtb
index e7e85c3..515979c 100644
--- a/content/public/android/java/strings/translations/android_content_strings_zh-TW.xtb
+++ b/content/public/android/java/strings/translations/android_content_strings_zh-TW.xtb
@@ -6,14 +6,14 @@
<translation id="7821540960913969614">設定日期</translation>
<translation id="4932733599132424254">日期</translation>
<translation id="6727102863431372879">設定</translation>
-<translation id="273860350361291195">很抱歉,這部影片的格式無效,因此無法在此裝置中串流播放。</translation>
+<translation id="273860350361291195">很抱歉,這部影片的格式有誤,無法透過這個裝置串流播放。</translation>
<translation id="2410828433627930127">很抱歉,無法播放這部影片。</translation>
<translation id="8987927404178983737">月</translation>
<translation id="2532336938189706096">網頁檢視</translation>
<translation id="7096034533295549981">正在載入影片</translation>
<translation id="1542044944667958430">網頁搜尋</translation>
<translation id="6527303717912515753">分享</translation>
-<translation id="2841013758207633010">時間</translation>
+<translation id="2841013758207633010">時間戳記</translation>
<translation id="6643016212128521049">清除</translation>
<translation id="7781164152564914424">設定月份</translation>
<translation id="6965382102122355670">確定</translation>
diff --git a/content/public/android/java/templates/NativeLibraries.template b/content/public/android/java/templates/NativeLibraries.template
new file mode 100644
index 0000000..a54c2c7
--- /dev/null
+++ b/content/public/android/java/templates/NativeLibraries.template
@@ -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.
+
+package org.chromium.content.app;
+
+public class NativeLibraries {
+ // This is the list of native libraries to be loaded (in the correct order)
+ // by LibraryLoader.java. The content java library is compiled with no
+ // array defined, and then the build system creates a version of the file
+ // with the real list of libraries required (which changes based upon which
+ // .apk is being built).
+ // TODO(cjhopman): This is public since it is referenced by ChromeNativeTestActivity.java
+ // directly. The two ways of library loading should be refactored into one.
+ public static String[] libraries
+#include <native_libraries_array.h>
+ ;
+}
diff --git a/content/public/android/java/templates/native_libraries_array.h b/content/public/android/java/templates/native_libraries_array.h
new file mode 100644
index 0000000..a86c574
--- /dev/null
+++ b/content/public/android/java/templates/native_libraries_array.h
@@ -0,0 +1,8 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This is a placeholder for compiling content_java. The content java library
+// is compiled with no array defined, and then the build system creates a
+// version of the file with the real list of libraries required (which changes
+// based upon which .apk is being built).
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/AddressDetectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/AddressDetectionTest.java
index 32ed9e7..ce7cfd6 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/AddressDetectionTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/AddressDetectionTest.java
@@ -6,7 +6,6 @@
import android.test.suitebuilder.annotation.MediumTest;
-import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
/**
@@ -22,14 +21,11 @@
return intentUrl.equals(expectedUrl);
}
- /*
@MediumTest
@Feature({"ContentDetection", "TabContents"})
- http://crbug.com/172786
- */
- @DisabledTest
public void testMultipleAddressesInText() throws Throwable {
startActivityWithTestUrl("content/content_detection/geo_address_multiple.html");
+ assertWaitForPageScaleFactorMatch(1.0f);
assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"),
"1600 Amphitheatre Parkway Mountain View, CA 94043"));
@@ -38,14 +34,11 @@
"76 Ninth Avenue 4th Floor New York, NY 10011"));
}
- /*
@MediumTest
@Feature({"ContentDetection", "TabContents"})
- http://crbug.com/172786
- */
- @DisabledTest
public void testSplitAddresses() throws Throwable {
startActivityWithTestUrl("content/content_detection/geo_address_split.html");
+ assertWaitForPageScaleFactorMatch(1.0f);
assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"),
"9606 North MoPac Expressway Suite 400 Austin, TX 78759"));
@@ -60,14 +53,11 @@
"1818 Library Street Suite 400, VA 20190"));
}
- /*
@MediumTest
@Feature({"ContentDetection", "TabContents"})
- http://crbug.com/172786
- */
- @DisabledTest
public void testAddressLimits() throws Throwable {
startActivityWithTestUrl("content/content_detection/geo_address_limits.html");
+ assertWaitForPageScaleFactorMatch(1.0f);
assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"),
"2590 Pearl Street Suite 100 Boulder, CO 80302"));
@@ -82,14 +72,11 @@
"1600 Amphitheatre Parkway Mountain View, CA 94043"));
}
- /*
@MediumTest
@Feature({"ContentDetection", "TabContents"})
- http://crbug.com/172786
- */
- @DisabledTest
public void testRealAddresses() throws Throwable {
startActivityWithTestUrl("content/content_detection/geo_address_real.html");
+ assertWaitForPageScaleFactorMatch(1.0f);
assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"),
"57th Street and Lake Shore Drive Chicago, IL 60637"));
@@ -104,14 +91,11 @@
"79th Street, New York, NY, 10024-5192"));
}
- /*
@MediumTest
@Feature({"ContentDetection", "TabContents"})
- http://crbug.com/172786
- */
- @DisabledTest
public void testSpecialChars() throws Throwable {
startActivityWithTestUrl("content/content_detection/geo_address_special_chars.html");
+ assertWaitForPageScaleFactorMatch(1.0f);
assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"),
"100 34th Avenue , San Francisco, CA 94121"));
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java
index 648bfde..5ee5d32 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java
@@ -10,6 +10,8 @@
import java.util.concurrent.TimeUnit;
import org.chromium.base.test.util.UrlUtils;
+import org.chromium.content.browser.test.util.Criteria;
+import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content.browser.test.util.DOMUtils;
import org.chromium.content.browser.test.util.JavaScriptUtils;
import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
@@ -94,4 +96,20 @@
TimeUnit.SECONDS);
getInstrumentation().waitForIdleSync();
}
+
+ // TODO(aelias): This method needs to be removed once http://crbug.com/179511 is fixed.
+ // Meanwhile, we have to wait if the page has the <meta viewport> tag.
+ /**
+ * Waits till the ContentViewCore receives the expected page scale factor
+ * from the compositor and asserts that this happens.
+ */
+ protected void assertWaitForPageScaleFactorMatch(final float expectedScale)
+ throws InterruptedException {
+ assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
+ @Override
+ public boolean isSatisfied() {
+ return getContentViewCore().getScale() == expectedScale;
+ }
+ }));
+ }
}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewGestureHandlerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewGestureHandlerTest.java
index 0969efb..d4a846e 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewGestureHandlerTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewGestureHandlerTest.java
@@ -5,12 +5,14 @@
package org.chromium.content.browser;
import android.content.Context;
+import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
import android.view.MotionEvent;
+import android.view.ViewConfiguration;
import org.chromium.base.test.util.Feature;
import org.chromium.content.browser.ContentViewGestureHandler.MotionEventDelegate;
@@ -92,7 +94,8 @@
}
@Override
- public boolean sendGesture(int type, long timeMs, int x, int y, Bundle extraParams) {
+ public boolean sendGesture(int type, long timeMs, int x, int y,
+ boolean lastInputEventForVSync, Bundle extraParams) {
Log.i(TAG,"Gesture event received with type id " + type);
return true;
}
@@ -184,7 +187,7 @@
mGestureHandler.hasTouchEventHandlers(true);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(1, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertTrue("Should not have a pending gesture", mMockGestureDetector.mLastEvent == null);
assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
@@ -192,36 +195,36 @@
downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(2, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
event = MotionEvent.obtain(
downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
assertTrue(mGestureHandler.onTouchEvent(event));
assertEquals("We should have coalesced move events into one"
- , 2, mGestureHandler.getNumberOfPendingMotionEvents());
+ , 2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
event = MotionEvent.obtain(
downTime, eventTime + 15, MotionEvent.ACTION_UP,
FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(3, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(3, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
mGestureHandler.confirmTouchEvent(
ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- assertEquals(2, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertEquals(MotionEvent.ACTION_MOVE,
- mGestureHandler.peekFirstInPendingMotionEvents().getActionMasked());
+ mGestureHandler.peekFirstInPendingMotionEventsForTesting().getActionMasked());
assertFalse("Pending LONG_PRESS should have been canceled",
mLongPressDetector.hasPendingMessage());
mGestureHandler.confirmTouchEvent(ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
- assertEquals(1, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertEquals(MotionEvent.ACTION_UP,
- mGestureHandler.peekFirstInPendingMotionEvents().getActionMasked());
+ mGestureHandler.peekFirstInPendingMotionEventsForTesting().getActionMasked());
mGestureHandler.confirmTouchEvent(ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
- assertEquals(0, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
// Synchronous, no need to wait.
assertTrue("Should not have a fling", mMockListener.mLastFling1 == null);
@@ -245,7 +248,7 @@
mGestureHandler.hasTouchEventHandlers(true);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(1, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertTrue("Should not have a pending gesture", mMockGestureDetector.mLastEvent == null);
assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
@@ -253,38 +256,38 @@
downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(2, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
event = MotionEvent.obtain(
downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
assertTrue(mGestureHandler.onTouchEvent(event));
assertEquals("We should have coalesced move events into one"
- , 2, mGestureHandler.getNumberOfPendingMotionEvents());
+ , 2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
event = MotionEvent.obtain(
downTime, eventTime + 15, MotionEvent.ACTION_UP,
FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(3, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(3, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
mGestureHandler.confirmTouchEvent(
ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
- assertEquals(2, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertEquals(MotionEvent.ACTION_MOVE,
- mGestureHandler.peekFirstInPendingMotionEvents().getActionMasked());
+ mGestureHandler.peekFirstInPendingMotionEventsForTesting().getActionMasked());
mGestureHandler.confirmTouchEvent(
ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- assertEquals(1, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertEquals(MotionEvent.ACTION_UP,
- mGestureHandler.peekFirstInPendingMotionEvents().getActionMasked());
+ mGestureHandler.peekFirstInPendingMotionEventsForTesting().getActionMasked());
assertTrue("Even though the last event was not consumed by JavaScript," +
"it shouldn't have been sent to the Gesture Detector",
mMockGestureDetector.mLastEvent == null);
mGestureHandler.confirmTouchEvent(ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
- assertEquals(0, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
// Synchronous, no need to wait.
assertTrue("Should not have a fling", mMockListener.mLastFling1 == null);
@@ -313,48 +316,48 @@
mGestureHandler.hasTouchEventHandlers(true);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(1, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
event = MotionEvent.obtain(
downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(2, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
event = MotionEvent.obtain(
downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(2, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
event = MotionEvent.obtain(
downTime, eventTime + 15, MotionEvent.ACTION_UP,
FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(3, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(3, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
event = motionEvent(MotionEvent.ACTION_DOWN, eventTime + 20, eventTime + 20);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(4, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(4, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
event = MotionEvent.obtain(
downTime, eventTime + 20, MotionEvent.ACTION_UP,
FAKE_COORD_X, FAKE_COORD_Y, 0);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(5, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(5, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
mGestureHandler.confirmTouchEvent(
ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
assertEquals("The queue should have been drained until first down since no consumer exists",
- 2, mGestureHandler.getNumberOfPendingMotionEvents());
+ 2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertEquals(MotionEvent.ACTION_DOWN,
- mGestureHandler.peekFirstInPendingMotionEvents().getActionMasked());
+ mGestureHandler.peekFirstInPendingMotionEventsForTesting().getActionMasked());
mGestureHandler.confirmTouchEvent(
ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
assertEquals("The queue should have been drained",
- 0, mGestureHandler.getNumberOfPendingMotionEvents());
+ 0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
}
/**
@@ -373,13 +376,13 @@
mGestureHandler.hasTouchEventHandlers(true);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(1, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertTrue("Should not have a pending gesture", mMockGestureDetector.mLastEvent == null);
assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
mGestureHandler.confirmTouchEvent(
ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- assertEquals(0, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertEquals("The down touch event should have been sent to the Gesture Detector",
event.getEventTime(), mMockGestureDetector.mLastEvent.getEventTime());
assertEquals("The down touch event should have been sent to the Gesture Detector",
@@ -389,7 +392,7 @@
downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(0, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertEquals("Motion events should be going to the Gesture Detector directly",
event.getEventTime(), mMockGestureDetector.mLastEvent.getEventTime());
assertEquals("Motion events should be going to the Gesture Detector directly",
@@ -399,7 +402,7 @@
downTime, eventTime + 10, MotionEvent.ACTION_UP,
FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(0, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertEquals("Motion events should be going to the Gesture Detector directly",
event.getEventTime(), mMockGestureDetector.mLastEvent.getEventTime());
assertEquals("Motion events should be going to the Gesture Detector directly",
@@ -425,28 +428,28 @@
mGestureHandler.hasTouchEventHandlers(true);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(1, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertTrue("Should not have a pending gesture", mMockGestureDetector.mLastEvent == null);
assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 5);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals(2, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
mGestureHandler.confirmTouchEvent(
ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- assertEquals(1, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertEquals("The down touch event should have been sent to the Gesture Detector",
event.getDownTime(), mMockGestureDetector.mLastEvent.getEventTime());
assertEquals("The next event should be ACTION_UP",
MotionEvent.ACTION_UP,
- mGestureHandler.peekFirstInPendingMotionEvents().getActionMasked());
+ mGestureHandler.peekFirstInPendingMotionEventsForTesting().getActionMasked());
mGestureHandler.confirmTouchEvent(
ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- assertEquals(0, mGestureHandler.getNumberOfPendingMotionEvents());
+ assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
assertEquals("The up touch event should have been sent to the Gesture Detector",
event.getEventTime(), mMockGestureDetector.mLastEvent.getEventTime());
@@ -487,6 +490,59 @@
}
/**
+ * Verify that for a normal fling (fling after scroll) the following events are sent:
+ * - GESTURE_SCROLL_BEGIN
+ * - GESTURE_FLING_START
+ * @throws Exception
+ */
+ @SmallTest
+ @Feature({"Gestures"})
+ public void testFlingEventSequence() throws Exception {
+ final long downTime = SystemClock.uptimeMillis();
+ final long eventTime = SystemClock.uptimeMillis();
+
+ GestureRecordingMotionEventDelegate mockDelegate =
+ new GestureRecordingMotionEventDelegate();
+ mGestureHandler = new ContentViewGestureHandler(
+ getInstrumentation().getTargetContext(), mockDelegate,
+ new MockZoomManager(getInstrumentation().getTargetContext(), null));
+
+ MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
+
+ assertTrue(mGestureHandler.onTouchEvent(event));
+
+ event = MotionEvent.obtain(
+ downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
+ FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
+ assertTrue(mGestureHandler.onTouchEvent(event));
+
+ assertTrue("A flingCancel event should have been sent",
+ mockDelegate.mGestureTypeList.contains(
+ ContentViewGestureHandler.GESTURE_FLING_CANCEL));
+ assertTrue("A scrollStart event should have been sent",
+ mockDelegate.mGestureTypeList.contains(
+ ContentViewGestureHandler.GESTURE_SCROLL_START));
+ assertEquals("We should have started scrolling",
+ ContentViewGestureHandler.GESTURE_SCROLL_BY,
+ mockDelegate.mMostRecentGestureEvent.mType);
+ assertEquals("Only flingCancel, scrollBegin and scrollBy should have been sent",
+ 3, mockDelegate.mGestureTypeList.size());
+
+ event = MotionEvent.obtain(
+ downTime, eventTime + 15, MotionEvent.ACTION_UP,
+ FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
+ assertTrue(mGestureHandler.onTouchEvent(event));
+ assertEquals("We should have started flinging",
+ ContentViewGestureHandler.GESTURE_FLING_START,
+ mockDelegate.mMostRecentGestureEvent.mType);
+ assertTrue("A scroll end event should not have been sent",
+ !mockDelegate.mGestureTypeList.contains(
+ ContentViewGestureHandler.GESTURE_SCROLL_END));
+ assertEquals("The last up should have caused flingCancel and flingStart to be sent",
+ 5, mockDelegate.mGestureTypeList.size());
+ }
+
+ /**
* Verify that a recent show pressed state gesture is canceled when scrolling begins.
* @throws Exception
*/
@@ -509,7 +565,7 @@
assertTrue(mGestureHandler.onTouchEvent(event));
assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
- mGestureHandler.sendShowPressedStateGestureForTest();
+ mGestureHandler.sendShowPressedStateGestureForTesting();
assertEquals("A show pressed state event should have been sent",
ContentViewGestureHandler.GESTURE_SHOW_PRESSED_STATE,
@@ -522,12 +578,6 @@
FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
assertTrue(mGestureHandler.onTouchEvent(event));
- // The first scroll event is ignored so submit a second one.
- event = MotionEvent.obtain(
- downTime, eventTime + 13, MotionEvent.ACTION_MOVE,
- FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
- assertTrue(mGestureHandler.onTouchEvent(event));
-
assertEquals("We should have started scrolling",
ContentViewGestureHandler.GESTURE_SCROLL_BY,
mockDelegate.mMostRecentGestureEvent.mType);
@@ -545,12 +595,11 @@
assertEquals("We should have started flinging",
ContentViewGestureHandler.GESTURE_FLING_START,
mockDelegate.mMostRecentGestureEvent.mType);
- assertTrue("A scroll end event should have been sent",
- mockDelegate.mGestureTypeList.contains(
+ assertTrue("A scroll end event should not have been sent",
+ !mockDelegate.mGestureTypeList.contains(
ContentViewGestureHandler.GESTURE_SCROLL_END));
- assertEquals(
- "The last up should have caused scrollEnd, flingCancel and flingStart to be sent",
- 8, mockDelegate.mGestureTypeList.size());
+ assertEquals("The last up should have caused flingCancel and flingStart to be sent",
+ 7, mockDelegate.mGestureTypeList.size());
}
/**
@@ -576,7 +625,7 @@
assertTrue(mGestureHandler.onTouchEvent(event));
assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
- mGestureHandler.sendShowPressedStateGestureForTest();
+ mGestureHandler.sendShowPressedStateGestureForTesting();
assertEquals("A show pressed state event should have been sent",
ContentViewGestureHandler.GESTURE_SHOW_PRESSED_STATE,
@@ -646,6 +695,7 @@
}
};
private GestureEvent mMostRecentGestureEvent;
+ private boolean mMostRecentGestureEventWasLastForVSync;
private final ArrayList<Integer> mGestureTypeList = new ArrayList<Integer>();
@Override
@@ -655,8 +705,10 @@
}
@Override
- public boolean sendGesture(int type, long timeMs, int x, int y, Bundle extraParams) {
+ public boolean sendGesture(int type, long timeMs, int x, int y,
+ boolean lastInputEventForVSync, Bundle extraParams) {
mMostRecentGestureEvent = new GestureEvent(type, timeMs, x, y, extraParams);
+ mMostRecentGestureEventWasLastForVSync = lastInputEventForVSync;
mGestureTypeList.add(mMostRecentGestureEvent.mType);
return true;
}
@@ -680,6 +732,59 @@
public GestureEvent getMostRecentGestureEvent() {
return mMostRecentGestureEvent;
}
+
+ public boolean mostRecentGestureEventForLastForVSync() {
+ return mMostRecentGestureEventWasLastForVSync;
+ }
+ }
+
+ /**
+ * Verify that the first event sent while the page is scrolling will be
+ * converted to a touchcancel. The touchcancel event should stay in the
+ * pending queue. Acking the touchcancel event will consume all the touch
+ * events of the current session.
+ */
+ @SmallTest
+ @Feature({"Gestures"})
+ public void testTouchEventsCanceledWhileScrolling() {
+ final int deltaY = 84;
+ final long downTime = SystemClock.uptimeMillis();
+
+ MockMotionEventDelegate delegate = new MockMotionEventDelegate();
+ ContentViewGestureHandler gestureHandler = new ContentViewGestureHandler(
+ getInstrumentation().getTargetContext(), delegate,
+ new MockZoomManager(getInstrumentation().getTargetContext(), null));
+ gestureHandler.hasTouchEventHandlers(true);
+ MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
+ assertTrue(gestureHandler.onTouchEvent(event));
+ gestureHandler.confirmTouchEvent(
+ ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+
+ event = MotionEvent.obtain(
+ downTime, downTime + 5, MotionEvent.ACTION_MOVE,
+ FAKE_COORD_X, FAKE_COORD_Y - deltaY / 2, 0);
+ assertTrue(gestureHandler.onTouchEvent(event));
+ gestureHandler.confirmTouchEvent(
+ ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+
+ // This event will be converted to touchcancel and put into the pending
+ // queue.
+ event = MotionEvent.obtain(
+ downTime, downTime + 10, MotionEvent.ACTION_MOVE,
+ FAKE_COORD_X, FAKE_COORD_Y - deltaY, 0);
+ assertTrue(gestureHandler.onTouchEvent(event));
+ assertEquals(1, gestureHandler.getNumberOfPendingMotionEventsForTesting());
+ assertTrue(gestureHandler.isEventCancelledForTesting(
+ gestureHandler.peekFirstInPendingMotionEventsForTesting()));
+
+ event = motionEvent(MotionEvent.ACTION_POINTER_DOWN, downTime + 15, downTime + 15);
+ assertTrue(gestureHandler.onTouchEvent(event));
+ assertEquals(2, gestureHandler.getNumberOfPendingMotionEventsForTesting());
+
+ // Acking the touchcancel will drain all the events.
+ gestureHandler.confirmTouchEvent(
+ ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ assertEquals(0, gestureHandler.getNumberOfPendingMotionEventsForTesting());
}
/**
@@ -697,7 +802,6 @@
ContentViewGestureHandler gestureHandler = new ContentViewGestureHandler(
getInstrumentation().getTargetContext(), delegate,
new MockZoomManager(getInstrumentation().getTargetContext(), null));
-
MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
assertTrue(gestureHandler.onTouchEvent(event));
assertNotNull(delegate.getMostRecentGestureEvent());
@@ -808,31 +912,98 @@
}
/**
- * Verify that the first scroll delta is ignored to avoid a jump when starting to scroll.
+ * Verify that the touch slop region is removed from the first scroll delta to avoid a jump when
+ * starting to scroll.
* @throws Exception
*/
@SmallTest
@Feature({"Gestures"})
- public void testFirstScrollDeltaIgnored() throws Exception {
+ public void testTouchSlopRemovedFromScroll() throws Exception {
+ Context context = getInstrumentation().getTargetContext();
final long downTime = SystemClock.uptimeMillis();
final long eventTime = SystemClock.uptimeMillis();
+ final int scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+ final int scrollDelta = 5;
GestureRecordingMotionEventDelegate mockDelegate =
new GestureRecordingMotionEventDelegate();
mGestureHandler = new ContentViewGestureHandler(
- getInstrumentation().getTargetContext(), mockDelegate,
- new MockZoomManager(getInstrumentation().getTargetContext(), null));
+ context, mockDelegate,
+ new MockZoomManager(context, null));
MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
assertTrue(mGestureHandler.onTouchEvent(event));
event = MotionEvent.obtain(
downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
- FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
+ FAKE_COORD_X, FAKE_COORD_Y + scaledTouchSlop + scrollDelta, 0);
assertTrue(mGestureHandler.onTouchEvent(event));
- assertEquals("We should not have started scrolling yet",
- ContentViewGestureHandler.GESTURE_FLING_CANCEL,
+ assertEquals("We should have started scrolling",
+ ContentViewGestureHandler.GESTURE_SCROLL_BY,
mockDelegate.mMostRecentGestureEvent.mType);
+
+ GestureRecordingMotionEventDelegate.GestureEvent gestureEvent =
+ mockDelegate.getMostRecentGestureEvent();
+ assertNotNull(gestureEvent);
+ Bundle extraParams = gestureEvent.getExtraParams();
+ assertEquals(0, extraParams.getInt(ContentViewGestureHandler.DISTANCE_X));
+ assertEquals(-scrollDelta, extraParams.getInt(ContentViewGestureHandler.DISTANCE_Y));
+ }
+
+ /**
+ * Verify that certain gesture events are sent with the "last for this vsync" flag set.
+ * @throws Exception
+ */
+ @SmallTest
+ @Feature({"Gestures"})
+ public void testFinalInputEventsForVSyncInterval() throws Exception {
+ Context context = getInstrumentation().getTargetContext();
+ final long downTime = SystemClock.uptimeMillis();
+ final long eventTime = SystemClock.uptimeMillis();
+ final boolean inputEventsDeliveredAtVSync =
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
+
+ GestureRecordingMotionEventDelegate mockDelegate =
+ new GestureRecordingMotionEventDelegate();
+ mGestureHandler = new ContentViewGestureHandler(
+ context, mockDelegate,
+ new MockZoomManager(context, null));
+
+ MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
+ assertTrue(mGestureHandler.onTouchEvent(event));
+ event = MotionEvent.obtain(
+ downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
+ FAKE_COORD_X, FAKE_COORD_Y + 30, 0);
+ assertTrue(mGestureHandler.onTouchEvent(event));
+ assertEquals("We should have started scrolling",
+ ContentViewGestureHandler.GESTURE_SCROLL_BY,
+ mockDelegate.mMostRecentGestureEvent.mType);
+
+ if (inputEventsDeliveredAtVSync) {
+ assertEquals("Gesture should be last for vsync",
+ true,
+ mockDelegate.mostRecentGestureEventForLastForVSync());
+ } else {
+ assertEquals("Gesture should not be last for vsync",
+ false,
+ mockDelegate.mostRecentGestureEventForLastForVSync());
+ }
+
+ mGestureHandler.pinchBegin(downTime, FAKE_COORD_X, FAKE_COORD_Y);
+ mGestureHandler.pinchBy(eventTime + 10, FAKE_COORD_X, FAKE_COORD_Y, 2);
+ assertEquals("We should have started pinch-zooming",
+ ContentViewGestureHandler.GESTURE_PINCH_BY,
+ mockDelegate.mMostRecentGestureEvent.mType);
+
+ if (inputEventsDeliveredAtVSync) {
+ assertEquals("Gesture should be last for vsync",
+ true,
+ mockDelegate.mostRecentGestureEventForLastForVSync());
+ } else {
+ assertEquals("Gesture should not be last for vsync",
+ false,
+ mockDelegate.mostRecentGestureEventForLastForVSync());
+ }
}
}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java
index f40d30e..d880a96 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java
@@ -4,6 +4,7 @@
package org.chromium.content.browser;
+import android.test.FlakyTest;
import android.test.suitebuilder.annotation.SmallTest;
import org.chromium.base.test.util.Feature;
@@ -84,8 +85,12 @@
assertEquals(0, getContentViewCore().getNativeScrollYForTest());
}
- @SmallTest
- @Feature({"Main"})
+ /**
+ * @SmallTest
+ * @Feature({"Main"})
+ * crbug.com/224458
+ */
+ @FlakyTest
public void testFling() throws Throwable {
// Vertical fling to lower-left.
fling(0, -1000);
@@ -108,8 +113,12 @@
assertWaitForScroll(false, false);
}
- @SmallTest
- @Feature({"Main"})
+ /**
+ * @SmallTest
+ * @Feature({"Main"})
+ * crbug.com/224458
+ */
+ @FlakyTest
public void testScroll() throws Throwable {
// Vertical scroll to lower-left.
scrollTo(0, 2500);
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/DeviceMotionAndOrientationTest.java b/content/public/android/javatests/src/org/chromium/content/browser/DeviceMotionAndOrientationTest.java
new file mode 100644
index 0000000..518b525
--- /dev/null
+++ b/content/public/android/javatests/src/org/chromium/content/browser/DeviceMotionAndOrientationTest.java
@@ -0,0 +1,299 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser;
+
+import org.chromium.base.ActivityStatus;
+import org.chromium.base.test.util.Feature;
+import org.chromium.content.app.LibraryLoader;
+import org.chromium.content.common.CommandLine;
+import org.chromium.content.common.ProcessInitException;
+import org.chromium.content_shell_apk.ContentShellApplication;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.test.UiThreadTest;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Handler;
+
+import com.google.common.collect.Sets;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+
+/**
+ * Test suite for DeviceMotionAndOrientation.
+ */
+public class DeviceMotionAndOrientationTest extends AndroidTestCase {
+
+ private DeviceMotionAndOrientationForTests mDeviceMotionAndOrientation;
+ private MockSensorManager mMockSensorManager;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mMockSensorManager = new MockSensorManager();
+ mDeviceMotionAndOrientation = DeviceMotionAndOrientationForTests.getInstance();
+ mDeviceMotionAndOrientation.setSensorManagerProxy(mMockSensorManager);
+ }
+
+ @SmallTest
+ public void testRegisterSensorsDeviceMotion() {
+ boolean start = mDeviceMotionAndOrientation.start(0,
+ DeviceMotionAndOrientation.DEVICE_MOTION, 100);
+
+ assertTrue(start);
+ assertTrue("should contain all motion sensors",
+ mDeviceMotionAndOrientation.mActiveSensors.containsAll(
+ DeviceMotionAndOrientation.DEVICE_MOTION_SENSORS));
+ assertTrue(mDeviceMotionAndOrientation.mDeviceMotionIsActive);
+ assertFalse(mDeviceMotionAndOrientation.mDeviceOrientationIsActive);
+
+ assertEquals(DeviceMotionAndOrientation.DEVICE_MOTION_SENSORS.size(),
+ mMockSensorManager.numRegistered);
+ assertEquals(0, mMockSensorManager.numUnRegistered);
+ }
+
+ @SmallTest
+ public void testRegisterSensorsDeviceOrientation() {
+ boolean start = mDeviceMotionAndOrientation.start(0,
+ DeviceMotionAndOrientation.DEVICE_ORIENTATION, 100);
+
+ assertTrue(start);
+ assertTrue("should contain all orientation sensors",
+ mDeviceMotionAndOrientation.mActiveSensors.containsAll(
+ DeviceMotionAndOrientation.DEVICE_ORIENTATION_SENSORS));
+ assertFalse(mDeviceMotionAndOrientation.mDeviceMotionIsActive);
+ assertTrue(mDeviceMotionAndOrientation.mDeviceOrientationIsActive);
+
+ assertEquals(DeviceMotionAndOrientation.DEVICE_ORIENTATION_SENSORS.size(),
+ mMockSensorManager.numRegistered);
+ assertEquals(0, mMockSensorManager.numUnRegistered);
+ }
+
+ @SmallTest
+ public void testRegisterSensorsDeviceMotionAndOrientation() {
+ boolean startOrientation = mDeviceMotionAndOrientation.start(0,
+ DeviceMotionAndOrientation.DEVICE_ORIENTATION, 100);
+ boolean startMotion = mDeviceMotionAndOrientation.start(0,
+ DeviceMotionAndOrientation.DEVICE_MOTION, 100);
+
+ assertTrue(startOrientation);
+ assertTrue(startMotion);
+ assertTrue("should contain all motion sensors",
+ mDeviceMotionAndOrientation.mActiveSensors.containsAll(
+ DeviceMotionAndOrientation.DEVICE_MOTION_SENSORS));
+ assertTrue("should contain all orientation sensors",
+ mDeviceMotionAndOrientation.mActiveSensors.containsAll(
+ DeviceMotionAndOrientation.DEVICE_ORIENTATION_SENSORS));
+
+ Set<Integer> union = Sets.newHashSet(DeviceMotionAndOrientation.DEVICE_ORIENTATION_SENSORS);
+ union.addAll(DeviceMotionAndOrientation.DEVICE_MOTION_SENSORS);
+
+ assertEquals(union.size(), mDeviceMotionAndOrientation.mActiveSensors.size());
+ assertTrue(mDeviceMotionAndOrientation.mDeviceMotionIsActive);
+ assertTrue(mDeviceMotionAndOrientation.mDeviceOrientationIsActive);
+ assertEquals(union.size(), mMockSensorManager.numRegistered);
+ assertEquals(0, mMockSensorManager.numUnRegistered);
+ }
+
+ @SmallTest
+ public void testUnregisterSensorsDeviceMotion() {
+ mDeviceMotionAndOrientation.start(0, DeviceMotionAndOrientation.DEVICE_MOTION, 100);
+ mDeviceMotionAndOrientation.stop(DeviceMotionAndOrientation.DEVICE_MOTION);
+
+ assertTrue("should contain no sensors",
+ mDeviceMotionAndOrientation.mActiveSensors.isEmpty());
+ assertFalse(mDeviceMotionAndOrientation.mDeviceMotionIsActive);
+ assertFalse(mDeviceMotionAndOrientation.mDeviceOrientationIsActive);
+ assertEquals(DeviceMotionAndOrientation.DEVICE_MOTION_SENSORS.size(),
+ mMockSensorManager.numUnRegistered);
+ }
+
+ @SmallTest
+ public void testUnregisterSensorsDeviceOrientation() {
+ mDeviceMotionAndOrientation.start(0, DeviceMotionAndOrientation.DEVICE_ORIENTATION, 100);
+ mDeviceMotionAndOrientation.stop(DeviceMotionAndOrientation.DEVICE_ORIENTATION);
+
+ assertTrue("should contain no sensors",
+ mDeviceMotionAndOrientation.mActiveSensors.isEmpty());
+ assertFalse(mDeviceMotionAndOrientation.mDeviceMotionIsActive);
+ assertFalse(mDeviceMotionAndOrientation.mDeviceOrientationIsActive);
+ assertEquals(DeviceMotionAndOrientation.DEVICE_ORIENTATION_SENSORS.size(),
+ mMockSensorManager.numUnRegistered);
+ }
+
+ @SmallTest
+ public void testUnRegisterSensorsDeviceMotionAndOrientation() {
+ mDeviceMotionAndOrientation.start(0, DeviceMotionAndOrientation.DEVICE_ORIENTATION, 100);
+ mDeviceMotionAndOrientation.start(0, DeviceMotionAndOrientation.DEVICE_MOTION, 100);
+ mDeviceMotionAndOrientation.stop(DeviceMotionAndOrientation.DEVICE_MOTION);
+
+ assertTrue("should contain all orientation sensors",
+ mDeviceMotionAndOrientation.mActiveSensors.containsAll(
+ DeviceMotionAndOrientation.DEVICE_ORIENTATION_SENSORS));
+
+ Set<Integer> diff = Sets.newHashSet(DeviceMotionAndOrientation.DEVICE_MOTION_SENSORS);
+ diff.removeAll(DeviceMotionAndOrientation.DEVICE_ORIENTATION_SENSORS);
+
+ assertEquals(diff.size(), mMockSensorManager.numUnRegistered);
+
+ mDeviceMotionAndOrientation.stop(DeviceMotionAndOrientation.DEVICE_ORIENTATION);
+
+ assertTrue("should contain no sensors",
+ mDeviceMotionAndOrientation.mActiveSensors.isEmpty());
+ assertEquals(diff.size() + DeviceMotionAndOrientation.DEVICE_ORIENTATION_SENSORS.size(),
+ mMockSensorManager.numUnRegistered);
+ }
+
+ @SmallTest
+ public void testSensorChangedgotAccelerationAndOrientation() {
+ boolean startOrientation = mDeviceMotionAndOrientation.start(0,
+ DeviceMotionAndOrientation.DEVICE_ORIENTATION, 100);
+ boolean startMotion = mDeviceMotionAndOrientation.start(0,
+ DeviceMotionAndOrientation.DEVICE_MOTION, 100);
+
+ assertTrue(startOrientation);
+ assertTrue(startMotion);
+ assertTrue(mDeviceMotionAndOrientation.mDeviceMotionIsActive);
+ assertTrue(mDeviceMotionAndOrientation.mDeviceOrientationIsActive);
+
+ float[] values = {0.0f, 0.0f, 9.0f};
+ float[] values2 = {10.0f, 10.0f, 10.0f};
+ mDeviceMotionAndOrientation.sensorChanged(Sensor.TYPE_ACCELEROMETER, values);
+ mDeviceMotionAndOrientation.sensorChanged(Sensor.TYPE_MAGNETIC_FIELD, values2);
+ mDeviceMotionAndOrientation.verifyCalls("gotAccelerationIncludingGravity" +
+ "gotOrientation");
+ mDeviceMotionAndOrientation.verifyValuesEpsilon(45, 0, 0);
+ }
+
+ @SmallTest
+ public void testSensorChangedgotAccelerationIncludingGravity() {
+ mDeviceMotionAndOrientation.start(0, DeviceMotionAndOrientation.DEVICE_MOTION, 100);
+
+ float[] values = {1, 2, 3};
+ mDeviceMotionAndOrientation.sensorChanged(Sensor.TYPE_ACCELEROMETER, values);
+ mDeviceMotionAndOrientation.verifyCalls("gotAccelerationIncludingGravity");
+ mDeviceMotionAndOrientation.verifyValues(1, 2, 3);
+ }
+
+ @SmallTest
+ public void testSensorChangedgotAcceleration() {
+ mDeviceMotionAndOrientation.start(0, DeviceMotionAndOrientation.DEVICE_MOTION, 100);
+
+ float[] values = {1, 2, 3};
+ mDeviceMotionAndOrientation.sensorChanged(Sensor.TYPE_LINEAR_ACCELERATION, values);
+ mDeviceMotionAndOrientation.verifyCalls("gotAcceleration");
+ mDeviceMotionAndOrientation.verifyValues(1, 2, 3);
+ }
+
+ @SmallTest
+ public void testSensorChangedgotRotationRate() {
+ mDeviceMotionAndOrientation.start(0, DeviceMotionAndOrientation.DEVICE_MOTION, 100);
+
+ float[] values = {1, 2, 3};
+ mDeviceMotionAndOrientation.sensorChanged(Sensor.TYPE_GYROSCOPE, values);
+ mDeviceMotionAndOrientation.verifyCalls("gotRotationRate");
+ mDeviceMotionAndOrientation.verifyValues(1, 2, 3);
+ }
+
+ @SmallTest
+ public void testSensorChangedmagneticField() {
+ mDeviceMotionAndOrientation.start(0, DeviceMotionAndOrientation.DEVICE_ORIENTATION, 100);
+
+ float[] values = {1, 2, 3};
+ mDeviceMotionAndOrientation.sensorChanged(Sensor.TYPE_MAGNETIC_FIELD, values);
+ mDeviceMotionAndOrientation.verifyCalls("");
+ }
+
+ private static class DeviceMotionAndOrientationForTests extends DeviceMotionAndOrientation {
+
+ private double value1 = 0;
+ private double value2 = 0;
+ private double value3 = 0;
+ private String mCalls = "";
+
+ private DeviceMotionAndOrientationForTests(){
+ }
+
+ static DeviceMotionAndOrientationForTests getInstance() {
+ return new DeviceMotionAndOrientationForTests();
+ }
+
+ private void verifyValues(double v1, double v2, double v3) {
+ assertEquals(v1, value1);
+ assertEquals(v2, value2);
+ assertEquals(v3, value3);
+ }
+
+ private void verifyValuesEpsilon(double v1, double v2, double v3) {
+ assertEquals(v1, value1, 0.1);
+ assertEquals(v2, value2, 0.1);
+ assertEquals(v3, value3, 0.1);
+ }
+
+ private void verifyCalls(String names) {
+ assertEquals(mCalls, names);
+ }
+
+ @Override
+ protected void gotOrientation(double alpha, double beta, double gamma) {
+ value1 = alpha;
+ value2 = beta;
+ value3 = gamma;
+ mCalls = mCalls.concat("gotOrientation");
+ }
+
+ @Override
+ protected void gotAcceleration(double x, double y, double z) {
+ value1 = x;
+ value2 = y;
+ value3 = z;
+ mCalls = mCalls.concat("gotAcceleration");
+ }
+
+ @Override
+ protected void gotAccelerationIncludingGravity(double x, double y, double z) {
+ value1 = x;
+ value2 = y;
+ value3 = z;
+ mCalls = mCalls.concat("gotAccelerationIncludingGravity");
+ }
+
+ @Override
+ protected void gotRotationRate(double alpha, double beta, double gamma) {
+ value1 = alpha;
+ value2 = beta;
+ value3 = gamma;
+ mCalls = mCalls.concat("gotRotationRate");
+ }
+ }
+
+ private static class MockSensorManager implements
+ DeviceMotionAndOrientation.SensorManagerProxy {
+
+ private int numRegistered = 0;
+ private int numUnRegistered = 0;
+
+ private MockSensorManager() {
+ }
+
+ @Override
+ public boolean registerListener(SensorEventListener listener, int sensorType, int rate,
+ Handler handler) {
+ numRegistered++;
+ return true;
+ }
+
+ @Override
+ public void unregisterListener(SensorEventListener listener, int sensorType) {
+ numUnRegistered++;
+ }
+ }
+}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/EmailAddressDetectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/EmailAddressDetectionTest.java
index 2dd5d34..2bd8797 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/EmailAddressDetectionTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/EmailAddressDetectionTest.java
@@ -6,7 +6,6 @@
import android.test.suitebuilder.annotation.MediumTest;
-import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
/**
@@ -22,14 +21,11 @@
return intentUrl.equals(expectedUrl);
}
- /*
@MediumTest
@Feature({"ContentDetection", "TabContents"})
- http://crbug.com/172786
- */
- @DisabledTest
public void testValidEmailAddresses() throws Throwable {
startActivityWithTestUrl("content/content_detection/email.html");
+ assertWaitForPageScaleFactorMatch(1.0f);
// valid_1: i.want.a.pony@chromium.org.
String intentUrl = scrollAndTapExpectingIntent("valid_1");
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayCoercionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayCoercionTest.java
index 9c737f2..9bd2f8f 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayCoercionTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayCoercionTest.java
@@ -248,12 +248,8 @@
// Test passing an array of JavaScript NaN values to a method which takes a
// Java array.
- /*
@SmallTest
@Feature({"AndroidWebView", "Android-JavaBridge"})
- Bug: http://code.google.com/p/chromium/issues/detail?id=145881
- */
- @DisabledTest
public void testPassNumberNaN() throws Throwable {
executeJavaScript("testObject.setBooleanArray([Number.NaN]);");
assertFalse(mTestObject.waitForBooleanArray()[0]);
@@ -294,12 +290,8 @@
// Test passing an array of JavaScript infinity values to a method which
// takes a Java array.
- /*
@SmallTest
@Feature({"AndroidWebView", "Android-JavaBridge"})
- Bug: http://code.google.com/p/chromium/issues/detail?id=145881
- */
- @DisabledTest
public void testPassNumberInfinity() throws Throwable {
executeJavaScript("testObject.setBooleanArray([Infinity]);");
assertFalse(mTestObject.waitForBooleanArray()[0]);
@@ -317,9 +309,8 @@
executeJavaScript("testObject.setIntArray([Infinity]);");
assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntArray()[0]);
- // LIVECONNECT_COMPLIANCE: Should be Long.MAX_VALUE.
executeJavaScript("testObject.setLongArray([Infinity]);");
- assertEquals(-1L, mTestObject.waitForLongArray()[0]);
+ assertEquals(Long.MAX_VALUE, mTestObject.waitForLongArray()[0]);
executeJavaScript("testObject.setFloatArray([Infinity]);");
assertEquals(Float.POSITIVE_INFINITY, mTestObject.waitForFloatArray()[0]);
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java
index 8cdc60a..dea76d1 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java
@@ -7,7 +7,6 @@
import android.test.suitebuilder.annotation.SmallTest;
import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.DisabledTest;
/**
* Part of the test suite for the Java Bridge. This class tests that
@@ -161,8 +160,10 @@
setUpContentView(mTestObject, "testObject");
}
- // Test passing a JavaScript number in the int32 range to a method of an
- // injected object.
+ // Test passing a 32-bit integer JavaScript number to a method of an
+ // injected object. Note that JavaScript may choose to represent these
+ // values as either 32-bit integers or doubles, though this should not
+ // affect the result.
@SmallTest
@Feature({"AndroidWebView", "Android-JavaBridge"})
public void testPassNumberInt32() throws Throwable {
@@ -212,21 +213,21 @@
assertNull(mTestObject.waitForCustomTypeValue());
}
- // Test passing a JavaScript number in the double range to a method of an
- // injected object.
- /*
+ // Test passing a floating-point JavaScript number to a method of an
+ // injected object. JavaScript represents these values as doubles.
@SmallTest
@Feature({"AndroidWebView", "Android-JavaBridge"})
- Bug: http://code.google.com/p/chromium/issues/detail?id=145881
- */
- @DisabledTest
public void testPassNumberDouble() throws Throwable {
executeJavaScript("testObject.setByteValue(42.1);");
assertEquals(42, mTestObject.waitForByteValue());
executeJavaScript("testObject.setByteValue(" + Byte.MAX_VALUE + " + 42.1);");
assertEquals(Byte.MIN_VALUE + 42 - 1, mTestObject.waitForByteValue());
+ executeJavaScript("testObject.setByteValue(" + Byte.MIN_VALUE + " - 42.1);");
+ assertEquals(Byte.MAX_VALUE - 42 + 1, mTestObject.waitForByteValue());
executeJavaScript("testObject.setByteValue(" + Integer.MAX_VALUE + " + 42.1);");
assertEquals(-1, mTestObject.waitForByteValue());
+ executeJavaScript("testObject.setByteValue(" + Integer.MIN_VALUE + " - 42.1);");
+ assertEquals(0, mTestObject.waitForByteValue());
// LIVECONNECT_COMPLIANCE: Should convert to numeric char value.
executeJavaScript("testObject.setCharValue(42.1);");
@@ -236,18 +237,25 @@
assertEquals(42, mTestObject.waitForShortValue());
executeJavaScript("testObject.setShortValue(" + Short.MAX_VALUE + " + 42.1);");
assertEquals(Short.MIN_VALUE + 42 - 1, mTestObject.waitForShortValue());
+ executeJavaScript("testObject.setShortValue(" + Short.MIN_VALUE + " - 42.1);");
+ assertEquals(Short.MAX_VALUE - 42 + 1, mTestObject.waitForShortValue());
executeJavaScript("testObject.setShortValue(" + Integer.MAX_VALUE + " + 42.1);");
assertEquals(-1, mTestObject.waitForShortValue());
+ executeJavaScript("testObject.setShortValue(" + Integer.MIN_VALUE + " - 42.1);");
+ assertEquals(0, mTestObject.waitForShortValue());
executeJavaScript("testObject.setIntValue(42.1);");
assertEquals(42, mTestObject.waitForIntValue());
executeJavaScript("testObject.setIntValue(" + Integer.MAX_VALUE + " + 42.1);");
assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntValue());
+ executeJavaScript("testObject.setIntValue(" + Integer.MIN_VALUE + " - 42.1);");
+ assertEquals(Integer.MIN_VALUE, mTestObject.waitForIntValue());
executeJavaScript("testObject.setLongValue(42.1);");
assertEquals(42L, mTestObject.waitForLongValue());
- // LIVECONNECT_COMPLIANCE: Should be Long.MAX_VALUE.
executeJavaScript("testObject.setLongValue(" + Long.MAX_VALUE + " + 42.1);");
+ assertEquals(Long.MAX_VALUE, mTestObject.waitForLongValue());
+ executeJavaScript("testObject.setLongValue(" + Long.MIN_VALUE + " - 42.1);");
assertEquals(Long.MIN_VALUE, mTestObject.waitForLongValue());
executeJavaScript("testObject.setFloatValue(42.1);");
@@ -275,12 +283,8 @@
}
// Test passing JavaScript NaN to a method of an injected object.
- /*
@SmallTest
@Feature({"AndroidWebView", "Android-JavaBridge"})
- Bug: http://code.google.com/p/chromium/issues/detail?id=145881
- */
- @DisabledTest
public void testPassNumberNaN() throws Throwable {
executeJavaScript("testObject.setByteValue(Number.NaN);");
assertEquals(0, mTestObject.waitForByteValue());
@@ -319,12 +323,8 @@
}
// Test passing JavaScript infinity to a method of an injected object.
- /*
@SmallTest
@Feature({"AndroidWebView", "Android-JavaBridge"})
- Bug: http://code.google.com/p/chromium/issues/detail?id=145881
- */
- @DisabledTest
public void testPassNumberInfinity() throws Throwable {
executeJavaScript("testObject.setByteValue(Infinity);");
assertEquals(-1, mTestObject.waitForByteValue());
@@ -339,9 +339,8 @@
executeJavaScript("testObject.setIntValue(Infinity);");
assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntValue());
- // LIVECONNECT_COMPLIANCE: Should be Long.MAX_VALUE.
executeJavaScript("testObject.setLongValue(Infinity);");
- assertEquals(-1L, mTestObject.waitForLongValue());
+ assertEquals(Long.MAX_VALUE, mTestObject.waitForLongValue());
executeJavaScript("testObject.setFloatValue(Infinity);");
assertEquals(Float.POSITIVE_INFINITY, mTestObject.waitForFloatValue());
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/PhoneNumberDetectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/PhoneNumberDetectionTest.java
index 34432d6..a0ad8d2 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/PhoneNumberDetectionTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/PhoneNumberDetectionTest.java
@@ -4,10 +4,10 @@
package org.chromium.content.browser;
+import android.test.FlakyTest;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
-import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
import org.chromium.content.common.CommandLine;
@@ -38,14 +38,12 @@
startActivityWithTestUrlAndCommandLineArgs(testUrl, cmdlineArgs);
}
- /*
- @LargeTest
+ /* @LargeTest */
+ @FlakyTest
@Feature({"ContentDetection", "TabContents"})
- http://crbug.com/172786
- */
- @DisabledTest
public void testInternationalNumberIntents() throws Throwable {
startActivityWithTestUrl("content/content_detection/phone_international.html");
+ assertWaitForPageScaleFactorMatch(1.0f);
// US: +1 650-253-0000.
String intentUrl = scrollAndTapExpectingIntent("US");
@@ -156,14 +154,12 @@
assertTrue(isExpectedTelephoneIntent(intentUrl, "+97144509500"));
}
- /*
- @MediumTest
+ /* @MediumTest */
+ @FlakyTest
@Feature({"ContentDetection", "TabContents"})
- http://crbug.com/172786
- */
- @DisabledTest
public void testLocalUSNumbers() throws Throwable {
startActivityWithTestUrlAndCountryIso("content/content_detection/phone_local.html", "US");
+ assertWaitForPageScaleFactorMatch(1.0f);
// US_1: 1-888-433-5788.
String intentUrl = scrollAndTapExpectingIntent("US_1");
@@ -182,14 +178,12 @@
assertTrue(isExpectedTelephoneIntent(intentUrl, "+31205045100"));
}
- /*
- @MediumTest
+ /* @MediumTest */
+ @FlakyTest
@Feature({"ContentDetection", "TabContents"})
- http://crbug.com/172786
- */
- @DisabledTest
public void testLocalUKNumbers() throws Throwable {
startActivityWithTestUrlAndCountryIso("content/content_detection/phone_local.html", "GB");
+ assertWaitForPageScaleFactorMatch(1.0f);
// GB_1: (0) 20 7323 8299.
String intentUrl = scrollAndTapExpectingIntent("GB_1");
@@ -208,14 +202,12 @@
assertTrue(isExpectedTelephoneIntent(intentUrl, "+31205045100"));
}
- /*
- @MediumTest
+ /* @MediumTest */
+ @FlakyTest
@Feature({"ContentDetection", "TabContents"})
- http://crbug.com/172786
- */
- @DisabledTest
public void testLocalFRNumbers() throws Throwable {
startActivityWithTestUrlAndCountryIso("content/content_detection/phone_local.html", "FR");
+ assertWaitForPageScaleFactorMatch(1.0f);
// FR_1: 01 40 20 50 50.
String intentUrl = scrollAndTapExpectingIntent("FR_1");
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ImeTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
similarity index 60%
rename from content/public/android/javatests/src/org/chromium/content/browser/ImeTest.java
rename to content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
index c3e03b6..51bc7b5 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ImeTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.content.browser;
+package org.chromium.content.browser.input;
import android.app.Activity;
import android.content.ClipData;
@@ -20,19 +20,19 @@
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.UrlUtils;
-import org.chromium.content.browser.ImeAdapter.AdapterInputConnection;
+import org.chromium.content.browser.ContentView;
+import org.chromium.content.browser.ContentViewCore;
import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content.browser.test.util.DOMUtils;
import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
import org.chromium.content_shell_apk.ContentShellTestBase;
+import java.util.ArrayList;
import java.util.concurrent.Callable;
public class ImeTest extends ContentShellTestBase {
- private static final int INVALID_SELECTION = -2;
- private static final int INVALID_COMPOSITION = -2;
private static final String DATA_URL = UrlUtils.encodeHtmlDataUri(
"<html><head><meta name=\"viewport\"" +
"content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0\" /></head>" +
@@ -70,91 +70,52 @@
mConnection = (TestAdapterInputConnection) getAdapterInputConnection();
mImeAdapter = getImeAdapter();
- assertWaitForSetEditableCallback(1, mConnection);
- assertEquals("", mConnection.mText);
- assertEquals(0, mConnection.mSelectionStart);
- assertEquals(0, mConnection.mSelectionEnd);
- assertEquals(-1, mConnection.mCompositionStart);
- assertEquals(-1, mConnection.mCompositionEnd);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 0, "", 0, 0, -1, -1);
assertEquals(1, mInputMethodManagerWrapper.mShowSoftInputCounter);
+ assertEquals(0, mInputMethodManagerWrapper.mEditorInfo.initialSelStart);
+ assertEquals(0, mInputMethodManagerWrapper.mEditorInfo.initialSelEnd);
}
@MediumTest
@Feature({"TextInput", "Main"})
public void testKeyboardDismissedAfterClickingGo() throws Throwable {
- mImeAdapter.checkCompositionQueueAndCallNative("hello", 1, false);
- assertWaitForSetEditableCallback(2, mConnection);
- assertEquals("hello", mConnection.mText);
- assertEquals(5, mConnection.mSelectionStart);
- assertEquals(5, mConnection.mSelectionEnd);
- assertEquals(0, mConnection.mCompositionStart);
- assertEquals(5, mConnection.mCompositionEnd);
+ mConnection.setComposingText("hello", 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "hello", 5, 5, 0, 5);
performGo(getAdapterInputConnection(), mCallbackContainer);
- assertWaitForSetEditableCallback(3, mConnection);
- assertEquals("", mConnection.mText);
- assertEquals(0, mConnection.mSelectionStart);
- assertEquals(0, mConnection.mSelectionEnd);
- assertEquals(-1, mConnection.mCompositionStart);
- assertEquals(-1, mConnection.mCompositionEnd);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "", 0, 0, -1, -1);
assertWaitForKeyboardStatus(false);
}
@SmallTest
@Feature({"TextInput", "Main"})
public void testGetTextUpdatesAfterEnteringText() throws Throwable {
- mImeAdapter.checkCompositionQueueAndCallNative("h", 1, false);
- assertWaitForSetEditableCallback(2, mConnection);
- assertEquals("h", mConnection.mText);
- assertEquals(1, mConnection.mSelectionStart);
- assertEquals(1, mConnection.mSelectionEnd);
- assertEquals(0, mConnection.mCompositionStart);
- assertEquals(1, mConnection.mCompositionEnd);
+ mConnection.setComposingText("h", 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "h", 1, 1, 0, 1);
assertEquals(1, mInputMethodManagerWrapper.mShowSoftInputCounter);
- mImeAdapter.checkCompositionQueueAndCallNative("he", 1, false);
- assertWaitForSetEditableCallback(3, mConnection);
- assertEquals("he", mConnection.mText);
- assertEquals(2, mConnection.mSelectionStart);
- assertEquals(2, mConnection.mSelectionEnd);
- assertEquals(0, mConnection.mCompositionStart);
- assertEquals(2, mConnection.mCompositionEnd);
+ mConnection.setComposingText("he", 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "he", 2, 2, 0, 2);
assertEquals(1, mInputMethodManagerWrapper.mShowSoftInputCounter);
- mImeAdapter.checkCompositionQueueAndCallNative("hel", 1, false);
- assertWaitForSetEditableCallback(4, mConnection);
- assertEquals("hel", mConnection.mText);
- assertEquals(3, mConnection.mSelectionStart);
- assertEquals(3, mConnection.mSelectionEnd);
- assertEquals(0, mConnection.mCompositionStart);
- assertEquals(3, mConnection.mCompositionEnd);
+ mConnection.setComposingText("hel", 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 3, "hel", 3, 3, 0, 3);
assertEquals(1, mInputMethodManagerWrapper.mShowSoftInputCounter);
- mImeAdapter.checkCompositionQueueAndCallNative("hel", 1, true);
- assertWaitForSetEditableCallback(5, mConnection);
- assertEquals("hel", mConnection.mText);
- assertEquals(3, mConnection.mSelectionStart);
- assertEquals(3, mConnection.mSelectionEnd);
- assertEquals(-1, mConnection.mCompositionStart);
- assertEquals(-1, mConnection.mCompositionEnd);
+ mConnection.commitText("hel", 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 4, "hel", 3, 3, -1, -1);
assertEquals(1, mInputMethodManagerWrapper.mShowSoftInputCounter);
}
@SmallTest
@Feature({"TextInput"})
public void testImeCopy() throws Exception {
- mImeAdapter.checkCompositionQueueAndCallNative("hello", 1, true);
- assertWaitForSetEditableCallback(2, mConnection);
- assertEquals("hello", mConnection.mText);
- assertEquals(5, mConnection.mSelectionStart);
- assertEquals(5, mConnection.mSelectionEnd);
+ mConnection.commitText("hello", 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "hello", 5, 5, -1, -1);
- mImeAdapter.setEditableSelectionOffsets(2, 5);
- assertWaitForSetEditableCallback(3, mConnection);
- assertEquals("hello", mConnection.mText);
- assertEquals(2, mConnection.mSelectionStart);
- assertEquals(5, mConnection.mSelectionEnd);
+ mConnection.setSelection(2, 5);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "hello", 2, 5, -1, -1);
mImeAdapter.copy();
assertClipboardContents(getActivity(), "llo");
@@ -162,24 +123,30 @@
@SmallTest
@Feature({"TextInput"})
- public void testImeCut() throws Exception {
- mImeAdapter.checkCompositionQueueAndCallNative("snarful", 1, true);
- assertWaitForSetEditableCallback(2, mConnection);
- assertEquals("snarful", mConnection.mText);
- assertEquals(7, mConnection.mSelectionStart);
- assertEquals(7, mConnection.mSelectionEnd);
+ public void testEnterTextAndRefocus() throws Exception {
+ mConnection.commitText("hello", 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "hello", 5, 5, -1, -1);
- mImeAdapter.setEditableSelectionOffsets(1, 5);
- assertWaitForSetEditableCallback(3, mConnection);
- assertEquals("snarful", mConnection.mText);
- assertEquals(1, mConnection.mSelectionStart);
- assertEquals(5, mConnection.mSelectionEnd);
+ DOMUtils.clickNode(this, mContentView, mCallbackContainer, "input_radio");
+ assertWaitForKeyboardStatus(false);
+
+ DOMUtils.clickNode(this, mContentView, mCallbackContainer, "input_text");
+ assertWaitForKeyboardStatus(true);
+ assertEquals(5, mInputMethodManagerWrapper.mEditorInfo.initialSelStart);
+ assertEquals(5, mInputMethodManagerWrapper.mEditorInfo.initialSelEnd);
+ }
+
+ @SmallTest
+ @Feature({"TextInput"})
+ public void testImeCut() throws Exception {
+ mConnection.commitText("snarful", 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "snarful", 7, 7, -1, -1);
+
+ mConnection.setSelection(1, 5);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "snarful", 1, 5, -1, -1);
mImeAdapter.cut();
- assertWaitForSetEditableCallback(4, mConnection);
- assertEquals("sul", mConnection.mText);
- assertEquals(1, mConnection.mSelectionStart);
- assertEquals(1, mConnection.mSelectionEnd);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 3, "sul", 1, 1, -1, -1);
assertClipboardContents(getActivity(), "narf");
}
@@ -198,50 +165,32 @@
});
mImeAdapter.paste();
- assertWaitForSetEditableCallback(2, mConnection);
- assertEquals("blarg", mConnection.mText);
- assertEquals(5, mConnection.mSelectionStart);
- assertEquals(5, mConnection.mSelectionEnd);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "blarg", 5, 5, -1, -1);
- mImeAdapter.setEditableSelectionOffsets(3, 5);
- assertWaitForSetEditableCallback(3, mConnection);
- assertEquals("blarg", mConnection.mText);
- assertEquals(3, mConnection.mSelectionStart);
- assertEquals(5, mConnection.mSelectionEnd);
+ mConnection.setSelection(3, 5);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "blarg", 3, 5, -1, -1);
mImeAdapter.paste();
- assertWaitForSetEditableCallback(5, mConnection);
- assertEquals("blablarg", mConnection.mText);
- assertEquals(8, mConnection.mSelectionStart);
- assertEquals(8, mConnection.mSelectionEnd);
+ // Paste is a two step process when there is a non-zero selection.
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 3, "bla", 3, 3, -1, -1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 4, "blablarg", 8, 8, -1, -1);
mImeAdapter.paste();
- assertWaitForSetEditableCallback(6, mConnection);
- assertEquals("blablargblarg", mConnection.mText);
- assertEquals(13, mConnection.mSelectionStart);
- assertEquals(13, mConnection.mSelectionEnd);
+ waitAndVerifyEditableCallback(
+ mConnection.mImeUpdateQueue, 5, "blablargblarg", 13, 13, -1, -1);
}
@SmallTest
@Feature({"TextInput"})
public void testImeSelectAndUnSelectAll() throws Exception {
- mImeAdapter.checkCompositionQueueAndCallNative("hello", 1, true);
- assertWaitForSetEditableCallback(2, mConnection);
- assertEquals("hello", mConnection.mText);
- assertEquals(5, mConnection.mSelectionStart);
- assertEquals(5, mConnection.mSelectionEnd);
+ mConnection.commitText("hello", 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "hello", 5, 5, -1, -1);
mImeAdapter.selectAll();
- assertWaitForSetEditableCallback(3, mConnection);
- assertEquals("hello", mConnection.mText);
- assertEquals(0, mConnection.mSelectionStart);
- assertEquals(5, mConnection.mSelectionEnd);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "hello", 0, 5, -1, -1);
mImeAdapter.unselect();
- assertWaitForSetEditableCallback(4, mConnection);
- assertEquals("", mConnection.mText);
- assertEquals(0, mConnection.mSelectionStart);
- assertEquals(0, mConnection.mSelectionEnd);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 3, "", 0, 0, -1, -1);
assertWaitForKeyboardStatus(false);
}
@@ -252,31 +201,16 @@
mConnection.beginBatchEdit();
assertWaitForSetIgnoreUpdates(true, mConnection);
- mImeAdapter.checkCompositionQueueAndCallNative("h", 1, false);
- assertWaitForSetEditableCallback(2, mConnection);
- assertEquals("h", mConnection.mText);
- assertEquals(1, mConnection.mSelectionStart);
- assertEquals(1, mConnection.mSelectionEnd);
- assertEquals(0, mConnection.mCompositionStart);
- assertEquals(1, mConnection.mCompositionEnd);
+ mConnection.setComposingText("h", 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "h", 1, 1, 0, 1);
assertTrue(mConnection.isIgnoringTextInputStateUpdates());
- mImeAdapter.checkCompositionQueueAndCallNative("he", 1, false);
- assertWaitForSetEditableCallback(3, mConnection);
- assertEquals("he", mConnection.mText);
- assertEquals(2, mConnection.mSelectionStart);
- assertEquals(2, mConnection.mSelectionEnd);
- assertEquals(0, mConnection.mCompositionStart);
- assertEquals(2, mConnection.mCompositionEnd);
+ mConnection.setComposingText("he", 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "he", 2, 2, 0, 2);
assertTrue(mConnection.isIgnoringTextInputStateUpdates());
- mImeAdapter.checkCompositionQueueAndCallNative("hel", 1, false);
- assertWaitForSetEditableCallback(4, mConnection);
- assertEquals("hel", mConnection.mText);
- assertEquals(3, mConnection.mSelectionStart);
- assertEquals(3, mConnection.mSelectionEnd);
- assertEquals(0, mConnection.mCompositionStart);
- assertEquals(3, mConnection.mCompositionEnd);
+ mConnection.setComposingText("hel", 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 3, "hel", 3, 3, 0, 3);
assertEquals(0, mConnection.mUpdateSelectionCounter);
assertTrue(mConnection.isIgnoringTextInputStateUpdates());
@@ -300,6 +234,27 @@
assertWaitForKeyboardStatus(true);
}
+ @SmallTest
+ @Feature({"TextInput", "Main"})
+ public void testFinishComposingText() throws Throwable {
+ mConnection.commitText("hllo", 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 1, "hllo", 4, 4, -1, -1);
+
+ mConnection.commitText(" ", 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 2, "hllo ", 5, 5, -1, -1);
+
+ mConnection.setSelection(1, 1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 3, "hllo ", 1, 1, -1, -1);
+
+ mConnection.setComposingRegion(0, 4);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 4, "hllo ", 1, 1, 0, 4);
+
+ mConnection.finishComposingText();
+ // finishComposingText() is a two step IME event.
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 5, "hllo ", 4, 4, -1, -1);
+ waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 6, "hllo ", 1, 1, -1, -1);
+ }
+
private void performShowImeIfNeeded() {
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
@@ -342,14 +297,17 @@
}));
}
- private void assertWaitForSetEditableCallback(final int callbackNumber,
- final TestAdapterInputConnection connection) throws InterruptedException {
+ private void waitAndVerifyEditableCallback(final ArrayList<TestImeState> states,
+ final int index, String text, int selectionStart, int selectionEnd,
+ int compositionStart, int compositionEnd) throws InterruptedException {
assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
@Override
public boolean isSatisfied() {
- return callbackNumber == connection.mSetEditableTextCallCounter;
+ return states.size() > index;
}
}));
+ states.get(index).assertEqualState(
+ text, selectionStart, selectionEnd, compositionStart, compositionEnd);
}
private void assertClipboardContents(final Activity activity, final String expectedContents)
@@ -386,7 +344,7 @@
return getContentViewCore().getImeAdapterForTest();
}
- private ImeAdapter.AdapterInputConnection getAdapterInputConnection() {
+ private AdapterInputConnection getAdapterInputConnection() {
return getContentViewCore().getInputConnectionForTest();
}
@@ -399,14 +357,9 @@
}
}
- private static class TestAdapterInputConnection extends ImeAdapter.AdapterInputConnection {
- private int mSetEditableTextCallCounter = 0;
+ private static class TestAdapterInputConnection extends AdapterInputConnection {
private int mUpdateSelectionCounter = 0;
- private String mText;
- private int mSelectionStart = INVALID_SELECTION;
- private int mSelectionEnd = INVALID_SELECTION;
- private int mCompositionStart = INVALID_COMPOSITION;
- private int mCompositionEnd = INVALID_COMPOSITION;
+ private ArrayList<TestImeState> mImeUpdateQueue = new ArrayList<ImeTest.TestImeState>();
public TestAdapterInputConnection(View view, ImeAdapter imeAdapter, EditorInfo outAttrs) {
super(view, imeAdapter, outAttrs);
@@ -415,12 +368,8 @@
@Override
public void setEditableText(String text, int selectionStart, int selectionEnd,
int compositionStart, int compositionEnd) {
- mText = text;
- mSelectionStart = selectionStart;
- mSelectionEnd = selectionEnd;
- mCompositionStart = compositionStart;
- mCompositionEnd = compositionEnd;
- mSetEditableTextCallCounter++;
+ mImeUpdateQueue.add(new TestImeState(text, selectionStart, selectionEnd,
+ compositionStart, compositionEnd));
super.setEditableText(
text, selectionStart, selectionEnd, compositionStart, compositionEnd);
}
@@ -437,6 +386,7 @@
private ContentViewCore mContentViewCore;
private InputConnection mInputConnection;
private int mShowSoftInputCounter = 0;
+ private EditorInfo mEditorInfo;
public TestInputMethodManagerWrapper(ContentViewCore contentViewCore) {
super(null);
@@ -445,14 +395,16 @@
@Override
public void restartInput(View view) {
- mInputConnection = mContentViewCore.onCreateInputConnection(new EditorInfo());
+ mEditorInfo = new EditorInfo();
+ mInputConnection = mContentViewCore.onCreateInputConnection(mEditorInfo);
}
@Override
public void showSoftInput(View view, int flags, ResultReceiver resultReceiver) {
mShowSoftInputCounter++;
if (mInputConnection != null) return;
- mInputConnection = mContentViewCore.onCreateInputConnection(new EditorInfo());
+ mEditorInfo = new EditorInfo();
+ mInputConnection = mContentViewCore.onCreateInputConnection(mEditorInfo);
}
@Override
@@ -474,4 +426,30 @@
int candidatesStart, int candidatesEnd) {
}
}
+
+ private static class TestImeState {
+ private final String mText;
+ private final int mSelectionStart;
+ private final int mSelectionEnd;
+ private final int mCompositionStart;
+ private final int mCompositionEnd;
+
+ public TestImeState(String text, int selectionStart, int selectionEnd,
+ int compositionStart, int compositionEnd) {
+ mText = text;
+ mSelectionStart = selectionStart;
+ mSelectionEnd = selectionEnd;
+ mCompositionStart = compositionStart;
+ mCompositionEnd = compositionEnd;
+ }
+
+ public void assertEqualState(String text, int selectionStart, int selectionEnd,
+ int compositionStart, int compositionEnd) {
+ assertEquals("Text did not match", mText, text);
+ assertEquals("Selection start did not match", mSelectionStart, selectionStart);
+ assertEquals("Selection end did not match", mSelectionEnd, selectionEnd);
+ assertEquals("Composition start did not match", mCompositionStart, compositionStart);
+ assertEquals("Composition end did not match", mCompositionEnd, compositionEnd);
+ }
+ }
}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/InsertionHandleTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/InsertionHandleTest.java
similarity index 96%
rename from content/public/android/javatests/src/org/chromium/content/browser/InsertionHandleTest.java
rename to content/public/android/javatests/src/org/chromium/content/browser/input/InsertionHandleTest.java
index 845e64a..42ee232 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/InsertionHandleTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/input/InsertionHandleTest.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.content.browser;
+package org.chromium.content.browser.input;
import android.content.ClipData;
import android.content.ClipboardManager;
@@ -14,6 +14,8 @@
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
+import org.chromium.content.browser.ContentView;
+import org.chromium.content.browser.RenderCoordinates;
import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content.browser.test.util.DOMUtils;
@@ -190,10 +192,12 @@
new TestCallbackHelperContainer(getContentView()), nodeId);
RenderCoordinates renderCoordinates = getContentView().getRenderCoordinates();
- float left = renderCoordinates.fromLocalCssToPix(nodeBounds.left);
- float right = renderCoordinates.fromLocalCssToPix(nodeBounds.right);
- float top = renderCoordinates.fromLocalCssToPix(nodeBounds.top);
- float bottom = renderCoordinates.fromLocalCssToPix(nodeBounds.bottom);
+ int offsetX = getContentView().getContentViewCore().getViewportSizeOffsetWidthPix();
+ int offsetY = getContentView().getContentViewCore().getViewportSizeOffsetHeightPix();
+ float left = renderCoordinates.fromLocalCssToPix(nodeBounds.left) + offsetX;
+ float right = renderCoordinates.fromLocalCssToPix(nodeBounds.right) + offsetX;
+ float top = renderCoordinates.fromLocalCssToPix(nodeBounds.top) + offsetY;
+ float bottom = renderCoordinates.fromLocalCssToPix(nodeBounds.bottom) + offsetY;
TouchCommon touchCommon = new TouchCommon(this);
touchCommon.singleClickView(getContentView(),
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/SelectPopupTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java
similarity index 97%
rename from content/public/android/javatests/src/org/chromium/content/browser/SelectPopupTest.java
rename to content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java
index 81e03c1..7e65a25 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/SelectPopupTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java
@@ -2,13 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.content.browser;
+package org.chromium.content.browser.input;
import android.test.suitebuilder.annotation.LargeTest;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.UrlUtils;
+import org.chromium.content.browser.ContentView;
import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content.browser.test.util.DOMUtils;
diff --git a/content/public/browser/OWNERS b/content/public/browser/OWNERS
deleted file mode 100644
index 39e58a2..0000000
--- a/content/public/browser/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# rdsmith@chromium.org only for download* files. All other reviews
-# must use OWNERS from parent directories.
-rdsmith@chromium.org
diff --git a/content/public/browser/android/compositor.h b/content/public/browser/android/compositor.h
index 4554074..b6a5352 100644
--- a/content/public/browser/android/compositor.h
+++ b/content/public/browser/android/compositor.h
@@ -33,6 +33,9 @@
// The compositor has completed swapping a frame.
virtual void OnSwapBuffersCompleted() {}
+
+ // The compositor will eventually swap a frame.
+ virtual void OnSwapBuffersPosted() {}
};
virtual ~Compositor() {}
@@ -86,6 +89,9 @@
// The buffer is not modified if false is returned.
virtual bool CompositeAndReadback(void *pixels, const gfx::Rect& rect) = 0;
+ // Invalidate the whole viewport.
+ virtual void SetNeedsRedraw() = 0;
+
// Composite immediately. Used in single-threaded mode.
virtual void Composite() = 0;
diff --git a/content/public/browser/android/content_view_core.h b/content/public/browser/android/content_view_core.h
index b0417de..6ba7e4b 100644
--- a/content/public/browser/android/content_view_core.h
+++ b/content/public/browser/android/content_view_core.h
@@ -17,12 +17,14 @@
}
namespace gfx {
+class Rect;
class Size;
class SizeF;
class Vector2dF;
}
namespace ui {
+class ViewAndroid;
class WindowAndroid;
}
@@ -44,12 +46,10 @@
virtual WebContents* GetWebContents() const = 0;
virtual base::android::ScopedJavaLocalRef<jobject> GetJavaObject() = 0;
- virtual base::android::ScopedJavaLocalRef<jobject> GetContainerViewDelegate()
- = 0;
+ virtual ui::ViewAndroid* GetViewAndroid() const = 0;
virtual ui::WindowAndroid* GetWindowAndroid() const = 0;
virtual scoped_refptr<cc::Layer> GetLayer() const = 0;
virtual void LoadUrl(NavigationController::LoadURLParams& params) = 0;
- virtual void OnWebPreferencesUpdated() = 0;
virtual jint GetCurrentRenderProcessId(JNIEnv* env, jobject obj) = 0;
virtual void ShowPastePopup(int x, int y) = 0;
virtual unsigned int GetScaledContentTexture(
@@ -58,6 +58,8 @@
virtual float GetDpiScale() const = 0;
virtual void SetInputHandler(
WebKit::WebCompositorInputHandler* input_handler) = 0;
+ virtual void RequestContentClipping(const gfx::Rect& clipping,
+ const gfx::Size& content_size) = 0;
// Observer callback for frame metadata updates.
typedef base::Callback<void(
diff --git a/content/public/browser/android/download_controller_android.h b/content/public/browser/android/download_controller_android.h
index df0470e..65da4b8 100644
--- a/content/public/browser/android/download_controller_android.h
+++ b/content/public/browser/android/download_controller_android.h
@@ -6,10 +6,10 @@
#define CONTENT_PUBLIC_BROWSER_ANDROID_DOWNLOAD_CONTROLLER_ANDROID_H_
#include "content/common/content_export.h"
+#include "content/public/common/context_menu_params.h"
namespace content {
class DownloadItem;
-class RenderViewHost;
class WebContents;
// Interface to request GET downloads and send notifications for POST
@@ -21,11 +21,23 @@
// Starts a new download request with Android. Should be called on the
// UI thread.
- virtual void CreateGETDownload(RenderViewHost* source, int request_id) = 0;
+ virtual void CreateGETDownload(int render_process_id, int render_view_id,
+ int request_id) = 0;
- // Should be called when a POST download is started. Notifies the embedding
+ // Should be called when a download is started. It can be either a GET
+ // request with authentication or a POST request. Notifies the embedding
// app about the download. Should be called on the UI thread.
- virtual void OnPostDownloadStarted(DownloadItem* download_item) = 0;
+ virtual void OnDownloadStarted(DownloadItem* download_item) = 0;
+
+ // Called when a download is initiated by context menu.
+ virtual void StartContextMenuDownload(
+ const ContextMenuParams& params, WebContents* web_contents,
+ bool is_link) = 0;
+
+ // Called when a dangerous download item is verified or rejected.
+ virtual void DangerousDownloadValidated(
+ WebContents* web_contents, int download_id, bool accept) = 0;
+
protected:
virtual ~DownloadControllerAndroid() {};
};
diff --git a/content/public/browser/browser_accessibility_state.h b/content/public/browser/browser_accessibility_state.h
index 16cf706..6f8d6d2 100644
--- a/content/public/browser/browser_accessibility_state.h
+++ b/content/public/browser/browser_accessibility_state.h
@@ -6,6 +6,7 @@
#define CONTENT_PUBLIC_BROWSER_BROWSER_ACCESSIBILITY_STATE_H_
#include "base/callback_forward.h"
+
#include "content/common/content_export.h"
namespace content {
@@ -20,8 +21,11 @@
// Returns the singleton instance.
static BrowserAccessibilityState* GetInstance();
- // Called when accessibility is enabled manually (via command-line flag).
- virtual void OnAccessibilityEnabledManually() = 0;
+ // Enables accessibility for all running tabs.
+ virtual void EnableAccessibility() = 0;
+
+ // Disables accessibility for all running tabs.
+ virtual void DisableAccessibility() = 0;
// Called when screen reader client is detected.
virtual void OnScreenReaderDetected() = 0;
diff --git a/content/public/browser/browser_context.h b/content/public/browser/browser_context.h
index a565cac..c7c664d 100644
--- a/content/public/browser/browser_context.h
+++ b/content/public/browser/browser_context.h
@@ -10,7 +10,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/supports_user_data.h"
#include "content/common/content_export.h"
-#include "ui/base/clipboard/clipboard.h"
+#include "ui/base/clipboard/clipboard_sourcetag.h"
class GURL;
@@ -98,8 +98,7 @@
// Returns a Clipboard::SourceTag (pointer) if |context| is OffTheRecord
// context. Otherwise, NULL. If the clipboard contains that SourceTag at the
// time of |context| destruction it will be flushed.
- static ui::Clipboard::SourceTag GetMarkerForOffTheRecordContext(
- BrowserContext* context);
+ static ui::SourceTag GetMarkerForOffTheRecordContext(BrowserContext* context);
virtual ~BrowserContext();
@@ -107,7 +106,6 @@
virtual base::FilePath GetPath() = 0;
// Return whether this context is incognito. Default is false.
- // This doesn't belong here; http://crbug.com/89628
virtual bool IsOffTheRecord() const = 0;
// Returns the request context information associated with this context. Call
@@ -118,8 +116,8 @@
// Returns the request context appropriate for the given renderer. If the
// renderer process doesn't have an associated installed app, or if the
- // installed app's is_storage_isolated() returns false, this is equivalent to
- // calling GetRequestContext().
+ // installed app doesn't have isolated storage, this is equivalent to calling
+ // GetRequestContext().
virtual net::URLRequestContextGetter* GetRequestContextForRenderProcess(
int renderer_child_id) = 0;
diff --git a/content/public/browser/browser_message_filter.cc b/content/public/browser/browser_message_filter.cc
index 4d3c2b2..6a602a9 100644
--- a/content/public/browser/browser_message_filter.cc
+++ b/content/public/browser/browser_message_filter.cc
@@ -31,7 +31,7 @@
}
void BrowserMessageFilter::OnChannelConnected(int32 peer_pid) {
- if (!base::OpenProcessHandle(peer_pid, &peer_handle_)) {
+ if (!base::OpenPrivilegedProcessHandle(peer_pid, &peer_handle_)) {
NOTREACHED();
}
}
diff --git a/content/public/browser/browser_ppapi_host.h b/content/public/browser/browser_ppapi_host.h
index d23908e..b831e09 100644
--- a/content/public/browser/browser_ppapi_host.h
+++ b/content/public/browser/browser_ppapi_host.h
@@ -47,7 +47,8 @@
IPC::ChannelProxy* channel,
net::HostResolver* host_resolver,
int render_process_id,
- int render_view_id);
+ int render_view_id,
+ const base::FilePath& profile_directory);
virtual ~BrowserPpapiHost() {}
diff --git a/content/public/browser/browser_thread.h b/content/public/browser/browser_thread.h
index 9ab2052..6e2fc67 100644
--- a/content/public/browser/browser_thread.h
+++ b/content/public/browser/browser_thread.h
@@ -19,9 +19,8 @@
#include "base/logging.h"
#endif // UNIT_TEST
-class MessageLoop;
-
namespace base {
+class MessageLoop;
class SequencedWorkerPool;
class Thread;
}
@@ -216,7 +215,7 @@
//
// Ownership remains with the BrowserThread implementation, so you
// must not delete the pointer.
- static MessageLoop* UnsafeGetMessageLoopForThread(ID identifier);
+ static base::MessageLoop* UnsafeGetMessageLoopForThread(ID identifier);
// Sets the delegate for the specified BrowserThread.
//
@@ -268,7 +267,6 @@
struct DeleteOnIOThread : public DeleteOnThread<IO> { };
struct DeleteOnFileThread : public DeleteOnThread<FILE> { };
struct DeleteOnDBThread : public DeleteOnThread<DB> { };
- struct DeleteOnWebKitThread : public DeleteOnThread<WEBKIT_DEPRECATED> { };
private:
friend class BrowserThreadImpl;
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 27ebe56..05b7da9 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -26,6 +26,14 @@
return NULL;
}
+GURL ContentBrowserClient::GetPossiblyPrivilegedURL(
+ content::BrowserContext* browser_context,
+ const GURL& url,
+ bool is_renderer_initiated,
+ SiteInstance* current_instance) {
+ return url;
+}
+
GURL ContentBrowserClient::GetEffectiveURL(BrowserContext* browser_context,
const GURL& url) {
return url;
@@ -36,10 +44,6 @@
return false;
}
-std::vector<std::string> ContentBrowserClient::GetAdditionalWebUISchemes() {
- return std::vector<std::string>();
-}
-
net::URLRequestContextGetter* ContentBrowserClient::CreateRequestContext(
BrowserContext* browser_context,
ProtocolHandlerMap* protocol_handlers) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index b89fffa..c7fe000 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -13,9 +13,10 @@
#include "base/callback_forward.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
#include "content/public/browser/file_descriptor_info.h"
-#include "content/public/common/socket_permission_request.h"
#include "content/public/common/content_client.h"
+#include "content/public/common/socket_permission_request.h"
#include "content/public/common/window_container_type.h"
#include "net/base/mime_util.h"
#include "net/cookies/canonical_cookie.h"
@@ -29,6 +30,7 @@
class CommandLine;
class GURL;
+struct WebPreferences;
namespace base {
class FilePath;
@@ -61,8 +63,8 @@
class SelectFilePolicy;
}
-namespace webkit_glue {
-struct WebPreferences;
+namespace fileapi {
+class FileSystemMountPointProvider;
}
namespace content {
@@ -125,9 +127,6 @@
virtual WebContentsViewDelegate* GetWebContentsViewDelegate(
WebContents* web_contents);
- // Notifies that a new RenderHostView has been created.
- virtual void RenderViewHostCreated(RenderViewHost* render_view_host) {}
-
// Notifies that a <webview> guest WebContents has been created.
virtual void GuestWebContentsCreated(WebContents* guest_web_contents,
WebContents* embedder_web_contents) {}
@@ -140,6 +139,22 @@
// Notifies that a BrowserChildProcessHost has been created.
virtual void BrowserChildProcessHostCreated(BrowserChildProcessHost* host) {}
+ // Determines whether a navigation from |current_instance| to |url| would be a
+ // valid entry point to a "privileged site," based on whether it
+ // |is_renderer_initiated|. A privileged site requires careful process
+ // isolation to ensure its privileges do not leak, and it can only be entered
+ // via known navigation paths.
+ //
+ // If this is a valid entry to a privileged site, this function should rewrite
+ // the origin of |url| with a non-http(s) origin that represents the
+ // privileged site. This will distinguish the resulting SiteInstance from
+ // other SiteInstances in the process model.
+ virtual GURL GetPossiblyPrivilegedURL(
+ content::BrowserContext* browser_context,
+ const GURL& url,
+ bool is_renderer_initiated,
+ SiteInstance* current_instance);
+
// Get the effective URL for the given actual URL, to allow an embedder to
// group different url schemes in the same SiteInstance.
virtual GURL GetEffectiveURL(BrowserContext* browser_context,
@@ -154,7 +169,8 @@
// act as aliases to the chrome: scheme. The additional schemes may or may
// not serve specific WebUI pages depending on the particular URLDataSource
// and its override of URLDataSource::ShouldServiceRequest.
- virtual std::vector<std::string> GetAdditionalWebUISchemes();
+ virtual void GetAdditionalWebUISchemes(
+ std::vector<std::string>* additional_schemes) {}
// Creates the main net::URLRequestContextGetter. Should only be called once
// per ContentBrowserClient object.
@@ -441,16 +457,13 @@
// to the embedder to update it if it wants.
virtual void OverrideWebkitPrefs(RenderViewHost* render_view_host,
const GURL& url,
- webkit_glue::WebPreferences* prefs) {}
+ WebPreferences* prefs) {}
// Inspector setting was changed and should be persisted.
virtual void UpdateInspectorSetting(RenderViewHost* rvh,
const std::string& key,
const std::string& value) {}
- // Clear the Inspector settings.
- virtual void ClearInspectorSettings(RenderViewHost* rvh) {}
-
// Notifies that BrowserURLHandler has been created, so that the embedder can
// optionally add their own handlers.
virtual void BrowserURLHandlerCreated(BrowserURLHandler* handler) {}
@@ -496,6 +509,17 @@
virtual ui::SelectFilePolicy* CreateSelectFilePolicy(
WebContents* web_contents);
+ // Returns additional allowed scheme set which can access files in
+ // FileSystem API.
+ virtual void GetAdditionalAllowedSchemesForFileSystem(
+ std::vector<std::string>* additional_schemes) {}
+
+ // Returns additional MountPointProviders for FileSystem API.
+ virtual void GetAdditionalFileSystemMountPointProviders(
+ const base::FilePath& storage_partition_path,
+ ScopedVector<fileapi::FileSystemMountPointProvider>*
+ additional_providers) {}
+
#if defined(OS_POSIX) && !defined(OS_MACOSX)
// Populates |mappings| with all files that need to be mapped before launching
// a child process.
diff --git a/content/public/browser/cookie_store_factory.h b/content/public/browser/cookie_store_factory.h
new file mode 100644
index 0000000..c7a9c6e
--- /dev/null
+++ b/content/public/browser/cookie_store_factory.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_COOKIE_STORE_FACTORY_H_
+#define CONTENT_PUBLIC_BROWSER_COOKIE_STORE_FACTORY_H_
+
+#include "content/common/content_export.h"
+#include "net/cookies/cookie_monster.h"
+
+namespace base {
+class FilePath;
+}
+
+namespace quota {
+class SpecialStoragePolicy;
+}
+
+namespace content {
+
+CONTENT_EXPORT net::CookieStore* CreatePersistentCookieStore(
+ const base::FilePath& path,
+ bool restore_old_session_cookies,
+ quota::SpecialStoragePolicy* storage_policy,
+ net::CookieMonster::Delegate* cookie_monster_delegate);
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_COOKIE_STORE_FACTORY_H_
diff --git a/content/public/browser/devtools_agent_host.h b/content/public/browser/devtools_agent_host.h
index 9b9a0cc..80182fe 100644
--- a/content/public/browser/devtools_agent_host.h
+++ b/content/public/browser/devtools_agent_host.h
@@ -52,6 +52,9 @@
// Returns a list of all existing RenderViewHost's that can be debugged.
static std::vector<RenderViewHost*> GetValidRenderViewHosts();
+ // Returns true if there is a client attached.
+ virtual bool IsAttached() = 0;
+
// Starts inspecting element at position (|x|, |y|) in the specified page.
virtual void InspectElement(int x, int y) = 0;
diff --git a/content/public/browser/devtools_external_agent_proxy.h b/content/public/browser/devtools_external_agent_proxy.h
new file mode 100644
index 0000000..25d7016
--- /dev/null
+++ b/content/public/browser/devtools_external_agent_proxy.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_DEVTOOLS_EXTERNAL_AGENT_PROXY_H_
+#define CONTENT_PUBLIC_BROWSER_DEVTOOLS_EXTERNAL_AGENT_PROXY_H_
+
+#include <string>
+
+#include "content/common/content_export.h"
+
+namespace content {
+
+class DevToolsAgentHost;
+class DevToolsExternalAgentProxyDelegate;
+
+// Describes interface for communication with an external DevTools agent.
+class DevToolsExternalAgentProxy {
+ public:
+ // Creates DevToolsExternalAgentProxy to communicate with an agent
+ // via the provided |delegate|.
+ // Caller get the proxy ownership and keeps the |delegate| ownership.
+ static CONTENT_EXPORT DevToolsExternalAgentProxy* Create(
+ DevToolsExternalAgentProxyDelegate* delegate);
+
+ // Returns the local DevToolsAgentHost for the external agent.
+ virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() = 0;
+
+ // Sends the message to the client host.
+ virtual void DispatchOnClientHost(const std::string& message) = 0;
+
+ // Informs the client that the connection has closed.
+ virtual void ConnectionClosed() = 0;
+
+ virtual ~DevToolsExternalAgentProxy() {}
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_DEVTOOLS_EXTERNAL_AGENT_PROXY_H_
diff --git a/content/public/browser/devtools_external_agent_proxy_delegate.h b/content/public/browser/devtools_external_agent_proxy_delegate.h
new file mode 100644
index 0000000..d68854f
--- /dev/null
+++ b/content/public/browser/devtools_external_agent_proxy_delegate.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_DEVTOOLS_EXTERNAL_AGENT_PROXY_DELEGATE_H_
+#define CONTENT_PUBLIC_BROWSER_DEVTOOLS_EXTERNAL_AGENT_PROXY_DELEGATE_H_
+
+#include <string>
+
+#include "content/common/content_export.h"
+
+namespace content {
+
+// Describes the interface for sending messages to an external DevTools agent.
+class DevToolsExternalAgentProxyDelegate {
+ public:
+ // Informs the agent that a client host has attached.
+ virtual void Attach() = 0;
+
+ // Informs the agent that a client host has detached.
+ virtual void Detach() = 0;
+
+ // Sends a message to the agent.
+ virtual void SendMessageToBackend(const std::string& message) = 0;
+
+ protected:
+ virtual ~DevToolsExternalAgentProxyDelegate() {}
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_DEVTOOLS_EXTERNAL_AGENT_PROXY_DELEGATE_H_
diff --git a/content/public/browser/devtools_http_handler_delegate.h b/content/public/browser/devtools_http_handler_delegate.h
index e9b37d4..4476a17 100644
--- a/content/public/browser/devtools_http_handler_delegate.h
+++ b/content/public/browser/devtools_http_handler_delegate.h
@@ -9,6 +9,8 @@
#include <vector>
#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
+#include "net/socket/stream_listen_socket.h"
class GURL;
@@ -47,6 +49,12 @@
// Provides the delegate with an ability to supply a description for views.
virtual std::string GetViewDescription(content::RenderViewHost*) = 0;
+
+ // Creates named socket for reversed tethering implementation (used with
+ // remote debugging, primarily for mobile).
+ virtual scoped_refptr<net::StreamListenSocket> CreateSocketForTethering(
+ net::StreamListenSocket::Delegate* delegate,
+ std::string* name) = 0;
};
} // namespace content
diff --git a/content/public/browser/devtools_manager.h b/content/public/browser/devtools_manager.h
index ae5df5a..32082ea 100644
--- a/content/public/browser/devtools_manager.h
+++ b/content/public/browser/devtools_manager.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/callback.h"
#include "content/common/content_export.h"
namespace IPC {
@@ -34,31 +35,29 @@
virtual bool DispatchOnInspectorBackend(DevToolsClientHost* from,
const std::string& message) = 0;
- // Closes all open developer tools windows.
+ // Disconnects all client hostst.
virtual void CloseAllClientHosts() = 0;
- // Returns client attached to the |agent_host| if there is one.
- virtual DevToolsClientHost* GetDevToolsClientHostFor(
- DevToolsAgentHost* agent_host) = 0;
-
- // Returns agent that has |client_host| attachd to it if there is one.
+ // Returns agent that has |client_host| attached to it if there is one.
virtual DevToolsAgentHost* GetDevToolsAgentHostFor(
DevToolsClientHost* client_host) = 0;
- // Registers new DevToolsClientHost for inspected |agent_host|. There must be
- // no other DevToolsClientHosts registered for the |agent_host| at the moment.
+ // Registers new DevToolsClientHost for inspected |agent_host|. If there is
+ // another DevToolsClientHost registered for the |agent_host| at the moment
+ // it is disconnected.
virtual void RegisterDevToolsClientHostFor(
DevToolsAgentHost* agent_host,
DevToolsClientHost* client_host) = 0;
- // Unregisters given |agent_host|. DevToolsManager will notify corresponding
- // client if one is attached.
- virtual void UnregisterDevToolsClientHostFor(
- DevToolsAgentHost* agent_host) = 0;
// This method will remove all references from the manager to the
// DevToolsClientHost and unregister all listeners related to the
// DevToolsClientHost. Called by closing client.
virtual void ClientHostClosing(DevToolsClientHost* client_host) = 0;
+
+ typedef base::Callback<void(DevToolsAgentHost*, bool attached)> Callback;
+
+ virtual void AddAgentStateCallback(const Callback& callback) = 0;
+ virtual void RemoveAgentStateCallback(const Callback& callback) = 0;
};
} // namespace content
diff --git a/content/public/browser/download_manager.h b/content/public/browser/download_manager.h
index 330aa57..e34f080 100644
--- a/content/public/browser/download_manager.h
+++ b/content/public/browser/download_manager.h
@@ -102,9 +102,6 @@
// clearing |downloads| first.
virtual void GetAllDownloads(DownloadVector* downloads) = 0;
- // Returns true if initialized properly.
- virtual bool Init(BrowserContext* browser_context) = 0;
-
// Called by a download source (Currently DownloadResourceHandler)
// to initiate the non-source portions of a download.
// Returns the id assigned to the download. If the DownloadCreateInfo
diff --git a/content/public/browser/favicon_status.h b/content/public/browser/favicon_status.h
index 3d1af9a..cfa4773 100644
--- a/content/public/browser/favicon_status.h
+++ b/content/public/browser/favicon_status.h
@@ -8,7 +8,6 @@
#include "content/common/content_export.h"
#include "googleurl/src/gurl.h"
#include "ui/gfx/image/image.h"
-#include "third_party/skia/include/core/SkBitmap.h"
namespace content {
diff --git a/content/public/browser/gpu_data_manager.h b/content/public/browser/gpu_data_manager.h
index 8acdda3..f76907a 100644
--- a/content/public/browser/gpu_data_manager.h
+++ b/content/public/browser/gpu_data_manager.h
@@ -11,8 +11,6 @@
#include "base/callback_forward.h"
#include "base/process.h"
#include "content/common/content_export.h"
-#include "content/public/common/gpu_feature_type.h"
-#include "content/public/common/gpu_switching_option.h"
class GURL;
@@ -38,7 +36,7 @@
virtual void InitializeForTesting(const std::string& gpu_blacklist_json,
const content::GPUInfo& gpu_info) = 0;
- virtual GpuFeatureType GetBlacklistedFeatures() const = 0;
+ virtual bool IsFeatureBlacklisted(int feature) const = 0;
virtual GPUInfo GetGPUInfo() const = 0;
@@ -52,7 +50,9 @@
// process, establish GPU channel, and GPU info collection, should be
// blocked.
// Can be called on any thread.
- virtual bool GpuAccessAllowed() const = 0;
+ // If |reason| is not NULL and GPU access is blocked, upon return, |reason|
+ // contains a description of the reason why GPU access is blocked.
+ virtual bool GpuAccessAllowed(std::string* reason) const = 0;
// Requests complete GPUinfo if it has not already been requested
virtual void RequestCompleteGpuInfoIfNeeded() = 0;
@@ -63,10 +63,10 @@
// which can be retrieved via the GPU data manager's on-update function.
virtual void RequestVideoMemoryUsageStatsUpdate() const = 0;
- // Returns true if the software rendering should currently be used.
- virtual bool ShouldUseSoftwareRendering() const = 0;
+ // Returns true if SwiftShader should be used.
+ virtual bool ShouldUseSwiftShader() const = 0;
- // Register a path to the SwiftShader software renderer.
+ // Register a path to SwiftShader.
virtual void RegisterSwiftShaderPath(const base::FilePath& path) = 0;
// Registers/unregister |observer|.
diff --git a/content/public/browser/histogram_fetcher.h b/content/public/browser/histogram_fetcher.h
index 73dabde..5e6e090 100644
--- a/content/public/browser/histogram_fetcher.h
+++ b/content/public/browser/histogram_fetcher.h
@@ -10,7 +10,9 @@
#include "base/time.h"
#include "content/common/content_export.h"
+namespace base {
class MessageLoop;
+}
namespace content {
@@ -21,9 +23,11 @@
// been acquired, or when the wait time expires (whichever is sooner), post the
// callback to the specified message loop. Note the callback is posted exactly
// once.
-CONTENT_EXPORT void FetchHistogramsAsynchronously(MessageLoop* callback_thread,
- const base::Closure& callback,
- base::TimeDelta wait_time);
+CONTENT_EXPORT void FetchHistogramsAsynchronously(
+ base::MessageLoop* callback_thread,
+ const base::Closure& callback,
+ base::TimeDelta wait_time);
+
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_HISTOGRAM_FETCHER_H_
diff --git a/content/public/browser/indexed_db_context.h b/content/public/browser/indexed_db_context.h
index 9d87444..ce3c2c6 100644
--- a/content/public/browser/indexed_db_context.h
+++ b/content/public/browser/indexed_db_context.h
@@ -8,14 +8,10 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
-
-class GURL;
-
-namespace base {
-class Time;
-}
+#include "content/public/browser/indexed_db_info.h"
namespace content {
@@ -25,6 +21,7 @@
public:
// Methods used in response to QuotaManager requests.
virtual std::vector<GURL> GetAllOrigins() = 0;
+ virtual std::vector<IndexedDBInfo> GetAllOriginsInfo() = 0;
virtual int64 GetOriginDiskUsage(const GURL& origin_url) = 0;
virtual base::Time GetOriginLastModified(const GURL& origin_url) = 0;
diff --git a/content/public/browser/indexed_db_info.cc b/content/public/browser/indexed_db_info.cc
new file mode 100644
index 0000000..6f0116f
--- /dev/null
+++ b/content/public/browser/indexed_db_info.cc
@@ -0,0 +1,16 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/browser/indexed_db_info.h"
+
+namespace content {
+
+IndexedDBInfo::IndexedDBInfo(const GURL& origin,
+ int64 size,
+ const base::Time& last_modified,
+ const base::FilePath& path)
+ : origin_(origin), size_(size), last_modified_(last_modified), path_(path) {
+}
+
+} // namespace content
diff --git a/content/public/browser/indexed_db_info.h b/content/public/browser/indexed_db_info.h
new file mode 100644
index 0000000..951c968
--- /dev/null
+++ b/content/public/browser/indexed_db_info.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_INDEXED_DB_INFO_H_
+#define CONTENT_PUBLIC_BROWSER_INDEXED_DB_INFO_H_
+
+#include "base/files/file_path.h"
+#include "base/time.h"
+#include "content/common/content_export.h"
+#include "googleurl/src/gurl.h"
+
+namespace content {
+
+class CONTENT_EXPORT IndexedDBInfo {
+ public:
+ IndexedDBInfo(const GURL& origin,
+ int64 size,
+ const base::Time& last_modified,
+ const base::FilePath& path);
+
+ GURL origin_;
+ int64 size_;
+ base::Time last_modified_;
+ base::FilePath path_;
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_INDEXED_DB_INFO_H_
diff --git a/content/public/browser/load_from_memory_cache_details.h b/content/public/browser/load_from_memory_cache_details.h
index 49de85b..1ebf491 100644
--- a/content/public/browser/load_from_memory_cache_details.h
+++ b/content/public/browser/load_from_memory_cache_details.h
@@ -8,7 +8,7 @@
#include <string>
#include "base/basictypes.h"
#include "googleurl/src/gurl.h"
-#include "net/base/cert_status_flags.h"
+#include "net/cert/cert_status_flags.h"
#include "webkit/glue/resource_type.h"
namespace content {
diff --git a/content/public/browser/media_observer.h b/content/public/browser/media_observer.h
index 6b61528..65c9705 100644
--- a/content/public/browser/media_observer.h
+++ b/content/public/browser/media_observer.h
@@ -14,20 +14,6 @@
// ContentBrowserClient to receive callbacks as media events occur.
class MediaObserver {
public:
- // Called when capture devices are opened. The observer can call
- // |close_callback| to stop the stream.
- virtual void OnCaptureDevicesOpened(
- int render_process_id,
- int render_view_id,
- const MediaStreamDevices& devices,
- const base::Closure& close_callback) = 0;
-
- // Called when the opened capture devices are closed.
- virtual void OnCaptureDevicesClosed(
- int render_process_id,
- int render_view_id,
- const MediaStreamDevices& devices) = 0;
-
// Called when a audio capture device is plugged in or unplugged.
virtual void OnAudioCaptureDevicesChanged(
const MediaStreamDevices& devices) = 0;
@@ -43,12 +29,13 @@
const MediaStreamDevice& device,
MediaRequestState state) = 0;
- // Called when an audio stream is played or paused.
+ // Called when an audio stream transitions into playing audible or silent
+ // sound, and when the stream is stopped.
virtual void OnAudioStreamPlayingChanged(
int render_process_id,
int render_view_id,
int stream_id,
- bool playing) = 0;
+ bool is_playing_and_audible) = 0;
protected:
virtual ~MediaObserver() {}
diff --git a/content/public/browser/navigation_controller.cc b/content/public/browser/navigation_controller.cc
index 5fc56dc..fa1dc1b 100644
--- a/content/public/browser/navigation_controller.cc
+++ b/content/public/browser/navigation_controller.cc
@@ -16,7 +16,8 @@
override_user_agent(UA_OVERRIDE_INHERIT),
browser_initiated_post_data(NULL),
can_load_local_resources(false),
- is_cross_site_redirect(false) {
+ is_cross_site_redirect(false),
+ should_clear_history_list(false) {
}
NavigationController::LoadURLParams::~LoadURLParams() {
@@ -35,7 +36,8 @@
base_url_for_data_url(other.base_url_for_data_url),
virtual_url_for_data_url(other.virtual_url_for_data_url),
browser_initiated_post_data(other.browser_initiated_post_data),
- is_cross_site_redirect(false) {
+ is_cross_site_redirect(false),
+ should_clear_history_list(false) {
}
NavigationController::LoadURLParams&
@@ -53,6 +55,7 @@
virtual_url_for_data_url = other.virtual_url_for_data_url;
browser_initiated_post_data = other.browser_initiated_post_data;
is_cross_site_redirect = other.is_cross_site_redirect;
+ should_clear_history_list = other.should_clear_history_list;
return *this;
}
diff --git a/content/public/browser/navigation_controller.h b/content/public/browser/navigation_controller.h
index 1cb18ec..5109301 100644
--- a/content/public/browser/navigation_controller.h
+++ b/content/public/browser/navigation_controller.h
@@ -159,6 +159,14 @@
// navigated. This is currently only used in tests.
std::string frame_name;
+ // Indicates that during this navigation, the session history should be
+ // cleared such that the resulting page is the first and only entry of the
+ // session history.
+ //
+ // The clearing is done asynchronously, and completes when this navigation
+ // commits.
+ bool should_clear_history_list;
+
explicit LoadURLParams(const GURL& url);
~LoadURLParams();
diff --git a/content/public/browser/notification_types.h b/content/public/browser/notification_types.h
index 2902b04..db8654c 100644
--- a/content/public/browser/notification_types.h
+++ b/content/public/browser/notification_types.h
@@ -102,16 +102,6 @@
// issued. Details in the form of a ResourceRedirectDetails are provided.
NOTIFICATION_RESOURCE_RECEIVED_REDIRECT,
- // Devtools ------------------------------------------------------------------
-
- // Indicates that a devtools agent has attached to a client. The source is
- // the BrowserContext* and the details is the inspected RenderViewHost*.
- NOTIFICATION_DEVTOOLS_AGENT_ATTACHED,
-
- // Indicates that a devtools agent has detached from a client. The source is
- // the BrowserContext* and the details is the inspected RenderViewHost*.
- NOTIFICATION_DEVTOOLS_AGENT_DETACHED,
-
// WebContents ---------------------------------------------------------------
// This notification is sent when a render view host has connected to a
@@ -206,10 +196,6 @@
// Used only in testing.
NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK,
- // Sent from RenderViewHost constructor. The source is the RenderViewHost,
- // the details unused.
- NOTIFICATION_RENDER_VIEW_HOST_CREATED,
-
// Sent from RenderViewHost::ClosePage. The hosted RenderView has
// processed the onbeforeunload handler and is about to be sent a
// ViewMsg_ClosePage message to complete the tear-down process. The source
diff --git a/content/public/browser/render_view_host.h b/content/public/browser/render_view_host.h
index 311debe..e59f5bc 100644
--- a/content/public/browser/render_view_host.h
+++ b/content/public/browser/render_view_host.h
@@ -14,6 +14,7 @@
class GURL;
struct WebDropData;
+struct WebPreferences;
namespace gfx {
class Point;
@@ -34,10 +35,6 @@
struct WebPluginAction;
}
-namespace webkit_glue {
-struct WebPreferences;
-}
-
namespace content {
class ChildProcessSecurityPolicy;
@@ -60,8 +57,6 @@
// WebContents (see WebContents for an example) but also as views, etc.
class CONTENT_EXPORT RenderViewHost : virtual public RenderWidgetHost {
public:
- typedef base::Callback<void(const base::Value*)> JavascriptResultCallback;
-
// Returns the RenderViewHost given its ID and the ID of its render process.
// Returns NULL if the IDs do not correspond to a live RenderViewHost.
static RenderViewHost* FromID(int render_process_id, int render_view_id);
@@ -77,6 +72,11 @@
bool empty_allowed,
GURL* url);
+ // Adds/removes a callback called on creation of each new RenderViewHost.
+ typedef base::Callback<void(RenderViewHost*)> CreatedCallback;
+ static void AddCreatedCallback(const CreatedCallback& callback);
+ static void RemoveCreatedCallback(const CreatedCallback& callback);
+
virtual ~RenderViewHost() {}
// Tell the render view to enable a set of javascript bindings. The argument
@@ -178,6 +178,7 @@
// Runs some javascript within the context of a frame in the page. The result
// is sent back via the provided callback.
+ typedef base::Callback<void(const base::Value*)> JavascriptResultCallback;
virtual void ExecuteJavascriptInWebFrameCallbackResult(
const string16& frame_xpath,
const string16& jscript,
@@ -269,11 +270,10 @@
virtual void ToggleSpeechInput() = 0;
// Returns the current WebKit preferences.
- virtual webkit_glue::WebPreferences GetWebkitPreferences() = 0;
+ virtual WebPreferences GetWebkitPreferences() = 0;
// Passes a list of Webkit preferences to the renderer.
- virtual void UpdateWebkitPreferences(
- const webkit_glue::WebPreferences& prefs) = 0;
+ virtual void UpdateWebkitPreferences(const WebPreferences& prefs) = 0;
// Informs the renderer process of a change in timezone.
virtual void NotifyTimezoneChange() = 0;
diff --git a/content/public/browser/render_widget_host_view.h b/content/public/browser/render_widget_host_view.h
index 461ab6d..b881748 100644
--- a/content/public/browser/render_widget_host_view.h
+++ b/content/public/browser/render_widget_host_view.h
@@ -165,9 +165,8 @@
#endif
#if defined(OS_WIN) && defined(USE_AURA)
- // Set the parent native accessible view for this View.
- virtual void SetParentNativeViewAccessible(
- gfx::NativeViewAccessible accessible_parent) = 0;
+ virtual gfx::NativeViewAccessible AccessibleObjectFromChildId(long child_id)
+ = 0;
#endif
};
diff --git a/content/public/browser/render_widget_host_view_mac_delegate.h b/content/public/browser/render_widget_host_view_mac_delegate.h
index 4e79fcb..7d24ac92 100644
--- a/content/public/browser/render_widget_host_view_mac_delegate.h
+++ b/content/public/browser/render_widget_host_view_mac_delegate.h
@@ -41,6 +41,9 @@
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item
isValidItem:(BOOL*)valid;
+// Notification that the compositing IO surface has been created.
+- (void)compositingIOSurfaceCreated;
+
@end
#endif // CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_VIEW_MAC_DELEGATE_H_
diff --git a/content/public/browser/resource_request_details.h b/content/public/browser/resource_request_details.h
index 9504b30..4e94418 100644
--- a/content/public/browser/resource_request_details.h
+++ b/content/public/browser/resource_request_details.h
@@ -8,7 +8,7 @@
#include <string>
#include "googleurl/src/gurl.h"
-#include "net/base/cert_status_flags.h"
+#include "net/cert/cert_status_flags.h"
#include "net/base/host_port_pair.h"
#include "net/url_request/url_request_status.h"
#include "webkit/glue/resource_type.h"
diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h
index b0348da..bd7f90c 100644
--- a/content/public/browser/storage_partition.h
+++ b/content/public/browser/storage_partition.h
@@ -69,6 +69,12 @@
kLocalDomStorage = 1 << 3,
kSessionDomStorage = 1 << 4,
+ // Local shader storage.
+ kShaderStorage = 1 << 5,
+
+ // Corresponds to quota::kStorageTypeSyncable.
+ kQuotaManagedSyncableStorage = 1 << 6,
+
kAllStorage = -1,
};
@@ -91,6 +97,15 @@
// StoragePartition rather than just the data related to this origin.
virtual void AsyncClearData(uint32 storage_mask) = 0;
+ // Similar to AsyncClearDataForOrigin(), but deletes all the data out of the
+ // StoragePartion from between the given |begin| and |end| dates rather
+ // then just the data related to this origin.
+ //
+ // Note: This currently only supports the shader cache.
+ virtual void AsyncClearDataBetween(uint32 storage_mask,
+ const base::Time& begin,
+ const base::Time& end,
+ const base::Closure& callback) = 0;
protected:
virtual ~StoragePartition() {}
};
diff --git a/content/public/browser/trace_controller.h b/content/public/browser/trace_controller.h
index aac45acf..0049555 100644
--- a/content/public/browser/trace_controller.h
+++ b/content/public/browser/trace_controller.h
@@ -31,10 +31,11 @@
// or if another subscriber is tracing,
// BeginTracing will return false meaning it failed.
//
- // |categories| is a comma-delimited list of category wildcards.
- // A category can have an optional '-' prefix to make it an excluded category.
+ // |category_patterns| is a comma-delimited list of category wildcards.
+ // A category pattern can have an optional '-' prefix to exclude category
+ // groups that contain a matching category.
// All the same rules apply above, so for example, having both included and
- // excluded categories in the same list would not be supported.
+ // excluded category patterns in the same list would not be supported.
//
// |mode| is the tracing mode being used.
//
@@ -42,7 +43,7 @@
// Example: BeginTracing("test_MyTest*,test_OtherStuff");
// Example: BeginTracing("-excluded_category1,-excluded_category2");
virtual bool BeginTracing(TraceSubscriber* subscriber,
- const std::string& categories,
+ const std::string& category_patterns,
base::debug::TraceLog::Options options) = 0;
// Called by browser process to stop tracing events on all processes.
@@ -88,10 +89,10 @@
// Safe to call even if caller is not the current subscriber.
virtual void CancelSubscriber(TraceSubscriber* subscriber) = 0;
- // Get set of known categories. This can change as new code paths are reached.
- // If true is returned, subscriber->OnKnownCategoriesCollected will be called
- // once the categories are retrieved from child processes.
- virtual bool GetKnownCategoriesAsync(TraceSubscriber* subscriber) = 0;
+ // Get set of known category groups. This can change as new code paths are
+ // reached. If true is returned, subscriber->OnKnownCategoriesCollected will
+ // be called once the categories are retrieved from child processes.
+ virtual bool GetKnownCategoryGroupsAsync(TraceSubscriber* subscriber) = 0;
protected:
virtual ~TraceController() {}
diff --git a/content/public/browser/trace_subscriber.h b/content/public/browser/trace_subscriber.h
index ec8d070..02e9f1c 100644
--- a/content/public/browser/trace_subscriber.h
+++ b/content/public/browser/trace_subscriber.h
@@ -26,7 +26,7 @@
virtual void OnTraceDataCollected(
const scoped_refptr<base::RefCountedString>& trace_fragment) = 0;
- // Called once after TraceController::GetKnownCategoriesAsync.
+ // Called once after TraceController::GetKnownCategoryGroupsAsync.
virtual void OnKnownCategoriesCollected(
const std::set<std::string>& known_categories) {}
diff --git a/content/public/browser/url_data_source.cc b/content/public/browser/url_data_source.cc
index b3c62b3..669f5c8 100644
--- a/content/public/browser/url_data_source.cc
+++ b/content/public/browser/url_data_source.cc
@@ -16,7 +16,7 @@
URLDataManager::AddDataSource(browser_context, source);
}
-MessageLoop* URLDataSource::MessageLoopForRequestPath(
+base::MessageLoop* URLDataSource::MessageLoopForRequestPath(
const std::string& path) const {
return BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::UI);
}
diff --git a/content/public/browser/url_data_source.h b/content/public/browser/url_data_source.h
index 49daf87..d6ff1e0 100644
--- a/content/public/browser/url_data_source.h
+++ b/content/public/browser/url_data_source.h
@@ -10,9 +10,8 @@
#include "base/callback.h"
#include "content/common/content_export.h"
-class MessageLoop;
-
namespace base {
+class MessageLoop;
class RefCountedMemory;
}
@@ -38,7 +37,7 @@
// The name of this source.
// E.g., for favicons, this could be "favicon", which results in paths for
// specific resources like "favicon/34" getting sent to this source.
- virtual std::string GetSource() = 0;
+ virtual std::string GetSource() const = 0;
// Used by StartDataRequest so that the child class can return the data when
// it's available.
@@ -49,7 +48,8 @@
// data is available or if the request could not be satisfied. This can be
// called either in this callback or asynchronously with the response.
virtual void StartDataRequest(const std::string& path,
- bool is_incognito,
+ int render_process_id,
+ int render_view_id,
const GotDataCallback& callback) = 0;
// Return the mimetype that should be sent with this response, or empty
@@ -66,7 +66,8 @@
// on the IO thread. This can improve performance by satisfying such requests
// more rapidly when there is a large amount of UI thread contention. Or the
// delegate can return a specific thread's Messageloop if they wish.
- virtual MessageLoop* MessageLoopForRequestPath(const std::string& path) const;
+ virtual base::MessageLoop* MessageLoopForRequestPath(
+ const std::string& path) const;
// Returns true if the URLDataSource should replace an existing URLDataSource
// with the same name that has already been registered. The default is true.
@@ -106,6 +107,13 @@
// ContentBrowserClient::GetAdditionalWebUISchemes() to permit additional
// WebUI scheme support for an embedder.
virtual bool ShouldServiceRequest(const net::URLRequest* request) const;
+
+ // Called to inform the source that StartDataRequest() will be called soon.
+ // Gives the source an opportunity to rewrite |path| to incorporate extra
+ // information from the URLRequest prior to serving.
+ virtual void WillServiceRequest(
+ const net::URLRequest* request,
+ std::string* path) const {}
};
} // namespace content
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index 22f0fab..8a3d038 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -173,8 +173,6 @@
virtual WebUI* CreateWebUI(const GURL& url) = 0;
// Returns the committed WebUI if one exists, otherwise the pending one.
- // Callers who want to use the pending WebUI for the pending navigation entry
- // should use GetWebUIForCurrentState instead.
virtual WebUI* GetWebUI() const = 0;
virtual WebUI* GetCommittedWebUI() const = 0;
@@ -182,6 +180,11 @@
virtual void SetUserAgentOverride(const std::string& override) = 0;
virtual const std::string& GetUserAgentOverride() const = 0;
+#if defined(OS_WIN) && defined(USE_AURA)
+ virtual void SetParentNativeViewAccessible(
+ gfx::NativeViewAccessible accessible_parent) = 0;
+#endif
+
// Tab navigation state ------------------------------------------------------
// Returns the current navigation properties, which if a navigation is
@@ -384,10 +387,6 @@
// Get the content restrictions (see content::ContentRestriction).
virtual int GetContentRestrictions() const = 0;
- // Returns the WebUI for the current state of the tab. This will either be
- // the pending WebUI, the committed WebUI, or NULL.
- virtual WebUI* GetWebUIForCurrentState()= 0;
-
// Called when the reponse to a pending mouse lock request has arrived.
// Returns true if |allowed| is true and the mouse has been successfully
// locked.
@@ -412,19 +411,19 @@
const GURL&, /* image_url */
int, /* requested_size */
const std::vector<SkBitmap>& /* bitmaps*/)>
- FaviconDownloadCallback;
+ ImageDownloadCallback;
- // Sends a request to download the given favicon |url| and returns the unique
+ // Sends a request to download the given image |url| and returns the unique
// id of the download request. When the download is finished, |callback| will
- // be called with the bitmaps received from the renderer. If [is_favicon|,
- // the cookeis are not sent and not accepted during download. Note that
+ // be called with the bitmaps received from the renderer. If |is_favicon| is
+ // true, the cookies are not sent and not accepted during download. Note that
// |image_size| is a hint for images with multiple sizes. The downloaded image
// is not resized to the given image_size. If 0 is passed, the first frame of
// the image is returned.
- virtual int DownloadFavicon(const GURL& url,
- bool is_favicon,
- int image_size,
- const FaviconDownloadCallback& callback) = 0;
+ virtual int DownloadImage(const GURL& url,
+ bool is_favicon,
+ int image_size,
+ const ImageDownloadCallback& callback) = 0;
private:
// This interface should only be implemented inside content.
diff --git a/content/public/browser/web_contents_delegate.cc b/content/public/browser/web_contents_delegate.cc
index 7a4409d..db56c7e 100644
--- a/content/public/browser/web_contents_delegate.cc
+++ b/content/public/browser/web_contents_delegate.cc
@@ -69,10 +69,12 @@
return 0;
}
-bool WebContentsDelegate::CanDownload(RenderViewHost* render_view_host,
- int request_id,
- const std::string& request_method) {
- return true;
+void WebContentsDelegate::CanDownload(
+ RenderViewHost* render_view_host,
+ int request_id,
+ const std::string& request_method,
+ const base::Callback<void(bool)>& callback) {
+ callback.Run(true);
}
bool WebContentsDelegate::HandleContextMenu(
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h
index 6705514..60732ce 100644
--- a/content/public/browser/web_contents_delegate.h
+++ b/content/public/browser/web_contents_delegate.h
@@ -56,8 +56,6 @@
struct OpenURLParams;
-typedef base::Callback< void(const MediaStreamDevices&) > MediaResponseCallback;
-
// Objects implement this interface to get notified about changes in the
// WebContents and to provide necessary functionality.
class CONTENT_EXPORT WebContentsDelegate {
@@ -220,9 +218,11 @@
virtual void WebContentsFocused(WebContents* contents) {}
// Asks the delegate if the given tab can download.
- virtual bool CanDownload(RenderViewHost* render_view_host,
+ // Invoking the |callback| synchronously is OK.
+ virtual void CanDownload(RenderViewHost* render_view_host,
int request_id,
- const std::string& request_method);
+ const std::string& request_method,
+ const base::Callback<void(bool)>& callback);
// Return much extra vertical space should be allotted to the
// render view widget during various animations (e.g. infobar closing).
diff --git a/content/public/browser/web_ui.h b/content/public/browser/web_ui.h
index 3e72a64..88632db 100644
--- a/content/public/browser/web_ui.h
+++ b/content/public/browser/web_ui.h
@@ -57,21 +57,6 @@
// Javascript.
virtual ui::ScaleFactor GetDeviceScaleFactor() const = 0;
- // Returns true if the favicon should be hidden for the current tab.
- virtual bool ShouldHideFavicon() const = 0;
- virtual void HideFavicon() = 0;
-
- // Returns true if the location bar should be focused by default rather than
- // the page contents. Some pages will want to use this to encourage the user
- // to type in the URL bar.
- virtual bool ShouldFocusLocationBarByDefault() const = 0;
- virtual void FocusLocationBarByDefault() = 0;
-
- // Returns true if the page's URL should be hidden. Some Web UI pages
- // like the new tab page will want to hide it.
- virtual bool ShouldHideURL() const = 0;
- virtual void HideURL() = 0;
-
// Gets a custom tab title provided by the Web UI. If there is no title
// override, the string will be empty which should trigger the default title
// behavior for the tab.
diff --git a/content/public/common/child_process_sandbox_support_linux.h b/content/public/common/child_process_sandbox_support_linux.h
index 2094558..f653e35 100644
--- a/content/public/common/child_process_sandbox_support_linux.h
+++ b/content/public/common/child_process_sandbox_support_linux.h
@@ -31,14 +31,16 @@
// GetFontTable loads a specified font table from an open SFNT file.
// fd: a file descriptor to the SFNT file. The position doesn't matter.
-// table: the table in *big-endian* format, or 0 for the whole font file.
+// table_tag: the table tag in *big-endian* format, or 0 for the entire font.
+// offset: offset into the table or entire font where loading should start.
+// The offset must be between 0 and 1 GB - 1.
// output: a buffer of size output_length that gets the data. can be 0, in
// which case output_length will be set to the required size in bytes.
// output_length: size of output, if it's not 0.
//
// returns: true on success.
-CONTENT_EXPORT bool GetFontTable(int fd, uint32_t table, uint8_t* output,
- size_t* output_length);
+CONTENT_EXPORT bool GetFontTable(int fd, uint32_t table_tag, off_t offset,
+ uint8_t* output, size_t* output_length);
}; // namespace content
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h
index 11322eb..306d8b7 100644
--- a/content/public/common/common_param_traits_macros.h
+++ b/content/public/common/common_param_traits_macros.h
@@ -31,7 +31,7 @@
IPC_ENUM_TRAITS(content::SecurityStyle)
IPC_ENUM_TRAITS(WebKit::WebReferrerPolicy)
IPC_ENUM_TRAITS(WindowOpenDisposition)
-IPC_ENUM_TRAITS(webkit_glue::WebPreferences::EditingBehavior)
+IPC_ENUM_TRAITS(webkit_glue::EditingBehavior)
IPC_ENUM_TRAITS(content::PasswordForm::Type)
IPC_ENUM_TRAITS(net::RequestPriority)
@@ -54,6 +54,7 @@
IPC_STRUCT_TRAITS_MEMBER(submit_element)
IPC_STRUCT_TRAITS_MEMBER(username_element)
IPC_STRUCT_TRAITS_MEMBER(username_value)
+IPC_STRUCT_TRAITS_MEMBER(possible_usernames)
IPC_STRUCT_TRAITS_MEMBER(password_element)
IPC_STRUCT_TRAITS_MEMBER(password_value)
IPC_STRUCT_TRAITS_MEMBER(password_autocomplete_set)
@@ -92,7 +93,7 @@
IPC_STRUCT_TRAITS_MEMBER(pepper_permissions)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(webkit_glue::WebPreferences)
+IPC_STRUCT_TRAITS_BEGIN(WebPreferences)
IPC_STRUCT_TRAITS_MEMBER(standard_font_family_map)
IPC_STRUCT_TRAITS_MEMBER(fixed_font_family_map)
IPC_STRUCT_TRAITS_MEMBER(serif_font_family_map)
@@ -113,7 +114,6 @@
IPC_STRUCT_TRAITS_MEMBER(images_enabled)
IPC_STRUCT_TRAITS_MEMBER(plugins_enabled)
IPC_STRUCT_TRAITS_MEMBER(dom_paste_enabled)
- IPC_STRUCT_TRAITS_MEMBER(developer_extras_enabled)
IPC_STRUCT_TRAITS_MEMBER(inspector_settings)
IPC_STRUCT_TRAITS_MEMBER(site_specific_quirks_enabled)
IPC_STRUCT_TRAITS_MEMBER(shrinks_standalone_images_to_fit)
@@ -121,8 +121,6 @@
IPC_STRUCT_TRAITS_MEMBER(text_areas_are_resizable)
IPC_STRUCT_TRAITS_MEMBER(java_enabled)
IPC_STRUCT_TRAITS_MEMBER(allow_scripts_to_close_windows)
- IPC_STRUCT_TRAITS_MEMBER(uses_page_cache)
- IPC_STRUCT_TRAITS_MEMBER(page_cache_supports_plugins)
IPC_STRUCT_TRAITS_MEMBER(remote_fonts_enabled)
IPC_STRUCT_TRAITS_MEMBER(javascript_can_access_clipboard)
IPC_STRUCT_TRAITS_MEMBER(xss_auditor_enabled)
@@ -136,7 +134,6 @@
IPC_STRUCT_TRAITS_MEMBER(user_style_sheet_enabled)
IPC_STRUCT_TRAITS_MEMBER(user_style_sheet_location)
IPC_STRUCT_TRAITS_MEMBER(author_and_user_styles_enabled)
- IPC_STRUCT_TRAITS_MEMBER(frame_flattening_enabled)
IPC_STRUCT_TRAITS_MEMBER(allow_universal_access_from_file_urls)
IPC_STRUCT_TRAITS_MEMBER(allow_file_access_from_file_urls)
IPC_STRUCT_TRAITS_MEMBER(webaudio_enabled)
@@ -178,6 +175,7 @@
IPC_STRUCT_TRAITS_MEMBER(css_shaders_enabled)
IPC_STRUCT_TRAITS_MEMBER(css_variables_enabled)
IPC_STRUCT_TRAITS_MEMBER(css_grid_layout_enabled)
+ IPC_STRUCT_TRAITS_MEMBER(lazy_layout_enabled)
IPC_STRUCT_TRAITS_MEMBER(touch_enabled)
IPC_STRUCT_TRAITS_MEMBER(device_supports_touch)
IPC_STRUCT_TRAITS_MEMBER(device_supports_mouse)
@@ -195,6 +193,7 @@
IPC_STRUCT_TRAITS_MEMBER(smart_insert_delete_enabled)
IPC_STRUCT_TRAITS_MEMBER(cookie_enabled)
IPC_STRUCT_TRAITS_MEMBER(apply_page_scale_factor_in_compositor)
+ IPC_STRUCT_TRAITS_MEMBER(spatial_navigation_enabled)
#if defined(OS_ANDROID)
IPC_STRUCT_TRAITS_MEMBER(text_autosizing_enabled)
IPC_STRUCT_TRAITS_MEMBER(font_scale_factor)
@@ -202,6 +201,8 @@
IPC_STRUCT_TRAITS_MEMBER(double_tap_to_zoom_enabled)
IPC_STRUCT_TRAITS_MEMBER(user_gesture_required_for_media_playback)
IPC_STRUCT_TRAITS_MEMBER(default_video_poster_url)
+ IPC_STRUCT_TRAITS_MEMBER(support_deprecated_target_density_dpi)
+ IPC_STRUCT_TRAITS_MEMBER(use_wide_viewport)
#endif
IPC_STRUCT_TRAITS_END()
diff --git a/content/public/common/content_client.cc b/content/public/common/content_client.cc
index 31bbb8a..96cf48c 100644
--- a/content/public/common/content_client.cc
+++ b/content/public/common/content_client.cc
@@ -5,7 +5,7 @@
#include "content/public/common/content_client.h"
#include "base/logging.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "ui/gfx/image/image.h"
#include "webkit/user_agent/user_agent.h"
@@ -17,6 +17,21 @@
static ContentClient* g_client;
+class InternalTestInitializer {
+ public:
+ static ContentBrowserClient* SetBrowser(ContentBrowserClient* b) {
+ ContentBrowserClient* rv = g_client->browser_;
+ g_client->browser_ = b;
+ return rv;
+ }
+
+ static ContentRendererClient* SetRenderer(ContentRendererClient* r) {
+ ContentRendererClient* rv = g_client->renderer_;
+ g_client->renderer_ = r;
+ return rv;
+ }
+};
+
void SetContentClient(ContentClient* client) {
g_client = client;
@@ -32,6 +47,14 @@
return g_client;
}
+ContentBrowserClient* SetBrowserClientForTesting(ContentBrowserClient* b) {
+ return InternalTestInitializer::SetBrowser(b);
+}
+
+ContentRendererClient* SetRendererClientForTesting(ContentRendererClient* r) {
+ return InternalTestInitializer::SetRenderer(r);
+}
+
const std::string& GetUserAgent(const GURL& url) {
DCHECK(g_client);
return webkit_glue::GetUserAgent(url);
diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h
index ab397b0..198ecad 100644
--- a/content/public/common/content_client.h
+++ b/content/public/common/content_client.h
@@ -10,7 +10,7 @@
#include "base/basictypes.h"
#include "base/string16.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "ui/base/layout.h"
@@ -57,7 +57,18 @@
// Setter and getter for the client. The client should be set early, before any
// content code is called.
CONTENT_EXPORT void SetContentClient(ContentClient* client);
-CONTENT_EXPORT ContentClient* GetContentClient();
+
+#if defined(CONTENT_IMPLEMENTATION)
+// Content's embedder API should only be used by content.
+ContentClient* GetContentClient();
+#endif
+
+// Used for tests to override the relevant embedder interfaces. Each method
+// returns the old value.
+CONTENT_EXPORT ContentBrowserClient* SetBrowserClientForTesting(
+ ContentBrowserClient* b);
+CONTENT_EXPORT ContentRendererClient* SetRendererClientForTesting(
+ ContentRendererClient* r);
// Returns the user agent string being used by the browser. SetContentClient()
// must be called prior to calling this, and this routine must be used
@@ -154,11 +165,9 @@
virtual std::string GetCarbonInterposePath() const;
#endif
- void set_browser_for_testing(ContentBrowserClient* c) { browser_ = c; }
- void set_renderer_for_testing(ContentRendererClient* r) { renderer_ = r; }
-
private:
friend class ContentClientInitializer; // To set these pointers.
+ friend class InternalTestInitializer;
// The embedder API for participating in browser logic.
ContentBrowserClient* browser_;
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index 3281123..32b1237 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -44,6 +44,10 @@
// Disable antialiasing on 2d canvas.
const char kDisable2dCanvasAntialiasing[] = "disable-canvas-aa";
+// Enable experimental canvas features, e.g. canvas 2D context attributes
+const char kEnableExperimentalCanvasFeatures[]
+ = "enable-experimental-canvas-features";
+
// Disables accelerated compositing.
const char kDisableAcceleratedCompositing[] = "disable-accelerated-compositing";
@@ -73,9 +77,6 @@
// Disables HTML5 DB support.
const char kDisableDatabases[] = "disable-databases";
-// Disables data transfer items.
-const char kDisableDataTransferItems[] = "disable-data-transfer-items";
-
// Disables desktop notifications (default enabled on windows).
const char kDisableDesktopNotifications[] = "disable-desktop-notifications";
@@ -133,6 +134,9 @@
// Manager can be used to terminate the offending process in this case.
const char kDisableHangMonitor[] = "disable-hang-monitor";
+// Disables HTML-based desktop notifications.
+const char kDisableHTMLNotifications[] = "disable-html-notifications";
+
// Disable the RenderThread's HistogramCustomizer.
const char kDisableHistogramCustomizer[] = "disable-histogram-customizer";
@@ -183,10 +187,7 @@
// Disable smooth scrolling for testing.
const char kDisableSmoothScrolling[] = "disable-smooth-scrolling";
-// Disable the seccomp sandbox (Linux only)
-const char kDisableSeccompSandbox[] = "disable-seccomp-sandbox";
-
-// Disable the seccomp filter sandbox (Linux only)
+// Disable the seccomp filter sandbox (seccomp-bpf) (Linux only).
const char kDisableSeccompFilterSandbox[] = "disable-seccomp-filter-sandbox";
// Disable session storage.
@@ -204,6 +205,9 @@
// Specifies the request key for the continuous speech recognition webservice.
const char kSpeechRecognitionWebserviceKey[] = "speech-service-key";
+// Enables web speech synthesis api.
+const char kEnableSpeechSynthesis[] = "enable-speech-synthesis";
+
#if defined(OS_ANDROID)
// Enable web audio API.
const char kEnableWebAudio[] = "enable-webaudio";
@@ -215,11 +219,14 @@
const char kDisableWebAudio[] = "disable-webaudio";
#endif
+// Enables Web MIDI API.
+const char kEnableWebMIDI[] = "enable-web-midi";
+
// Don't enforce the same-origin policy. (Used by people testing their sites.)
const char kDisableWebSecurity[] = "disable-web-security";
-// Disable Web Sockets support.
-const char kDisableWebSockets[] = "disable-web-sockets";
+// Enable an experimental WebSocket implementation.
+const char kEnableExperimentalWebSocket[] = "enable-experimental-websocket";
// Disables WebKit's XSSAuditor. The XSSAuditor mitigates reflective XSS.
const char kDisableXSSAuditor[] = "disable-xss-auditor";
@@ -248,6 +255,12 @@
// Turns on extremely verbose logging of accessibility events.
const char kEnableAccessibilityLogging[] = "enable-accessibility-logging";
+// Enable notifications of audible/silent audio output from a render view.
+//
+// TODO(miu): Remove --enable-audible-notifications once the feature goes
+// live. http://crbug.com/178934
+const char kEnableAudibleNotifications[] = "enable-audible-notifications";
+
// Enables browser plugin compositing experiment.
const char kDisableBrowserPluginCompositing[] =
"disable-browser-plugin-compositing";
@@ -256,6 +269,10 @@
const char kEnableBrowserPluginForAllViewTypes[] =
"enable-browser-plugin-for-all-view-types";
+// Enables Drag and Drop into and out of Browser Plugin.
+// kEnableBrowserPluginGuestViews must also be set at this time.
+const char kEnableBrowserPluginDragDrop[] = "enable-browser-plugin-drag-drop";
+
// Enable/Disable the creation of compositing layers for fixed position
// elements. Three options are needed to support four possible scenarios:
// 1. Default (disabled)
@@ -292,9 +309,6 @@
// Disables the threaded HTML parser in WebKit
const char kDisableThreadedHTMLParser[] = "disable-threaded-html-parser";
-// Enables the fastback page cache.
-const char kEnableFastback[] = "enable-fastback";
-
// By default, a page is laid out to fill the entire width of the window.
// This flag fixes the layout of the page to a default of 980 CSS pixels,
// or to a specified width and height using --enable-fixed-layout=w,h
@@ -337,6 +351,10 @@
// Enables compositor-accelerated touch-screen pinch gestures.
const char kEnablePinch[] = "enable-pinch";
+const char kDisablePinch[] = "disable-pinch";
+
+// Enables use of cache if offline, even if it's stale
+const char kEnableOfflineCacheAccess[] = "enable-offline-cache-access";
// Enable caching of pre-parsed JS script data. See http://crbug.com/32407.
const char kEnablePreparsedJsCaching[] = "enable-preparsed-js-caching";
@@ -361,8 +379,8 @@
// is denied by the sandbox.
const char kEnableSandboxLogging[] = "enable-sandbox-logging";
-// Enable the seccomp sandbox (Linux only)
-const char kEnableSeccompSandbox[] = "enable-seccomp-sandbox";
+// Enable spatial navigation
+const char kEnableSpatialNavigation[] = "enable-spatial-navigation";
// On platforms that support it, enables smooth scroll animation.
const char kEnableSmoothScrolling[] = "enable-smooth-scrolling";
@@ -423,6 +441,11 @@
// via field trials.
const char kDisableForceCompositingMode[] = "disable-force-compositing-mode";
+// Enable the synchronous renderer compositor API. See
+// ContentRendererClient::DidCreateSynchronousCompositor()
+const char kEnableSynchronousRendererCompositor[] =
+ "enable-synchronous-renderer-compositor";
+
// Some field trials may be randomized in the browser, and the randomly selected
// outcome needs to be propagated to the renderer. For instance, this is used
// to modify histograms recorded in the renderer, or to get the renderer to
@@ -562,6 +585,11 @@
// Enables remote debug over HTTP on the specified port.
const char kRemoteDebuggingPort[] = "remote-debugging-port";
+#if defined(OS_ANDROID)
+// Enables remote debug over HTTP on the specified socket name.
+const char kRemoteDebuggingSocketName[] = "remote-debugging-socket-name";
+#endif
+
// Causes the renderer process to throw an assertion on launch.
const char kRendererAssertTest[] = "renderer-assert-test";
@@ -764,8 +792,16 @@
// Defer image decoding in WebKit until painting.
const char kEnableDeferredImageDecoding[] = "enable-deferred-image-decoding";
-// Disables history navigation in response to horizontal overscroll.
-const char kDisableOverscrollHistoryNavigation[] =
- "disable-overscroll-history-navigation";
+// Use a vsync signal from the browser to the renderer to schedule rendering.
+const char kEnableVsyncNotification[] = "enable-vsync-notification";
+
+// Enables or disables history navigation in response to horizontal overscroll.
+// Set the value to '1' to enable the feature, and set to '0' to disable.
+// Defaults to enabled.
+const char kOverscrollHistoryNavigation[] =
+ "overscroll-history-navigation";
+
+// Enables 'image/webp' accept header for image requests.
+const char kEnableWebPInAcceptHeader[] = "enable-webp-in-accept-header";
} // namespace switches
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index 3eb34a1..e31a21f 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -21,6 +21,7 @@
CONTENT_EXPORT extern const char kBrowserCrashTest[];
CONTENT_EXPORT extern const char kBrowserSubprocessPath[];
CONTENT_EXPORT extern const char kDisable2dCanvasAntialiasing[];
+CONTENT_EXPORT extern const char kEnableExperimentalCanvasFeatures[];
CONTENT_EXPORT extern const char kDisable3DAPIs[];
CONTENT_EXPORT extern const char kDisableAccelerated2dCanvas[];
CONTENT_EXPORT extern const char kDisableAcceleratedCompositing[];
@@ -32,7 +33,6 @@
CONTENT_EXPORT extern const char kDisableAudio[];
extern const char kDisableBackingStoreLimit[];
CONTENT_EXPORT extern const char kDisableDatabases[];
-extern const char kDisableDataTransferItems[];
extern const char kDisableDesktopNotifications[];
CONTENT_EXPORT extern const char kDisableDeviceOrientation[];
#if defined(OS_ANDROID)
@@ -57,6 +57,7 @@
extern const char kEnableGpuSandbox[];
extern const char kDisableGpuWatchdog[];
CONTENT_EXPORT extern const char kDisableHangMonitor[];
+CONTENT_EXPORT extern const char kDisableHTMLNotifications[];
extern const char kDisableHistogramCustomizer[];
extern const char kDisableImageTransportSurface[];
CONTENT_EXPORT extern const char kDisableJava[];
@@ -69,29 +70,32 @@
extern const char kDisableRemoteFonts[];
extern const char kDisableRendererAccessibility[];
extern const char kDisableSSLFalseStart[];
-extern const char kDisableSeccompSandbox[];
extern const char kDisableSeccompFilterSandbox[];
extern const char kDisableSessionStorage[];
extern const char kDisableSharedWorkers[];
extern const char kDisableSiteSpecificQuirks[];
CONTENT_EXPORT extern const char kDisableSpeechInput[];
extern const char kSpeechRecognitionWebserviceKey[];
+CONTENT_EXPORT extern const char kEnableSpeechSynthesis[];
#if defined(OS_ANDROID)
CONTENT_EXPORT extern const char kEnableWebAudio[];
CONTENT_EXPORT extern const char kDisableWebRTC[];
#else
CONTENT_EXPORT extern const char kDisableWebAudio[];
#endif
+extern const char kEnableWebMIDI[];
extern const char kDisableWebSecurity[];
-extern const char kDisableWebSockets[];
+extern const char kEnableExperimentalWebSocket[];
extern const char kDisableXSSAuditor[];
CONTENT_EXPORT extern const char kDomAutomationController[];
CONTENT_EXPORT extern const char kReduceSecurityForDomAutomationTests[];
CONTENT_EXPORT extern const char kEnableAcceleratedPainting[];
CONTENT_EXPORT extern const char kEnableAcceleratedFilters[];
extern const char kEnableAccessibilityLogging[];
+extern const char kEnableAudibleNotifications[];
CONTENT_EXPORT extern const char kDisableBrowserPluginCompositing[];
CONTENT_EXPORT extern const char kEnableBrowserPluginForAllViewTypes[];
+CONTENT_EXPORT extern const char kEnableBrowserPluginDragDrop[];
CONTENT_EXPORT extern const char kEnableCompositingForFixedPosition[];
CONTENT_EXPORT extern const char kEnableHighDpiCompositingForFixedPosition[];
CONTENT_EXPORT extern const char kDisableCompositingForFixedPosition[];
@@ -101,7 +105,6 @@
CONTENT_EXPORT extern const char kEnableDownloadResumption[];
CONTENT_EXPORT extern const char kEnableExperimentalWebKitFeatures[];
CONTENT_EXPORT extern const char kDisableThreadedHTMLParser[];
-extern const char kEnableFastback[];
CONTENT_EXPORT extern const char kEnableFixedLayout[];
CONTENT_EXPORT extern const char kDisableFullScreen[];
CONTENT_EXPORT extern const char kEnableTextServicesFramework[];
@@ -116,16 +119,19 @@
extern const char kEnableMonitorProfile[];
extern const char kEnableUserMediaScreenCapturing[];
extern const char kEnablePinch[];
+CONTENT_EXPORT extern const char kEnableOfflineCacheAccess[];
+extern const char kDisablePinch[];
extern const char kEnablePreparsedJsCaching[];
CONTENT_EXPORT extern const char kEnablePrivilegedWebGLExtensions[];
extern const char kEnablePruneGpuCommandBuffers[];
extern const char kEnableSSLCachedInfo[];
extern const char kEnableSandboxLogging[];
-extern const char kEnableSeccompSandbox[];
+extern const char kEnableSpatialNavigation[];
CONTENT_EXPORT extern const char kEnableSoftwareCompositingGLAdapter[];
CONTENT_EXPORT extern const char kEnableSmoothScrolling[];
CONTENT_EXPORT extern const char kEnableStatsTable[];
extern const char kEnableStrictSiteIsolation[];
+CONTENT_EXPORT extern const char kEnableSynchronousRendererCompositor[];
CONTENT_EXPORT extern const char kEnableThreadedCompositing[];
CONTENT_EXPORT extern const char kDisableThreadedCompositing[];
extern const char kEnableVirtualGLContexts[];
@@ -171,6 +177,9 @@
CONTENT_EXPORT extern const char kProcessType[];
CONTENT_EXPORT extern const char kRegisterPepperPlugins[];
CONTENT_EXPORT extern const char kRemoteDebuggingPort[];
+#if defined(OS_ANDROID)
+CONTENT_EXPORT extern const char kRemoteDebuggingSocketName[];
+#endif
CONTENT_EXPORT extern const char kRendererAssertTest[];
extern const char kRendererCmdPrefix[];
CONTENT_EXPORT extern const char kRendererProcess[];
@@ -211,6 +220,7 @@
CONTENT_EXPORT extern const char kEnableFixedPositionCreatesStackingContext[];
CONTENT_EXPORT extern const char kDisableFixedPositionCreatesStackingContext[];
CONTENT_EXPORT extern const char kEnableDeferredImageDecoding[];
+CONTENT_EXPORT extern const char kEnableVsyncNotification[];
extern const char kEnableVisualWordMovement[];
CONTENT_EXPORT extern const char kUseMobileUserAgent[];
@@ -219,7 +229,7 @@
extern const char kDisableMediaHistoryLogging[];
extern const char kDisableGestureRequirementForMediaPlayback[];
extern const char kNetworkCountryIso[];
-extern const char kEnableWebViewSynchronousAPIs[];
+CONTENT_EXPORT extern const char kEnableWebViewSynchronousAPIs[];
#endif
#if defined(OS_CHROMEOS)
@@ -238,7 +248,9 @@
CONTENT_EXPORT extern const char kTestCompositor[];
#endif
-CONTENT_EXPORT extern const char kDisableOverscrollHistoryNavigation[];
+extern const char kEnableWebPInAcceptHeader[];
+
+CONTENT_EXPORT extern const char kOverscrollHistoryNavigation[];
} // namespace switches
diff --git a/content/public/common/gpu_feature_type.h b/content/public/common/gpu_feature_type.h
index 892f41e..5822b7b 100644
--- a/content/public/common/gpu_feature_type.h
+++ b/content/public/common/gpu_feature_type.h
@@ -11,34 +11,20 @@
// on which chrome is currently running.
// If a bit is set to 1, corresponding feature is blacklisted.
enum GpuFeatureType {
- GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS = 1 << 0,
- GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING = 1 << 1,
- GPU_FEATURE_TYPE_WEBGL = 1 << 2,
- GPU_FEATURE_TYPE_MULTISAMPLING = 1 << 3,
- GPU_FEATURE_TYPE_FLASH3D = 1 << 4,
- GPU_FEATURE_TYPE_FLASH_STAGE3D = 1 << 5,
- GPU_FEATURE_TYPE_TEXTURE_SHARING = 1 << 6,
- GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE = 1 << 7,
- GPU_FEATURE_TYPE_3D_CSS = 1 << 8,
- GPU_FEATURE_TYPE_ACCELERATED_VIDEO = 1 << 9,
- GPU_FEATURE_TYPE_PANEL_FITTING = 1 << 10,
- GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE = 1 << 11,
- GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE = 1 << 12,
- GPU_FEATURE_TYPE_ALL = GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS |
- GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING |
- GPU_FEATURE_TYPE_WEBGL |
- GPU_FEATURE_TYPE_MULTISAMPLING |
- GPU_FEATURE_TYPE_FLASH3D |
- GPU_FEATURE_TYPE_FLASH_STAGE3D |
- GPU_FEATURE_TYPE_TEXTURE_SHARING |
- GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE |
- GPU_FEATURE_TYPE_3D_CSS |
- GPU_FEATURE_TYPE_ACCELERATED_VIDEO |
- GPU_FEATURE_TYPE_PANEL_FITTING |
- GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE |
- GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE,
- // All flags initialized to false, i.e., no feature is blacklisted.
- GPU_FEATURE_TYPE_UNKNOWN = 0
+ GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS = 0,
+ GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING,
+ GPU_FEATURE_TYPE_WEBGL,
+ GPU_FEATURE_TYPE_MULTISAMPLING,
+ GPU_FEATURE_TYPE_FLASH3D,
+ GPU_FEATURE_TYPE_FLASH_STAGE3D,
+ GPU_FEATURE_TYPE_TEXTURE_SHARING,
+ GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE,
+ GPU_FEATURE_TYPE_3D_CSS,
+ GPU_FEATURE_TYPE_ACCELERATED_VIDEO,
+ GPU_FEATURE_TYPE_PANEL_FITTING,
+ GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE,
+ GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE,
+ NUMBER_OF_GPU_FEATURE_TYPES
};
} // namespace content
diff --git a/content/public/common/media_stream_request.h b/content/public/common/media_stream_request.h
index 0118f3b..50545eb 100644
--- a/content/public/common/media_stream_request.h
+++ b/content/public/common/media_stream_request.h
@@ -10,6 +10,8 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/callback_forward.h"
+#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
#include "googleurl/src/gurl.h"
@@ -131,6 +133,23 @@
MediaStreamType video_type;
};
+// Interface used by the content layer to notify chrome about changes in the
+// state of a media stream. Instances of this class are passed to content layer
+// when MediaStream access is approved using MediaResponseCallback.
+class MediaStreamUI {
+ public:
+ virtual ~MediaStreamUI() {}
+
+ // Called when MediaStream capturing is started. Chrome layer can call |stop|
+ // to stop the stream.
+ virtual void OnStarted(const base::Closure& stop) = 0;
+};
+
+// Callback used return results of media access requests.
+typedef base::Callback<void(
+ const MediaStreamDevices& devices,
+ scoped_ptr<MediaStreamUI> ui)> MediaResponseCallback;
+
} // namespace content
#endif // CONTENT_PUBLIC_COMMON_MEDIA_STREAM_REQUEST_H_
diff --git a/content/public/common/page_transition_types_list.h b/content/public/common/page_transition_types_list.h
index 3f7076c..de00ca9 100644
--- a/content/public/common/page_transition_types_list.h
+++ b/content/public/common/page_transition_types_list.h
@@ -100,6 +100,9 @@
// Any of the core values above can be augmented by one or more qualifiers.
// These qualifiers further define the transition.
+// A managed user attempted to visit a URL but was blocked.
+PAGE_TRANSITION(BLOCKED, 0x00800000)
+
// User used the Forward or Back button to navigate among browsing history.
PAGE_TRANSITION(FORWARD_BACK, 0x01000000)
diff --git a/content/public/common/password_form.h b/content/public/common/password_form.h
index bfc4655..21b2e56 100644
--- a/content/public/common/password_form.h
+++ b/content/public/common/password_form.h
@@ -7,6 +7,7 @@
#include <map>
#include <string>
+#include <vector>
#include "base/time.h"
#include "content/common/content_export.h"
@@ -89,6 +90,13 @@
// has implemented some form of autofill.
string16 username_value;
+ // This member is populated in cases where we there are multiple input
+ // elements that could possibly be the username. Used when our heuristics for
+ // determining the username are incorrect. Optional.
+ //
+ // When parsing an HTML form, this is typically empty.
+ std::vector<string16> possible_usernames;
+
// The name of the password input element, Optional (improves scoring).
//
// When parsing an HTML form, this must always be set.
diff --git a/content/public/common/sandbox_init.h b/content/public/common/sandbox_init.h
index 646b083..b5ff62c 100644
--- a/content/public/common/sandbox_init.h
+++ b/content/public/common/sandbox_init.h
@@ -78,19 +78,6 @@
CONTENT_EXPORT bool InitializeSandbox(int sandbox_type,
const base::FilePath& allowed_path);
-#elif defined(OS_LINUX)
-
-// Initialize the sandbox (currently seccomp-legacy or seccomp-bpf, the setuid
-// sandbox works differently and is set-up in the Zygote).
-// The process sandbox type is determined at run time via the command line
-// switches. TODO(jln): switch to a model where the caller chooses a sandbox
-// type.
-// This should be called before any additional thread has been created.
-//
-// Returns true if a sandbox has been initialized successfully, false
-// otherwise.
-CONTENT_EXPORT bool InitializeSandbox();
-
#endif
} // namespace content
diff --git a/content/public/common/sandbox_linux.h b/content/public/common/sandbox_linux.h
index ac63433..6824d55 100644
--- a/content/public/common/sandbox_linux.h
+++ b/content/public/common/sandbox_linux.h
@@ -20,11 +20,8 @@
// SUID sandbox is using the network namespace.
kSandboxLinuxNetNS = 1 << 2,
- // seccomp-legacy sandbox active.
- kSandboxLinuxSeccompLegacy = 1 << 3,
-
// seccomp-bpf sandbox active.
- kSandboxLinuxSeccompBpf = 1 << 4,
+ kSandboxLinuxSeccompBpf = 1 << 3,
};
} // namespace content
diff --git a/content/public/common/socket_permission_request.h b/content/public/common/socket_permission_request.h
index 2743eeb..d2d0ea2 100644
--- a/content/public/common/socket_permission_request.h
+++ b/content/public/common/socket_permission_request.h
@@ -18,6 +18,7 @@
TCP_LISTEN,
UDP_BIND,
UDP_SEND_TO,
+ UDP_MULTICAST_MEMBERSHIP
};
SocketPermissionRequest(OperationType type,
diff --git a/content/public/common/ssl_status.h b/content/public/common/ssl_status.h
index 5d750a0..049a5af 100644
--- a/content/public/common/ssl_status.h
+++ b/content/public/common/ssl_status.h
@@ -7,7 +7,7 @@
#include "content/common/content_export.h"
#include "content/public/common/security_style.h"
-#include "net/base/cert_status_flags.h"
+#include "net/cert/cert_status_flags.h"
namespace content {
diff --git a/content/public/common/url_constants.cc b/content/public/common/url_constants.cc
index 40b3b03..1a03fa5 100644
--- a/content/public/common/url_constants.cc
+++ b/content/public/common/url_constants.cc
@@ -32,11 +32,16 @@
const char kAboutBlankURL[] = "about:blank";
const char kAboutSrcDocURL[] = "about:srcdoc";
+
+} // namespace chrome
+
+namespace content {
+
const char kChromeUIAppCacheInternalsHost[] = "appcache-internals";
+const char kChromeUIIndexedDBInternalsHost[] = "indexeddb-internals";
const char kChromeUIAccessibilityHost[] = "accessibility";
const char kChromeUIBlobInternalsHost[] = "blob-internals";
const char kChromeUIBrowserCrashHost[] = "inducebrowsercrashforrealz";
-const char kChromeUIDevToolsHost[] = "devtools";
const char kChromeUIGpuHost[] = "gpu";
const char kChromeUIHistogramHost[] = "histograms";
const char kChromeUIMediaInternalsHost[] = "media-internals";
@@ -46,10 +51,6 @@
const char kChromeUITracingHost[] = "tracing";
const char kChromeUIWebRTCInternalsHost[] = "webrtc-internals";
-} // namespace chrome
-
-namespace content {
-
const char kChromeUICrashURL[] = "chrome://crash";
const char kChromeUIGpuCleanURL[] = "chrome://gpuclean";
const char kChromeUIGpuCrashURL[] = "chrome://gpucrash";
diff --git a/content/public/common/url_constants.h b/content/public/common/url_constants.h
index ef45d26..515a45f 100644
--- a/content/public/common/url_constants.h
+++ b/content/public/common/url_constants.h
@@ -27,7 +27,6 @@
CONTENT_EXPORT extern const char kFileSystemScheme[];
CONTENT_EXPORT extern const char kFtpScheme[];
CONTENT_EXPORT extern const char kGuestScheme[];
-CONTENT_EXPORT extern const char kChromeUIGpuHost[];
CONTENT_EXPORT extern const char kHttpScheme[];
CONTENT_EXPORT extern const char kHttpsScheme[];
CONTENT_EXPORT extern const char kJavaScriptScheme[];
@@ -39,12 +38,18 @@
// Hosts for about URLs.
CONTENT_EXPORT extern const char kAboutBlankURL[];
CONTENT_EXPORT extern const char kAboutSrcDocURL[];
+
+} // namespace chrome
+
+namespace content {
+
CONTENT_EXPORT extern const char kChromeUIAccessibilityHost[];
CONTENT_EXPORT extern const char kChromeUIAppCacheInternalsHost[];
CONTENT_EXPORT extern const char kChromeUIBlobInternalsHost[];
CONTENT_EXPORT extern const char kChromeUIBrowserCrashHost[];
-CONTENT_EXPORT extern const char kChromeUIDevToolsHost[];
+CONTENT_EXPORT extern const char kChromeUIGpuHost[];
CONTENT_EXPORT extern const char kChromeUIHistogramHost[];
+CONTENT_EXPORT extern const char kChromeUIIndexedDBInternalsHost[];
CONTENT_EXPORT extern const char kChromeUIMediaInternalsHost[];
CONTENT_EXPORT extern const char kChromeUINetworkViewCacheHost[];
CONTENT_EXPORT extern const char kChromeUIResourcesHost[];
@@ -52,10 +57,6 @@
CONTENT_EXPORT extern const char kChromeUITracingHost[];
CONTENT_EXPORT extern const char kChromeUIWebRTCInternalsHost[];
-} // namespace chrome
-
-namespace content {
-
// Full about URLs (including schemes).
CONTENT_EXPORT extern const char kChromeUICrashURL[];
CONTENT_EXPORT extern const char kChromeUIGpuCleanURL[];
diff --git a/content/public/renderer/android/OWNERS b/content/public/renderer/android/OWNERS
new file mode 100644
index 0000000..cff1ac9
--- /dev/null
+++ b/content/public/renderer/android/OWNERS
@@ -0,0 +1,6 @@
+# While the SynchronousCompositor API is in active development include
+# all the following owners in any changes under this path.
+
+jamesr@chromium.org
+joth@chromium.org
+mkosiba@chromium.org
diff --git a/content/public/renderer/android/synchronous_compositor.h b/content/public/renderer/android/synchronous_compositor.h
new file mode 100644
index 0000000..f0c380d
--- /dev/null
+++ b/content/public/renderer/android/synchronous_compositor.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_RENDERER_ANDROID_SYNCHRONOUS_COMPOSTIOR_
+#define CONTENT_PUBLIC_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_
+
+class SkCanvas;
+
+namespace content {
+
+class SynchronousCompositorClient;
+
+// Interface for embedders that which to direct compositing operations
+// synchronously under their own control. Only meaningful when the
+// kEnableSyncrhonousRendererCompositor flag is specified.
+class SynchronousCompositor {
+ public:
+ // Allows changing or resetting the client to NULL (this must be used if
+ // the client is being deleted prior to the DidDestroyCompositor() call
+ // being received by the client). Ownership of |client| remains with
+ // the caller.
+ virtual void SetClient(SynchronousCompositorClient* client) = 0;
+
+ // "On demand" SW draw, into the supplied canvas (observing the transform
+ // and clip set there-in).
+ virtual bool DemandDrawSw(SkCanvas* canvas) = 0;
+
+ protected:
+ virtual ~SynchronousCompositor() {}
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_RENDERER_ANDROID_SYNCHRONOUS_COMPOSTIOR_
diff --git a/content/public/renderer/android/synchronous_compositor_client.h b/content/public/renderer/android/synchronous_compositor_client.h
new file mode 100644
index 0000000..dcbe09a
--- /dev/null
+++ b/content/public/renderer/android/synchronous_compositor_client.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_RENDERER_ANDROID_SYNCHRONOUS_COMPOSTIOR_CLIENT_H_
+#define CONTENT_PUBLIC_RENDERER_ANDROID_SYNCRHONOUS_COMPOSITOR_CLIENT_H_
+
+namespace content {
+
+class SynchronousCompositor;
+
+class SynchronousCompositorClient {
+ public:
+ // Indication to the client that |compositor| is going out of scope, and
+ // must not be accessed within or after this call.
+ // NOTE if the client goes away before the compositor it must call
+ // SynchronousCompositor::SetClient(NULL) to release the back pointer.
+ virtual void DidDestroyCompositor(SynchronousCompositor* compositor) = 0;
+
+ // TODO(joth): Add scroll getters and setters, and invalidations.
+
+ protected:
+ virtual ~SynchronousCompositorClient() {}
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_RENDERER_ANDROID_SYNCHRONOUS_COMPOSTIOR_CLIENT_H_
diff --git a/content/public/renderer/content_renderer_client.cc b/content/public/renderer/content_renderer_client.cc
index 8997832..fe80e4d 100644
--- a/content/public/renderer/content_renderer_client.cc
+++ b/content/public/renderer/content_renderer_client.cc
@@ -75,6 +75,11 @@
return NULL;
}
+WebKit::WebSpeechSynthesizer* ContentRendererClient::OverrideSpeechSynthesizer(
+ WebKit::WebSpeechSynthesizerClient* client) {
+ return NULL;
+}
+
bool ContentRendererClient::RunIdleHandlerWhenWidgetsHidden() {
return true;
}
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h
index b12633c..8d3c737 100644
--- a/content/public/renderer/content_renderer_client.h
+++ b/content/public/renderer/content_renderer_client.h
@@ -18,11 +18,11 @@
#include "v8/include/v8.h"
class GURL;
-class MessageLoop;
class SkBitmap;
namespace base {
class FilePath;
+class MessageLoop;
}
namespace WebKit {
@@ -37,6 +37,8 @@
class WebPluginContainer;
class WebRTCPeerConnectionHandler;
class WebRTCPeerConnectionHandlerClient;
+class WebSpeechSynthesizer;
+class WebSpeechSynthesizerClient;
class WebThemeEngine;
class WebURLRequest;
struct WebPluginParams;
@@ -59,6 +61,7 @@
namespace content {
class RenderView;
+class SynchronousCompositor;
// Embedder API for participating in renderer logic.
class CONTENT_EXPORT ContentRendererClient {
@@ -115,6 +118,7 @@
// (lack of information on the error code) so the caller should take care to
// initialize the string values with safe defaults before the call.
virtual void GetNavigationErrorStrings(
+ WebKit::WebFrame* frame,
const WebKit::WebURLRequest& failed_request,
const WebKit::WebURLError& error,
std::string* error_html,
@@ -156,6 +160,11 @@
// the content layer will provide an engine.
virtual WebKit::WebThemeEngine* OverrideThemeEngine();
+ // Allows the embedder to override the WebSpeechSynthesizer used.
+ // If it returns NULL the content layer will provide an engine.
+ virtual WebKit::WebSpeechSynthesizer* OverrideSpeechSynthesizer(
+ WebKit::WebSpeechSynthesizerClient* client);
+
// Returns true if the renderer process should schedule the idle handler when
// all widgets are hidden.
virtual bool RunIdleHandlerWhenWidgetsHidden();
@@ -231,7 +240,15 @@
// Allow the embedder to specify a different renderer compositor MessageLoop.
// If not NULL, the returned MessageLoop must be valid for the lifetime of
// RenderThreadImpl. If NULL, then a new thread will be created.
- virtual MessageLoop* OverrideCompositorMessageLoop() const;
+ virtual base::MessageLoop* OverrideCompositorMessageLoop() const;
+
+ // Called when a render view's compositor instance is created, when the
+ // kEnableSynchronousRendererCompositor flag is used.
+ // NOTE this is called on the Compositor thread: the embedder must
+ // implement OverrideCompositorMessageLoop() when using this interface.
+ virtual void DidCreateSynchronousCompositor(
+ int render_view_id,
+ SynchronousCompositor* compositor) {}
// Allow the embedder to disable input event filtering by the compositor.
virtual bool ShouldCreateCompositorInputHandler() const;
diff --git a/content/public/renderer/document_state.cc b/content/public/renderer/document_state.cc
index 231c9d6..854431b 100644
--- a/content/public/renderer/document_state.cc
+++ b/content/public/renderer/document_state.cc
@@ -6,28 +6,19 @@
#include "content/public/common/password_form.h"
#include "content/public/renderer/navigation_state.h"
-#include "webkit/glue/alt_error_page_resource_fetcher.h"
namespace content {
DocumentState::DocumentState()
: load_histograms_recorded_(false),
web_timing_histograms_recorded_(false),
- http_status_code_(0),
was_fetched_via_spdy_(false),
was_npn_negotiated_(false),
was_alternate_protocol_available_(false),
was_fetched_via_proxy_(false),
- use_error_page_(false),
- is_overriding_user_agent_(false),
- must_reset_scroll_and_scale_state_(false),
was_prefetcher_(false),
was_referred_by_prefetcher_(false),
load_type_(UNDEFINED_LOAD),
- cache_policy_override_set_(false),
- cache_policy_override_(WebKit::WebURLRequest::UseProtocolCachePolicy),
- referrer_policy_set_(false),
- referrer_policy_(WebKit::WebReferrerPolicyDefault),
can_load_local_resources_(false) {
}
@@ -38,11 +29,6 @@
password_form_data_.reset(data.release());
}
-void DocumentState::set_alt_error_page_fetcher(
- webkit_glue::AltErrorPageResourceFetcher* f) {
- alt_error_page_fetcher_.reset(f);
-}
-
void DocumentState::set_navigation_state(NavigationState* navigation_state) {
navigation_state_.reset(navigation_state);
}
diff --git a/content/public/renderer/document_state.h b/content/public/renderer/document_state.h
index 3168776..144eae4 100644
--- a/content/public/renderer/document_state.h
+++ b/content/public/renderer/document_state.h
@@ -9,15 +9,11 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/supports_user_data.h"
#include "base/time.h"
-#include "third_party/WebKit/Source/Platform/chromium/public/WebReferrerPolicy.h"
-#include "third_party/WebKit/Source/Platform/chromium/public/WebURLRequest.h"
+#include "content/common/content_export.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
-namespace webkit_glue {
-class AltErrorPageResourceFetcher;
-}
-
namespace content {
class NavigationState;
@@ -25,7 +21,9 @@
// The RenderView stores an instance of this class in the "extra data" of each
// WebDataSource (see RenderView::DidCreateDataSource).
-class DocumentState : public WebKit::WebDataSource::ExtraData {
+class CONTENT_EXPORT DocumentState
+ : NON_EXPORTED_BASE(public WebKit::WebDataSource::ExtraData),
+ public base::SupportsUserData {
public:
// The exact values of this enum are used in histograms, so new values must be
// added to the end.
@@ -129,11 +127,6 @@
web_timing_histograms_recorded_ = value;
}
- int http_status_code() const { return http_status_code_; }
- void set_http_status_code(int http_status_code) {
- http_status_code_ = http_status_code;
- }
-
// Indicator if SPDY was used as part of this page load.
bool was_fetched_via_spdy() const { return was_fetched_via_spdy_; }
void set_was_fetched_via_spdy(bool value) { was_fetched_via_spdy_ = value; }
@@ -160,47 +153,20 @@
was_fetched_via_proxy_ = value;
}
- const GURL& searchable_form_url() const { return searchable_form_url_; }
- void set_searchable_form_url(const GURL& url) { searchable_form_url_ = url; }
- const std::string& searchable_form_encoding() const {
- return searchable_form_encoding_;
- }
- void set_searchable_form_encoding(const std::string& encoding) {
- searchable_form_encoding_ = encoding;
- }
-
+ // If set, contains the PasswordForm that we believe triggered the current
+ // navigation (there is some ambiguity in the case of javascript initiated
+ // navigations). This information is used by the PasswordManager to determine
+ // if the user should be prompted to save their password.
+ //
+ // Note that setting this field doesn't affect where the data is sent or what
+ // origin we associate it with, only whether we prompt the user to save it.
+ // That is, a false positive is a usability issue (e.g. may try to save a
+ // mis-typed password) not a security issue.
PasswordForm* password_form_data() const {
return password_form_data_.get();
}
void set_password_form_data(scoped_ptr<PasswordForm> data);
- const std::string& security_info() const { return security_info_; }
- void set_security_info(const std::string& security_info) {
- security_info_ = security_info;
- }
-
- // True if an error page should be used, if the http status code also
- // indicates an error.
- bool use_error_page() const { return use_error_page_; }
- void set_use_error_page(bool use_error_page) {
- use_error_page_ = use_error_page;
- }
-
- // True if the user agent was overridden for this page.
- bool is_overriding_user_agent() const { return is_overriding_user_agent_; }
- void set_is_overriding_user_agent(bool state) {
- is_overriding_user_agent_ = state;
- }
-
- // True if we have to reset the scroll and scale state of the page
- // after the provisional load has been committed.
- bool must_reset_scroll_and_scale_state() const {
- return must_reset_scroll_and_scale_state_;
- }
- void set_must_reset_scroll_and_scale_state(bool state) {
- must_reset_scroll_and_scale_state_ = state;
- }
-
void set_was_prefetcher(bool value) { was_prefetcher_ = value; }
bool was_prefetcher() const { return was_prefetcher_; }
@@ -215,46 +181,6 @@
LoadType load_type() const { return load_type_; }
void set_load_type(LoadType load_type) { load_type_ = load_type; }
- // Sets the cache policy. The cache policy is only used if explicitly set and
- // by default is not set. You can mark a NavigationState as not having a cache
- // state by way of clear_cache_policy_override.
- void set_cache_policy_override(
- WebKit::WebURLRequest::CachePolicy cache_policy) {
- cache_policy_override_ = cache_policy;
- cache_policy_override_set_ = true;
- }
- WebKit::WebURLRequest::CachePolicy cache_policy_override() const {
- return cache_policy_override_;
- }
- void clear_cache_policy_override() {
- cache_policy_override_set_ = false;
- cache_policy_override_ = WebKit::WebURLRequest::UseProtocolCachePolicy;
- }
- bool is_cache_policy_override_set() const {
- return cache_policy_override_set_;
- }
-
- // Sets the referrer policy to use. This is only used for browser initiated
- // navigations, otherwise, the referrer policy is defined by the frame's
- // document.
- WebKit::WebReferrerPolicy referrer_policy() const {
- return referrer_policy_;
- }
- void set_referrer_policy(WebKit::WebReferrerPolicy referrer_policy) {
- referrer_policy_ = referrer_policy;
- referrer_policy_set_ = true;
- }
- void clear_referrer_policy() {
- referrer_policy_ = WebKit::WebReferrerPolicyDefault;
- referrer_policy_set_ = false;
- }
- bool is_referrer_policy_set() const { return referrer_policy_set_; }
-
- webkit_glue::AltErrorPageResourceFetcher* alt_error_page_fetcher() const {
- return alt_error_page_fetcher_.get();
- }
- void set_alt_error_page_fetcher(webkit_glue::AltErrorPageResourceFetcher* f);
-
NavigationState* navigation_state() { return navigation_state_.get(); }
void set_navigation_state(NavigationState* navigation_state);
@@ -273,22 +199,13 @@
base::Time first_paint_after_load_time_;
bool load_histograms_recorded_;
bool web_timing_histograms_recorded_;
- int http_status_code_;
bool was_fetched_via_spdy_;
bool was_npn_negotiated_;
std::string npn_negotiated_protocol_;
bool was_alternate_protocol_available_;
bool was_fetched_via_proxy_;
- GURL searchable_form_url_;
- std::string searchable_form_encoding_;
scoped_ptr<PasswordForm> password_form_data_;
- std::string security_info_;
-
- bool use_error_page_;
-
- bool is_overriding_user_agent_;
- bool must_reset_scroll_and_scale_state_;
// A prefetcher is a page that contains link rel=prefetch elements.
bool was_prefetcher_;
@@ -296,14 +213,6 @@
LoadType load_type_;
- bool cache_policy_override_set_;
- WebKit::WebURLRequest::CachePolicy cache_policy_override_;
-
- bool referrer_policy_set_;
- WebKit::WebReferrerPolicy referrer_policy_;
-
- scoped_ptr<webkit_glue::AltErrorPageResourceFetcher> alt_error_page_fetcher_;
-
scoped_ptr<NavigationState> navigation_state_;
bool can_load_local_resources_;
diff --git a/content/public/renderer/navigation_state.cc b/content/public/renderer/navigation_state.cc
index 9208efa..5745a2b 100644
--- a/content/public/renderer/navigation_state.cc
+++ b/content/public/renderer/navigation_state.cc
@@ -9,12 +9,14 @@
NavigationState::NavigationState(content::PageTransition transition_type,
bool is_content_initiated,
int32 pending_page_id,
- int pending_history_list_offset)
+ int pending_history_list_offset,
+ bool history_list_was_cleared)
: transition_type_(transition_type),
request_committed_(false),
is_content_initiated_(is_content_initiated),
pending_page_id_(pending_page_id),
pending_history_list_offset_(pending_history_list_offset),
+ history_list_was_cleared_(history_list_was_cleared),
was_within_same_page_(false),
transferred_request_child_id_(-1),
transferred_request_request_id_(-1),
diff --git a/content/public/renderer/navigation_state.h b/content/public/renderer/navigation_state.h
index 746b206..01f92a0 100644
--- a/content/public/renderer/navigation_state.h
+++ b/content/public/renderer/navigation_state.h
@@ -7,6 +7,7 @@
#include <string>
+#include "content/common/content_export.h"
#include "content/public/common/page_transition_types.h"
namespace content {
@@ -14,20 +15,25 @@
// NavigationState is the portion of DocumentState that is affected by
// in-document navigation.
// TODO(simonjam): Move this to HistoryItem's ExtraData.
-class NavigationState {
+class CONTENT_EXPORT NavigationState {
public:
virtual ~NavigationState();
static NavigationState* CreateBrowserInitiated(
int32 pending_page_id,
int pending_history_list_offset,
+ bool history_list_was_cleared,
content::PageTransition transition_type) {
- return new NavigationState(transition_type, false, pending_page_id,
- pending_history_list_offset);
+ return new NavigationState(transition_type,
+ false,
+ pending_page_id,
+ pending_history_list_offset,
+ history_list_was_cleared);
}
static NavigationState* CreateContentInitiated() {
- return new NavigationState(content::PAGE_TRANSITION_LINK, true, -1, -1);
+ return new NavigationState(
+ content::PAGE_TRANSITION_LINK, true, -1, -1, false);
}
// Contains the page_id for this navigation or -1 if there is none yet.
@@ -39,6 +45,12 @@
return pending_history_list_offset_;
}
+ // If pending_page_id() is not -1, then this returns true if the session
+ // history was cleared during this navigation.
+ bool history_list_was_cleared() const {
+ return history_list_was_cleared_;
+ }
+
// Contains the transition type that the browser specified when it
// initiated the load.
content::PageTransition transition_type() const { return transition_type_; }
@@ -90,13 +102,15 @@
NavigationState(content::PageTransition transition_type,
bool is_content_initiated,
int32 pending_page_id,
- int pending_history_list_offset);
+ int pending_history_list_offset,
+ bool history_list_was_cleared);
content::PageTransition transition_type_;
bool request_committed_;
bool is_content_initiated_;
int32 pending_page_id_;
int pending_history_list_offset_;
+ bool history_list_was_cleared_;
bool was_within_same_page_;
int transferred_request_child_id_;
diff --git a/content/public/renderer/render_thread.h b/content/public/renderer/render_thread.h
index a041657..7dcefd4 100644
--- a/content/public/renderer/render_thread.h
+++ b/content/public/renderer/render_thread.h
@@ -16,9 +16,9 @@
#endif
class GURL;
-class MessageLoop;
namespace base {
+class MessageLoop;
class MessageLoopProxy;
}
@@ -45,7 +45,7 @@
RenderThread();
virtual ~RenderThread();
- virtual MessageLoop* GetMessageLoop() = 0;
+ virtual base::MessageLoop* GetMessageLoop() = 0;
virtual IPC::SyncChannel* GetChannel() = 0;
virtual std::string GetLocale() = 0;
virtual IPC::SyncMessageFilter* GetSyncMessageFilter() = 0;
diff --git a/content/public/renderer/render_view.h b/content/public/renderer/render_view.h
index 44dc636..8024f49 100644
--- a/content/public/renderer/render_view.h
+++ b/content/public/renderer/render_view.h
@@ -15,10 +15,7 @@
#include "ui/gfx/native_widget_types.h"
class SkPicture;
-
-namespace webkit_glue {
struct WebPreferences;
-}
namespace WebKit {
class WebFrame;
@@ -73,12 +70,11 @@
virtual gfx::Size GetSize() const = 0;
// Gets WebKit related preferences associated with this view.
- virtual webkit_glue::WebPreferences& GetWebkitPreferences() = 0;
+ virtual WebPreferences& GetWebkitPreferences() = 0;
// Overrides the WebKit related preferences associated with this view. Note
// that the browser process may update the preferences at any time.
- virtual void SetWebkitPreferences(
- const webkit_glue::WebPreferences& preferences) = 0;
+ virtual void SetWebkitPreferences(const WebPreferences& preferences) = 0;
// Returns the associated WebView. May return NULL when the view is closing.
virtual WebKit::WebView* GetWebView() = 0;
diff --git a/content/public/renderer/renderer_ppapi_host.h b/content/public/renderer/renderer_ppapi_host.h
index 51a5e1f..e5eaa4b 100644
--- a/content/public/renderer/renderer_ppapi_host.h
+++ b/content/public/renderer/renderer_ppapi_host.h
@@ -32,12 +32,6 @@
}
}
-namespace webkit {
-namespace ppapi {
-class PluginInstance;
-}
-}
-
namespace WebKit {
class WebPluginContainer;
}
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java
index 2888c51..db61486 100644
--- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java
+++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java
@@ -156,8 +156,10 @@
Rect bounds = getNodeBounds(view, viewClient, nodeName);
Assert.assertNotNull("Failed to get DOM element bounds of '" + nodeName + "'.", bounds);
- int clickX = (int) view.getRenderCoordinates().fromLocalCssToPix(bounds.exactCenterX());
- int clickY = (int) view.getRenderCoordinates().fromLocalCssToPix(bounds.exactCenterY());
+ int clickX = (int) view.getRenderCoordinates().fromLocalCssToPix(bounds.exactCenterX())
+ + (int) view.getContentViewCore().getViewportSizeOffsetWidthPix();
+ int clickY = (int) view.getRenderCoordinates().fromLocalCssToPix(bounds.exactCenterY())
+ + (int) view.getContentViewCore().getViewportSizeOffsetHeightPix();
return new int[] { clickX, clickY };
}
}
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TouchCommon.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TouchCommon.java
index 70b046d..9e962d1 100644
--- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TouchCommon.java
+++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TouchCommon.java
@@ -118,6 +118,13 @@
}
/**
+ * Sends (synchronously) a single click to the center of the View.
+ */
+ public void singleClickView(View v) {
+ singleClickView(v, v.getWidth() / 2, v.getHeight() / 2);
+ }
+
+ /**
* Sends (synchronously) a single click on the specified relative coordinates inside
* a given view.
*
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc
index 04d6ff0..e89c28c 100644
--- a/content/public/test/browser_test_base.cc
+++ b/content/public/test/browser_test_base.cc
@@ -8,12 +8,15 @@
#include "base/command_line.h"
#include "base/debug/stack_trace.h"
#include "base/process_util.h"
+#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
+#include "content/public/test/test_utils.h"
#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
-#include "base/system_monitor/system_monitor.h"
+#include "base/power_monitor/power_monitor.h"
#endif
#if defined(OS_ANDROID)
@@ -22,6 +25,7 @@
#include "content/public/browser/browser_thread.h"
#endif
+namespace content {
namespace {
#if defined(OS_POSIX)
@@ -43,16 +47,20 @@
}
#endif // defined(OS_POSIX)
+void RunTaskOnRendererThread(const base::Closure& task,
+ const base::Closure& quit_task) {
+ task.Run();
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_task);
+}
+
} // namespace
-namespace content {
-
-extern int BrowserMain(const content::MainFunctionParams&);
+extern int BrowserMain(const MainFunctionParams&);
BrowserTestBase::BrowserTestBase() {
#if defined(OS_MACOSX)
base::mac::SetOverrideAmIBundled(true);
- base::SystemMonitor::AllocateSystemIOPorts();
+ base::PowerMonitor::AllocateSystemIOPorts();
#endif
#if defined(OS_POSIX)
@@ -114,10 +122,26 @@
void BrowserTestBase::CreateTestServer(const base::FilePath& test_server_base) {
CHECK(!test_server_.get());
- test_server_.reset(new net::TestServer(
- net::TestServer::TYPE_HTTP,
- net::TestServer::kLocalhost,
+ test_server_.reset(new net::SpawnedTestServer(
+ net::SpawnedTestServer::TYPE_HTTP,
+ net::SpawnedTestServer::kLocalhost,
test_server_base));
}
+void BrowserTestBase::PostTaskToInProcessRendererAndWait(
+ const base::Closure& task) {
+ CHECK(CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess));
+
+ scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
+
+ base::MessageLoop* renderer_loop =
+ RenderProcessHostImpl::GetInProcessRendererThreadForTesting();
+ CHECK(renderer_loop);
+
+ renderer_loop->PostTask(
+ FROM_HERE,
+ base::Bind(&RunTaskOnRendererThread, task, runner->QuitClosure()));
+ runner->Run();
+}
+
} // namespace content
diff --git a/content/public/test/browser_test_base.h b/content/public/test/browser_test_base.h
index 026bf32..8ddcba0 100644
--- a/content/public/test/browser_test_base.h
+++ b/content/public/test/browser_test_base.h
@@ -5,9 +5,10 @@
#ifndef CONTENT_PUBLIC_TEST_BROWSER_TEST_BASE_H_
#define CONTENT_PUBLIC_TEST_BROWSER_TEST_BASE_H_
+#include "base/callback.h"
#include "base/compiler_specific.h"
+#include "net/test/spawned_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "net/test/test_server.h"
class CommandLine;
@@ -63,8 +64,10 @@
virtual void RunTestOnMainThreadLoop() = 0;
// Returns the testing server. Guaranteed to be non-NULL.
- const net::TestServer* test_server() const { return test_server_.get(); }
- net::TestServer* test_server() { return test_server_.get(); }
+ const net::SpawnedTestServer* test_server() const {
+ return test_server_.get();
+ }
+ net::SpawnedTestServer* test_server() { return test_server_.get(); }
#if defined(OS_POSIX)
// This is only needed by a test that raises SIGTERM to ensure that a specific
@@ -82,11 +85,16 @@
// server.
void CreateTestServer(const base::FilePath& test_server_base);
+ // When the test is running in --single-process mode, runs the given task on
+ // the in-process renderer thread. A nested message loop is run until it
+ // returns.
+ void PostTaskToInProcessRendererAndWait(const base::Closure& task);
+
private:
void ProxyRunTestOnMainThreadLoop();
// Testing server, started on demand.
- scoped_ptr<net::TestServer> test_server_;
+ scoped_ptr<net::SpawnedTestServer> test_server_;
#if defined(OS_POSIX)
bool handle_sigterm_;
diff --git a/content/public/test/content_test_suite_base.cc b/content/public/test/content_test_suite_base.cc
index ea83b47..459c37d 100644
--- a/content/public/test/content_test_suite_base.cc
+++ b/content/public/test/content_test_suite_base.cc
@@ -22,8 +22,10 @@
#include "base/android/jni_android.h"
#include "content/browser/android/browser_jni_registrar.h"
#include "content/common/android/common_jni_registrar.h"
+#include "media/base/android/media_jni_registrar.h"
#include "net/android/net_jni_registrar.h"
#include "ui/android/ui_jni_registrar.h"
+#include "ui/gl/android/gl_jni_registrar.h"
#include "ui/shell_dialogs/android/shell_dialogs_jni_registrar.h"
#endif
@@ -53,6 +55,7 @@
JNIEnv* env = base::android::AttachCurrentThread();
content::android::RegisterCommonJni(env);
content::android::RegisterBrowserJni(env);
+ media::RegisterJni(env);
net::android::RegisterJni(env);
ui::android::RegisterJni(env);
ui::shell_dialogs::RegisterJni(env);
diff --git a/content/public/test/download_test_observer.cc b/content/public/test/download_test_observer.cc
index 6a0504e..3d91825 100644
--- a/content/public/test/download_test_observer.cc
+++ b/content/public/test/download_test_observer.cc
@@ -78,7 +78,7 @@
if (filter_.Run(item_))
event_seen_ = true;
if (waiting_ && event_seen_)
- MessageLoopForUI::current()->Quit();
+ base::MessageLoopForUI::current()->Quit();
}
void DownloadUpdatedObserver::OnDownloadDestroyed(DownloadItem* item) {
@@ -86,7 +86,7 @@
item_->RemoveObserver(this);
item_ = NULL;
if (waiting_)
- MessageLoopForUI::current()->Quit();
+ base::MessageLoopForUI::current()->Quit();
}
DownloadTestObserver::DownloadTestObserver(
@@ -231,7 +231,7 @@
void DownloadTestObserver::SignalIfFinished() {
if (waiting_ && IsFinished())
- MessageLoopForUI::current()->Quit();
+ base::MessageLoopForUI::current()->Quit();
}
DownloadTestObserverTerminal::DownloadTestObserverTerminal(
@@ -379,7 +379,7 @@
base::Bind(&DownloadTestFlushObserver::PingFileThread, this, cycle));
} else {
BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure());
+ BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure());
}
}
@@ -415,7 +415,7 @@
DCHECK_EQ(1u, called_back_count_);
if (waiting_)
- MessageLoopForUI::current()->Quit();
+ base::MessageLoopForUI::current()->Quit();
}
const DownloadUrlParameters::OnStartedCallback
diff --git a/content/public/test/fake_speech_recognition_manager.cc b/content/public/test/fake_speech_recognition_manager.cc
index 3bc2946..8f89255 100644
--- a/content/public/test/fake_speech_recognition_manager.cc
+++ b/content/public/test/fake_speech_recognition_manager.cc
@@ -54,14 +54,16 @@
if (should_send_fake_response_) {
// Give the fake result in a short while.
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
- &FakeSpeechRecognitionManager::SetFakeRecognitionResult,
- // This class does not need to be refcounted (typically done by
- // PostTask) since it will outlive the test and gets released only
- // when the test shuts down. Disabling refcounting here saves a bit
- // of unnecessary code and the factory method can return a plain
- // pointer below as required by the real code.
- base::Unretained(this)));
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &FakeSpeechRecognitionManager::SetFakeRecognitionResult,
+ // This class does not need to be refcounted (typically done by
+ // PostTask) since it will outlive the test and gets released only
+ // when the test shuts down. Disabling refcounting here saves a bit
+ // of unnecessary code and the factory method can return a plain
+ // pointer below as required by the real code.
+ base::Unretained(this)));
}
recognition_started_event_.Signal();
}
diff --git a/content/public/test/layouttest_support.h b/content/public/test/layouttest_support.h
index 7c370bc..e35196e 100644
--- a/content/public/test/layouttest_support.h
+++ b/content/public/test/layouttest_support.h
@@ -66,6 +66,9 @@
// Set the device scale factor and force the compositor to resize.
void SetDeviceScaleFactor(RenderView* render_view, float factor);
+// Disable system calls related to drag & drop.
+void DisableSystemDragDrop();
+
} // namespace content
#endif // CONTENT_PUBLIC_TEST_LAYOUTTEST_SUPPORT_H_
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc
index d877d44..235afa5 100644
--- a/content/public/test/mock_render_process_host.cc
+++ b/content/public/test/mock_render_process_host.cc
@@ -168,7 +168,7 @@
NOTIFICATION_RENDERER_PROCESS_TERMINATED,
Source<RenderProcessHost>(this),
NotificationService::NoDetails());
- MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
RenderProcessHostImpl::UnregisterHost(GetID());
}
}
diff --git a/content/public/test/mock_render_thread.cc b/content/public/test/mock_render_thread.cc
index a5d8e13..c680760 100644
--- a/content/public/test/mock_render_thread.cc
+++ b/content/public/test/mock_render_thread.cc
@@ -39,7 +39,7 @@
// through this function messages, messages with reply and reply messages.
// We can only handle one synchronous message at a time.
if (msg->is_reply()) {
- if (reply_deserializer_.get()) {
+ if (reply_deserializer_) {
reply_deserializer_->SerializeOutputParameters(*msg);
reply_deserializer_.reset();
}
diff --git a/content/public/test/mock_render_thread.h b/content/public/test/mock_render_thread.h
index c8f1419..d90275c 100644
--- a/content/public/test/mock_render_thread.h
+++ b/content/public/test/mock_render_thread.h
@@ -38,7 +38,7 @@
// RenderThread implementation:
virtual bool Send(IPC::Message* msg) OVERRIDE;
- virtual MessageLoop* GetMessageLoop() OVERRIDE;
+ virtual base::MessageLoop* GetMessageLoop() OVERRIDE;
virtual IPC::SyncChannel* GetChannel() OVERRIDE;
virtual std::string GetLocale() OVERRIDE;
virtual IPC::SyncMessageFilter* GetSyncMessageFilter() OVERRIDE;
diff --git a/content/public/test/render_view_fake_resources_test.cc b/content/public/test/render_view_fake_resources_test.cc
index 4bb0204..eda8ef9 100644
--- a/content/public/test/render_view_fake_resources_test.cc
+++ b/content/public/test/render_view_fake_resources_test.cc
@@ -60,7 +60,7 @@
// but we use a real RenderThread so that we can use the ResourceDispatcher
// to fetch network resources. These are then served canned content
// in OnRequestResource().
- GetContentClient()->set_renderer_for_testing(&content_renderer_client_);
+ SetRendererClientForTesting(&content_renderer_client_);
// Generate a unique channel id so that multiple instances of the test can
// run in parallel.
std::string channel_id = IPC::Channel::GenerateVerifiedChannelID(
diff --git a/content/public/test/render_view_fake_resources_test.h b/content/public/test/render_view_fake_resources_test.h
index cde8596..a9688d9 100644
--- a/content/public/test/render_view_fake_resources_test.h
+++ b/content/public/test/render_view_fake_resources_test.h
@@ -127,7 +127,7 @@
static const int32 kViewId; // arbitrary id for our testing view
- MessageLoopForIO message_loop_;
+ base::MessageLoopForIO message_loop_;
ContentRendererClient content_renderer_client_;
// channel that the renderer uses to talk to the browser.
// For this test, we will handle the browser end of the channel.
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc
index dec696e..da2513e 100644
--- a/content/public/test/render_view_test.cc
+++ b/content/public/test/render_view_test.cc
@@ -5,6 +5,7 @@
#include "content/public/test/render_view_test.h"
#include "base/run_loop.h"
+#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/common/renderer_preferences.h"
@@ -76,7 +77,7 @@
}
void RenderViewTest::ProcessPendingMessages() {
- msg_loop_.PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ msg_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
msg_loop_.Run();
}
@@ -126,12 +127,14 @@
void RenderViewTest::SetUp() {
// Subclasses can set the ContentClient's renderer before calling
// RenderViewTest::SetUp().
- if (!GetContentClient()->renderer())
- GetContentClient()->set_renderer_for_testing(&content_renderer_client_);
+ ContentRendererClient* old_client =
+ SetRendererClientForTesting(&content_renderer_client_);
+ if (old_client)
+ SetRendererClientForTesting(old_client);
// Subclasses can set render_thread_ with their own implementation before
// calling RenderViewTest::SetUp().
- if (!render_thread_.get())
+ if (!render_thread_)
render_thread_.reset(new MockRenderThread());
render_thread_->set_routing_id(kRouteId);
render_thread_->set_surface_id(kSurfaceId);
@@ -164,7 +167,7 @@
RenderViewImpl* view = RenderViewImpl::Create(
kOpenerId,
RendererPreferences(),
- webkit_glue::WebPreferences(),
+ WebPreferences(),
new SharedRenderViewCounter(0),
kRouteId,
kSurfaceId,
@@ -213,13 +216,14 @@
void RenderViewTest::SendWebKeyboardEvent(
const WebKit::WebKeyboardEvent& key_event) {
RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
- impl->OnMessageReceived(ViewMsg_HandleInputEvent(0, &key_event, false));
+ impl->OnMessageReceived(InputMsg_HandleInputEvent(0, &key_event, false));
}
void RenderViewTest::SendWebMouseEvent(
const WebKit::WebMouseEvent& mouse_event) {
RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
- impl->OnMessageReceived(ViewMsg_HandleInputEvent(0, &mouse_event, false));
+ impl->OnMessageReceived(
+ InputMsg_HandleInputEvent(0, &mouse_event, false));
}
const char* const kGetCoordinatesScript =
@@ -278,7 +282,7 @@
mouse_event.y = bounds.CenterPoint().y();
mouse_event.clickCount = 1;
scoped_ptr<IPC::Message> input_message(
- new ViewMsg_HandleInputEvent(0, &mouse_event, false));
+ new InputMsg_HandleInputEvent(0, &mouse_event, false));
RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
impl->OnMessageReceived(*input_message);
return true;
diff --git a/content/public/test/render_view_test.h b/content/public/test/render_view_test.h
index 3b1e160..a30adac 100644
--- a/content/public/test/render_view_test.h
+++ b/content/public/test/render_view_test.h
@@ -124,7 +124,7 @@
virtual void TearDown() OVERRIDE;
- MessageLoop msg_loop_;
+ base::MessageLoop msg_loop_;
scoped_ptr<MockRenderProcess> mock_process_;
// We use a naked pointer because we don't want to expose RenderViewImpl in
// the embedder's namespace.
diff --git a/content/public/test/test_browser_context.cc b/content/public/test/test_browser_context.cc
index b3aa752..c410d42 100644
--- a/content/public/test/test_browser_context.cc
+++ b/content/public/test/test_browser_context.cc
@@ -70,7 +70,7 @@
}
net::URLRequestContextGetter* TestBrowserContext::GetRequestContext() {
- if (!request_context_.get()) {
+ if (!request_context_) {
request_context_ = new TestContextURLRequestContextGetter(
GetResourceContext()->GetRequestContext());
}
@@ -100,7 +100,7 @@
}
ResourceContext* TestBrowserContext::GetResourceContext() {
- if (!resource_context_.get())
+ if (!resource_context_)
resource_context_.reset(new MockResourceContext());
return resource_context_.get();
}
diff --git a/content/public/test/test_browser_thread.cc b/content/public/test/test_browser_thread.cc
index 6920ce0..f024a21 100644
--- a/content/public/test/test_browser_thread.cc
+++ b/content/public/test/test_browser_thread.cc
@@ -19,10 +19,9 @@
}
TestBrowserThreadImpl(BrowserThread::ID identifier,
- MessageLoop* message_loop)
+ base::MessageLoop* message_loop)
: BrowserThreadImpl(identifier, message_loop),
- notification_service_(NULL) {
- }
+ notification_service_(NULL) {}
virtual ~TestBrowserThreadImpl() {
Stop();
@@ -50,9 +49,8 @@
}
TestBrowserThread::TestBrowserThread(BrowserThread::ID identifier,
- MessageLoop* message_loop)
- : impl_(new TestBrowserThreadImpl(identifier, message_loop)) {
-}
+ base::MessageLoop* message_loop)
+ : impl_(new TestBrowserThreadImpl(identifier, message_loop)) {}
TestBrowserThread::~TestBrowserThread() {
Stop();
@@ -64,7 +62,7 @@
bool TestBrowserThread::StartIOThread() {
base::Thread::Options options;
- options.message_loop_type = MessageLoop::TYPE_IO;
+ options.message_loop_type = base::MessageLoop::TYPE_IO;
return impl_->StartWithOptions(options);
}
diff --git a/content/public/test/test_browser_thread.h b/content/public/test/test_browser_thread.h
index 24182e1..c4c386b 100644
--- a/content/public/test/test_browser_thread.h
+++ b/content/public/test/test_browser_thread.h
@@ -9,9 +9,8 @@
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/browser_thread.h"
-class MessageLoop;
-
namespace base {
+class MessageLoop;
class Thread;
}
@@ -24,7 +23,8 @@
class TestBrowserThread {
public:
explicit TestBrowserThread(BrowserThread::ID identifier);
- TestBrowserThread(BrowserThread::ID identifier, MessageLoop* message_loop);
+ TestBrowserThread(BrowserThread::ID identifier,
+ base::MessageLoop* message_loop);
~TestBrowserThread();
// We provide a subset of the capabilities of the Thread interface
diff --git a/content/public/test/test_content_client_initializer.cc b/content/public/test/test_content_client_initializer.cc
index b2ecdfe..0c210d2 100644
--- a/content/public/test/test_content_client_initializer.cc
+++ b/content/public/test/test_content_client_initializer.cc
@@ -16,12 +16,11 @@
TestContentClientInitializer::TestContentClientInitializer() {
notification_service_.reset(new NotificationServiceImpl());
- DCHECK(!GetContentClient());
content_client_.reset(new TestContentClient);
SetContentClient(content_client_.get());
content_browser_client_.reset(new TestContentBrowserClient());
- content_client_->set_browser_for_testing(content_browser_client_.get());
+ content::SetBrowserClientForTesting(content_browser_client_.get());
}
TestContentClientInitializer::~TestContentClientInitializer() {
@@ -29,7 +28,6 @@
rph_factory_.reset();
notification_service_.reset();
- DCHECK_EQ(content_client_.get(), GetContentClient());
SetContentClient(NULL);
content_client_.reset();
diff --git a/content/public/test/test_launcher.cc b/content/public/test/test_launcher.cc
index 40545d5..1d80605 100644
--- a/content/public/test/test_launcher.cc
+++ b/content/public/test/test_launcher.cc
@@ -175,7 +175,7 @@
// If the given path ends with '/', consider it is a directory.
// Note: This does NOT check that a directory (or file) actually exists
// (the behavior is same as what gtest does).
- if (file_util::EndsWithSeparator(path)) {
+ if (path.EndsWithSeparator()) {
base::FilePath executable = command_line.GetProgram().BaseName();
path = path.Append(executable.ReplaceExtension(
base::FilePath::StringType(FILE_PATH_LITERAL("xml"))));
@@ -454,7 +454,7 @@
// Split --gtest_filter at '-', if there is one, to separate into
// positive filter and negative filter portions.
std::string positive_filter = filter;
- std::string negative_filter = "";
+ std::string negative_filter;
size_t dash_pos = filter.find('-');
if (dash_pos != std::string::npos) {
positive_filter = filter.substr(0, dash_pos); // Everything up to the dash.
diff --git a/content/public/test/test_renderer_host.cc b/content/public/test/test_renderer_host.cc
index 6da75ed..9a1cc85 100644
--- a/content/public/test/test_renderer_host.cc
+++ b/content/public/test/test_renderer_host.cc
@@ -125,7 +125,7 @@
#endif
// See comment above browser_context_ decl for why we check for NULL here.
- if (!browser_context_.get())
+ if (!browser_context_)
browser_context_.reset(new TestBrowserContext());
// This will be deleted when the WebContentsImpl goes away.
@@ -146,6 +146,14 @@
rvh())->SendNavigate(entry->GetPageID(), entry->GetURL());
}
+void RenderViewHostTestHarness::FailedReload() {
+ NavigationEntry* entry = controller().GetLastCommittedEntry();
+ DCHECK(entry);
+ controller().Reload(false);
+ static_cast<TestRenderViewHost*>(
+ rvh())->SendFailedNavigate(entry->GetPageID(), entry->GetURL());
+}
+
void RenderViewHostTestHarness::SetUp() {
#if defined(OS_WIN)
ole_initializer_.reset(new ui::ScopedOleInitializer());
@@ -167,7 +175,7 @@
base::RunLoop().RunUntilIdle();
// Delete any RenderProcessHosts before the BrowserContext goes away.
- if (rvh_test_enabler_.rph_factory_.get())
+ if (rvh_test_enabler_.rph_factory_)
rvh_test_enabler_.rph_factory_.reset();
// Release the browser context on the UI thread.
diff --git a/content/public/test/test_renderer_host.h b/content/public/test/test_renderer_host.h
index 7dba135..44b5ff8 100644
--- a/content/public/test/test_renderer_host.h
+++ b/content/public/test/test_renderer_host.h
@@ -75,6 +75,7 @@
// setting the rest of the parameters in the message to the "typical" values.
// This is a helper function for simulating the most common types of loads.
virtual void SendNavigate(int page_id, const GURL& url) = 0;
+ virtual void SendFailedNavigate(int page_id, const GURL& url) = 0;
// Calls OnMsgNavigate on the RenderViewHost with the given information,
// including a custom PageTransition. Sets the rest of the
@@ -147,6 +148,7 @@
// Simulates a reload of the current page.
void Reload();
+ void FailedReload();
protected:
// testing::Test
@@ -166,7 +168,7 @@
// SetUp().
scoped_ptr<BrowserContext> browser_context_;
- MessageLoopForUI message_loop_;
+ base::MessageLoopForUI message_loop_;
private:
// It is important not to use this directly in the implementation as
diff --git a/content/public/test/test_utils.cc b/content/public/test/test_utils.cc
index ab0fcd6..6c318c3 100644
--- a/content/public/test/test_utils.cc
+++ b/content/public/test/test_utils.cc
@@ -34,7 +34,8 @@
if (num_quit_deferrals <= 0) {
quit_task.Run();
} else {
- MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
base::Bind(&DeferredQuitRunLoop, quit_task, num_quit_deferrals - 1));
}
}
@@ -63,7 +64,7 @@
void ScriptCallback::ResultCallback(const base::Value* result) {
if (result)
result_.reset(result->DeepCopy());
- MessageLoop::current()->Quit();
+ base::MessageLoop::current()->Quit();
}
} // namespace
@@ -74,7 +75,8 @@
}
void RunThisRunLoop(base::RunLoop* run_loop) {
- MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
+ base::MessageLoop::ScopedNestableTaskAllower allow(
+ base::MessageLoop::current());
// If we're running inside a browser test, we might need to allow the test
// launcher to do extra work before/after running a nested message loop.
@@ -90,8 +92,8 @@
}
void RunAllPendingInMessageLoop() {
- MessageLoop::current()->PostTask(FROM_HERE,
- MessageLoop::QuitWhenIdleClosure());
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
RunMessageLoop();
}
@@ -127,7 +129,7 @@
string16(), // frame_xpath,
UTF8ToUTF16(script),
base::Bind(&ScriptCallback::ResultCallback, base::Unretained(&observer)));
- MessageLoop* loop = MessageLoop::current();
+ base::MessageLoop* loop = base::MessageLoop::current();
loop->Run();
return observer.result().Pass();
}
diff --git a/content/public/test/web_contents_tester.h b/content/public/test/web_contents_tester.h
index d6a1f7a..8b0734a 100644
--- a/content/public/test/web_contents_tester.h
+++ b/content/public/test/web_contents_tester.h
@@ -8,10 +8,7 @@
#include "content/public/common/page_transition_types.h"
class GURL;
-
-namespace webkit_glue {
struct WebPreferences;
-}
namespace content {
@@ -91,7 +88,7 @@
PageTransition transition) = 0;
// Promote GetWebkitPrefs to public.
- virtual webkit_glue::WebPreferences TestGetWebkitPrefs() = 0;
+ virtual WebPreferences TestGetWebkitPrefs() = 0;
};
} // namespace content
diff --git a/content/renderer/DEPS b/content/renderer/DEPS
index e28b22a..f309b29 100644
--- a/content/renderer/DEPS
+++ b/content/renderer/DEPS
@@ -1,7 +1,5 @@
include_rules = [
"+content/public/renderer",
- "+content/public/browser/native_web_keyboard_event.h", # For tests.
- "+content/public/browser/web_ui_controller_factory.h", # For tests.
"+jingle/glue",
"+media", # For audio input/output and audio/video decoding.
"+third_party/hyphen/hyphen.h",
@@ -10,3 +8,10 @@
"+third_party/tcmalloc",
"+v8/include",
]
+
+specific_include_rules = {
+ '.*_[a-z]*browsertest.*': [
+ "+content/public/browser",
+ "+content/shell",
+ ],
+}
diff --git a/content/renderer/accessibility/accessibility_node_serializer.cc b/content/renderer/accessibility/accessibility_node_serializer.cc
index bb010b1..7fb5d91 100644
--- a/content/renderer/accessibility/accessibility_node_serializer.cc
+++ b/content/renderer/accessibility/accessibility_node_serializer.cc
@@ -557,6 +557,9 @@
std::set<int> unique_cell_id_set;
dst->int_attributes[dst->ATTR_TABLE_COLUMN_COUNT] = column_count;
dst->int_attributes[dst->ATTR_TABLE_ROW_COUNT] = row_count;
+ WebAccessibilityObject header = src.headerContainerObject();
+ if (!header.isDetached())
+ dst->int_attributes[dst->ATTR_TABLE_HEADER_ID] = header.axID();
for (int i = 0; i < column_count * row_count; ++i) {
WebAccessibilityObject cell = src.cellForColumnAndRow(
i % column_count, i / column_count);
@@ -573,6 +576,20 @@
}
}
+ if (dst->role == dst->ROLE_ROW) {
+ dst->int_attributes[dst->ATTR_TABLE_ROW_INDEX] = src.rowIndex();
+ WebAccessibilityObject header = src.rowHeader();
+ if (!header.isDetached())
+ dst->int_attributes[dst->ATTR_TABLE_ROW_HEADER_ID] = header.axID();
+ }
+
+ if (dst->role == dst->ROLE_COLUMN) {
+ dst->int_attributes[dst->ATTR_TABLE_COLUMN_INDEX] = src.columnIndex();
+ WebAccessibilityObject header = src.columnHeader();
+ if (!header.isDetached())
+ dst->int_attributes[dst->ATTR_TABLE_COLUMN_HEADER_ID] = header.axID();
+ }
+
if (dst->role == dst->ROLE_CELL ||
dst->role == dst->ROLE_ROW_HEADER ||
dst->role == dst->ROLE_COLUMN_HEADER) {
diff --git a/content/renderer/accessibility/renderer_accessibility_browsertest.cc b/content/renderer/accessibility/renderer_accessibility_browsertest.cc
index 062ced8..db3daf2 100644
--- a/content/renderer/accessibility/renderer_accessibility_browsertest.cc
+++ b/content/renderer/accessibility/renderer_accessibility_browsertest.cc
@@ -331,6 +331,12 @@
EXPECT_EQ(4, accessibility->browser_tree_node_count());
EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser());
+ WebDocument document = view()->GetWebView()->mainFrame()->document();
+ WebAccessibilityObject root_obj = document.accessibilityObject();
+ WebAccessibilityObject node_a = root_obj.childAt(0);
+ WebAccessibilityObject node_b = node_a.childAt(0);
+ WebAccessibilityObject node_c = node_b.childAt(0);
+
// Hide node 'B' ('C' stays visible).
ExecuteJavaScript(
"document.getElementById('B').style.visibility = 'hidden';");
@@ -339,9 +345,6 @@
// Send a childrenChanged on 'A'.
sink_->ClearMessages();
- WebDocument document = view()->GetWebView()->mainFrame()->document();
- WebAccessibilityObject root_obj = document.accessibilityObject();
- WebAccessibilityObject node_a = root_obj.childAt(0);
accessibility->HandleWebAccessibilityNotification(
node_a,
WebKit::WebAccessibilityNotificationChildrenChanged);
@@ -350,8 +353,15 @@
EXPECT_EQ(3, accessibility->browser_tree_node_count());
AccessibilityHostMsg_NotificationParams notification;
GetLastAccNotification(¬ification);
- ASSERT_EQ(2U, notification.nodes.size());
- EXPECT_EQ(2, CountAccessibilityNodesSentToBrowser());
+ ASSERT_EQ(3U, notification.nodes.size());
+
+ // RendererAccessibilityComplete notices that 'C' is being reparented,
+ // so it updates 'B' first to remove 'C' as a child, then 'A' to add it,
+ // and finally it updates 'C'.
+ EXPECT_EQ(node_b.axID(), notification.nodes[0].id);
+ EXPECT_EQ(node_a.axID(), notification.nodes[1].id);
+ EXPECT_EQ(node_c.axID(), notification.nodes[2].id);
+ EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser());
}
TEST_F(RendererAccessibilityTest, ShowAccessibilityObject) {
diff --git a/content/renderer/accessibility/renderer_accessibility_complete.cc b/content/renderer/accessibility/renderer_accessibility_complete.cc
index 6ce31d7..c8111d3 100644
--- a/content/renderer/accessibility/renderer_accessibility_complete.cc
+++ b/content/renderer/accessibility/renderer_accessibility_complete.cc
@@ -4,6 +4,8 @@
#include "content/renderer/accessibility/renderer_accessibility_complete.h"
+#include <queue>
+
#include "base/bind.h"
#include "base/message_loop.h"
#include "content/renderer/accessibility/accessibility_node_serializer.h"
@@ -102,7 +104,7 @@
RendererAccessibilityComplete::RendererAccessibilityComplete(
RenderViewImpl* render_view)
: RendererAccessibility(render_view),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+ weak_factory_(this),
browser_root_(NULL),
last_scroll_offset_(gfx::Size()),
ack_pending_(false) {
@@ -227,12 +229,11 @@
// When no accessibility notifications are in-flight post a task to send
// the notifications to the browser. We use PostTask so that we can queue
// up additional notifications.
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(
- &RendererAccessibilityComplete::
- SendPendingAccessibilityNotifications,
- weak_factory_.GetWeakPtr()));
+ base::Bind(&RendererAccessibilityComplete::
+ SendPendingAccessibilityNotifications,
+ weak_factory_.GetWeakPtr()));
}
}
@@ -360,9 +361,54 @@
#endif
}
+ AppendLocationChangeNotifications(¬ification_msgs);
+
Send(new AccessibilityHostMsg_Notifications(routing_id(), notification_msgs));
}
+void RendererAccessibilityComplete::AppendLocationChangeNotifications(
+ std::vector<AccessibilityHostMsg_NotificationParams>* notification_msgs) {
+ std::queue<WebAccessibilityObject> objs_to_explore;
+ std::vector<BrowserTreeNode*> location_changes;
+ WebAccessibilityObject root_object = GetMainDocument().accessibilityObject();
+ objs_to_explore.push(root_object);
+
+ while (objs_to_explore.size()) {
+ WebAccessibilityObject obj = objs_to_explore.front();
+ objs_to_explore.pop();
+ int id = obj.axID();
+ if (browser_id_map_.find(id) != browser_id_map_.end()) {
+ BrowserTreeNode* browser_node = browser_id_map_[id];
+ gfx::Rect new_location = obj.boundingBoxRect();
+ if (browser_node->location != new_location) {
+ browser_node->location = new_location;
+ location_changes.push_back(browser_node);
+ }
+ }
+
+ for (unsigned i = 0; i < obj.childCount(); ++i)
+ objs_to_explore.push(obj.childAt(i));
+ }
+
+ if (location_changes.size() == 0)
+ return;
+
+ AccessibilityHostMsg_NotificationParams notification_msg;
+ notification_msg.notification_type =
+ static_cast<AccessibilityNotification>(-1);
+ notification_msg.id = root_object.axID();
+ notification_msg.nodes.resize(location_changes.size());
+ for (size_t i = 0; i < location_changes.size(); i++) {
+ AccessibilityNodeData& serialized_node = notification_msg.nodes[i];
+ serialized_node.id = location_changes[i]->id;
+ serialized_node.location = location_changes[i]->location;
+ serialized_node.bool_attributes[
+ AccessibilityNodeData::ATTR_UPDATE_LOCATION_ONLY] = true;
+ }
+
+ notification_msgs->push_back(notification_msg);
+}
+
RendererAccessibilityComplete::BrowserTreeNode*
RendererAccessibilityComplete::CreateBrowserTreeNode() {
return new RendererAccessibilityComplete::BrowserTreeNode();
@@ -397,24 +443,45 @@
browser_root_ = CreateBrowserTreeNode();
browser_node = browser_root_;
browser_node->id = obj.axID();
+ browser_node->location = obj.boundingBoxRect();
+ browser_node->parent = NULL;
browser_id_map_[browser_node->id] = browser_node;
}
- // Serialize this node. This fills in all of the fields in
- // AccessibilityNodeData except child_ids, which we handle below.
- dst->push_back(AccessibilityNodeData());
- AccessibilityNodeData* serialized_node = &dst->back();
- SerializeAccessibilityNode(obj, serialized_node);
- if (serialized_node->id == browser_root_->id)
- serialized_node->role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA;
-
- // Create set of the ids of the children of |obj| so we can quickly look
+ // Iterate over the ids of the children of |obj|.
+ // Create a set of the child ids so we can quickly look
// up which children are new and which ones were there before.
+ // Also catch the case where a child is already in the browser tree
+ // data structure with a different parent, and make sure the old parent
+ // clears this node first.
base::hash_set<int32> new_child_ids;
+ const WebDocument& document = GetMainDocument();
for (unsigned i = 0; i < obj.childCount(); i++) {
WebAccessibilityObject child = obj.childAt(i);
if (ShouldIncludeChildNode(obj, child)) {
- new_child_ids.insert(child.axID());
+ int new_child_id = child.axID();
+ new_child_ids.insert(new_child_id);
+
+ BrowserTreeNode* child = browser_id_map_[new_child_id];
+ if (child && child->parent != browser_node) {
+ // The child is being reparented. Find the WebKit accessibility
+ // object corresponding to the old parent, or the closest ancestor
+ // still in the tree.
+ BrowserTreeNode* parent = child->parent;
+ WebAccessibilityObject parent_obj;
+ while (parent) {
+ parent_obj = document.accessibilityObjectFromID(parent->id);
+ if (!parent_obj.isDetached())
+ break;
+ parent = parent->parent;
+ }
+ CHECK(parent);
+ // Call SerializeChangedNodes recursively on the old parent,
+ // so that the update that clears |child| from its old parent
+ // occurs stricly before the update that adds |child| to its
+ // new parent.
+ SerializeChangedNodes(parent_obj, dst);
+ }
}
}
@@ -439,6 +506,14 @@
}
}
+ // Serialize this node. This fills in all of the fields in
+ // AccessibilityNodeData except child_ids, which we handle below.
+ dst->push_back(AccessibilityNodeData());
+ AccessibilityNodeData* serialized_node = &dst->back();
+ SerializeAccessibilityNode(obj, serialized_node);
+ if (serialized_node->id == browser_root_->id)
+ serialized_node->role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA;
+
// Iterate over the children, make note of the ones that are new
// and need to be serialized, and update the BrowserTreeNode
// data structure to reflect the new tree.
@@ -462,10 +537,14 @@
new_child_ids.erase(child_id);
serialized_node->child_ids.push_back(child_id);
if (browser_child_id_map.find(child_id) != browser_child_id_map.end()) {
- browser_node->children.push_back(browser_child_id_map[child_id]);
+ BrowserTreeNode* reused_child = browser_child_id_map[child_id];
+ reused_child->location = obj.boundingBoxRect();
+ browser_node->children.push_back(reused_child);
} else {
BrowserTreeNode* new_child = CreateBrowserTreeNode();
new_child->id = child_id;
+ new_child->location = obj.boundingBoxRect();
+ new_child->parent = browser_node;
browser_node->children.push_back(new_child);
browser_id_map_[child_id] = new_child;
children_to_serialize.push_back(child);
@@ -625,7 +704,7 @@
}
void RendererAccessibilityComplete::OnFatalError() {
- CHECK(false);
+ CHECK(false) << "Invalid accessibility tree.";
}
} // namespace content
diff --git a/content/renderer/accessibility/renderer_accessibility_complete.h b/content/renderer/accessibility/renderer_accessibility_complete.h
index 41d0880..7fff8c2 100644
--- a/content/renderer/accessibility/renderer_accessibility_complete.h
+++ b/content/renderer/accessibility/renderer_accessibility_complete.h
@@ -54,6 +54,8 @@
BrowserTreeNode();
virtual ~BrowserTreeNode();
int32 id;
+ gfx::Rect location;
+ BrowserTreeNode* parent;
std::vector<BrowserTreeNode*> children;
};
@@ -63,6 +65,13 @@
// Send queued notifications from the renderer to the browser.
void SendPendingAccessibilityNotifications();
+ // Check the entire accessibility tree to see if any nodes have
+ // changed location, by comparing their locations to the cached
+ // versions. If any have moved, append a notification to |notifications|
+ // that updates the coordinates of these objects.
+ void AppendLocationChangeNotifications(
+ std::vector<AccessibilityHostMsg_NotificationParams>* notifications);
+
private:
// Handle an accessibility notification to be sent to the browser process.
void HandleAccessibilityNotification(
diff --git a/content/renderer/accessibility/renderer_accessibility_focus_only.cc b/content/renderer/accessibility/renderer_accessibility_focus_only.cc
index 71da433..aab2746 100644
--- a/content/renderer/accessibility/renderer_accessibility_focus_only.cc
+++ b/content/renderer/accessibility/renderer_accessibility_focus_only.cc
@@ -96,9 +96,11 @@
// has focus, otherwise the focused node.
notification.id = node_has_focus ? next_id_ : 1;
- // Always include the root of the tree, the document. It always has id 1.
- notification.nodes.push_back(AccessibilityNodeData());
+ notification.nodes.resize(2);
AccessibilityNodeData& root = notification.nodes[0];
+ AccessibilityNodeData& child = notification.nodes[1];
+
+ // Always include the root of the tree, the document. It always has id 1.
root.id = 1;
root.role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA;
root.state =
@@ -109,8 +111,6 @@
root.location = gfx::Rect(render_view_->size());
root.child_ids.push_back(next_id_);
- notification.nodes.push_back(AccessibilityNodeData());
- AccessibilityNodeData& child = notification.nodes[1];
child.id = next_id_;
child.role = AccessibilityNodeData::ROLE_GROUP;
diff --git a/content/renderer/active_notification_tracker.cc b/content/renderer/active_notification_tracker.cc
index 5f4a40e..11e16c2 100644
--- a/content/renderer/active_notification_tracker.cc
+++ b/content/renderer/active_notification_tracker.cc
@@ -55,7 +55,7 @@
scoped_ptr<WebNotification> notification(notification_table_.Lookup(id));
notification_table_.Remove(id);
DCHECK(notification.get());
- if (notification.get())
+ if (notification)
reverse_notification_table_.erase(*notification);
}
diff --git a/content/renderer/android/synchronous_compositor_output_surface.cc b/content/renderer/android/synchronous_compositor_output_surface.cc
new file mode 100644
index 0000000..87792ea
--- /dev/null
+++ b/content/renderer/android/synchronous_compositor_output_surface.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/android/synchronous_compositor_output_surface.h"
+
+#include "base/logging.h"
+#include "cc/output/output_surface_client.h"
+#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
+#include "content/public/renderer/android/synchronous_compositor_client.h"
+#include "content/public/renderer/content_renderer_client.h"
+#include "skia/ext/refptr.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkPicture.h"
+
+namespace content {
+
+SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface(
+ int32 routing_id,
+ WebGraphicsContext3DCommandBufferImpl* context)
+ : cc::OutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D>(context)),
+ compositor_client_(NULL),
+ routing_id_(routing_id) {
+ // WARNING: may be called on any thread.
+}
+
+SynchronousCompositorOutputSurface::~SynchronousCompositorOutputSurface() {
+ DCHECK(CalledOnValidThread());
+ if (compositor_client_)
+ compositor_client_->DidDestroyCompositor(this);
+}
+
+bool SynchronousCompositorOutputSurface::BindToClient(
+ cc::OutputSurfaceClient* surface_client) {
+ DCHECK(CalledOnValidThread());
+ if (!cc::OutputSurface::BindToClient(surface_client))
+ return false;
+ GetContentClient()->renderer()->DidCreateSynchronousCompositor(routing_id_,
+ this);
+ return true;
+}
+
+void SynchronousCompositorOutputSurface::SendFrameToParentCompositor(
+ cc::CompositorFrame* frame) {
+ // Intentional no-op: see http://crbug.com/237006
+}
+
+void SynchronousCompositorOutputSurface::SetClient(
+ SynchronousCompositorClient* compositor_client) {
+ DCHECK(CalledOnValidThread());
+ compositor_client_ = compositor_client;
+}
+
+bool SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) {
+ DCHECK(CalledOnValidThread());
+ NOTIMPLEMENTED(); // TODO(joth): call through to OutputSurfaceClient
+ return false;
+}
+
+// Not using base::NonThreadSafe as we want to enforce a more exacting threading
+// requirement: SynchronousCompositorOutputSurface() must only be used by
+// embedders that supply their own compositor loop via
+// OverrideCompositorMessageLoop().
+bool SynchronousCompositorOutputSurface::CalledOnValidThread() const {
+ return base::MessageLoop::current() && (base::MessageLoop::current() ==
+ GetContentClient()->renderer()->OverrideCompositorMessageLoop());
+}
+
+} // namespace content
diff --git a/content/renderer/android/synchronous_compositor_output_surface.h b/content/renderer/android/synchronous_compositor_output_surface.h
new file mode 100644
index 0000000..04af44f
--- /dev/null
+++ b/content/renderer/android/synchronous_compositor_output_surface.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_OUTPUT_SURFACE_H_
+#define CONTENT_RENDERER_ANDOIRD_SYNCHRONOUS_COMPOSITOR_OUTPUT_SURFACE_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "cc/output/output_surface.h"
+#include "content/public/renderer/android/synchronous_compositor.h"
+
+namespace content {
+
+class SynchronousCompositorClient;
+class WebGraphicsContext3DCommandBufferImpl;
+
+// Specialization of the output surface that adapts it to implement the
+// content::SynchronousCompositor public API. This class effects an "inversion
+// of control" - enabling drawing to be orchestrated by the embedding
+// layer, instead of driven by the compositor internals - hence it holds two
+// 'client' pointers (including |client_| in the OutputSurface baseclass) which
+// represent the consumers of the two roles in plays.
+// This class can be created only on the main thread, but then becomes pinned
+// to a fixed thread when BindToClient is called.
+class SynchronousCompositorOutputSurface
+ : NON_EXPORTED_BASE(public cc::OutputSurface),
+ NON_EXPORTED_BASE(public SynchronousCompositor) {
+ public:
+ SynchronousCompositorOutputSurface(
+ int32 routing_id,
+ WebGraphicsContext3DCommandBufferImpl* context);
+ virtual ~SynchronousCompositorOutputSurface();
+
+ // OutputSurface.
+ virtual bool BindToClient(cc::OutputSurfaceClient* surface_client) OVERRIDE;
+ virtual void SendFrameToParentCompositor(cc::CompositorFrame* frame) OVERRIDE;
+
+ // SynchronousCompositor.
+ virtual void SetClient(SynchronousCompositorClient* compositor_client)
+ OVERRIDE;
+ virtual bool DemandDrawSw(SkCanvas* canvas) OVERRIDE;
+
+ private:
+ bool CalledOnValidThread() const;
+
+ SynchronousCompositorClient* compositor_client_;
+ int routing_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorOutputSurface);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_OUTPUT_SURFACE_H_
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc
index b4921e5..002d2a5 100644
--- a/content/renderer/browser_plugin/browser_plugin.cc
+++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -52,25 +52,6 @@
namespace {
-static bool shouldIgnoreKeyBoardEvent(const WebKit::WebKeyboardEvent* event) {
- if (event->type == WebKit::WebInputEvent::Char)
- return false;
- int keycode = event->windowsKeyCode;
- if (keycode == ui::VKEY_SHIFT ||
- keycode == ui::VKEY_CONTROL ||
- keycode == ui::VKEY_MENU ||
- keycode == ui::VKEY_LWIN) // The search key on chromeOS.
- return true;
- // We don't want to handle keys like volume control, or app launchers inside
- // of BrowserPlugin. These keys should be handled either by the browser, or
- // the OS.
- if ((keycode >= ui::VKEY_BROWSER_BACK &&
- keycode <= ui::VKEY_MEDIA_LAUNCH_APP2) ||
- (keycode >= ui::VKEY_F1 && keycode <= ui::VKEY_F24))
- return true;
- return false;
-}
-
static std::string TerminationStatusToString(base::TerminationStatus status) {
switch (status) {
case base::TERMINATION_STATUS_NORMAL_TERMINATION:
@@ -95,6 +76,8 @@
static std::string PermissionTypeToString(BrowserPluginPermissionType type) {
switch (type) {
+ case BrowserPluginPermissionTypeDownload:
+ return browser_plugin::kPermissionTypeDownload;
case BrowserPluginPermissionTypeGeolocation:
return browser_plugin::kPermissionTypeGeolocation;
case BrowserPluginPermissionTypeMedia:
@@ -108,7 +91,7 @@
NOTREACHED();
break;
}
- return "";
+ return std::string();
}
typedef std::map<WebKit::WebPluginContainer*,
@@ -128,6 +111,7 @@
container_(NULL),
damage_buffer_sequence_id_(0),
resize_ack_received_(true),
+ last_device_scale_factor_(1.0f),
sad_guest_(NULL),
guest_crashed_(false),
auto_size_ack_pending_(false),
@@ -139,13 +123,12 @@
plugin_focused_(false),
visible_(true),
size_changed_in_flight_(false),
- allocate_instance_id_sent_(false),
- browser_plugin_manager_(render_view->browser_plugin_manager()),
+ before_first_navigation_(true),
+ browser_plugin_manager_(render_view->GetBrowserPluginManager()),
current_nav_entry_index_(0),
nav_entry_count_(0),
compositing_enabled_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- weak_ptr_factory_(this)) {
+ weak_ptr_factory_(this) {
}
BrowserPlugin::~BrowserPlugin() {
@@ -171,8 +154,14 @@
bool BrowserPlugin::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(BrowserPlugin, message)
+ IPC_MESSAGE_HANDLER(BrowserPluginMsg_AddMessageToConsole,
+ OnAddMessageToConsole)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_AdvanceFocus, OnAdvanceFocus)
+ IPC_MESSAGE_HANDLER(BrowserPluginMsg_Attach_ACK, OnAttachACK)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_BuffersSwapped, OnBuffersSwapped)
+ IPC_MESSAGE_HANDLER(BrowserPluginMsg_Close, OnClose)
+ IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginMsg_CompositorFrameSwapped,
+ OnCompositorFrameSwapped(message))
IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestContentWindowReady,
OnGuestContentWindowReady)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestGone, OnGuestGone)
@@ -222,7 +211,7 @@
std::string BrowserPlugin::GetDOMAttributeValue(
const std::string& attribute_name) const {
if (!container())
- return "";
+ return std::string();
return container()->element().getAttribute(
WebKit::WebString::fromUTF8(attribute_name)).utf8();
@@ -332,16 +321,16 @@
if (!HasGuest()) {
// On initial navigation, we request an instance ID from the browser
// process. We essentially ignore all subsequent calls to SetSrcAttribute
- // until we receive an instance ID. |allocate_instance_id_sent_|
+ // until we receive an instance ID. |before_first_navigation_|
// prevents BrowserPlugin from allocating more than one instance ID.
// Upon receiving an instance ID from the browser process, we continue
// the process of navigation by populating the
- // BrowserPluginHostMsg_CreateGuest_Params with the current state of
+ // BrowserPluginHostMsg_Attach_Params with the current state of
// BrowserPlugin and sending a BrowserPluginHostMsg_CreateGuest to the
// browser process in order to create a new guest.
- if (!allocate_instance_id_sent_) {
+ if (before_first_navigation_) {
browser_plugin_manager()->AllocateInstanceID(this);
- allocate_instance_id_sent_ = true;
+ before_first_navigation_ = false;
}
return true;
}
@@ -413,37 +402,46 @@
bool BrowserPlugin::UsesPendingDamageBuffer(
const BrowserPluginMsg_UpdateRect_Params& params) {
- if (!pending_damage_buffer_.get())
+ if (!pending_damage_buffer_)
return false;
return damage_buffer_sequence_id_ == params.damage_buffer_sequence_id;
}
-void BrowserPlugin::SetInstanceID(int instance_id, bool new_guest) {
+void BrowserPlugin::Attach(int instance_id) {
CHECK(instance_id != browser_plugin::kInstanceIDNone);
+ before_first_navigation_ = false;
instance_id_ = instance_id;
browser_plugin_manager()->AddBrowserPlugin(instance_id, this);
- BrowserPluginHostMsg_CreateGuest_Params create_guest_params;
+ BrowserPluginHostMsg_Attach_Params create_guest_params;
create_guest_params.focused = ShouldGuestBeFocused();
create_guest_params.visible = visible_;
create_guest_params.name = GetNameAttribute();
- GetDamageBufferWithSizeParams(&create_guest_params.auto_size_params,
- &create_guest_params.resize_guest_params);
-
- if (!new_guest) {
- browser_plugin_manager()->Send(
- new BrowserPluginHostMsg_Attach(render_view_routing_id_,
- instance_id_, create_guest_params));
- return;
- }
-
create_guest_params.storage_partition_id = storage_partition_id_;
create_guest_params.persist_storage = persist_storage_;
create_guest_params.src = GetSrcAttribute();
+ GetDamageBufferWithSizeParams(&create_guest_params.auto_size_params,
+ &create_guest_params.resize_guest_params);
+
browser_plugin_manager()->Send(
- new BrowserPluginHostMsg_CreateGuest(render_view_routing_id_,
- instance_id_,
- create_guest_params));
+ new BrowserPluginHostMsg_Attach(render_view_routing_id_,
+ instance_id_, create_guest_params));
+}
+
+void BrowserPlugin::DidCommitCompositorFrame() {
+ if (compositing_helper_)
+ compositing_helper_->DidCommitCompositorFrame();
+}
+
+void BrowserPlugin::OnAddMessageToConsole(
+ int instance_id, const base::DictionaryValue& message_info) {
+ std::map<std::string, base::Value*> props;
+ // Fill in the info provided by the browser.
+ for (DictionaryValue::Iterator iter(message_info); !iter.IsAtEnd();
+ iter.Advance()) {
+ props[iter.key()] = iter.value().DeepCopy();
+ }
+ TriggerEvent(browser_plugin::kEventConsoleMessage, &props);
}
void BrowserPlugin::OnAdvanceFocus(int instance_id, bool reverse) {
@@ -451,6 +449,20 @@
render_view_->GetWebView()->advanceFocus(reverse);
}
+void BrowserPlugin::OnAttachACK(
+ int instance_id,
+ const BrowserPluginMsg_Attach_ACK_Params& params) {
+ // Update BrowserPlugin attributes to match the state of the guest.
+ if (!params.name.empty())
+ OnUpdatedName(instance_id, params.name);
+ if (!params.storage_partition_id.empty()) {
+ std::string partition_name =
+ (params.persist_storage ? browser_plugin::kPersistPrefix : "") +
+ params.storage_partition_id;
+ UpdateDOMAttribute(browser_plugin::kAttributePartition, partition_name);
+ }
+}
+
void BrowserPlugin::OnBuffersSwapped(int instance_id,
const gfx::Size& size,
std::string mailbox_name,
@@ -466,6 +478,23 @@
GetDeviceScaleFactor());
}
+void BrowserPlugin::OnClose(int instance_id) {
+ TriggerEvent(browser_plugin::kEventClose, NULL);
+}
+
+void BrowserPlugin::OnCompositorFrameSwapped(const IPC::Message& message) {
+ BrowserPluginMsg_CompositorFrameSwapped::Param param;
+ if (!BrowserPluginMsg_CompositorFrameSwapped::Read(&message, ¶m))
+ return;
+ scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
+ param.b.AssignTo(frame.get());
+
+ EnableCompositing(true);
+ compositing_helper_->OnCompositorFrameSwapped(frame.Pass(),
+ param.c /* route_id */,
+ param.d /* host_id */);
+}
+
void BrowserPlugin::OnGuestContentWindowReady(int instance_id,
int content_window_routing_id) {
DCHECK(content_window_routing_id != MSG_ROUTING_NONE);
@@ -655,7 +684,8 @@
if ((!auto_size && (width() != params.view_size.width() ||
height() != params.view_size.height())) ||
- (auto_size && (!InAutoSizeBounds(params.view_size)))) {
+ (auto_size && (!InAutoSizeBounds(params.view_size))) ||
+ GetDeviceScaleFactor() != params.scale_factor) {
// We are HW accelerated, render widget does not expect an ack,
// but we still need to update the size.
if (!params.needs_ack) {
@@ -702,7 +732,7 @@
// with the last seen view size.
if (container_ && !size_changed_in_flight_) {
size_changed_in_flight_ = true;
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&BrowserPlugin::SizeChangedDueToAutoSize,
base::Unretained(this),
@@ -735,11 +765,9 @@
params.scroll_rect,
params.view_size);
}
- for (unsigned i = 0; i < params.copy_rects.size(); i++) {
- backing_store_->PaintToBackingStore(params.bitmap_rect,
- params.copy_rects,
- current_damage_buffer_->memory());
- }
+ backing_store_->PaintToBackingStore(params.bitmap_rect,
+ params.copy_rects,
+ current_damage_buffer_->memory());
// Invalidate the container.
// If the BrowserPlugin is scheduled to be deleted, then container_ will be
@@ -769,8 +797,8 @@
NPObject* BrowserPlugin::GetContentWindow() const {
if (content_window_routing_id_ == MSG_ROUTING_NONE)
return NULL;
- RenderViewImpl* guest_render_view = static_cast<RenderViewImpl*>(
- ChildThread::current()->ResolveRoute(content_window_routing_id_));
+ RenderViewImpl* guest_render_view = RenderViewImpl::FromRoutingID(
+ content_window_routing_id_);
if (!guest_render_view)
return NULL;
WebKit::WebFrame* guest_frame = guest_render_view->GetWebView()->mainFrame();
@@ -808,11 +836,11 @@
// If the BrowserPlugin already has a guest attached to it then we probably
// shouldn't allow attaching a different guest.
// TODO(fsamuel): We may wish to support reattaching guests in the future:
- // http://crbug.com/156219
+ // http://crbug.com/156219.
if (browser_plugin->HasGuest())
return false;
- browser_plugin->SetInstanceID(window_id, false);
+ browser_plugin->Attach(window_id);
return true;
}
@@ -830,7 +858,7 @@
}
bool BrowserPlugin::ParsePartitionAttribute(std::string* error_message) {
- if (allocate_instance_id_sent_) {
+ if (!before_first_navigation_) {
*error_message = browser_plugin::kErrorAlreadyNavigated;
return false;
}
@@ -883,6 +911,18 @@
return render_view_->GetWebView()->deviceScaleFactor();
}
+void BrowserPlugin::UpdateDeviceScaleFactor(float device_scale_factor) {
+ if (last_device_scale_factor_ == device_scale_factor || !resize_ack_received_)
+ return;
+
+ BrowserPluginHostMsg_ResizeGuest_Params params;
+ PopulateResizeGuestParameters(¶ms, gfx::Size(width(), height()));
+ browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest(
+ render_view_routing_id_,
+ instance_id_,
+ params));
+}
+
void BrowserPlugin::TriggerEvent(const std::string& event_name,
std::map<std::string, base::Value*>* props) {
if (!container() || !container()->element().document().frame())
@@ -938,9 +978,8 @@
}
v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::Persistent<v8::Value> weak_request =
- v8::Persistent<v8::Value>::New(isolate,
- WebKit::WebBindings::toV8Value(request));
+ v8::Persistent<v8::Value> weak_request(
+ isolate, WebKit::WebBindings::toV8Value(request));
AliveV8PermissionRequestItem* new_item =
new std::pair<int, base::WeakPtr<BrowserPlugin> >(
@@ -973,10 +1012,11 @@
// Asynchronously remove item from |alive_v8_permission_request_objects_|.
// Note that we are using weak pointer for the following PostTask, so we
// don't need to worry about BrowserPlugin going away.
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&BrowserPlugin::OnRequestObjectGarbageCollected,
- plugin, request_id));
+ plugin,
+ request_id));
}
}
@@ -1143,11 +1183,11 @@
// Will be a no-op if the mouse is not currently locked.
if (render_view_)
render_view_->mouse_lock_dispatcher()->OnLockTargetDestroyed(this);
- MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
NPObject* BrowserPlugin::scriptableObject() {
- if (!bindings_.get())
+ if (!bindings_)
return NULL;
NPObject* browser_plugin_np_object(bindings_->np_object());
@@ -1224,8 +1264,12 @@
bool BrowserPlugin::ShouldForwardToBrowserPlugin(
const IPC::Message& message) {
switch (message.type()) {
+ case BrowserPluginMsg_AddMessageToConsole::ID:
case BrowserPluginMsg_AdvanceFocus::ID:
+ case BrowserPluginMsg_Attach_ACK::ID:
case BrowserPluginMsg_BuffersSwapped::ID:
+ case BrowserPluginMsg_Close::ID:
+ case BrowserPluginMsg_CompositorFrameSwapped::ID:
case BrowserPluginMsg_GuestContentWindowReady::ID:
case BrowserPluginMsg_GuestGone::ID:
case BrowserPluginMsg_GuestResponsive::ID:
@@ -1288,6 +1332,10 @@
const gfx::Size& view_size) {
params->view_size = view_size;
params->scale_factor = GetDeviceScaleFactor();
+ if (last_device_scale_factor_ != params->scale_factor){
+ params->repaint = true;
+ last_device_scale_factor_ = params->scale_factor;
+ }
// In HW compositing mode, we do not need a damage buffer.
if (compositing_enabled_)
@@ -1306,7 +1354,7 @@
params->damage_buffer_size = size;
pending_damage_buffer_.reset(
CreateDamageBuffer(size, ¶ms->damage_buffer_handle));
- if (!pending_damage_buffer_.get())
+ if (!pending_damage_buffer_)
NOTREACHED();
params->damage_buffer_sequence_id = ++damage_buffer_sequence_id_;
}
@@ -1332,7 +1380,7 @@
content::RenderThread::Get()->HostAllocateSharedMemoryBuffer(
size).release());
- if (shared_buf.get()) {
+ if (shared_buf) {
if (shared_buf->Map(size)) {
// Insert the magic word.
*static_cast<unsigned int*>(shared_buf->memory()) = 0xdeadbeef;
@@ -1403,16 +1451,6 @@
event.type == WebKit::WebInputEvent::ContextMenu)
return false;
- if (WebKit::WebInputEvent::isKeyboardEventType(event.type)) {
- // TODO(mthiesse): This is a temporary solution for BrowserPlugin capturing
- // keys like the search key on chromeOS. The guest should be allowed to
- // handle these key events (as javascript allows this), so a better solution
- // is needed.
- if (shouldIgnoreKeyBoardEvent(
- static_cast<const WebKit::WebKeyboardEvent*>(&event)))
- return false;
- }
-
const WebKit::WebInputEvent* modified_event = &event;
scoped_ptr<WebKit::WebTouchEvent> touch_event;
// WebKit gives BrowserPlugin a list of touches that are down, but the browser
@@ -1455,7 +1493,7 @@
WebDropData(drag_data),
mask,
position));
- return false;
+ return true;
}
void BrowserPlugin::didReceiveResponse(
@@ -1481,6 +1519,16 @@
const WebKit::WebURLError& error) {
}
+bool BrowserPlugin::executeEditCommand(const WebKit::WebString& name) {
+ browser_plugin_manager()->Send(new BrowserPluginHostMsg_ExecuteEditCommand(
+ render_view_routing_id_,
+ instance_id_,
+ name.utf8()));
+
+ // BrowserPlugin swallows edit commands.
+ return true;
+}
+
void BrowserPlugin::OnLockMouseACK(bool succeeded) {
browser_plugin_manager()->Send(new BrowserPluginHostMsg_LockMouse_ACK(
render_view_routing_id_,
diff --git a/content/renderer/browser_plugin/browser_plugin.h b/content/renderer/browser_plugin/browser_plugin.h
index 4c7d14b..be6b995 100644
--- a/content/renderer/browser_plugin/browser_plugin.h
+++ b/content/renderer/browser_plugin/browser_plugin.h
@@ -14,6 +14,7 @@
#if defined(OS_WIN)
#include "base/shared_memory.h"
#endif
+#include "base/values.h"
#include "content/common/browser_plugin/browser_plugin_message_enums.h"
#include "content/renderer/browser_plugin/browser_plugin_backing_store.h"
#include "content/renderer/browser_plugin/browser_plugin_bindings.h"
@@ -23,6 +24,7 @@
struct BrowserPluginHostMsg_AutoSize_Params;
struct BrowserPluginHostMsg_ResizeGuest_Params;
+struct BrowserPluginMsg_Attach_ACK_Params;
struct BrowserPluginMsg_LoadCommit_Params;
struct BrowserPluginMsg_UpdateRect_Params;
@@ -114,6 +116,10 @@
// Indicates whether the guest should be focused.
bool ShouldGuestBeFocused() const;
+ // Embedder's device scale factor changed, we need to update the guest
+ // renderer.
+ void UpdateDeviceScaleFactor(float device_scale_factor);
+
// Tells the BrowserPlugin to tell the guest to navigate to the previous
// navigation entry in the navigation history.
void Back();
@@ -149,9 +155,16 @@
// Called by browser plugin binding.
void OnEmbedderDecidedPermission(int request_id, bool allow);
- // Sets the instance ID of the BrowserPlugin and requests a guest from the
- // browser process.
- void SetInstanceID(int instance_id, bool new_guest);
+ // Attaches this BrowserPlugin to a guest with the provided |instance_id|.
+ // If the |instance_id| is not yet associated with a guest, a new guest
+ // will be created. If the |instance_id| has not yet been allocated or the
+ // embedder is not permitted access to that particular guest, then the
+ // embedder will be killed.
+ void Attach(int instance_id);
+
+ // Notify the plugin about a compositor commit so that frame ACKs could be
+ // sent, if needed.
+ void DidCommitCompositorFrame();
// Returns whether a message should be forwarded to BrowserPlugin.
static bool ShouldForwardToBrowserPlugin(const IPC::Message& message);
@@ -194,6 +207,7 @@
const WebKit::WebURL& url,
void* notify_data,
const WebKit::WebURLError& error) OVERRIDE;
+ virtual bool executeEditCommand(const WebKit::WebString& name) OVERRIDE;
// MouseLockDispatcher::LockTarget implementation.
virtual void OnLockMouseACK(bool succeeded) OVERRIDE;
@@ -288,10 +302,6 @@
bool UsesPendingDamageBuffer(
const BrowserPluginMsg_UpdateRect_Params& params);
- // Sets the instance ID of the BrowserPlugin and requests a guest from the
- // browser process.
- void SetInstanceID(int instance_id);
-
void AddPermissionRequestToMap(int request_id,
BrowserPluginPermissionType type);
@@ -318,12 +328,19 @@
// IPC message handlers.
// Please keep in alphabetical order.
+ void OnAddMessageToConsole(
+ int instance_id,
+ const base::DictionaryValue& message_info);
void OnAdvanceFocus(int instance_id, bool reverse);
+ void OnAttachACK(int instance_id,
+ const BrowserPluginMsg_Attach_ACK_Params& ack_params);
void OnBuffersSwapped(int instance_id,
const gfx::Size& size,
std::string mailbox_name,
int gpu_route_id,
int gpu_host_id);
+ void OnClose(int instance_id);
+ void OnCompositorFrameSwapped(const IPC::Message& message);
void OnGuestContentWindowReady(int instance_id,
int content_window_routing_id);
void OnGuestGone(int instance_id, int process_id, int status);
@@ -367,6 +384,7 @@
uint32 damage_buffer_sequence_id_;
bool resize_ack_received_;
gfx::Rect plugin_rect_;
+ float last_device_scale_factor_;
// Bitmap for crashed plugin. Lazily initialized, non-owning pointer.
SkBitmap* sad_guest_;
bool guest_crashed_;
@@ -387,7 +405,7 @@
gfx::Size last_view_size_;
bool size_changed_in_flight_;
- bool allocate_instance_id_sent_;
+ bool before_first_navigation_;
// Each permission request item in the map is a pair of request id and
// permission type.
diff --git a/content/renderer/browser_plugin/browser_plugin_bindings.cc b/content/renderer/browser_plugin/browser_plugin_bindings.cc
index 0ec0936..9ded3f9 100644
--- a/content/renderer/browser_plugin/browser_plugin_bindings.cc
+++ b/content/renderer/browser_plugin/browser_plugin_bindings.cc
@@ -815,7 +815,7 @@
BrowserPluginBindings::BrowserPluginBindings(BrowserPlugin* instance)
: instance_(instance),
np_object_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
+ weak_ptr_factory_(this) {
NPObject* obj =
WebBindings::createObject(NULL, &browser_plugin_message_class);
np_object_ = static_cast<BrowserPluginBindings::BrowserPluginNPObject*>(obj);
diff --git a/content/renderer/browser_plugin/browser_plugin_browsertest.cc b/content/renderer/browser_plugin/browser_plugin_browsertest.cc
index e8f38ee..7b6a373 100644
--- a/content/renderer/browser_plugin/browser_plugin_browsertest.cc
+++ b/content/renderer/browser_plugin/browser_plugin_browsertest.cc
@@ -98,8 +98,7 @@
void BrowserPluginTest::SetUp() {
test_content_renderer_client_.reset(new TestContentRendererClient);
- GetContentClient()->set_renderer_for_testing(
- test_content_renderer_client_.get());
+ SetRendererClientForTesting(test_content_renderer_client_.get());
BrowserPluginManager::set_factory_for_testing(
TestBrowserPluginManagerFactory::GetInstance());
content::RenderViewTest::SetUp();
@@ -122,7 +121,7 @@
v8::Local<v8::String> v8_str = value->ToString();
int length = v8_str->Utf8Length() + 1;
- scoped_array<char> str(new char[length]);
+ scoped_ptr<char[]> str(new char[length]);
v8_str->WriteUtf8(str.get(), length);
return str.get();
}
@@ -160,15 +159,15 @@
// satisfy its resize request.
TEST_F(BrowserPluginTest, InitialResize) {
LoadHTML(GetHTMLForBrowserPluginObject().c_str());
- // Verify that the information in CreateGuest is correct.
+ // Verify that the information in Attach is correct.
int instance_id = 0;
{
const IPC::Message* msg =
browser_plugin_manager()->sink().GetUniqueMessageMatching(
- BrowserPluginHostMsg_CreateGuest::ID);
+ BrowserPluginHostMsg_Attach::ID);
ASSERT_TRUE(msg);
- BrowserPluginHostMsg_CreateGuest_Params params;
- BrowserPluginHostMsg_CreateGuest::Read(msg, &instance_id, ¶ms);
+ BrowserPluginHostMsg_Attach_Params params;
+ BrowserPluginHostMsg_Attach::Read(msg, &instance_id, ¶ms);
EXPECT_EQ(640, params.resize_guest_params.view_size.width());
EXPECT_EQ(480, params.resize_guest_params.view_size.height());
}
@@ -235,15 +234,15 @@
// Verify that we're reporting the correct URL to navigate to based on the
// src attribute.
{
- // Ensure we get a CreateGuest on the initial navigation.
+ // Ensure we get a Attach on the initial navigation.
const IPC::Message* msg =
browser_plugin_manager()->sink().GetUniqueMessageMatching(
- BrowserPluginHostMsg_CreateGuest::ID);
+ BrowserPluginHostMsg_Attach::ID);
ASSERT_TRUE(msg);
int instance_id = 0;
- BrowserPluginHostMsg_CreateGuest_Params params;
- BrowserPluginHostMsg_CreateGuest::Read(msg, &instance_id, ¶ms);
+ BrowserPluginHostMsg_Attach_Params params;
+ BrowserPluginHostMsg_Attach::Read(msg, &instance_id, ¶ms);
EXPECT_EQ("foo", params.src);
}
@@ -253,10 +252,10 @@
// Verify that the src attribute is updated as well.
ExecuteJavaScript("document.getElementById('browserplugin').src = 'bar'");
{
- // Verify that we do not get a CreateGuest on subsequent navigations.
+ // Verify that we do not get a Attach on subsequent navigations.
const IPC::Message* create_msg =
browser_plugin_manager()->sink().GetUniqueMessageMatching(
- BrowserPluginHostMsg_CreateGuest::ID);
+ BrowserPluginHostMsg_Attach::ID);
ASSERT_FALSE(create_msg);
const IPC::Message* msg =
@@ -279,14 +278,14 @@
LoadHTML(GetHTMLForBrowserPluginObject().c_str());
int instance_id = 0;
{
- // Ensure we get a CreateGuest on the initial navigation and grab the
+ // Ensure we get a Attach on the initial navigation and grab the
// BrowserPlugin's instance_id from there.
const IPC::Message* msg =
browser_plugin_manager()->sink().GetUniqueMessageMatching(
- BrowserPluginHostMsg_CreateGuest::ID);
+ BrowserPluginHostMsg_Attach::ID);
ASSERT_TRUE(msg);
- BrowserPluginHostMsg_CreateGuest_Params params;
- BrowserPluginHostMsg_CreateGuest::Read(msg, &instance_id, ¶ms);
+ BrowserPluginHostMsg_Attach_Params params;
+ BrowserPluginHostMsg_Attach::Read(msg, &instance_id, ¶ms);
}
MockBrowserPlugin* browser_plugin =
static_cast<MockBrowserPlugin*>(
@@ -374,15 +373,15 @@
TEST_F(BrowserPluginTest, GuestCrash) {
LoadHTML(GetHTMLForBrowserPluginObject().c_str());
- // Grab the BrowserPlugin's instance ID from its CreateGuest message.
+ // Grab the BrowserPlugin's instance ID from its Attach message.
int instance_id = 0;
{
const IPC::Message* msg =
browser_plugin_manager()->sink().GetFirstMessageMatching(
- BrowserPluginHostMsg_CreateGuest::ID);
+ BrowserPluginHostMsg_Attach::ID);
ASSERT_TRUE(msg);
- BrowserPluginHostMsg_CreateGuest_Params params;
- BrowserPluginHostMsg_CreateGuest::Read(msg, &instance_id, ¶ms);
+ BrowserPluginHostMsg_Attach_Params params;
+ BrowserPluginHostMsg_Attach::Read(msg, &instance_id, ¶ms);
}
MockBrowserPlugin* browser_plugin =
static_cast<MockBrowserPlugin*>(
@@ -483,11 +482,11 @@
// Grab the BrowserPlugin's instance ID from its resize message.
const IPC::Message* msg =
browser_plugin_manager()->sink().GetFirstMessageMatching(
- BrowserPluginHostMsg_CreateGuest::ID);
+ BrowserPluginHostMsg_Attach::ID);
ASSERT_TRUE(msg);
int instance_id = 0;
- BrowserPluginHostMsg_CreateGuest_Params params;
- BrowserPluginHostMsg_CreateGuest::Read(msg, &instance_id, ¶ms);
+ BrowserPluginHostMsg_Attach_Params params;
+ BrowserPluginHostMsg_Attach::Read(msg, &instance_id, ¶ms);
MockBrowserPlugin* browser_plugin =
static_cast<MockBrowserPlugin*>(
@@ -653,12 +652,12 @@
{
const IPC::Message* create_msg =
browser_plugin_manager()->sink().GetUniqueMessageMatching(
- BrowserPluginHostMsg_CreateGuest::ID);
+ BrowserPluginHostMsg_Attach::ID);
ASSERT_TRUE(create_msg);
int create_instance_id = 0;
- BrowserPluginHostMsg_CreateGuest_Params params;
- BrowserPluginHostMsg_CreateGuest::Read(
+ BrowserPluginHostMsg_Attach_Params params;
+ BrowserPluginHostMsg_Attach::Read(
create_msg,
&create_instance_id,
¶ms);
@@ -704,14 +703,14 @@
LoadHTML(GetHTMLForBrowserPluginObject().c_str());
ExecuteJavaScript(kAddEventListener);
- // Grab the BrowserPlugin's instance ID from its CreateGuest message.
+ // Grab the BrowserPlugin's instance ID from its Attach message.
const IPC::Message* msg =
browser_plugin_manager()->sink().GetFirstMessageMatching(
- BrowserPluginHostMsg_CreateGuest::ID);
+ BrowserPluginHostMsg_Attach::ID);
ASSERT_TRUE(msg);
int instance_id = 0;
- BrowserPluginHostMsg_CreateGuest_Params params;
- BrowserPluginHostMsg_CreateGuest::Read(msg, &instance_id, ¶ms);
+ BrowserPluginHostMsg_Attach_Params params;
+ BrowserPluginHostMsg_Attach::Read(msg, &instance_id, ¶ms);
MockBrowserPlugin* browser_plugin =
static_cast<MockBrowserPlugin*>(
@@ -761,14 +760,14 @@
LoadHTML(GetHTMLForBrowserPluginObject().c_str());
ExecuteJavaScript(kAddEventListener);
- // Grab the BrowserPlugin's instance ID from its CreateGuest message.
+ // Grab the BrowserPlugin's instance ID from its Attach message.
const IPC::Message* msg =
browser_plugin_manager()->sink().GetFirstMessageMatching(
- BrowserPluginHostMsg_CreateGuest::ID);
+ BrowserPluginHostMsg_Attach::ID);
ASSERT_TRUE(msg);
int instance_id = 0;
- BrowserPluginHostMsg_CreateGuest_Params params;
- BrowserPluginHostMsg_CreateGuest::Read(msg, &instance_id, ¶ms);
+ BrowserPluginHostMsg_Attach_Params params;
+ BrowserPluginHostMsg_Attach::Read(msg, &instance_id, ¶ms);
MockBrowserPlugin* browser_plugin =
static_cast<MockBrowserPlugin*>(
@@ -789,15 +788,15 @@
TEST_F(BrowserPluginTest, RemoveBrowserPluginOnExit) {
LoadHTML(GetHTMLForBrowserPluginObject().c_str());
- // Grab the BrowserPlugin's instance ID from its CreateGuest message.
+ // Grab the BrowserPlugin's instance ID from its Attach message.
int instance_id = 0;
{
const IPC::Message* msg =
browser_plugin_manager()->sink().GetFirstMessageMatching(
- BrowserPluginHostMsg_CreateGuest::ID);
+ BrowserPluginHostMsg_Attach::ID);
ASSERT_TRUE(msg);
- BrowserPluginHostMsg_CreateGuest_Params params;
- BrowserPluginHostMsg_CreateGuest::Read(msg, &instance_id, ¶ms);
+ BrowserPluginHostMsg_Attach_Params params;
+ BrowserPluginHostMsg_Attach::Read(msg, &instance_id, ¶ms);
}
MockBrowserPlugin* browser_plugin =
@@ -844,18 +843,18 @@
int instance_id = 0;
// Set some autosize parameters before navigating then navigate.
- // Verify that the BrowserPluginHostMsg_CreateGuest message contains
+ // Verify that the BrowserPluginHostMsg_Attach message contains
// the correct autosize parameters.
ExecuteJavaScript(kSetAutoSizeParametersAndNavigate);
ProcessPendingMessages();
{
const IPC::Message* create_msg =
browser_plugin_manager()->sink().GetUniqueMessageMatching(
- BrowserPluginHostMsg_CreateGuest::ID);
+ BrowserPluginHostMsg_Attach::ID);
ASSERT_TRUE(create_msg);
- BrowserPluginHostMsg_CreateGuest_Params params;
- BrowserPluginHostMsg_CreateGuest::Read(
+ BrowserPluginHostMsg_Attach_Params params;
+ BrowserPluginHostMsg_Attach::Read(
create_msg,
&instance_id,
¶ms);
diff --git a/content/renderer/browser_plugin/browser_plugin_browsertest.h b/content/renderer/browser_plugin/browser_plugin_browsertest.h
index 42d378f..44f10a9 100644
--- a/content/renderer/browser_plugin/browser_plugin_browsertest.h
+++ b/content/renderer/browser_plugin/browser_plugin_browsertest.h
@@ -31,7 +31,7 @@
virtual void TearDown() OVERRIDE;
MockBrowserPluginManager* browser_plugin_manager() const {
return static_cast<MockBrowserPluginManager*>(
- static_cast<RenderViewImpl*>(view_)->browser_plugin_manager());
+ static_cast<RenderViewImpl*>(view_)->GetBrowserPluginManager());
}
std::string ExecuteScriptAndReturnString(const std::string& script);
int ExecuteScriptAndReturnInt(const std::string& script);
diff --git a/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc b/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc
index cdaeefc..fb32cdc 100644
--- a/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc
+++ b/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc
@@ -4,6 +4,7 @@
#include "content/renderer/browser_plugin/browser_plugin_compositing_helper.h"
+#include "cc/layers/delegated_renderer_layer.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/layers/texture_layer.h"
#include "cc/output/context_provider.h"
@@ -26,8 +27,8 @@
int host_routing_id)
: instance_id_(instance_id),
host_routing_id_(host_routing_id),
- last_gpu_route_id_(0),
- last_gpu_host_id_(0),
+ last_route_id_(0),
+ last_host_id_(0),
last_mailbox_valid_(false),
ack_pending_(true),
ack_pending_for_crashed_guest_(false),
@@ -38,23 +39,51 @@
BrowserPluginCompositingHelper::~BrowserPluginCompositingHelper() {
}
-void BrowserPluginCompositingHelper::EnableCompositing(bool enable) {
- if (enable && !texture_layer_) {
- texture_layer_ = cc::TextureLayer::CreateForMailbox();
- texture_layer_->SetIsDrawable(true);
- texture_layer_->SetContentsOpaque(true);
+void BrowserPluginCompositingHelper::DidCommitCompositorFrame() {
+ if (!delegated_layer_ || !ack_pending_)
+ return;
+ cc::CompositorFrameAck ack;
+ delegated_layer_->TakeUnusedResourcesForChildCompositor(&ack.resources);
+
+ browser_plugin_manager_->Send(
+ new BrowserPluginHostMsg_CompositorFrameACK(
+ host_routing_id_,
+ instance_id_,
+ last_route_id_,
+ last_host_id_,
+ ack));
+
+ ack_pending_ = false;
+}
+
+void BrowserPluginCompositingHelper::EnableCompositing(bool enable) {
+ if (enable && !background_layer_) {
background_layer_ = cc::SolidColorLayer::Create();
background_layer_->SetMasksToBounds(true);
background_layer_->SetBackgroundColor(
SkColorSetARGBInline(255, 255, 255, 255));
- background_layer_->AddChild(texture_layer_);
web_layer_.reset(new webkit::WebLayerImpl(background_layer_));
}
container_->setWebLayer(enable ? web_layer_.get() : NULL);
}
+void BrowserPluginCompositingHelper::CheckSizeAndAdjustLayerBounds(
+ const gfx::Size& new_size,
+ float device_scale_factor,
+ cc::Layer* layer) {
+ if (buffer_size_ != new_size) {
+ buffer_size_ = new_size;
+ // The container size is in DIP, so is the layer size.
+ // Buffer size is in physical pixels, so we need to adjust
+ // it by the device scale factor.
+ gfx::Size device_scale_adjusted_size = gfx::ToFlooredSize(
+ gfx::ScaleSize(buffer_size_, 1.0f / device_scale_factor));
+ layer->SetBounds(device_scale_adjusted_size);
+ }
+}
+
// If we have a mailbox that was freed up from the compositor,
// but we are not expected to return it to the guest renderer
// via an ACK, we should free it because we now own it.
@@ -95,17 +124,24 @@
const std::string& mailbox_name,
int gpu_route_id,
int gpu_host_id,
- unsigned sync_point) {
+ unsigned sync_point,
+ bool lost_resource) {
+ if (lost_resource) {
+ // Recurse with an empty mailbox if the one being released was lost.
+ MailboxReleased(std::string(), gpu_route_id, gpu_host_id, 0, false);
+ return;
+ }
+
// This means the GPU process crashed and we have nothing further to do.
// Nobody is expecting an ACK and the buffer doesn't need to be deleted
// because it went away with the GPU process.
- if (last_gpu_host_id_ != gpu_host_id)
+ if (last_host_id_ != gpu_host_id)
return;
// This means the guest crashed.
// Either ACK the last buffer, so texture transport could
// be destroyed of delete the mailbox if nobody wants it back.
- if (last_gpu_route_id_ != gpu_route_id) {
+ if (last_route_id_ != gpu_route_id) {
if (!ack_pending_for_crashed_guest_) {
FreeMailboxMemory(mailbox_name, sync_point);
} else {
@@ -148,6 +184,7 @@
container_ = NULL;
texture_layer_ = NULL;
+ delegated_layer_ = NULL;
background_layer_ = NULL;
web_layer_.reset();
}
@@ -158,29 +195,38 @@
int gpu_route_id,
int gpu_host_id,
float device_scale_factor) {
+ DCHECK(!delegated_layer_);
// If the guest crashed but the GPU process didn't, we may still have
// a transport surface waiting on an ACK, which we must send to
// avoid leaking.
- if (last_gpu_route_id_ != gpu_route_id && last_gpu_host_id_ == gpu_host_id)
+ if (last_route_id_ != gpu_route_id && last_host_id_ == gpu_host_id)
ack_pending_for_crashed_guest_ = ack_pending_;
// If these mismatch, we are either just starting up, GPU process crashed or
// guest renderer crashed.
// In this case, we are communicating with a new image transport
// surface and must ACK with the new ID's and an empty mailbox.
- if (last_gpu_route_id_ != gpu_route_id || last_gpu_host_id_ != gpu_host_id)
+ if (last_route_id_ != gpu_route_id || last_host_id_ != gpu_host_id)
last_mailbox_valid_ = false;
- last_gpu_route_id_ = gpu_route_id;
- last_gpu_host_id_ = gpu_host_id;
+ last_route_id_ = gpu_route_id;
+ last_host_id_ = gpu_host_id;
ack_pending_ = true;
// Browser plugin getting destroyed, do a fast ACK.
- if (!texture_layer_) {
- MailboxReleased(mailbox_name, gpu_route_id, gpu_host_id, 0);
+ if (!background_layer_) {
+ MailboxReleased(mailbox_name, gpu_route_id, gpu_host_id, 0, false);
return;
}
+ if (!texture_layer_) {
+ texture_layer_ = cc::TextureLayer::CreateForMailbox(NULL);
+ texture_layer_->SetIsDrawable(true);
+ texture_layer_->SetContentsOpaque(true);
+
+ background_layer_->AddChild(texture_layer_);
+ }
+
// The size of browser plugin container is not always equal to the size
// of the buffer that arrives here. This could be for a number of reasons,
// including autosize and a resize in progress.
@@ -191,19 +237,13 @@
// when a new buffer arrives.
// Visually, this will either display a smaller part of the buffer
// or introduce a gutter around it.
- if (buffer_size_ != size) {
- buffer_size_ = size;
- // The container size is in DIP, so is the layer size.
- // Buffer size is in physical pixels, so we need to adjust
- // it by the device scale factor.
- gfx::Size device_scale_adjusted_size = gfx::ToFlooredSize(
- gfx::ScaleSize(buffer_size_, 1.0f / device_scale_factor));
- texture_layer_->SetBounds(device_scale_adjusted_size);
- }
+ CheckSizeAndAdjustLayerBounds(size,
+ device_scale_factor,
+ texture_layer_.get());
bool current_mailbox_valid = !mailbox_name.empty();
if (!last_mailbox_valid_) {
- MailboxReleased(std::string(), gpu_route_id, gpu_host_id, 0);
+ MailboxReleased(std::string(), gpu_route_id, gpu_host_id, 0, false);
if (!current_mailbox_valid)
return;
}
@@ -222,9 +262,39 @@
last_mailbox_valid_ = current_mailbox_valid;
}
+void BrowserPluginCompositingHelper::OnCompositorFrameSwapped(
+ scoped_ptr<cc::CompositorFrame> frame,
+ int route_id,
+ int host_id) {
+ DCHECK(!texture_layer_);
+ if (!delegated_layer_) {
+ delegated_layer_ = cc::DelegatedRendererLayer::Create();
+ delegated_layer_->SetIsDrawable(true);
+ delegated_layer_->SetContentsOpaque(true);
+
+ background_layer_->AddChild(delegated_layer_);
+ }
+
+ cc::DelegatedFrameData *frame_data = frame->delegated_frame_data.get();
+ if (!frame_data)
+ return;
+
+ CheckSizeAndAdjustLayerBounds(
+ frame_data->render_pass_list.back()->output_rect.size(),
+ frame->metadata.device_scale_factor,
+ delegated_layer_.get());
+
+ delegated_layer_->SetFrameData(frame->delegated_frame_data.Pass());
+ last_route_id_ = route_id;
+ last_host_id_ = host_id;
+ ack_pending_ = true;
+}
+
void BrowserPluginCompositingHelper::UpdateVisibility(bool visible) {
if (texture_layer_)
texture_layer_->SetIsDrawable(visible);
+ if (delegated_layer_)
+ delegated_layer_->SetIsDrawable(visible);
}
} // namespace content
diff --git a/content/renderer/browser_plugin/browser_plugin_compositing_helper.h b/content/renderer/browser_plugin/browser_plugin_compositing_helper.h
index 998b739..b323aae 100644
--- a/content/renderer/browser_plugin/browser_plugin_compositing_helper.h
+++ b/content/renderer/browser_plugin/browser_plugin_compositing_helper.h
@@ -13,8 +13,11 @@
#include "ui/gfx/size.h"
namespace cc {
+class CompositorFrame;
+class Layer;
class SolidColorLayer;
class TextureLayer;
+class DelegatedRendererLayer;
}
namespace WebKit {
@@ -33,6 +36,7 @@
BrowserPluginManager* manager,
int instance_id,
int host_routing_id);
+ void DidCommitCompositorFrame();
void EnableCompositing(bool);
void OnContainerDestroy();
void OnBuffersSwapped(const gfx::Size& size,
@@ -40,22 +44,29 @@
int gpu_route_id,
int gpu_host_id,
float device_scale_factor);
+ void OnCompositorFrameSwapped(scoped_ptr<cc::CompositorFrame> frame,
+ int route_id,
+ int host_id);
void UpdateVisibility(bool);
protected:
// Friend RefCounted so that the dtor can be non-public.
friend class base::RefCounted<BrowserPluginCompositingHelper>;
private:
~BrowserPluginCompositingHelper();
+ void CheckSizeAndAdjustLayerBounds(const gfx::Size& new_size,
+ float device_scale_factor,
+ cc::Layer* layer);
void FreeMailboxMemory(const std::string& mailbox_name,
unsigned sync_point);
void MailboxReleased(const std::string& mailbox_name,
int gpu_route_id,
int gpu_host_id,
- unsigned sync_point);
+ unsigned sync_point,
+ bool lost_resource);
int instance_id_;
int host_routing_id_;
- int last_gpu_route_id_;
- int last_gpu_host_id_;
+ int last_route_id_;
+ int last_host_id_;
bool last_mailbox_valid_;
bool ack_pending_;
bool ack_pending_for_crashed_guest_;
@@ -64,6 +75,7 @@
scoped_refptr<cc::SolidColorLayer> background_layer_;
scoped_refptr<cc::TextureLayer> texture_layer_;
+ scoped_refptr<cc::DelegatedRendererLayer> delegated_layer_;
scoped_ptr<WebKit::WebLayer> web_layer_;
WebKit::WebPluginContainer* container_;
diff --git a/content/renderer/browser_plugin/browser_plugin_manager.cc b/content/renderer/browser_plugin/browser_plugin_manager.cc
index c7458e1..e960120 100644
--- a/content/renderer/browser_plugin/browser_plugin_manager.cc
+++ b/content/renderer/browser_plugin/browser_plugin_manager.cc
@@ -45,6 +45,14 @@
return instances_.Lookup(instance_id);
}
+void BrowserPluginManager::UpdateDeviceScaleFactor(float device_scale_factor) {
+ IDMap<BrowserPlugin>::iterator iter(&instances_);
+ while (!iter.IsAtEnd()) {
+ iter.GetCurrentValue()->UpdateDeviceScaleFactor(device_scale_factor);
+ iter.Advance();
+ }
+}
+
void BrowserPluginManager::UpdateFocusState() {
IDMap<BrowserPlugin>::iterator iter(&instances_);
while (!iter.IsAtEnd()) {
diff --git a/content/renderer/browser_plugin/browser_plugin_manager.h b/content/renderer/browser_plugin/browser_plugin_manager.h
index a4a59da..a0fea21 100644
--- a/content/renderer/browser_plugin/browser_plugin_manager.h
+++ b/content/renderer/browser_plugin/browser_plugin_manager.h
@@ -53,6 +53,7 @@
void AddBrowserPlugin(int instance_id, BrowserPlugin* browser_plugin);
void RemoveBrowserPlugin(int instance_id);
BrowserPlugin* GetBrowserPlugin(int instance_id) const;
+ void UpdateDeviceScaleFactor(float device_scale_factor);
void UpdateFocusState();
RenderViewImpl* render_view() const { return render_view_; }
diff --git a/content/renderer/browser_plugin/browser_plugin_manager_impl.cc b/content/renderer/browser_plugin/browser_plugin_manager_impl.cc
index cbe7245..11b7be0 100644
--- a/content/renderer/browser_plugin/browser_plugin_manager_impl.cc
+++ b/content/renderer/browser_plugin/browser_plugin_manager_impl.cc
@@ -67,13 +67,21 @@
return handled;
}
+void BrowserPluginManagerImpl::DidCommitCompositorFrame() {
+ IDMap<BrowserPlugin>::iterator iter(&instances_);
+ while (!iter.IsAtEnd()) {
+ iter.GetCurrentValue()->DidCommitCompositorFrame();
+ iter.Advance();
+ }
+}
+
void BrowserPluginManagerImpl::OnAllocateInstanceIDACK(
const IPC::Message& message, int request_id, int instance_id) {
BrowserPlugin* plugin =
pending_allocate_instance_id_requests_.Lookup(request_id);
pending_allocate_instance_id_requests_.Remove(request_id);
if (plugin)
- plugin->SetInstanceID(instance_id, true /* new_guest */);
+ plugin->Attach(instance_id);
}
void BrowserPluginManagerImpl::OnPluginAtPositionRequest(
diff --git a/content/renderer/browser_plugin/browser_plugin_manager_impl.h b/content/renderer/browser_plugin/browser_plugin_manager_impl.h
index 2496474..2ac49ab 100644
--- a/content/renderer/browser_plugin/browser_plugin_manager_impl.h
+++ b/content/renderer/browser_plugin/browser_plugin_manager_impl.h
@@ -34,6 +34,8 @@
// RenderViewObserver override. Call on render thread.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+ virtual void DidCommitCompositorFrame() OVERRIDE;
+
private:
virtual ~BrowserPluginManagerImpl();
diff --git a/content/renderer/browser_plugin/mock_browser_plugin_manager.cc b/content/renderer/browser_plugin/mock_browser_plugin_manager.cc
index 7c314c4..3759535 100644
--- a/content/renderer/browser_plugin/mock_browser_plugin_manager.cc
+++ b/content/renderer/browser_plugin/mock_browser_plugin_manager.cc
@@ -30,7 +30,7 @@
void MockBrowserPluginManager::AllocateInstanceID(
BrowserPlugin* browser_plugin) {
int instance_id = ++browser_plugin_counter_;
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&MockBrowserPluginManager::AllocateInstanceIDACK,
this,
@@ -41,7 +41,7 @@
void MockBrowserPluginManager::AllocateInstanceIDACK(
BrowserPlugin* browser_plugin,
int instance_id) {
- browser_plugin->SetInstanceID(instance_id, true);
+ browser_plugin->Attach(instance_id);
}
bool MockBrowserPluginManager::Send(IPC::Message* msg) {
@@ -50,7 +50,7 @@
// through this function messages, messages with reply and reply messages.
// We can only handle one synchronous message at a time.
if (msg->is_reply()) {
- if (reply_deserializer_.get()) {
+ if (reply_deserializer_) {
reply_deserializer_->SerializeOutputParameters(*msg);
reply_deserializer_.reset();
}
diff --git a/content/renderer/cpp_bound_class_unittest.cc b/content/renderer/cpp_bound_class_unittest.cc
new file mode 100644
index 0000000..df2cd22
--- /dev/null
+++ b/content/renderer/cpp_bound_class_unittest.cc
@@ -0,0 +1,229 @@
+// 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.
+
+// Tests for CppBoundClass, in conjunction with CppBindingExample. Binds
+// a CppBindingExample class into JavaScript in a custom test shell and tests
+// the binding from the outside by loading JS into the shell.
+
+#include "base/utf_string_conversions.h"
+#include "content/public/renderer/render_view_observer.h"
+#include "content/public/test/render_view_test.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebURLRequest.h"
+#include "webkit/glue/cpp_binding_example.h"
+#include "webkit/glue/webkit_glue.h"
+
+using webkit_glue::CppArgumentList;
+using webkit_glue::CppBindingExample;
+using webkit_glue::CppVariant;
+
+namespace content {
+
+class CppBindingExampleSubObject : public CppBindingExample {
+ public:
+ CppBindingExampleSubObject() {
+ sub_value_.Set("sub!");
+ BindProperty("sub_value", &sub_value_);
+ }
+ private:
+ CppVariant sub_value_;
+};
+
+
+class CppBindingExampleWithOptionalFallback : public CppBindingExample {
+ public:
+ CppBindingExampleWithOptionalFallback() {
+ BindProperty("sub_object", sub_object_.GetAsCppVariant());
+ }
+
+ void set_fallback_method_enabled(bool state) {
+ BindFallbackCallback(state ?
+ base::Bind(&CppBindingExampleWithOptionalFallback::fallbackMethod,
+ base::Unretained(this))
+ : CppBoundClass::Callback());
+ }
+
+ // The fallback method does nothing, but because of it the JavaScript keeps
+ // running when a nonexistent method is called on an object.
+ void fallbackMethod(const CppArgumentList& args, CppVariant* result) {
+ }
+
+ private:
+ CppBindingExampleSubObject sub_object_;
+};
+
+class TestObserver : public RenderViewObserver {
+ public:
+ explicit TestObserver(RenderView* render_view)
+ : RenderViewObserver(render_view) {}
+ virtual void DidClearWindowObject(WebKit::WebFrame* frame) OVERRIDE {
+ example_bound_class_.BindToJavascript(frame, "example");
+ }
+ void set_fallback_method_enabled(bool use_fallback) {
+ example_bound_class_.set_fallback_method_enabled(use_fallback);
+ }
+ private:
+ CppBindingExampleWithOptionalFallback example_bound_class_;
+};
+
+class CppBoundClassTest : public RenderViewTest {
+ public:
+ CppBoundClassTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ RenderViewTest::SetUp();
+ observer_.reset(new TestObserver(view_));
+ observer_->set_fallback_method_enabled(useFallback());
+
+ WebKit::WebURLRequest url_request;
+ url_request.initialize();
+ url_request.setURL(GURL("about:blank"));
+
+ GetMainFrame()->loadRequest(url_request);
+ ProcessPendingMessages();
+ }
+
+ // Executes the specified JavaScript and checks that the resulting document
+ // text is empty.
+ void CheckJavaScriptFailure(const std::string& javascript) {
+ ExecuteJavaScript(javascript.c_str());
+ EXPECT_EQ("", UTF16ToASCII(webkit_glue::DumpDocumentText(GetMainFrame())));
+ }
+
+ void CheckTrue(const std::string& expression) {
+ int was_page_a = -1;
+ string16 check_page_a =
+ ASCIIToUTF16(std::string("Number(") + expression + ")");
+ EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_a, &was_page_a));
+ EXPECT_EQ(1, was_page_a);
+ }
+
+ protected:
+ virtual bool useFallback() {
+ return false;
+ }
+
+ private:
+ scoped_ptr<TestObserver> observer_;
+};
+
+class CppBoundClassWithFallbackMethodTest : public CppBoundClassTest {
+ protected:
+ virtual bool useFallback() OVERRIDE {
+ return true;
+ }
+};
+
+// Ensures that the example object has been bound to JS.
+TEST_F(CppBoundClassTest, ObjectExists) {
+ CheckTrue("typeof window.example == 'object'");
+
+ // An additional check to test our test.
+ CheckTrue("typeof window.invalid_object == 'undefined'");
+}
+
+TEST_F(CppBoundClassTest, PropertiesAreInitialized) {
+ CheckTrue("example.my_value == 10");
+
+ CheckTrue("example.my_other_value == 'Reinitialized!'");
+}
+
+TEST_F(CppBoundClassTest, SubOject) {
+ CheckTrue("typeof window.example.sub_object == 'object'");
+
+ CheckTrue("example.sub_object.sub_value == 'sub!'");
+}
+
+TEST_F(CppBoundClassTest, SetAndGetProperties) {
+ // The property on the left will be set to the value on the right, then
+ // checked to make sure it holds that same value.
+ static const std::string tests[] = {
+ "example.my_value", "7",
+ "example.my_value", "'test'",
+ "example.my_other_value", "3.14",
+ "example.my_other_value", "false",
+ "" // Array end marker: insert additional test pairs before this.
+ };
+
+ for (int i = 0; tests[i] != ""; i += 2) {
+ std::string left = tests[i];
+ std::string right = tests[i + 1];
+ // left = right;
+ std::string js = left;
+ js.append(" = ");
+ js.append(right);
+ js.append(";");
+ ExecuteJavaScript(js.c_str());
+ std::string expression = left;
+ expression += " == ";
+ expression += right;
+ CheckTrue(expression);
+ }
+}
+
+TEST_F(CppBoundClassTest, SetAndGetPropertiesWithCallbacks) {
+ // TODO(dglazkov): fix NPObject issues around failing property setters and
+ // getters and add tests for situations when GetProperty or SetProperty fail.
+ ExecuteJavaScript("example.my_value_with_callback = 10;");
+ CheckTrue("example.my_value_with_callback == 10");
+
+ ExecuteJavaScript("example.my_value_with_callback = 11;");
+ CheckTrue("example.my_value_with_callback == 11");
+
+ CheckTrue("example.same == 42");
+
+ ExecuteJavaScript("example.same = 24;");
+ CheckTrue("example.same == 42");
+}
+
+TEST_F(CppBoundClassTest, InvokeMethods) {
+ // The expression on the left is expected to return the value on the right.
+ static const std::string tests[] = {
+ "example.echoValue(true) == true",
+ "example.echoValue(13) == 13",
+ "example.echoValue(2.718) == 2.718",
+ "example.echoValue('yes') == 'yes'",
+ "example.echoValue() == null", // Too few arguments
+
+ "example.echoType(false) == true",
+ "example.echoType(19) == 3.14159",
+ "example.echoType(9.876) == 3.14159",
+ "example.echoType('test string') == 'Success!'",
+ "example.echoType() == null", // Too few arguments
+
+ // Comparing floats that aren't integer-valued is usually problematic due
+ // to rounding, but exact powers of 2 should also be safe.
+ "example.plus(2.5, 18.0) == 20.5",
+ "example.plus(2, 3.25) == 5.25",
+ "example.plus(2, 3) == 5",
+ "example.plus() == null", // Too few arguments
+ "example.plus(1) == null", // Too few arguments
+ "example.plus(1, 'test') == null", // Wrong argument type
+ "example.plus('test', 2) == null", // Wrong argument type
+ "example.plus('one', 'two') == null", // Wrong argument type
+ "" // Array end marker: insert additional test pairs before this.
+ };
+
+ for (int i = 0; tests[i] != ""; i++)
+ CheckTrue(tests[i]);
+
+ ExecuteJavaScript("example.my_value = 3.25; example.my_other_value = 1.25;");
+ CheckTrue("example.plus(example.my_value, example.my_other_value) == 4.5");
+}
+
+// Tests that invoking a nonexistent method with no fallback method stops the
+// script's execution
+TEST_F(CppBoundClassTest,
+ InvokeNonexistentMethodNoFallback) {
+ std::string js = "example.nonExistentMethod();document.writeln('SUCCESS');";
+ CheckJavaScriptFailure(js);
+}
+
+// Ensures existent methods can be invoked successfully when the fallback method
+// is used
+TEST_F(CppBoundClassWithFallbackMethodTest,
+ InvokeExistentMethodsWithFallback) {
+ CheckTrue("example.echoValue(34) == 34");
+}
+
+} // namespace content
diff --git a/content/renderer/date_time_formatter.cc b/content/renderer/date_time_formatter.cc
index d3c16e3..1adb0de 100644
--- a/content/renderer/date_time_formatter.cc
+++ b/content/renderer/date_time_formatter.cc
@@ -95,7 +95,7 @@
UErrorCode success = U_ZERO_ERROR;
if (year_ == 0 && month_ == 0 && day_ == 0 &&
hour_ == 0 && minute_ == 0 && second_ == 0) {
- return "";
+ return std::string();
}
std::string result;
@@ -113,7 +113,7 @@
return result;
}
LOG(WARNING) << "Calendar not created: error " << success;
- return "";
+ return std::string();
}
void DateTimeFormatter::ExtractType(
diff --git a/content/renderer/devtools/devtools_agent.cc b/content/renderer/devtools/devtools_agent.cc
index 868f5ec..674cbc5 100644
--- a/content/renderer/devtools/devtools_agent.cc
+++ b/content/renderer/devtools/devtools_agent.cc
@@ -47,19 +47,17 @@
class WebKitClientMessageLoopImpl
: public WebDevToolsAgentClient::WebKitClientMessageLoop {
public:
- WebKitClientMessageLoopImpl() : message_loop_(MessageLoop::current()) { }
- virtual ~WebKitClientMessageLoopImpl() {
- message_loop_ = NULL;
- }
+ WebKitClientMessageLoopImpl() : message_loop_(base::MessageLoop::current()) {}
+ virtual ~WebKitClientMessageLoopImpl() { message_loop_ = NULL; }
virtual void run() {
- MessageLoop::ScopedNestableTaskAllower allow(message_loop_);
+ base::MessageLoop::ScopedNestableTaskAllower allow(message_loop_);
message_loop_->Run();
}
virtual void quitNow() {
message_loop_->QuitNow();
}
private:
- MessageLoop* message_loop_;
+ base::MessageLoop* message_loop_;
};
typedef std::map<int, DevToolsAgent*> IdToAgentMap;
@@ -69,7 +67,9 @@
} // namespace
DevToolsAgent::DevToolsAgent(RenderViewImpl* render_view)
- : RenderViewObserver(render_view), is_attached_(false) {
+ : RenderViewObserver(render_view),
+ is_attached_(false),
+ is_devtools_client_(false) {
g_agent_for_routing_id.Get()[routing_id()] = this;
render_view->webview()->setDevToolsAgentClient(this);
@@ -135,7 +135,13 @@
void DevToolsAgent::setTraceEventCallback(TraceEventCallback cb) {
TraceLog* trace_log = TraceLog::GetInstance();
trace_log->SetEventCallback(cb);
- trace_log->SetEnabled(!!cb, TraceLog::RECORD_UNTIL_FULL);
+ if (!!cb) {
+ trace_log->SetEnabled(base::debug::CategoryFilter(
+ base::debug::CategoryFilter::kDefaultCategoryFilterString),
+ TraceLog::RECORD_UNTIL_FULL);
+ } else {
+ trace_log->SetDisabled();
+ }
}
#if defined(USE_TCMALLOC) && !defined(OS_WIN)
@@ -237,6 +243,10 @@
}
void DevToolsAgent::OnSetupDevToolsClient() {
+ // We only want to register once per render view.
+ if (is_devtools_client_)
+ return;
+ is_devtools_client_ = true;
new DevToolsClient(static_cast<RenderViewImpl*>(render_view()));
}
diff --git a/content/renderer/devtools/devtools_agent.h b/content/renderer/devtools/devtools_agent.h
index e3a3bdd..7926f44 100644
--- a/content/renderer/devtools/devtools_agent.h
+++ b/content/renderer/devtools/devtools_agent.h
@@ -65,6 +65,7 @@
void OnSetupDevToolsClient();
bool is_attached_;
+ bool is_devtools_client_;
DISALLOW_COPY_AND_ASSIGN(DevToolsAgent);
};
diff --git a/content/renderer/devtools/devtools_agent_filter.cc b/content/renderer/devtools/devtools_agent_filter.cc
index 7a4e90b..76062d9 100644
--- a/content/renderer/devtools/devtools_agent_filter.cc
+++ b/content/renderer/devtools/devtools_agent_filter.cc
@@ -42,9 +42,8 @@
DevToolsAgentFilter::DevToolsAgentFilter()
: message_handled_(false),
- render_thread_loop_(MessageLoop::current()),
- current_routing_id_(0) {
-}
+ render_thread_loop_(base::MessageLoop::current()),
+ current_routing_id_(0) {}
bool DevToolsAgentFilter::OnMessageReceived(const IPC::Message& message) {
// Dispatch debugger commands directly from IO.
diff --git a/content/renderer/devtools/devtools_agent_filter.h b/content/renderer/devtools/devtools_agent_filter.h
index 9e4f8ae..e7f7861 100644
--- a/content/renderer/devtools/devtools_agent_filter.h
+++ b/content/renderer/devtools/devtools_agent_filter.h
@@ -9,9 +9,12 @@
#include "ipc/ipc_channel_proxy.h"
-class MessageLoop;
struct DevToolsMessageData;
+namespace base {
+class MessageLoop;
+}
+
namespace content {
// DevToolsAgentFilter is registered as an IPC filter in order to be able to
@@ -37,7 +40,7 @@
void OnDispatchOnInspectorBackend(const std::string& message);
bool message_handled_;
- MessageLoop* render_thread_loop_;
+ base::MessageLoop* render_thread_loop_;
int current_routing_id_;
DISALLOW_COPY_AND_ASSIGN(DevToolsAgentFilter);
diff --git a/content/renderer/devtools/devtools_client.cc b/content/renderer/devtools/devtools_client.cc
index 7ec522c..5f760e6 100644
--- a/content/renderer/devtools/devtools_client.cc
+++ b/content/renderer/devtools/devtools_client.cc
@@ -9,12 +9,14 @@
#include "base/utf_string_conversions.h"
#include "content/common/devtools_messages.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/url_constants.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebFloatPoint.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDevToolsFrontend.h"
#include "ui/base/ui_base_switches.h"
+#include "webkit/appcache/appcache_interfaces.h"
using WebKit::WebDevToolsFrontend;
using WebKit::WebString;
@@ -35,6 +37,7 @@
render_view->webview(),
this,
ASCIIToUTF16(command_line.GetSwitchValueASCII(switches::kLang))));
+ appcache::AddSupportedScheme(chrome::kChromeDevToolsScheme);
}
DevToolsClient::~DevToolsClient() {
diff --git a/content/renderer/do_not_track_bindings.cc b/content/renderer/do_not_track_bindings.cc
deleted file mode 100644
index 0c2731b..0000000
--- a/content/renderer/do_not_track_bindings.cc
+++ /dev/null
@@ -1,49 +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/renderer/do_not_track_bindings.h"
-
-#include "content/renderer/render_view_impl.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
-#include "v8/include/v8.h"
-
-using WebKit::WebFrame;
-
-namespace content {
-
-namespace {
-
-v8::Handle<v8::Value> GetDoNotTrack(v8::Local<v8::String> property,
- const v8::AccessorInfo& info) {
- WebFrame* frame = WebFrame::frameForCurrentContext();
- if (!frame)
- return v8::Null();
- RenderViewImpl* view = RenderViewImpl::FromWebView(frame->view());
- if (!view)
- return v8::Null();
- if (view->enable_do_not_track())
- return v8::String::New("1");
- return v8::Null();
-}
-
-} // namespace
-
-void InjectDoNotTrackBindings(WebFrame* frame) {
- v8::HandleScope handle_scope;
-
- v8::Handle<v8::Context> v8_context = frame->mainWorldScriptContext();
- if (v8_context.IsEmpty())
- return;
-
- v8::Context::Scope scope(v8_context);
-
- v8::Handle<v8::Object> global = v8_context->Global();
- v8::Handle<v8::Object> navigator =
- global->Get(v8::String::New("navigator"))->ToObject();
- if (navigator.IsEmpty())
- return;
- navigator->SetAccessor(v8::String::New("doNotTrack"), GetDoNotTrack);
-}
-
-} // namespace content
diff --git a/content/renderer/do_not_track_bindings.h b/content/renderer/do_not_track_bindings.h
deleted file mode 100644
index cc0edff..0000000
--- a/content/renderer/do_not_track_bindings.h
+++ /dev/null
@@ -1,16 +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_RENDERER_DO_NOT_TRACK_BINDINGS_H_
-#define CONTENT_RENDERER_DO_NOT_TRACK_BINDINGS_H_
-
-namespace WebKit {
-class WebFrame;
-}
-
-namespace content {
-void InjectDoNotTrackBindings(WebKit::WebFrame* frame);
-} // namespace content
-
-#endif // CONTENT_RENDERER_DO_NOT_TRACK_BINDINGS_H_
diff --git a/content/renderer/dom_operations_browsertest.cc b/content/renderer/dom_operations_browsertest.cc
new file mode 100644
index 0000000..0d333a5
--- /dev/null
+++ b/content/renderer/dom_operations_browsertest.cc
@@ -0,0 +1,139 @@
+// 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/bind.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/renderer/render_view.h"
+#include "content/shell/shell.h"
+#include "content/test/content_browser_test.h"
+#include "content/test/content_browser_test_utils.h"
+#include "net/base/net_util.h"
+#include "webkit/glue/dom_operations.h"
+
+namespace content {
+
+class DomOperationsTests : public ContentBrowserTest {
+ public:
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ command_line->AppendSwitch(switches::kSingleProcess);
+#if defined(OS_WIN) && defined(USE_AURA)
+ // Don't want to try to create a GPU process.
+ command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
+#endif
+ }
+
+ // Test function GetAllSavableResourceLinksForCurrentPage with a web page.
+ // We expect result of GetAllSavableResourceLinksForCurrentPage exactly
+ // matches expected_resources_set.
+ void GetSavableResourceLinksForPage(
+ const base::FilePath& page_file_path,
+ const std::set<GURL>& expected_resources_set) {
+ // Convert local file path to file URL.
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ // Load the test file.
+ NavigateToURL(shell(), file_url);
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(&DomOperationsTests::CheckResources, base::Unretained(this),
+ page_file_path, expected_resources_set, file_url,
+ shell()->web_contents()->GetRoutingID()));
+ }
+
+ void CheckResources(const base::FilePath& page_file_path,
+ const std::set<GURL>& expected_resources_set,
+ const GURL& file_url,
+ int render_view_id) {
+ // Get all savable resource links for the page.
+ std::vector<GURL> resources_list;
+ std::vector<GURL> referrer_urls_list;
+ std::vector<WebKit::WebReferrerPolicy> referrer_policies_list;
+ std::vector<GURL> frames_list;
+ webkit_glue::SavableResourcesResult result(&resources_list,
+ &referrer_urls_list,
+ &referrer_policies_list,
+ &frames_list);
+
+ const char* savable_schemes[] = {
+ "http",
+ "https",
+ "file",
+ NULL
+ };
+
+ RenderView* render_view = RenderView::FromRoutingID(render_view_id);
+
+ ASSERT_TRUE(webkit_glue::GetAllSavableResourceLinksForCurrentPage(
+ render_view->GetWebView(), file_url, &result, savable_schemes));
+ // Check all links of sub-resource
+ for (std::vector<GURL>::const_iterator cit = resources_list.begin();
+ cit != resources_list.end(); ++cit) {
+ ASSERT_TRUE(expected_resources_set.find(*cit) !=
+ expected_resources_set.end());
+ }
+ // Check all links of frame.
+ for (std::vector<GURL>::const_iterator cit = frames_list.begin();
+ cit != frames_list.end(); ++cit) {
+ ASSERT_TRUE(expected_resources_set.find(*cit) !=
+ expected_resources_set.end());
+ }
+ }
+};
+
+// Test function GetAllSavableResourceLinksForCurrentPage with a web page
+// which has valid savable resource links.
+IN_PROC_BROWSER_TEST_F(DomOperationsTests,
+ GetSavableResourceLinksWithPageHasValidLinks) {
+ std::set<GURL> expected_resources_set;
+
+ const char* expected_sub_resource_links[] = {
+ "file:///c:/yt/css/base_all-vfl36460.css",
+ "file:///c:/yt/js/base_all_with_bidi-vfl36451.js",
+ "file:///c:/yt/img/pixel-vfl73.gif"
+ };
+ const char* expected_frame_links[] = {
+ "youtube_1.htm",
+ "youtube_2.htm"
+ };
+ // Add all expected links of sub-resource to expected set.
+ for (size_t i = 0; i < arraysize(expected_sub_resource_links); ++i)
+ expected_resources_set.insert(GURL(expected_sub_resource_links[i]));
+ // Add all expected links of frame to expected set.
+ for (size_t i = 0; i < arraysize(expected_frame_links); ++i) {
+ const base::FilePath expected_frame_url =
+ GetTestFilePath("dom_serializer", expected_frame_links[i]);
+ expected_resources_set.insert(
+ net::FilePathToFileURL(expected_frame_url));
+ }
+
+ base::FilePath page_file_path =
+ GetTestFilePath("dom_serializer", "youtube_1.htm");
+ GetSavableResourceLinksForPage(page_file_path, expected_resources_set);
+}
+
+// Test function GetAllSavableResourceLinksForCurrentPage with a web page
+// which does not have valid savable resource links.
+IN_PROC_BROWSER_TEST_F(DomOperationsTests,
+ GetSavableResourceLinksWithPageHasInvalidLinks) {
+ std::set<GURL> expected_resources_set;
+
+ const char* expected_frame_links[] = {
+ "youtube_2.htm"
+ };
+ // Add all expected links of frame to expected set.
+ for (size_t i = 0; i < arraysize(expected_frame_links); ++i) {
+ base::FilePath expected_frame_url =
+ GetTestFilePath("dom_serializer", expected_frame_links[i]);
+ expected_resources_set.insert(
+ net::FilePathToFileURL(expected_frame_url));
+ }
+
+ base::FilePath page_file_path =
+ GetTestFilePath("dom_serializer", "youtube_2.htm");
+ GetSavableResourceLinksForPage(page_file_path, expected_resources_set);
+}
+
+} // namespace content
diff --git a/content/renderer/dom_serializer_browsertest.cc b/content/renderer/dom_serializer_browsertest.cc
new file mode 100644
index 0000000..3df004d
--- /dev/null
+++ b/content/renderer/dom_serializer_browsertest.cc
@@ -0,0 +1,1019 @@
+// 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/bind.h"
+#include "base/command_line.h"
+#include "base/compiler_specific.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/hash_tables.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/renderer/render_view.h"
+#include "content/public/renderer/render_view_observer.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/shell.h"
+#include "content/test/content_browser_test.h"
+#include "content/test/content_browser_test_utils.h"
+#include "net/base/net_util.h"
+#include "net/url_request/url_request_context.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebData.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebNodeCollection.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebNodeList.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebPageSerializer.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebPageSerializerClient.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
+#include "webkit/base/file_path_string_conversions.h"
+#include "webkit/glue/dom_operations.h"
+
+using WebKit::WebCString;
+using WebKit::WebData;
+using WebKit::WebDocument;
+using WebKit::WebElement;
+using WebKit::WebFrame;
+using WebKit::WebNode;
+using WebKit::WebNodeCollection;
+using WebKit::WebNodeList;
+using WebKit::WebPageSerializer;
+using WebKit::WebPageSerializerClient;
+using WebKit::WebNode;
+using WebKit::WebString;
+using WebKit::WebURL;
+using WebKit::WebView;
+using WebKit::WebVector;
+
+namespace content {
+
+// Iterate recursively over sub-frames to find one with with a given url.
+WebFrame* FindSubFrameByURL(WebView* web_view, const GURL& url) {
+ if (!web_view->mainFrame())
+ return NULL;
+
+ std::vector<WebFrame*> stack;
+ stack.push_back(web_view->mainFrame());
+
+ while (!stack.empty()) {
+ WebFrame* current_frame = stack.back();
+ stack.pop_back();
+ if (GURL(current_frame->document().url()) == url)
+ return current_frame;
+ WebNodeCollection all = current_frame->document().all();
+ for (WebNode node = all.firstItem();
+ !node.isNull(); node = all.nextItem()) {
+ if (!node.isElementNode())
+ continue;
+ // Check frame tag and iframe tag
+ WebElement element = node.to<WebElement>();
+ if (!element.hasTagName("frame") && !element.hasTagName("iframe"))
+ continue;
+ WebFrame* sub_frame = WebFrame::fromFrameOwnerElement(element);
+ if (sub_frame)
+ stack.push_back(sub_frame);
+ }
+ }
+ return NULL;
+}
+
+// Helper function that test whether the first node in the doc is a doc type
+// node.
+bool HasDocType(const WebDocument& doc) {
+ WebNode node = doc.firstChild();
+ if (node.isNull())
+ return false;
+ return node.nodeType() == WebNode::DocumentTypeNode;
+}
+
+ // Helper function for checking whether input node is META tag. Return true
+// means it is META element, otherwise return false. The parameter charset_info
+// return actual charset info if the META tag has charset declaration.
+bool IsMetaElement(const WebNode& node, std::string& charset_info) {
+ if (!node.isElementNode())
+ return false;
+ const WebElement meta = node.toConst<WebElement>();
+ if (!meta.hasTagName("meta"))
+ return false;
+ charset_info.erase(0, charset_info.length());
+ // Check the META charset declaration.
+ WebString httpEquiv = meta.getAttribute("http-equiv");
+ if (LowerCaseEqualsASCII(httpEquiv, "content-type")) {
+ std::string content = meta.getAttribute("content").utf8();
+ int pos = content.find("charset", 0);
+ if (pos > -1) {
+ // Add a dummy charset declaration to charset_info, which indicates this
+ // META tag has charset declaration although we do not get correct value
+ // yet.
+ charset_info.append("has-charset-declaration");
+ int remaining_length = content.length() - pos - 7;
+ if (!remaining_length)
+ return true;
+ int start_pos = pos + 7;
+ // Find "=" symbol.
+ while (remaining_length--)
+ if (content[start_pos++] == L'=')
+ break;
+ // Skip beginning space.
+ while (remaining_length) {
+ if (content[start_pos] > 0x0020)
+ break;
+ ++start_pos;
+ --remaining_length;
+ }
+ if (!remaining_length)
+ return true;
+ int end_pos = start_pos;
+ // Now we find out the start point of charset info. Search the end point.
+ while (remaining_length--) {
+ if (content[end_pos] <= 0x0020 || content[end_pos] == L';')
+ break;
+ ++end_pos;
+ }
+ // Get actual charset info.
+ charset_info = content.substr(start_pos, end_pos - start_pos);
+ return true;
+ }
+ }
+ return true;
+}
+
+class LoadObserver : public RenderViewObserver {
+ public:
+ LoadObserver(RenderView* render_view, const base::Closure& quit_closure)
+ : RenderViewObserver(render_view),
+ quit_closure_(quit_closure) {}
+
+ virtual void DidFinishLoad(WebKit::WebFrame* frame) OVERRIDE {
+ if (frame == render_view()->GetWebView()->mainFrame())
+ quit_closure_.Run();
+ }
+
+ private:
+ base::Closure quit_closure_;
+};
+
+class DomSerializerTests : public ContentBrowserTest,
+ public WebPageSerializerClient {
+ public:
+ DomSerializerTests()
+ : serialized_(false),
+ local_directory_name_(FILE_PATH_LITERAL("./dummy_files/")) {}
+
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ command_line->AppendSwitch(switches::kSingleProcess);
+#if defined(OS_WIN) && defined(USE_AURA)
+ // Don't want to try to create a GPU process.
+ command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
+#endif
+ }
+
+ // DomSerializerDelegate.
+ virtual void didSerializeDataForFrame(const WebURL& frame_web_url,
+ const WebCString& data,
+ PageSerializationStatus status) {
+
+ GURL frame_url(frame_web_url);
+ // If the all frames are finished saving, check all finish status
+ if (status == WebPageSerializerClient::AllFramesAreFinished) {
+ SerializationFinishStatusMap::iterator it =
+ serialization_finish_status_.begin();
+ for (; it != serialization_finish_status_.end(); ++it)
+ ASSERT_TRUE(it->second);
+ serialized_ = true;
+ return;
+ }
+
+ // Check finish status of current frame.
+ SerializationFinishStatusMap::iterator it =
+ serialization_finish_status_.find(frame_url.spec());
+ // New frame, set initial status as false.
+ if (it == serialization_finish_status_.end())
+ serialization_finish_status_[frame_url.spec()] = false;
+
+ it = serialization_finish_status_.find(frame_url.spec());
+ ASSERT_TRUE(it != serialization_finish_status_.end());
+ // In process frame, finish status should be false.
+ ASSERT_FALSE(it->second);
+
+ // Add data to corresponding frame's content.
+ serialized_frame_map_[frame_url.spec()] += data.data();
+
+ // Current frame is completed saving, change the finish status.
+ if (status == WebPageSerializerClient::CurrentFrameIsFinished)
+ it->second = true;
+ }
+
+ bool HasSerializedFrame(const GURL& frame_url) {
+ return serialized_frame_map_.find(frame_url.spec()) !=
+ serialized_frame_map_.end();
+ }
+
+ const std::string& GetSerializedContentForFrame(
+ const GURL& frame_url) {
+ return serialized_frame_map_[frame_url.spec()];
+ }
+
+ RenderView* GetRenderView() {
+ // We could have the test on the UI thread get the WebContent's routing ID,
+ // but we know this will be the first RV so skip that and just hardcode it.
+ return RenderView::FromRoutingID(1);
+ }
+
+ WebView* GetWebView() {
+ return GetRenderView()->GetWebView();
+ }
+
+ WebFrame* GetMainFrame() {
+ return GetWebView()->mainFrame();
+ }
+
+ // Load web page according to input content and relative URLs within
+ // the document.
+ void LoadContents(const std::string& contents,
+ const GURL& base_url,
+ const WebString encoding_info) {
+ scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
+ LoadObserver observer(GetRenderView(), runner->QuitClosure());
+
+ // If input encoding is empty, use UTF-8 as default encoding.
+ if (encoding_info.isEmpty()) {
+ GetMainFrame()->loadHTMLString(contents, base_url);
+ } else {
+ WebData data(contents.data(), contents.length());
+
+ // Do not use WebFrame.LoadHTMLString because it assumes that input
+ // html contents use UTF-8 encoding.
+ // TODO(darin): This should use WebFrame::loadData.
+ WebFrame* web_frame = GetMainFrame();
+
+ ASSERT_TRUE(web_frame != NULL);
+
+ web_frame->loadData(data, "text/html", encoding_info, base_url);
+ }
+
+ runner->Run();
+ }
+
+ // Serialize page DOM according to specific page URL. The parameter
+ // recursive_serialization indicates whether we will serialize all
+ // sub-frames.
+ void SerializeDomForURL(const GURL& page_url,
+ bool recursive_serialization) {
+ // Find corresponding WebFrame according to page_url.
+ WebFrame* web_frame = FindSubFrameByURL(GetWebView(), page_url);
+ ASSERT_TRUE(web_frame != NULL);
+ // Add input file URl to links_.
+ links_.assign(&page_url,1);
+ // Add dummy file path to local_path_.
+ WebString file_path = webkit_base::FilePathStringToWebString(
+ FILE_PATH_LITERAL("c:\\dummy.htm"));
+ local_paths_.assign(&file_path, 1);
+ // Start serializing DOM.
+ bool result = WebPageSerializer::serialize(web_frame,
+ recursive_serialization,
+ static_cast<WebPageSerializerClient*>(this),
+ links_,
+ local_paths_,
+ webkit_base::FilePathToWebString(local_directory_name_));
+ ASSERT_TRUE(result);
+ ASSERT_TRUE(serialized_);
+ }
+
+ void SerializeHTMLDOMWithDocTypeOnRenderer(const GURL& file_url) {
+ // Make sure original contents have document type.
+ WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url);
+ ASSERT_TRUE(web_frame != NULL);
+ WebDocument doc = web_frame->document();
+ ASSERT_TRUE(HasDocType(doc));
+ // Do serialization.
+ SerializeDomForURL(file_url, false);
+ // Load the serialized contents.
+ ASSERT_TRUE(HasSerializedFrame(file_url));
+ const std::string& serialized_contents =
+ GetSerializedContentForFrame(file_url);
+ LoadContents(serialized_contents, file_url,
+ web_frame->document().encoding());
+ // Make sure serialized contents still have document type.
+ web_frame = GetMainFrame();
+ doc = web_frame->document();
+ ASSERT_TRUE(HasDocType(doc));
+ }
+
+ void SerializeHTMLDOMWithoutDocTypeOnRenderer(const GURL& file_url) {
+ // Make sure original contents do not have document type.
+ WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url);
+ ASSERT_TRUE(web_frame != NULL);
+ WebDocument doc = web_frame->document();
+ ASSERT_TRUE(!HasDocType(doc));
+ // Do serialization.
+ SerializeDomForURL(file_url, false);
+ // Load the serialized contents.
+ ASSERT_TRUE(HasSerializedFrame(file_url));
+ const std::string& serialized_contents =
+ GetSerializedContentForFrame(file_url);
+ LoadContents(serialized_contents, file_url,
+ web_frame->document().encoding());
+ // Make sure serialized contents do not have document type.
+ web_frame = GetMainFrame();
+ doc = web_frame->document();
+ ASSERT_TRUE(!HasDocType(doc));
+ }
+
+ void SerializeXMLDocWithBuiltInEntitiesOnRenderer(
+ const GURL& xml_file_url, const std::string& original_contents) {
+ // Do serialization.
+ SerializeDomForURL(xml_file_url, false);
+ // Compare the serialized contents with original contents.
+ ASSERT_TRUE(HasSerializedFrame(xml_file_url));
+ const std::string& serialized_contents =
+ GetSerializedContentForFrame(xml_file_url);
+ ASSERT_EQ(original_contents, serialized_contents);
+ }
+
+ void SerializeHTMLDOMWithAddingMOTWOnRenderer(
+ const GURL& file_url, const std::string& original_contents) {
+ // Make sure original contents does not have MOTW;
+ std::string motw_declaration =
+ WebPageSerializer::generateMarkOfTheWebDeclaration(file_url).utf8();
+ ASSERT_FALSE(motw_declaration.empty());
+ // The encoding of original contents is ISO-8859-1, so we convert the MOTW
+ // declaration to ASCII and search whether original contents has it or not.
+ ASSERT_TRUE(std::string::npos == original_contents.find(motw_declaration));
+
+ // Do serialization.
+ SerializeDomForURL(file_url, false);
+ // Make sure the serialized contents have MOTW ;
+ ASSERT_TRUE(HasSerializedFrame(file_url));
+ const std::string& serialized_contents =
+ GetSerializedContentForFrame(file_url);
+ ASSERT_FALSE(std::string::npos ==
+ serialized_contents.find(motw_declaration));
+ }
+
+ void SerializeHTMLDOMWithNoMetaCharsetInOriginalDocOnRenderer(
+ const GURL& file_url) {
+ // Make sure there is no META charset declaration in original document.
+ WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url);
+ ASSERT_TRUE(web_frame != NULL);
+ WebDocument doc = web_frame->document();
+ ASSERT_TRUE(doc.isHTMLDocument());
+ WebElement head_element = doc.head();
+ ASSERT_TRUE(!head_element.isNull());
+ // Go through all children of HEAD element.
+ for (WebNode child = head_element.firstChild(); !child.isNull();
+ child = child.nextSibling()) {
+ std::string charset_info;
+ if (IsMetaElement(child, charset_info))
+ ASSERT_TRUE(charset_info.empty());
+ }
+ // Do serialization.
+ SerializeDomForURL(file_url, false);
+
+ // Load the serialized contents.
+ ASSERT_TRUE(HasSerializedFrame(file_url));
+ const std::string& serialized_contents =
+ GetSerializedContentForFrame(file_url);
+ LoadContents(serialized_contents, file_url,
+ web_frame->document().encoding());
+ // Make sure the first child of HEAD element is META which has charset
+ // declaration in serialized contents.
+ web_frame = GetMainFrame();
+ ASSERT_TRUE(web_frame != NULL);
+ doc = web_frame->document();
+ ASSERT_TRUE(doc.isHTMLDocument());
+ head_element = doc.head();
+ ASSERT_TRUE(!head_element.isNull());
+ WebNode meta_node = head_element.firstChild();
+ ASSERT_TRUE(!meta_node.isNull());
+ // Get meta charset info.
+ std::string charset_info2;
+ ASSERT_TRUE(IsMetaElement(meta_node, charset_info2));
+ ASSERT_TRUE(!charset_info2.empty());
+ ASSERT_EQ(charset_info2,
+ std::string(web_frame->document().encoding().utf8()));
+
+ // Make sure no more additional META tags which have charset declaration.
+ for (WebNode child = meta_node.nextSibling(); !child.isNull();
+ child = child.nextSibling()) {
+ std::string charset_info;
+ if (IsMetaElement(child, charset_info))
+ ASSERT_TRUE(charset_info.empty());
+ }
+ }
+
+ void SerializeHTMLDOMWithMultipleMetaCharsetInOriginalDocOnRenderer(
+ const GURL& file_url) {
+ // Make sure there are multiple META charset declarations in original
+ // document.
+ WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url);
+ ASSERT_TRUE(web_frame != NULL);
+ WebDocument doc = web_frame->document();
+ ASSERT_TRUE(doc.isHTMLDocument());
+ WebElement head_ele = doc.head();
+ ASSERT_TRUE(!head_ele.isNull());
+ // Go through all children of HEAD element.
+ int charset_declaration_count = 0;
+ for (WebNode child = head_ele.firstChild(); !child.isNull();
+ child = child.nextSibling()) {
+ std::string charset_info;
+ if (IsMetaElement(child, charset_info) && !charset_info.empty())
+ charset_declaration_count++;
+ }
+ // The original doc has more than META tags which have charset declaration.
+ ASSERT_TRUE(charset_declaration_count > 1);
+
+ // Do serialization.
+ SerializeDomForURL(file_url, false);
+
+ // Load the serialized contents.
+ ASSERT_TRUE(HasSerializedFrame(file_url));
+ const std::string& serialized_contents =
+ GetSerializedContentForFrame(file_url);
+ LoadContents(serialized_contents, file_url,
+ web_frame->document().encoding());
+ // Make sure only first child of HEAD element is META which has charset
+ // declaration in serialized contents.
+ web_frame = GetMainFrame();
+ ASSERT_TRUE(web_frame != NULL);
+ doc = web_frame->document();
+ ASSERT_TRUE(doc.isHTMLDocument());
+ head_ele = doc.head();
+ ASSERT_TRUE(!head_ele.isNull());
+ WebNode meta_node = head_ele.firstChild();
+ ASSERT_TRUE(!meta_node.isNull());
+ // Get meta charset info.
+ std::string charset_info2;
+ ASSERT_TRUE(IsMetaElement(meta_node, charset_info2));
+ ASSERT_TRUE(!charset_info2.empty());
+ ASSERT_EQ(charset_info2,
+ std::string(web_frame->document().encoding().utf8()));
+
+ // Make sure no more additional META tags which have charset declaration.
+ for (WebNode child = meta_node.nextSibling(); !child.isNull();
+ child = child.nextSibling()) {
+ std::string charset_info;
+ if (IsMetaElement(child, charset_info))
+ ASSERT_TRUE(charset_info.empty());
+ }
+ }
+
+ void SerializeHTMLDOMWithEntitiesInTextOnRenderer() {
+ base::FilePath page_file_path = GetTestFilePath(
+ "dom_serializer", "dom_serializer/htmlentities_in_text.htm");
+ // Get file URL. The URL is dummy URL to identify the following loading
+ // actions. The test content is in constant:original_contents.
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ ASSERT_TRUE(file_url.SchemeIsFile());
+ // Test contents.
+ static const char* const original_contents =
+ "<html><body>&<>\"\'</body></html>";
+ // Load the test contents.
+ LoadContents(original_contents, file_url, WebString());
+
+ // Get BODY's text content in DOM.
+ WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url);
+ ASSERT_TRUE(web_frame != NULL);
+ WebDocument doc = web_frame->document();
+ ASSERT_TRUE(doc.isHTMLDocument());
+ WebElement body_ele = doc.body();
+ ASSERT_TRUE(!body_ele.isNull());
+ WebNode text_node = body_ele.firstChild();
+ ASSERT_TRUE(text_node.isTextNode());
+ ASSERT_TRUE(std::string(text_node.createMarkup().utf8()) ==
+ "&<>\"\'");
+ // Do serialization.
+ SerializeDomForURL(file_url, false);
+ // Compare the serialized contents with original contents.
+ ASSERT_TRUE(HasSerializedFrame(file_url));
+ const std::string& serialized_contents =
+ GetSerializedContentForFrame(file_url);
+ // Compare the serialized contents with original contents to make sure
+ // they are same.
+ // Because we add MOTW when serializing DOM, so before comparison, we also
+ // need to add MOTW to original_contents.
+ std::string original_str =
+ WebPageSerializer::generateMarkOfTheWebDeclaration(file_url).utf8();
+ original_str += original_contents;
+ // Since WebCore now inserts a new HEAD element if there is no HEAD element
+ // when creating BODY element. (Please see
+ // HTMLParser::bodyCreateErrorCheck.) We need to append the HEAD content and
+ // corresponding META content if we find WebCore-generated HEAD element.
+ if (!doc.head().isNull()) {
+ WebString encoding = web_frame->document().encoding();
+ std::string htmlTag("<html>");
+ std::string::size_type pos = original_str.find(htmlTag);
+ ASSERT_NE(std::string::npos, pos);
+ pos += htmlTag.length();
+ std::string head_part("<head>");
+ head_part +=
+ WebPageSerializer::generateMetaCharsetDeclaration(encoding).utf8();
+ head_part += "</head>";
+ original_str.insert(pos, head_part);
+ }
+ ASSERT_EQ(original_str, serialized_contents);
+ }
+
+ void SerializeHTMLDOMWithEntitiesInAttributeValueOnRenderer() {
+ base::FilePath page_file_path = GetTestFilePath(
+ "dom_serializer", "dom_serializer/htmlentities_in_attribute_value.htm");
+ // Get file URL. The URL is dummy URL to identify the following loading
+ // actions. The test content is in constant:original_contents.
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ ASSERT_TRUE(file_url.SchemeIsFile());
+ // Test contents.
+ static const char* const original_contents =
+ "<html><body title=\"&<>"'\"></body></html>";
+ // Load the test contents.
+ LoadContents(original_contents, file_url, WebString());
+ // Get value of BODY's title attribute in DOM.
+ WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url);
+ ASSERT_TRUE(web_frame != NULL);
+ WebDocument doc = web_frame->document();
+ ASSERT_TRUE(doc.isHTMLDocument());
+ WebElement body_ele = doc.body();
+ ASSERT_TRUE(!body_ele.isNull());
+ WebString value = body_ele.getAttribute("title");
+ ASSERT_TRUE(std::string(value.utf8()) == "&<>\"\'");
+ // Do serialization.
+ SerializeDomForURL(file_url, false);
+ // Compare the serialized contents with original contents.
+ ASSERT_TRUE(HasSerializedFrame(file_url));
+ const std::string& serialized_contents =
+ GetSerializedContentForFrame(file_url);
+ // Compare the serialized contents with original contents to make sure
+ // they are same.
+ std::string original_str =
+ WebPageSerializer::generateMarkOfTheWebDeclaration(file_url).utf8();
+ original_str += original_contents;
+ if (!doc.isNull()) {
+ WebString encoding = web_frame->document().encoding();
+ std::string htmlTag("<html>");
+ std::string::size_type pos = original_str.find(htmlTag);
+ ASSERT_NE(std::string::npos, pos);
+ pos += htmlTag.length();
+ std::string head_part("<head>");
+ head_part +=
+ WebPageSerializer::generateMetaCharsetDeclaration(encoding).utf8();
+ head_part += "</head>";
+ original_str.insert(pos, head_part);
+ }
+ ASSERT_EQ(original_str, serialized_contents);
+ }
+
+ void SerializeHTMLDOMWithNonStandardEntitiesOnRenderer(const GURL& file_url) {
+ // Get value of BODY's title attribute in DOM.
+ WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url);
+ WebDocument doc = web_frame->document();
+ ASSERT_TRUE(doc.isHTMLDocument());
+ WebElement body_element = doc.body();
+ // Unescaped string for "%⊅¹'".
+ static const wchar_t parsed_value[] = {
+ '%', 0x2285, 0x00b9, '\'', 0
+ };
+ WebString value = body_element.getAttribute("title");
+ ASSERT_TRUE(UTF16ToWide(value) == parsed_value);
+ ASSERT_TRUE(UTF16ToWide(body_element.innerText()) == parsed_value);
+
+ // Do serialization.
+ SerializeDomForURL(file_url, false);
+ // Check the serialized string.
+ ASSERT_TRUE(HasSerializedFrame(file_url));
+ const std::string& serialized_contents =
+ GetSerializedContentForFrame(file_url);
+ // Confirm that the serialized string has no non-standard HTML entities.
+ ASSERT_EQ(std::string::npos, serialized_contents.find("%"));
+ ASSERT_EQ(std::string::npos, serialized_contents.find("⊅"));
+ ASSERT_EQ(std::string::npos, serialized_contents.find("¹"));
+ ASSERT_EQ(std::string::npos, serialized_contents.find("'"));
+ }
+
+ void SerializeHTMLDOMWithBaseTagOnRenderer(const GURL& file_url,
+ const GURL& path_dir_url) {
+ // There are total 2 available base tags in this test file.
+ const int kTotalBaseTagCountInTestFile = 2;
+
+ // Since for this test, we assume there is no savable sub-resource links for
+ // this test file, also all links are relative URLs in this test file, so we
+ // need to check those relative URLs and make sure document has BASE tag.
+ WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url);
+ ASSERT_TRUE(web_frame != NULL);
+ WebDocument doc = web_frame->document();
+ ASSERT_TRUE(doc.isHTMLDocument());
+ // Go through all descent nodes.
+ WebNodeCollection all = doc.all();
+ int original_base_tag_count = 0;
+ for (WebNode node = all.firstItem(); !node.isNull();
+ node = all.nextItem()) {
+ if (!node.isElementNode())
+ continue;
+ WebElement element = node.to<WebElement>();
+ if (element.hasTagName("base")) {
+ original_base_tag_count++;
+ } else {
+ // Get link.
+ WebString value =
+ webkit_glue::GetSubResourceLinkFromElement(element);
+ if (value.isNull() && element.hasTagName("a")) {
+ value = element.getAttribute("href");
+ if (value.isEmpty())
+ value = WebString();
+ }
+ // Each link is relative link.
+ if (!value.isNull()) {
+ GURL link(value.utf8());
+ ASSERT_TRUE(link.scheme().empty());
+ }
+ }
+ }
+ ASSERT_EQ(original_base_tag_count, kTotalBaseTagCountInTestFile);
+ // Make sure in original document, the base URL is not equal with the
+ // |path_dir_url|.
+ GURL original_base_url(doc.baseURL());
+ ASSERT_NE(original_base_url, path_dir_url);
+
+ // Do serialization.
+ SerializeDomForURL(file_url, false);
+
+ // Load the serialized contents.
+ ASSERT_TRUE(HasSerializedFrame(file_url));
+ const std::string& serialized_contents =
+ GetSerializedContentForFrame(file_url);
+ LoadContents(serialized_contents, file_url,
+ web_frame->document().encoding());
+
+ // Make sure all links are absolute URLs and doc there are some number of
+ // BASE tags in serialized HTML data. Each of those BASE tags have same base
+ // URL which is as same as URL of current test file.
+ web_frame = GetMainFrame();
+ ASSERT_TRUE(web_frame != NULL);
+ doc = web_frame->document();
+ ASSERT_TRUE(doc.isHTMLDocument());
+ // Go through all descent nodes.
+ all = doc.all();
+ int new_base_tag_count = 0;
+ for (WebNode node = all.firstItem(); !node.isNull();
+ node = all.nextItem()) {
+ if (!node.isElementNode())
+ continue;
+ WebElement element = node.to<WebElement>();
+ if (element.hasTagName("base")) {
+ new_base_tag_count++;
+ } else {
+ // Get link.
+ WebString value =
+ webkit_glue::GetSubResourceLinkFromElement(element);
+ if (value.isNull() && element.hasTagName("a")) {
+ value = element.getAttribute("href");
+ if (value.isEmpty())
+ value = WebString();
+ }
+ // Each link is absolute link.
+ if (!value.isNull()) {
+ GURL link(std::string(value.utf8()));
+ ASSERT_FALSE(link.scheme().empty());
+ }
+ }
+ }
+ // We have one more added BASE tag which is generated by JavaScript.
+ ASSERT_EQ(new_base_tag_count, original_base_tag_count + 1);
+ // Make sure in new document, the base URL is equal with the |path_dir_url|.
+ GURL new_base_url(doc.baseURL());
+ ASSERT_EQ(new_base_url, path_dir_url);
+ }
+
+ void SerializeHTMLDOMWithEmptyHeadOnRenderer() {
+ base::FilePath page_file_path = GetTestFilePath(
+ "dom_serializer", "empty_head.htm");
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ ASSERT_TRUE(file_url.SchemeIsFile());
+
+ // Load the test html content.
+ static const char* const empty_head_contents =
+ "<html><head></head><body>hello world</body></html>";
+ LoadContents(empty_head_contents, file_url, WebString());
+
+ // Make sure the head tag is empty.
+ WebFrame* web_frame = GetMainFrame();
+ ASSERT_TRUE(web_frame != NULL);
+ WebDocument doc = web_frame->document();
+ ASSERT_TRUE(doc.isHTMLDocument());
+ WebElement head_element = doc.head();
+ ASSERT_TRUE(!head_element.isNull());
+ ASSERT_TRUE(!head_element.hasChildNodes());
+ ASSERT_TRUE(head_element.childNodes().length() == 0);
+
+ // Do serialization.
+ SerializeDomForURL(file_url, false);
+ // Make sure the serialized contents have META ;
+ ASSERT_TRUE(HasSerializedFrame(file_url));
+ const std::string& serialized_contents =
+ GetSerializedContentForFrame(file_url);
+
+ // Reload serialized contents and make sure there is only one META tag.
+ LoadContents(serialized_contents, file_url,
+ web_frame->document().encoding());
+ web_frame = GetMainFrame();
+ ASSERT_TRUE(web_frame != NULL);
+ doc = web_frame->document();
+ ASSERT_TRUE(doc.isHTMLDocument());
+ head_element = doc.head();
+ ASSERT_TRUE(!head_element.isNull());
+ ASSERT_TRUE(head_element.hasChildNodes());
+ ASSERT_TRUE(head_element.childNodes().length() == 1);
+ WebNode meta_node = head_element.firstChild();
+ ASSERT_TRUE(!meta_node.isNull());
+ // Get meta charset info.
+ std::string charset_info;
+ ASSERT_TRUE(IsMetaElement(meta_node, charset_info));
+ ASSERT_TRUE(!charset_info.empty());
+ ASSERT_EQ(charset_info,
+ std::string(web_frame->document().encoding().utf8()));
+
+ // Check the body's first node is text node and its contents are
+ // "hello world"
+ WebElement body_element = doc.body();
+ ASSERT_TRUE(!body_element.isNull());
+ WebNode text_node = body_element.firstChild();
+ ASSERT_TRUE(text_node.isTextNode());
+ WebString text_node_contents = text_node.nodeValue();
+ ASSERT_TRUE(std::string(text_node_contents.utf8()) == "hello world");
+ }
+
+ void SerializeDocumentWithDownloadedIFrameOnRenderer(const GURL& file_url) {
+ // Do a recursive serialization. We pass if we don't crash.
+ SerializeDomForURL(file_url, true);
+ }
+
+ void SubResourceForElementsInNonHTMLNamespaceOnRenderer(
+ const GURL& file_url) {
+ WebFrame* web_frame = FindSubFrameByURL(GetWebView(), file_url);
+ ASSERT_TRUE(web_frame != NULL);
+ WebDocument doc = web_frame->document();
+ WebNode lastNodeInBody = doc.body().lastChild();
+ ASSERT_EQ(WebNode::ElementNode, lastNodeInBody.nodeType());
+ WebString uri = webkit_glue::GetSubResourceLinkFromElement(
+ lastNodeInBody.to<WebElement>());
+ EXPECT_TRUE(uri.isNull());
+ }
+
+ private:
+ // Map frame_url to corresponding serialized_content.
+ typedef base::hash_map<std::string, std::string> SerializedFrameContentMap;
+ SerializedFrameContentMap serialized_frame_map_;
+ // Map frame_url to corresponding status of serialization finish.
+ typedef base::hash_map<std::string, bool> SerializationFinishStatusMap;
+ SerializationFinishStatusMap serialization_finish_status_;
+ // Flag indicates whether the process of serializing DOM is finished or not.
+ bool serialized_;
+ // The links_ contain dummy original URLs of all saved links.
+ WebVector<WebURL> links_;
+ // The local_paths_ contain dummy corresponding local file paths of all saved
+ // links, which matched links_ one by one.
+ WebVector<WebString> local_paths_;
+ // The local_directory_name_ is dummy relative path of directory which
+ // contain all saved auxiliary files included all sub frames and resources.
+ const base::FilePath local_directory_name_;
+};
+
+// If original contents have document type, the serialized contents also have
+// document type.
+IN_PROC_BROWSER_TEST_F(DomSerializerTests, SerializeHTMLDOMWithDocType) {
+ base::FilePath page_file_path =
+ GetTestFilePath("dom_serializer", "youtube_1.htm");
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ ASSERT_TRUE(file_url.SchemeIsFile());
+ // Load the test file.
+ NavigateToURL(shell(), file_url);
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(&DomSerializerTests::SerializeHTMLDOMWithDocTypeOnRenderer,
+ base::Unretained(this), file_url));
+}
+
+// If original contents do not have document type, the serialized contents
+// also do not have document type.
+IN_PROC_BROWSER_TEST_F(DomSerializerTests, SerializeHTMLDOMWithoutDocType) {
+ base::FilePath page_file_path =
+ GetTestFilePath("dom_serializer", "youtube_2.htm");
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ ASSERT_TRUE(file_url.SchemeIsFile());
+ // Load the test file.
+ NavigateToURL(shell(), file_url);
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(
+ &DomSerializerTests::SerializeHTMLDOMWithoutDocTypeOnRenderer,
+ base::Unretained(this), file_url));
+}
+
+// Serialize XML document which has all 5 built-in entities. After
+// finishing serialization, the serialized contents should be same
+// with original XML document.
+IN_PROC_BROWSER_TEST_F(DomSerializerTests, SerializeXMLDocWithBuiltInEntities) {
+ base::FilePath page_file_path =
+ GetTestFilePath("dom_serializer", "note.html");
+ base::FilePath xml_file_path = GetTestFilePath("dom_serializer", "note.xml");
+ // Read original contents for later comparison.
+ std::string original_contents;
+ ASSERT_TRUE(file_util::ReadFileToString(xml_file_path, &original_contents));
+ // Get file URL.
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ GURL xml_file_url = net::FilePathToFileURL(xml_file_path);
+ ASSERT_TRUE(file_url.SchemeIsFile());
+ // Load the test file.
+ NavigateToURL(shell(), file_url);
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(
+ &DomSerializerTests::SerializeXMLDocWithBuiltInEntitiesOnRenderer,
+ base::Unretained(this), xml_file_url, original_contents));
+}
+
+// When serializing DOM, we add MOTW declaration before html tag.
+IN_PROC_BROWSER_TEST_F(DomSerializerTests, SerializeHTMLDOMWithAddingMOTW) {
+ base::FilePath page_file_path =
+ GetTestFilePath("dom_serializer", "youtube_2.htm");
+ // Read original contents for later comparison .
+ std::string original_contents;
+ ASSERT_TRUE(file_util::ReadFileToString(page_file_path, &original_contents));
+ // Get file URL.
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ ASSERT_TRUE(file_url.SchemeIsFile());
+
+ // Load the test file.
+ NavigateToURL(shell(), file_url);
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(
+ &DomSerializerTests::SerializeHTMLDOMWithAddingMOTWOnRenderer,
+ base::Unretained(this), file_url, original_contents));
+}
+
+// When serializing DOM, we will add the META which have correct charset
+// declaration as first child of HEAD element for resolving WebKit bug:
+// http://bugs.webkit.org/show_bug.cgi?id=16621 even the original document
+// does not have META charset declaration.
+IN_PROC_BROWSER_TEST_F(DomSerializerTests,
+ SerializeHTMLDOMWithNoMetaCharsetInOriginalDoc) {
+ base::FilePath page_file_path =
+ GetTestFilePath("dom_serializer", "youtube_1.htm");
+ // Get file URL.
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ ASSERT_TRUE(file_url.SchemeIsFile());
+ // Load the test file.
+ NavigateToURL(shell(), file_url);
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(
+ &DomSerializerTests::
+ SerializeHTMLDOMWithNoMetaCharsetInOriginalDocOnRenderer,
+ base::Unretained(this), file_url));
+}
+
+// When serializing DOM, if the original document has multiple META charset
+// declaration, we will add the META which have correct charset declaration
+// as first child of HEAD element and remove all original META charset
+// declarations.
+IN_PROC_BROWSER_TEST_F(DomSerializerTests,
+ SerializeHTMLDOMWithMultipleMetaCharsetInOriginalDoc) {
+ base::FilePath page_file_path =
+ GetTestFilePath("dom_serializer", "youtube_2.htm");
+ // Get file URL.
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ ASSERT_TRUE(file_url.SchemeIsFile());
+ // Load the test file.
+ NavigateToURL(shell(), file_url);
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(
+ &DomSerializerTests::
+ SerializeHTMLDOMWithMultipleMetaCharsetInOriginalDocOnRenderer,
+ base::Unretained(this), file_url));
+}
+
+// Test situation of html entities in text when serializing HTML DOM.
+IN_PROC_BROWSER_TEST_F(DomSerializerTests, SerializeHTMLDOMWithEntitiesInText) {
+ // Need to spin up the renderer and also navigate to a file url so that the
+ // renderer code doesn't attempt a fork when it sees a load to file scheme
+ // from non-file scheme.
+ NavigateToURL(shell(), GetTestUrl(".", "simple_page.html"));
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(
+ &DomSerializerTests::SerializeHTMLDOMWithEntitiesInTextOnRenderer,
+ base::Unretained(this)));
+}
+
+// Test situation of html entities in attribute value when serializing
+// HTML DOM.
+// This test started to fail at WebKit r65388. See http://crbug.com/52279.
+IN_PROC_BROWSER_TEST_F(DomSerializerTests,
+ SerializeHTMLDOMWithEntitiesInAttributeValue) {
+ // Need to spin up the renderer and also navigate to a file url so that the
+ // renderer code doesn't attempt a fork when it sees a load to file scheme
+ // from non-file scheme.
+ NavigateToURL(shell(), GetTestUrl(".", "simple_page.html"));
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(
+ &DomSerializerTests::
+ SerializeHTMLDOMWithEntitiesInAttributeValueOnRenderer,
+ base::Unretained(this)));
+}
+
+// Test situation of non-standard HTML entities when serializing HTML DOM.
+// This test started to fail at WebKit r65351. See http://crbug.com/52279.
+IN_PROC_BROWSER_TEST_F(DomSerializerTests,
+ SerializeHTMLDOMWithNonStandardEntities) {
+ // Make a test file URL and load it.
+ base::FilePath page_file_path = GetTestFilePath(
+ "dom_serializer", "nonstandard_htmlentities.htm");
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ NavigateToURL(shell(), file_url);
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(
+ &DomSerializerTests::
+ SerializeHTMLDOMWithNonStandardEntitiesOnRenderer,
+ base::Unretained(this), file_url));
+}
+
+// Test situation of BASE tag in original document when serializing HTML DOM.
+// When serializing, we should comment the BASE tag, append a new BASE tag.
+// rewrite all the savable URLs to relative local path, and change other URLs
+// to absolute URLs.
+IN_PROC_BROWSER_TEST_F(DomSerializerTests, SerializeHTMLDOMWithBaseTag) {
+ base::FilePath page_file_path = GetTestFilePath(
+ "dom_serializer", "html_doc_has_base_tag.htm");
+
+ // Get page dir URL which is base URL of this file.
+ base::FilePath dir_name = page_file_path.DirName();
+ dir_name = dir_name.Append(
+ base::FilePath::StringType(base::FilePath::kSeparators[0], 1));
+ GURL path_dir_url = net::FilePathToFileURL(dir_name);
+
+ // Get file URL.
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ ASSERT_TRUE(file_url.SchemeIsFile());
+ // Load the test file.
+ NavigateToURL(shell(), file_url);
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(
+ &DomSerializerTests::SerializeHTMLDOMWithBaseTagOnRenderer,
+ base::Unretained(this), file_url, path_dir_url));
+}
+
+// Serializing page which has an empty HEAD tag.
+IN_PROC_BROWSER_TEST_F(DomSerializerTests, SerializeHTMLDOMWithEmptyHead) {
+ // Need to spin up the renderer and also navigate to a file url so that the
+ // renderer code doesn't attempt a fork when it sees a load to file scheme
+ // from non-file scheme.
+ NavigateToURL(shell(), GetTestUrl(".", "simple_page.html"));
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(&DomSerializerTests::SerializeHTMLDOMWithEmptyHeadOnRenderer,
+ base::Unretained(this)));
+}
+
+// Test that we don't crash when the page contains an iframe that
+// was handled as a download (http://crbug.com/42212).
+IN_PROC_BROWSER_TEST_F(DomSerializerTests,
+ SerializeDocumentWithDownloadedIFrame) {
+ base::FilePath page_file_path = GetTestFilePath(
+ "dom_serializer", "iframe-src-is-exe.htm");
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ ASSERT_TRUE(file_url.SchemeIsFile());
+ // Load the test file.
+ NavigateToURL(shell(), file_url);
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(
+ &DomSerializerTests::
+ SerializeDocumentWithDownloadedIFrameOnRenderer,
+ base::Unretained(this), file_url));
+}
+
+IN_PROC_BROWSER_TEST_F(DomSerializerTests,
+ SubResourceForElementsInNonHTMLNamespace) {
+ base::FilePath page_file_path = GetTestFilePath(
+ "dom_serializer", "non_html_namespace.htm");
+ GURL file_url = net::FilePathToFileURL(page_file_path);
+ NavigateToURL(shell(), file_url);
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(
+ &DomSerializerTests::
+ SubResourceForElementsInNonHTMLNamespaceOnRenderer,
+ base::Unretained(this), file_url));
+}
+
+} // namespace content
diff --git a/content/renderer/dom_storage/webstoragearea_impl.cc b/content/renderer/dom_storage/webstoragearea_impl.cc
index c09ed03..72d5fe2 100644
--- a/content/renderer/dom_storage/webstoragearea_impl.cc
+++ b/content/renderer/dom_storage/webstoragearea_impl.cc
@@ -37,8 +37,7 @@
WebStorageAreaImpl::WebStorageAreaImpl(
int64 namespace_id, const GURL& origin)
- : ALLOW_THIS_IN_INITIALIZER_LIST(
- connection_id_(g_all_areas_map.Pointer()->Add(this))),
+ : connection_id_(g_all_areas_map.Pointer()->Add(this)),
cached_area_(dispatcher()->
OpenCachedArea(connection_id_, namespace_id, origin)) {
}
diff --git a/content/renderer/favicon_helper.cc b/content/renderer/favicon_helper.cc
deleted file mode 100644
index 541847e..0000000
--- a/content/renderer/favicon_helper.cc
+++ /dev/null
@@ -1,220 +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/renderer/favicon_helper.h"
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/message_loop.h"
-#include "content/common/icon_messages.h"
-#include "content/public/renderer/render_view.h"
-#include "net/base/data_url.h"
-#include "third_party/WebKit/Source/Platform/chromium/public/WebURLRequest.h"
-#include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
-#include "ui/base/ui_base_switches.h"
-#include "ui/gfx/favicon_size.h"
-#include "ui/gfx/size.h"
-#include "ui/gfx/skbitmap_operations.h"
-#include "webkit/glue/image_decoder.h"
-#include "webkit/glue/multi_resolution_image_resource_fetcher.h"
-#include "webkit/glue/webkit_glue.h"
-
-using WebKit::WebFrame;
-using WebKit::WebIconURL;
-using WebKit::WebVector;
-using WebKit::WebURL;
-using WebKit::WebURLRequest;
-using webkit_glue::MultiResolutionImageResourceFetcher;
-
-namespace content {
-
-namespace {
-
-bool TouchEnabled() {
-// Based on the definition of chrome::kEnableTouchIcon.
-#if defined(OS_ANDROID)
- return true;
-#else
- return false;
-#endif
-}
-
-} // namespace
-
-
-static FaviconURL::IconType ToFaviconType(WebIconURL::Type type) {
- switch (type) {
- case WebIconURL::TypeFavicon:
- return FaviconURL::FAVICON;
- case WebIconURL::TypeTouch:
- return FaviconURL::TOUCH_ICON;
- case WebIconURL::TypeTouchPrecomposed:
- return FaviconURL::TOUCH_PRECOMPOSED_ICON;
- case WebIconURL::TypeInvalid:
- return FaviconURL::INVALID_ICON;
- }
- return FaviconURL::INVALID_ICON;
-}
-
-FaviconHelper::FaviconHelper(RenderView* render_view)
- : RenderViewObserver(render_view),
- icon_types_changed_(WebIconURL::TypeInvalid),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
-}
-
-void FaviconHelper::DidChangeIcon(WebKit::WebFrame* frame,
- WebKit::WebIconURL::Type icon_type) {
- if (frame->parent())
- return;
-
- if (!TouchEnabled() && icon_type != WebIconURL::TypeFavicon)
- return;
-
- DCHECK(!render_view()->GetWebView() ||
- frame == render_view()->GetWebView()->mainFrame());
-
- weak_ptr_factory_.InvalidateWeakPtrs();
- icon_types_changed_ =
- static_cast<WebKit::WebIconURL::Type>(icon_types_changed_ | icon_type);
- MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&FaviconHelper::ProcessDidChangeIcon,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-FaviconHelper::~FaviconHelper() {
-}
-
-void FaviconHelper::ProcessDidChangeIcon() {
- WebKit::WebIconURL::Type icon_types = icon_types_changed_;
- icon_types_changed_ = WebIconURL::TypeInvalid;
- WebKit::WebView* web_view = render_view()->GetWebView();
- if (!web_view) {
- return;
- }
- WebFrame* frame = web_view->mainFrame();
- if (!frame) {
- return;
- }
- WebVector<WebIconURL> icon_urls = frame->iconURLs(icon_types);
- std::vector<FaviconURL> urls;
- for (size_t i = 0; i < icon_urls.size(); i++) {
- urls.push_back(FaviconURL(icon_urls[i].iconURL(),
- ToFaviconType(icon_urls[i].iconType())));
- }
- SendUpdateFaviconURL(routing_id(), render_view()->GetPageId(), urls);
-}
-
-void FaviconHelper::OnDownloadFavicon(int id,
- const GURL& image_url,
- bool is_favicon,
- int image_size) {
- std::vector<SkBitmap> result_images;
- if (image_url.SchemeIs("data")) {
- SkBitmap data_image = ImageFromDataUrl(image_url);
- if (!data_image.empty())
- result_images.push_back(data_image);
- } else {
- if (DownloadFavicon(id, image_url, is_favicon, image_size)) {
- // Will complete asynchronously via FaviconHelper::DidDownloadFavicon
- return;
- }
- }
-
- Send(new IconHostMsg_DidDownloadFavicon(routing_id(),
- id,
- image_url,
- image_size,
- result_images));
-}
-
-bool FaviconHelper::DownloadFavicon(int id,
- const GURL& image_url,
- bool is_favicon,
- int image_size) {
- // Make sure webview was not shut down.
- if (!render_view()->GetWebView())
- return false;
- // Create an image resource fetcher and assign it with a call back object.
- image_fetchers_.push_back(new MultiResolutionImageResourceFetcher(
- image_url,
- render_view()->GetWebView()->mainFrame(),
- id,
- is_favicon ? WebURLRequest::TargetIsFavicon :
- WebURLRequest::TargetIsImage,
- base::Bind(&FaviconHelper::DidDownloadFavicon,
- base::Unretained(this), image_size)));
- return true;
-}
-
-void FaviconHelper::DidDownloadFavicon(
- int requested_size,
- MultiResolutionImageResourceFetcher* fetcher,
- const std::vector<SkBitmap>& images) {
- // Notify requester of image download status.
- Send(new IconHostMsg_DidDownloadFavicon(routing_id(),
- fetcher->id(),
- fetcher->image_url(),
- requested_size,
- images));
-
- // Remove the image fetcher from our pending list. We're in the callback from
- // MultiResolutionImageResourceFetcher, best to delay deletion.
- ImageResourceFetcherList::iterator iter =
- std::find(image_fetchers_.begin(), image_fetchers_.end(), fetcher);
- if (iter != image_fetchers_.end()) {
- image_fetchers_.weak_erase(iter);
- MessageLoop::current()->DeleteSoon(FROM_HERE, fetcher);
- }
-}
-
-SkBitmap FaviconHelper::ImageFromDataUrl(const GURL& url) const {
- std::string mime_type, char_set, data;
- if (net::DataURL::Parse(url, &mime_type, &char_set, &data) && !data.empty()) {
- // Decode the favicon using WebKit's image decoder.
- webkit_glue::ImageDecoder decoder(
- gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize));
- const unsigned char* src_data =
- reinterpret_cast<const unsigned char*>(&data[0]);
-
- return decoder.Decode(src_data, data.size());
- }
- return SkBitmap();
-}
-
-void FaviconHelper::SendUpdateFaviconURL(int32 routing_id,
- int32 page_id,
- const std::vector<FaviconURL>& urls) {
- if (!urls.empty())
- Send(new IconHostMsg_UpdateFaviconURL(routing_id, page_id, urls));
-}
-
-bool FaviconHelper::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(FaviconHelper, message)
- IPC_MESSAGE_HANDLER(IconMsg_DownloadFavicon, OnDownloadFavicon)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
-
- return handled;
-}
-
-void FaviconHelper::DidStopLoading() {
- int icon_types = WebIconURL::TypeFavicon;
- if (TouchEnabled())
- icon_types |= WebIconURL::TypeTouchPrecomposed | WebIconURL::TypeTouch;
-
- WebVector<WebIconURL> icon_urls =
- render_view()->GetWebView()->mainFrame()->iconURLs(icon_types);
- std::vector<FaviconURL> urls;
- for (size_t i = 0; i < icon_urls.size(); i++) {
- WebURL url = icon_urls[i].iconURL();
- if (!url.isEmpty())
- urls.push_back(FaviconURL(url, ToFaviconType(icon_urls[i].iconType())));
- }
- SendUpdateFaviconURL(routing_id(), render_view()->GetPageId(), urls);
-}
-
-} // namespace content
diff --git a/content/renderer/favicon_helper.h b/content/renderer/favicon_helper.h
deleted file mode 100644
index 65032ec..0000000
--- a/content/renderer/favicon_helper.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_FAVICON_HELPER_H_
-#define CONTENT_RENDERER_FAVICON_HELPER_H_
-
-#include <string>
-#include <vector>
-
-#include "base/memory/linked_ptr.h"
-#include "base/memory/scoped_vector.h"
-#include "base/memory/weak_ptr.h"
-#include "content/public/common/content_constants.h"
-#include "content/public/renderer/render_view_observer.h"
-#include "googleurl/src/gurl.h"
-
-class SkBitmap;
-
-namespace content {
-struct FaviconURL;
-}
-
-namespace webkit_glue {
-class MultiResolutionImageResourceFetcher;
-}
-
-namespace content {
-
-struct FaviconURL;
-
-// This class deals with favicon downloading.
-// There is one FaviconHelper per RenderView, which is owned by the RenderView.
-class FaviconHelper : public RenderViewObserver {
- public:
- explicit FaviconHelper(RenderView* render_view);
-
- // Send a message that the favicon has changed.
- void DidChangeIcon(WebKit::WebFrame* frame,
- WebKit::WebIconURL::Type icon_type);
-
- private:
- virtual ~FaviconHelper();
-
- // Start processing the icon change. This done async from DidChangeIcon in
- // case there are several calls to DidChangeIcon in a row.
- void ProcessDidChangeIcon();
-
- // Message handler.
- void OnDownloadFavicon(int id,
- const GURL& image_url,
- bool is_favicon,
- int image_size);
-
- // Requests to download a favicon image. When done, the RenderView
- // is notified by way of DidDownloadFavicon. Returns true if the
- // request was successfully started, false otherwise. id is used to
- // uniquely identify the request and passed back to the
- // DidDownloadFavicon method. If the image is a favicon, cookies are
- // not sent and not accepted during download.
- // If the image has multiple frames, the
- // frame whose size is image_size is returned. If the image doesn't
- // have a frame at the specified size, the first is returned.
- bool DownloadFavicon(int id,
- const GURL& image_url,
- bool is_favicon,
- int image_size);
-
- // This callback is triggered when DownloadFavicon completes, either
- // succesfully or with a failure. See DownloadFavicon for more
- // details.
- void DidDownloadFavicon(
- int requested_size,
- webkit_glue::MultiResolutionImageResourceFetcher* fetcher,
- const std::vector<SkBitmap>& images);
-
- // Decodes a data: URL image or returns an empty image in case of failure.
- SkBitmap ImageFromDataUrl(const GURL&) const;
-
- // Send a message to update the favicon URL for a page.
- void SendUpdateFaviconURL(int32 routing_id,
- int32 page_id,
- const std::vector<FaviconURL>& urls);
-
- // RenderViewObserver implementation.
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
- virtual void DidStopLoading() OVERRIDE;
-
- typedef ScopedVector<webkit_glue::MultiResolutionImageResourceFetcher>
- ImageResourceFetcherList;
-
- // ImageResourceFetchers schedule via DownloadImage.
- ImageResourceFetcherList image_fetchers_;
-
- // The set of flags which have been sent to DidChangeIcon but not yet
- // processed.
- WebKit::WebIconURL::Type icon_types_changed_;
-
- base::WeakPtrFactory<FaviconHelper> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(FaviconHelper);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_FAVICON_HELPER_H_
diff --git a/content/renderer/geolocation_dispatcher.cc b/content/renderer/geolocation_dispatcher.cc
index ca9aa53..312761d 100644
--- a/content/renderer/geolocation_dispatcher.cc
+++ b/content/renderer/geolocation_dispatcher.cc
@@ -12,7 +12,6 @@
#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 WebKit::WebGeolocationController;
using WebKit::WebGeolocationError;
diff --git a/content/renderer/gpu/compositor_output_surface.cc b/content/renderer/gpu/compositor_output_surface.cc
index cc55ffa..8d24043 100644
--- a/content/renderer/gpu/compositor_output_surface.cc
+++ b/content/renderer/gpu/compositor_output_surface.cc
@@ -9,12 +9,13 @@
#include "cc/output/compositor_frame.h"
#include "cc/output/compositor_frame_ack.h"
#include "cc/output/output_surface_client.h"
+#include "content/common/gpu/client/command_buffer_proxy_impl.h"
+#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_switches.h"
#include "content/renderer/render_thread_impl.h"
#include "ipc/ipc_forwarding_message_filter.h"
#include "ipc/ipc_sync_channel.h"
-#include "ipc/ipc_sync_message_filter.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
#if defined(OS_ANDROID)
@@ -22,8 +23,6 @@
#include <sys/resource.h>
#endif
-using cc::CompositorFrame;
-using cc::SoftwareOutputDevice;
using WebKit::WebGraphicsContext3D;
namespace {
@@ -42,7 +41,10 @@
{
uint32 messages_to_filter[] = {
ViewMsg_UpdateVSyncParameters::ID,
- ViewMsg_SwapCompositorFrameAck::ID
+ ViewMsg_SwapCompositorFrameAck::ID,
+#if defined(OS_ANDROID)
+ ViewMsg_DidVSync::ID
+#endif
};
return new IPC::ForwardingMessageFilter(
@@ -52,9 +54,9 @@
CompositorOutputSurface::CompositorOutputSurface(
int32 routing_id,
- WebGraphicsContext3D* context3D,
+ WebGraphicsContext3DCommandBufferImpl* context3D,
cc::SoftwareOutputDevice* software_device)
- : OutputSurface(make_scoped_ptr(context3D),
+ : OutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D>(context3D),
make_scoped_ptr(software_device)),
output_surface_filter_(
RenderThreadImpl::current()->compositor_output_surface_filter()),
@@ -66,6 +68,8 @@
capabilities_.has_parent_compositor = command_line->HasSwitch(
switches::kEnableDelegatedRenderer);
DetachFromThread();
+ message_sender_ = RenderThreadImpl::current()->sync_message_filter();
+ DCHECK(message_sender_);
}
CompositorOutputSurface::~CompositorOutputSurface() {
@@ -100,6 +104,30 @@
Send(new ViewHostMsg_SwapCompositorFrame(routing_id_, *frame));
}
+void CompositorOutputSurface::SwapBuffers(
+ const cc::LatencyInfo& latency_info) {
+ WebGraphicsContext3DCommandBufferImpl* command_buffer =
+ static_cast<WebGraphicsContext3DCommandBufferImpl*>(context3d());
+ CommandBufferProxyImpl* command_buffer_proxy =
+ command_buffer->GetCommandBufferProxy();
+ DCHECK(command_buffer_proxy);
+ context3d()->shallowFlushCHROMIUM();
+ command_buffer_proxy->SetLatencyInfo(latency_info);
+ OutputSurface::SwapBuffers(latency_info);
+}
+
+void CompositorOutputSurface::PostSubBuffer(
+ gfx::Rect rect, const cc::LatencyInfo& latency_info) {
+ WebGraphicsContext3DCommandBufferImpl* command_buffer =
+ static_cast<WebGraphicsContext3DCommandBufferImpl*>(context3d());
+ CommandBufferProxyImpl* command_buffer_proxy =
+ command_buffer->GetCommandBufferProxy();
+ DCHECK(command_buffer_proxy);
+ context3d()->shallowFlushCHROMIUM();
+ command_buffer_proxy->SetLatencyInfo(latency_info);
+ OutputSurface::PostSubBuffer(rect, latency_info);
+}
+
void CompositorOutputSurface::OnMessageReceived(const IPC::Message& message) {
DCHECK(CalledOnValidThread());
if (!client_)
@@ -107,22 +135,36 @@
IPC_BEGIN_MESSAGE_MAP(CompositorOutputSurface, message)
IPC_MESSAGE_HANDLER(ViewMsg_UpdateVSyncParameters, OnUpdateVSyncParameters);
IPC_MESSAGE_HANDLER(ViewMsg_SwapCompositorFrameAck, OnSwapAck);
+#if defined(OS_ANDROID)
+ IPC_MESSAGE_HANDLER(ViewMsg_DidVSync, OnDidVSync);
+#endif
IPC_END_MESSAGE_MAP()
}
void CompositorOutputSurface::OnUpdateVSyncParameters(
base::TimeTicks timebase, base::TimeDelta interval) {
DCHECK(CalledOnValidThread());
- DCHECK(client_);
client_->OnVSyncParametersChanged(timebase, interval);
}
+#if defined(OS_ANDROID)
+void CompositorOutputSurface::EnableVSyncNotification(bool enable) {
+ DCHECK(CalledOnValidThread());
+ Send(new ViewHostMsg_SetVSyncNotificationEnabled(routing_id_, enable));
+}
+
+void CompositorOutputSurface::OnDidVSync(base::TimeTicks frame_time) {
+ DCHECK(CalledOnValidThread());
+ client_->DidVSync(frame_time);
+}
+#endif // defined(OS_ANDROID)
+
void CompositorOutputSurface::OnSwapAck(const cc::CompositorFrameAck& ack) {
client_->OnSendFrameToParentCompositorAck(ack);
}
bool CompositorOutputSurface::Send(IPC::Message* message) {
- return ChildThread::current()->sync_message_filter()->Send(message);
+ return message_sender_->Send(message);
}
namespace {
diff --git a/content/renderer/gpu/compositor_output_surface.h b/content/renderer/gpu/compositor_output_surface.h
index 255c618..e62990c 100644
--- a/content/renderer/gpu/compositor_output_surface.h
+++ b/content/renderer/gpu/compositor_output_surface.h
@@ -13,6 +13,7 @@
#include "base/threading/platform_thread.h"
#include "base/time.h"
#include "cc/output/output_surface.h"
+#include "ipc/ipc_sync_message_filter.h"
namespace base {
class TaskRunner;
@@ -24,11 +25,14 @@
}
namespace cc {
+class CompositorFrame;
class CompositorFrameAck;
}
namespace content {
+class WebGraphicsContext3DCommandBufferImpl;
+
// This class can be created only on the main thread, but then becomes pinned
// to a fixed thread when bindToClient is called.
class CompositorOutputSurface
@@ -39,13 +43,18 @@
base::TaskRunner* target_task_runner);
CompositorOutputSurface(int32 routing_id,
- WebKit::WebGraphicsContext3D* context3d,
+ WebGraphicsContext3DCommandBufferImpl* context3d,
cc::SoftwareOutputDevice* software);
virtual ~CompositorOutputSurface();
// cc::OutputSurface implementation.
virtual bool BindToClient(cc::OutputSurfaceClient* client) OVERRIDE;
virtual void SendFrameToParentCompositor(cc::CompositorFrame*) OVERRIDE;
+ virtual void PostSubBuffer(gfx::Rect rect, const cc::LatencyInfo&) OVERRIDE;
+ virtual void SwapBuffers(const cc::LatencyInfo&) OVERRIDE;
+#if defined(OS_ANDROID)
+ virtual void EnableVSyncNotification(bool enable) OVERRIDE;
+#endif
// TODO(epenner): This seems out of place here and would be a better fit
// int CompositorThread after it is fully refactored (http://crbug/170828)
@@ -78,10 +87,14 @@
void OnMessageReceived(const IPC::Message& message);
void OnUpdateVSyncParameters(
base::TimeTicks timebase, base::TimeDelta interval);
+#if defined(OS_ANDROID)
+ void OnDidVSync(base::TimeTicks frame_time);
+#endif
bool Send(IPC::Message* message);
scoped_refptr<IPC::ForwardingMessageFilter> output_surface_filter_;
scoped_refptr<CompositorOutputSurfaceProxy> output_surface_proxy_;
+ scoped_refptr<IPC::SyncMessageFilter> message_sender_;
int routing_id_;
bool prefers_smoothness_;
base::PlatformThreadId main_thread_id_;
diff --git a/content/renderer/gpu/compositor_software_output_device.cc b/content/renderer/gpu/compositor_software_output_device.cc
new file mode 100644
index 0000000..cd22bed
--- /dev/null
+++ b/content/renderer/gpu/compositor_software_output_device.cc
@@ -0,0 +1,149 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/gpu/compositor_software_output_device.h"
+
+#include "base/logging.h"
+#include "cc/output/software_frame_data.h"
+#include "content/renderer/render_process.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkDevice.h"
+#include "third_party/skia/include/core/SkPixelRef.h"
+#include "ui/gfx/skia_util.h"
+#include "ui/surface/transport_dib.h"
+
+namespace content {
+
+CompositorSoftwareOutputDevice::DIB::DIB(size_t size) {
+ RenderProcess* render_process = RenderProcess::current();
+ dib_ = render_process->CreateTransportDIB(size);
+ CHECK(dib_);
+ bool success = dib_->Map();
+ CHECK(success);
+}
+
+CompositorSoftwareOutputDevice::DIB::~DIB() {
+ RenderProcess* render_process = RenderProcess::current();
+ render_process->FreeTransportDIB(dib_);
+}
+
+CompositorSoftwareOutputDevice::CompositorSoftwareOutputDevice()
+ : front_buffer_(-1),
+ num_free_buffers_(0) {
+ DetachFromThread();
+}
+
+CompositorSoftwareOutputDevice::~CompositorSoftwareOutputDevice() {
+ DCHECK(CalledOnValidThread());
+}
+
+CompositorSoftwareOutputDevice::DIB*
+CompositorSoftwareOutputDevice::CreateDIB() {
+ const size_t size = 4 * viewport_size_.GetArea();
+ return new DIB(size);
+}
+
+void CompositorSoftwareOutputDevice::Resize(gfx::Size viewport_size) {
+ DCHECK(CalledOnValidThread());
+
+ if (viewport_size_ == viewport_size)
+ return;
+
+ // Keep non-ACKed dibs open.
+ int first_non_free = front_buffer_ + num_free_buffers_ + 1;
+ int num_non_free = dibs_.size() - num_free_buffers_;
+ for (int i = 0; i < num_non_free; ++i) {
+ int index = (first_non_free + i) % dibs_.size();
+ awaiting_ack_.push_back(dibs_[index]);
+ dibs_[index] = NULL;
+ }
+
+ dibs_.clear();
+ front_buffer_ = -1;
+ num_free_buffers_ = 0;
+ viewport_size_ = viewport_size;
+}
+
+SkCanvas* CompositorSoftwareOutputDevice::BeginPaint(gfx::Rect damage_rect) {
+ DCHECK(CalledOnValidThread());
+
+ gfx::Rect last_damage_rect = damage_rect_;
+ damage_rect_ = damage_rect;
+
+ int last_buffer = front_buffer_;
+ if (num_free_buffers_ == 0) {
+ dibs_.insert(dibs_.begin() + (front_buffer_ + 1), CreateDIB());
+ last_damage_rect = gfx::Rect(viewport_size_);
+ } else {
+ --num_free_buffers_;
+ }
+ front_buffer_ = (front_buffer_ + 1) % dibs_.size();
+
+ TransportDIB* front_dib = dibs_[front_buffer_]->dib();
+ DCHECK(front_dib);
+ DCHECK(front_dib->memory());
+
+ // Set up a canvas for the current front buffer.
+ bitmap_.setConfig(SkBitmap::kARGB_8888_Config,
+ viewport_size_.width(),
+ viewport_size_.height());
+ bitmap_.setPixels(front_dib->memory());
+ device_ = skia::AdoptRef(new SkDevice(bitmap_));
+ canvas_ = skia::AdoptRef(new SkCanvas(device_.get()));
+
+ // Copy over previous damage.
+ if (last_buffer != -1) {
+ TransportDIB* last_dib = dibs_[last_buffer]->dib();
+ SkBitmap back_bitmap;
+ back_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
+ viewport_size_.width(),
+ viewport_size_.height());
+ back_bitmap.setPixels(last_dib->memory());
+
+ SkRegion region(RectToSkIRect(last_damage_rect));
+ region.op(RectToSkIRect(damage_rect), SkRegion::kDifference_Op);
+ for (SkRegion::Iterator it(region); !it.done(); it.next()) {
+ const SkIRect& src_rect = it.rect();
+ SkRect dst_rect = SkRect::Make(src_rect);
+ canvas_->drawBitmapRect(back_bitmap, &src_rect, dst_rect, NULL);
+ }
+ }
+
+ return canvas_.get();
+}
+
+void CompositorSoftwareOutputDevice::EndPaint(
+ cc::SoftwareFrameData* frame_data) {
+ DCHECK(CalledOnValidThread());
+
+ if (frame_data) {
+ frame_data->size = viewport_size_;
+ frame_data->damage_rect = damage_rect_;
+ frame_data->dib_id = dibs_[front_buffer_]->dib()->id();
+ }
+}
+
+void CompositorSoftwareOutputDevice::ReclaimDIB(const TransportDIB::Id& id) {
+ DCHECK(CalledOnValidThread());
+
+ if (!TransportDIB::is_valid_id(id))
+ return;
+
+ // The reclaimed dib id might not be among the currently
+ // active dibs if we got a resize event in the mean time.
+ ScopedVector<DIB>::iterator it =
+ std::find_if(dibs_.begin(), dibs_.end(), CompareById(id));
+ if (it != dibs_.end()) {
+ ++num_free_buffers_;
+ DCHECK_LE(static_cast<size_t>(num_free_buffers_), dibs_.size());
+ return;
+ } else {
+ it = std::find_if(awaiting_ack_.begin(), awaiting_ack_.end(),
+ CompareById(id));
+ DCHECK(it != awaiting_ack_.end());
+ awaiting_ack_.erase(it);
+ }
+}
+
+} // namespace content
diff --git a/content/renderer/gpu/compositor_software_output_device.h b/content/renderer/gpu/compositor_software_output_device.h
new file mode 100644
index 0000000..b82ffe2
--- /dev/null
+++ b/content/renderer/gpu/compositor_software_output_device.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_GPU_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_H_
+#define CONTENT_RENDERER_GPU_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_H_
+
+#include "base/memory/scoped_vector.h"
+#include "base/threading/non_thread_safe.h"
+#include "cc/output/software_output_device.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+namespace content {
+
+// This class can be created only on the main thread, but then becomes pinned
+// to a fixed thread when BindToClient is called.
+class CompositorSoftwareOutputDevice
+ : NON_EXPORTED_BASE(public cc::SoftwareOutputDevice),
+ NON_EXPORTED_BASE(public base::NonThreadSafe) {
+public:
+ CompositorSoftwareOutputDevice();
+ virtual ~CompositorSoftwareOutputDevice();
+
+ virtual void Resize(gfx::Size size) OVERRIDE;
+
+ virtual SkCanvas* BeginPaint(gfx::Rect damage_rect) OVERRIDE;
+ virtual void EndPaint(cc::SoftwareFrameData* frame_data) OVERRIDE;
+
+ virtual void ReclaimDIB(const TransportDIB::Id& id) OVERRIDE;
+
+private:
+ class DIB {
+ public:
+ explicit DIB(size_t size);
+ ~DIB();
+
+ TransportDIB* dib() const {
+ return dib_;
+ }
+
+ private:
+ TransportDIB* dib_;
+
+ DISALLOW_COPY_AND_ASSIGN(DIB);
+ };
+
+ class CompareById {
+ public:
+ CompareById(const TransportDIB::Id& id) : id_(id) {}
+
+ bool operator()(const DIB* dib) const {
+ return dib->dib() && dib->dib()->id() == id_;
+ }
+
+ private:
+ TransportDIB::Id id_;
+ };
+
+ DIB* CreateDIB();
+
+ int front_buffer_;
+ int num_free_buffers_;
+ ScopedVector<DIB> dibs_;
+ ScopedVector<DIB> awaiting_ack_;
+ SkBitmap bitmap_;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_GPU_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_H_
diff --git a/content/renderer/gpu/compositor_software_output_device_gl_adapter.cc b/content/renderer/gpu/compositor_software_output_device_gl_adapter.cc
deleted file mode 100644
index 1c3793b..0000000
--- a/content/renderer/gpu/compositor_software_output_device_gl_adapter.cc
+++ /dev/null
@@ -1,148 +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/renderer/gpu/compositor_software_output_device_gl_adapter.h"
-
-#include "base/debug/trace_event.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/core/SkDevice.h"
-#include "third_party/skia/include/core/SkPixelRef.h"
-
-#include <GLES2/gl2.h>
-
-namespace content {
-
-CompositorSoftwareOutputDeviceGLAdapter::
- CompositorSoftwareOutputDeviceGLAdapter(
- WebKit::WebGraphicsContext3D* context3d)
- : program_(0),
- vertex_shader_(0),
- fragment_shader_(0),
- vertex_buffer_(0),
- texture_id_(0),
- context3d_(context3d) {
- CHECK(context3d);
-}
-
-CompositorSoftwareOutputDeviceGLAdapter::
- ~CompositorSoftwareOutputDeviceGLAdapter() {
- if (!device_)
- return;
-
- context3d_->makeContextCurrent();
- context3d_->deleteShader(vertex_shader_);
- context3d_->deleteShader(fragment_shader_);
- context3d_->deleteProgram(program_);
- context3d_->deleteBuffer(vertex_buffer_);
- context3d_->deleteTexture(texture_id_);
-}
-
-void CompositorSoftwareOutputDeviceGLAdapter::Resize(
- gfx::Size viewport_size) {
- if (!device_)
- InitShaders();
-
- cc::SoftwareOutputDevice::Resize(viewport_size);
-
- context3d_->makeContextCurrent();
- context3d_->ensureBackbufferCHROMIUM();
- context3d_->viewport(0, 0, viewport_size.width(), viewport_size.height());
- context3d_->reshape(viewport_size.width(), viewport_size.height());
-}
-
-void CompositorSoftwareOutputDeviceGLAdapter::EndPaint(
- cc::SoftwareFrameData* frame_data) {
- DCHECK(device_);
- DCHECK(frame_data == NULL);
-
- TRACE_EVENT0("renderer", "CompositorSoftwareOutputDeviceGLAdapter::EndPaint");
- const SkBitmap& bitmap = device_->accessBitmap(false);
-
- context3d_->makeContextCurrent();
- context3d_->ensureBackbufferCHROMIUM();
- context3d_->clear(GL_COLOR_BUFFER_BIT);
- context3d_->bindTexture(GL_TEXTURE_2D, texture_id_);
- context3d_->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
- viewport_size_.width(), viewport_size_.height(),
- 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap.pixelRef()->pixels());
- context3d_->drawArrays(GL_TRIANGLE_STRIP, 0, 4);
- context3d_->prepareTexture();
-}
-
-void CompositorSoftwareOutputDeviceGLAdapter::InitShaders() {
- // Vertex shader that flips the y axis.
- static const char g_vertex_shader[] =
- "attribute vec4 a_Position;"
- "attribute vec2 a_texCoord;"
- "varying vec2 v_texCoord;"
- "void main() {"
- " gl_Position = a_Position;"
- " gl_Position.y = -gl_Position.y;"
- " v_texCoord = a_texCoord;"
- "}";
-
- // Pixel shader that swizzles RGBA -> BGRA.
- static const char g_fragment_shader[] =
- "precision mediump float;"
- "varying vec2 v_texCoord;"
- "uniform sampler2D s_texture;"
- "void main() {"
- " gl_FragColor = texture2D(s_texture, v_texCoord).bgra;"
- "}";
-
- const GLfloat attribs[] = {
- -1.0f, -1.0f,
- 1.0f, -1.0f,
- -1.0f, 1.0f,
- 1.0f, 1.0f,
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- 0.0f, 1.0f,
- 1.0f, 1.0f
- };
-
- context3d_->makeContextCurrent();
-
- vertex_shader_ = context3d_->createShader(GL_VERTEX_SHADER);
- context3d_->shaderSource(vertex_shader_, g_vertex_shader);
- context3d_->compileShader(vertex_shader_);
-
- fragment_shader_ = context3d_->createShader(GL_FRAGMENT_SHADER);
- context3d_->shaderSource(fragment_shader_, g_fragment_shader);
- context3d_->compileShader(fragment_shader_);
-
- program_ = context3d_->createProgram();
- context3d_->attachShader(program_, vertex_shader_);
- context3d_->attachShader(program_, fragment_shader_);
-
- vertex_buffer_ = context3d_->createBuffer();
- context3d_->bindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
- context3d_->bufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), attribs,
- GL_STATIC_DRAW);
- context3d_->enableVertexAttribArray(0);
- context3d_->vertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
- context3d_->bindAttribLocation(program_, 0, "a_Position");
- context3d_->enableVertexAttribArray(1);
- context3d_->vertexAttribPointer(
- 1, 2, GL_FLOAT, GL_FALSE, 0, 8 * sizeof(GLfloat));
- context3d_->bindAttribLocation(program_, 1, "a_texCoord");
-
- context3d_->linkProgram(program_);
- context3d_->useProgram(program_);
-
- int texture_uniform = context3d_->getUniformLocation(program_, "s_texture");
- context3d_->uniform1i(texture_uniform, 0);
- context3d_->disable(GL_SCISSOR_TEST);
- context3d_->clearColor(0, 0, 1, 1);
-
- texture_id_ = context3d_->createTexture();
- context3d_->bindTexture(GL_TEXTURE_2D, texture_id_);
- context3d_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- context3d_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- context3d_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- context3d_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-}
-
-} // namespace content
diff --git a/content/renderer/gpu/compositor_software_output_device_gl_adapter.h b/content/renderer/gpu/compositor_software_output_device_gl_adapter.h
deleted file mode 100644
index 66a1bed..0000000
--- a/content/renderer/gpu/compositor_software_output_device_gl_adapter.h
+++ /dev/null
@@ -1,41 +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_RENDERER_GPU_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_GL_ADAPTER_H_
-#define CONTENT_RENDERER_GPU_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_GL_ADAPTER_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "base/threading/non_thread_safe.h"
-#include "cc/output/software_output_device.h"
-#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
-
-namespace content {
-
-// This class can be created only on the main thread, but then becomes pinned
-// to a fixed thread when bindToClient is called.
-class CompositorSoftwareOutputDeviceGLAdapter
- : NON_EXPORTED_BASE(public cc::SoftwareOutputDevice),
- NON_EXPORTED_BASE(public base::NonThreadSafe) {
- public:
- CompositorSoftwareOutputDeviceGLAdapter(
- WebKit::WebGraphicsContext3D* context3d);
- virtual ~CompositorSoftwareOutputDeviceGLAdapter();
-
- virtual void Resize(gfx::Size size) OVERRIDE;
- virtual void EndPaint(cc::SoftwareFrameData* frame_data) OVERRIDE;
-
- private:
- void InitShaders();
-
- unsigned program_;
- unsigned vertex_shader_;
- unsigned fragment_shader_;
- unsigned vertex_buffer_;
- unsigned texture_id_;
- scoped_ptr<WebKit::WebGraphicsContext3D> context3d_;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_GPU_COMPOSITOR_SOFTWARE_OUTPUT_DEVICE_GL_ADAPTER_H_
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.cc b/content/renderer/gpu/gpu_benchmarking_extension.cc
index 8238b42..9d864de 100644
--- a/content/renderer/gpu/gpu_benchmarking_extension.cc
+++ b/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -14,6 +14,7 @@
#include "content/common/gpu/gpu_rendering_stats.h"
#include "content/public/renderer/render_thread.h"
#include "content/renderer/all_rendering_benchmarks.h"
+#include "content/renderer/gpu/render_widget_compositor.h"
#include "content/renderer/render_view_impl.h"
#include "content/renderer/rendering_benchmark.h"
#include "third_party/skia/include/core/SkGraphics.h"
@@ -22,6 +23,7 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebViewBenchmarkSupport.h"
+#include "ui/gfx/codec/png_codec.h"
#include "v8/include/v8.h"
#include "webkit/compositor_bindings/web_rendering_stats_impl.h"
@@ -35,6 +37,15 @@
const char kGpuBenchmarkingExtensionName[] = "v8/GpuBenchmarking";
+static bool PNGEncodeBitmapToStream(SkWStream* stream, const SkBitmap& bm) {
+ std::vector<unsigned char> vector;
+ if (gfx::PNGCodec::EncodeBGRASkBitmap(bm, true, &vector)) {
+ if (stream->write(&vector.front() , vector.size()))
+ return true;
+ }
+ return false;
+}
+
namespace {
// Always called on the main render thread.
@@ -73,7 +84,7 @@
DCHECK(!filepath.empty());
SkFILEWStream file(filepath.c_str());
DCHECK(file.isValid());
- picture_.serialize(&file);
+ picture_.serialize(&file, &PNGEncodeBitmapToStream);
}
private:
@@ -123,6 +134,10 @@
"if (typeof(chrome.gpuBenchmarking) == 'undefined') {"
" chrome.gpuBenchmarking = {};"
"};"
+ "chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers = function() {"
+ " native function SetNeedsDisplayOnAllLayers();"
+ " return SetNeedsDisplayOnAllLayers();"
+ "};"
"chrome.gpuBenchmarking.renderingStats = function() {"
" native function GetRenderingStats();"
" return GetRenderingStats();"
@@ -158,6 +173,8 @@
virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
v8::Handle<v8::String> name) OVERRIDE {
+ if (name->Equals(v8::String::New("SetNeedsDisplayOnAllLayers")))
+ return v8::FunctionTemplate::New(SetNeedsDisplayOnAllLayers);
if (name->Equals(v8::String::New("GetRenderingStats")))
return v8::FunctionTemplate::New(GetRenderingStats);
if (name->Equals(v8::String::New("PrintToSkPicture")))
@@ -172,6 +189,29 @@
return v8::Handle<v8::FunctionTemplate>();
}
+ static v8::Handle<v8::Value> SetNeedsDisplayOnAllLayers(
+ const v8::Arguments& args) {
+ WebFrame* web_frame = WebFrame::frameForCurrentContext();
+ if (!web_frame)
+ return v8::Undefined();
+
+ WebView* web_view = web_frame->view();
+ if (!web_view)
+ return v8::Undefined();
+
+ RenderViewImpl* render_view_impl = RenderViewImpl::FromWebView(web_view);
+ if (!render_view_impl)
+ return v8::Undefined();
+
+ RenderWidgetCompositor* compositor = render_view_impl->compositor();
+ if (!compositor)
+ return v8::Undefined();
+
+ compositor->SetNeedsDisplayOnAllLayers();
+
+ return v8::Undefined();
+ }
+
static v8::Handle<v8::Value> GetRenderingStats(const v8::Arguments& args) {
WebFrame* web_frame = WebFrame::frameForCurrentContext();
@@ -277,11 +317,9 @@
v8::Local<v8::Function> callback_local =
v8::Local<v8::Function>(v8::Function::Cast(*args[1]));
v8::Isolate* isolate = args.GetIsolate();
- v8::Persistent<v8::Function> callback =
- v8::Persistent<v8::Function>::New(isolate, callback_local);
- v8::Persistent<v8::Context> context =
- v8::Persistent<v8::Context>::New(isolate,
- web_frame->mainWorldScriptContext());
+ v8::Persistent<v8::Function> callback(isolate, callback_local);
+ v8::Persistent<v8::Context> context(isolate,
+ web_frame->mainWorldScriptContext());
int pixels_to_scroll = args[2]->IntegerValue();
@@ -332,7 +370,7 @@
name_filter = "";
} else {
char filter[256];
- args[0]->ToString()->WriteAscii(filter, 0, sizeof(filter)-1);
+ args[0]->ToString()->WriteUtf8(filter, sizeof(filter)-1);
name_filter = std::string(filter);
}
@@ -438,11 +476,9 @@
v8::Local<v8::Function> callback_local =
v8::Local<v8::Function>(v8::Function::Cast(*args[0]));
v8::Isolate* isolate = args.GetIsolate();
- v8::Persistent<v8::Function> callback =
- v8::Persistent<v8::Function>::New(isolate, callback_local);
- v8::Persistent<v8::Context> context =
- v8::Persistent<v8::Context>::New(isolate,
- web_frame->mainWorldScriptContext());
+ v8::Persistent<v8::Function> callback(isolate, callback_local);
+ v8::Persistent<v8::Context> context(isolate,
+ web_frame->mainWorldScriptContext());
render_view_impl->GetWindowSnapshot(
base::Bind(&OnSnapshotCompleted, callback, context));
diff --git a/content/renderer/gpu/input_event_filter.cc b/content/renderer/gpu/input_event_filter.cc
index 79ab8b7..96a7034 100644
--- a/content/renderer/gpu/input_event_filter.cc
+++ b/content/renderer/gpu/input_event_filter.cc
@@ -6,7 +6,7 @@
#include "base/debug/trace_event.h"
#include "base/location.h"
#include "base/message_loop_proxy.h"
-#include "content/common/view_messages.h"
+#include "content/common/input_messages.h"
#include "content/renderer/gpu/input_event_filter.h"
using WebKit::WebInputEvent;
@@ -74,8 +74,17 @@
sender_ = NULL;
}
+// This function returns true if the IPC message is one that the compositor
+// thread can handle *or* one that needs to preserve relative order with
+// messages that the compositor thread can handle. Returning true for a message
+// type means that the message will go through an extra copy and thread hop, so
+// use with care.
+static bool RequiresThreadBounce(const IPC::Message& message) {
+ return IPC_MESSAGE_ID_CLASS(message.type()) == InputMsgStart;
+}
+
bool InputEventFilter::OnMessageReceived(const IPC::Message& message) {
- if (message.type() != ViewMsg_HandleInputEvent::ID)
+ if (!RequiresThreadBounce(message))
return false;
{
@@ -93,7 +102,7 @@
// static
const WebInputEvent* InputEventFilter::CrackMessage(
const IPC::Message& message) {
- DCHECK(message.type() == ViewMsg_HandleInputEvent::ID);
+ DCHECK(message.type() == InputMsg_HandleInputEvent::ID);
PickleIterator iter(message);
const WebInputEvent* event = NULL;
@@ -111,6 +120,14 @@
void InputEventFilter::ForwardToHandler(const IPC::Message& message) {
DCHECK(target_loop_->BelongsToCurrentThread());
+ if (message.type() != InputMsg_HandleInputEvent::ID) {
+ main_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&InputEventFilter::ForwardToMainListener,
+ this, message));
+ return;
+ }
+
// Save this message for later, in case we need to bounce it back up to the
// main listener.
//
@@ -143,7 +160,8 @@
return; // Filter was removed.
sender_->Send(
- new ViewHostMsg_HandleInputEvent_ACK(routing_id, event_type, ack_result));
+ new InputHostMsg_HandleInputEvent_ACK(
+ routing_id, event_type, ack_result));
}
} // namespace content
diff --git a/content/renderer/gpu/input_event_filter.h b/content/renderer/gpu/input_event_filter.h
index 855e844..9e94819 100644
--- a/content/renderer/gpu/input_event_filter.h
+++ b/content/renderer/gpu/input_event_filter.h
@@ -15,7 +15,7 @@
#include "ipc/ipc_channel_proxy.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
-// This class can be used to intercept ViewMsg_HandleInputEvent messages
+// This class can be used to intercept InputMsg_HandleInputEvent messages
// and have them be delivered to a target thread. Input events are filtered
// based on routing_id (see AddRoute and RemoveRoute).
//
@@ -38,11 +38,12 @@
// must be called on the target thread.
//
// If DidNotHandleInputEvent is called with send_to_widget set to true, then
- // the original ViewMsg_HandleInputEvent message will be delivered to
+ // the original InputMsg_HandleInputEvent message will be delivered to
// |main_listener| on the main thread. (The "main thread" in this context is
// the thread where the InputEventFilter was constructed.) If send_to_widget
- // is true, then a ViewHostMsg_HandleInputEvent_ACK will not be generated,
- // leaving that responsibility up to the eventual handler on the main thread.
+ // is true, then a InputHostMsg_HandleInputEvent_ACK will not be
+ // generated, leaving that responsibility up to the eventual handler on the
+ // main thread.
//
InputEventFilter(IPC::Listener* main_listener,
const scoped_refptr<base::MessageLoopProxy>& target_loop,
@@ -62,7 +63,7 @@
virtual void OnChannelClosing() OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
- // Expects a ViewMsg_HandleInputEvent message.
+ // Expects a InputMsg_HandleInputEvent message.
static const WebKit::WebInputEvent* CrackMessage(const IPC::Message& message);
private:
diff --git a/content/renderer/gpu/input_event_filter_unittest.cc b/content/renderer/gpu/input_event_filter_unittest.cc
index 32b7bc1..24064db 100644
--- a/content/renderer/gpu/input_event_filter_unittest.cc
+++ b/content/renderer/gpu/input_event_filter_unittest.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/message_loop.h"
+#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/renderer/gpu/input_event_filter.h"
#include "ipc/ipc_test_sink.h"
@@ -103,87 +104,107 @@
event->y = y;
}
+void AddMessagesToFilter(IPC::ChannelProxy::MessageFilter* message_filter,
+ const std::vector<IPC::Message>& events) {
+ for (size_t i = 0; i < events.size(); ++i) {
+ message_filter->OnMessageReceived(events[i]);
+ }
+
+ base::MessageLoop::current()->RunUntilIdle();
+}
+
void AddEventsToFilter(IPC::ChannelProxy::MessageFilter* message_filter,
const WebMouseEvent events[],
size_t count) {
+ std::vector<IPC::Message> messages;
for (size_t i = 0; i < count; ++i) {
- ViewMsg_HandleInputEvent message(kTestRoutingID, &events[i], false);
- message_filter->OnMessageReceived(message);
+ messages.push_back(
+ InputMsg_HandleInputEvent(kTestRoutingID, &events[i], false));
}
- MessageLoop::current()->RunUntilIdle();
+ AddMessagesToFilter(message_filter, messages);
}
} // namespace
-TEST(InputEventFilterTest, Basic) {
- MessageLoop message_loop;
+class InputEventFilterTest : public testing::Test {
+ public:
+ virtual void SetUp() OVERRIDE {
+ filter_ = new InputEventFilter(
+ &message_recorder_,
+ message_loop_.message_loop_proxy(),
+ base::Bind(&InputEventRecorder::HandleInputEvent,
+ base::Unretained(&event_recorder_)));
+ event_recorder_.set_filter(filter_);
+
+ filter_->OnFilterAdded(&ipc_sink_);
+ }
+
+
+ protected:
+ base::MessageLoop message_loop_;
// Used to record IPCs sent by the filter to the RenderWidgetHost.
- IPC::TestSink ipc_sink;
+ IPC::TestSink ipc_sink_;
// Used to record IPCs forwarded by the filter to the main thread.
- IPCMessageRecorder message_recorder;
+ IPCMessageRecorder message_recorder_;
// Used to record WebInputEvents delivered to the handler.
- InputEventRecorder event_recorder;
+ InputEventRecorder event_recorder_;
- scoped_refptr<InputEventFilter> filter =
- new InputEventFilter(&message_recorder,
- message_loop.message_loop_proxy(),
- base::Bind(&InputEventRecorder::HandleInputEvent,
- base::Unretained(&event_recorder)));
- event_recorder.set_filter(filter);
+ scoped_refptr<InputEventFilter> filter_;
+};
- filter->OnFilterAdded(&ipc_sink);
-
+TEST_F(InputEventFilterTest, Basic) {
WebMouseEvent kEvents[3];
InitMouseEvent(&kEvents[0], WebInputEvent::MouseDown, 10, 10);
InitMouseEvent(&kEvents[1], WebInputEvent::MouseMove, 20, 20);
InitMouseEvent(&kEvents[2], WebInputEvent::MouseUp, 30, 30);
- AddEventsToFilter(filter, kEvents, arraysize(kEvents));
- EXPECT_EQ(0U, ipc_sink.message_count());
- EXPECT_EQ(0U, event_recorder.record_count());
- EXPECT_EQ(0U, message_recorder.message_count());
+ AddEventsToFilter(filter_, kEvents, arraysize(kEvents));
+ EXPECT_EQ(0U, ipc_sink_.message_count());
+ EXPECT_EQ(0U, event_recorder_.record_count());
+ EXPECT_EQ(0U, message_recorder_.message_count());
- filter->AddRoute(kTestRoutingID);
+ filter_->AddRoute(kTestRoutingID);
- AddEventsToFilter(filter, kEvents, arraysize(kEvents));
- ASSERT_EQ(arraysize(kEvents), ipc_sink.message_count());
- ASSERT_EQ(arraysize(kEvents), event_recorder.record_count());
- EXPECT_EQ(0U, message_recorder.message_count());
+ AddEventsToFilter(filter_, kEvents, arraysize(kEvents));
+ ASSERT_EQ(arraysize(kEvents), ipc_sink_.message_count());
+ ASSERT_EQ(arraysize(kEvents), event_recorder_.record_count());
+ EXPECT_EQ(0U, message_recorder_.message_count());
for (size_t i = 0; i < arraysize(kEvents); ++i) {
- const IPC::Message* message = ipc_sink.GetMessageAt(i);
+ const IPC::Message* message = ipc_sink_.GetMessageAt(i);
EXPECT_EQ(kTestRoutingID, message->routing_id());
- EXPECT_EQ(ViewHostMsg_HandleInputEvent_ACK::ID, message->type());
+ EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
WebInputEvent::Type event_type = WebInputEvent::Undefined;
InputEventAckState ack_result = INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
- EXPECT_TRUE(ViewHostMsg_HandleInputEvent_ACK::Read(message, &event_type,
- &ack_result));
+ EXPECT_TRUE(InputHostMsg_HandleInputEvent_ACK::Read(message,
+ &event_type,
+ &ack_result));
EXPECT_EQ(kEvents[i].type, event_type);
EXPECT_EQ(ack_result, INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- const WebInputEvent* event = event_recorder.record_at(i);
+ const WebInputEvent* event = event_recorder_.record_at(i);
ASSERT_TRUE(event);
EXPECT_EQ(kEvents[i].size, event->size);
EXPECT_TRUE(memcmp(&kEvents[i], event, event->size) == 0);
}
- event_recorder.set_send_to_widget(true);
+ event_recorder_.set_send_to_widget(true);
- AddEventsToFilter(filter, kEvents, arraysize(kEvents));
- EXPECT_EQ(arraysize(kEvents), ipc_sink.message_count());
- EXPECT_EQ(2 * arraysize(kEvents), event_recorder.record_count());
- EXPECT_EQ(arraysize(kEvents), message_recorder.message_count());
+ AddEventsToFilter(filter_, kEvents, arraysize(kEvents));
+ EXPECT_EQ(arraysize(kEvents), ipc_sink_.message_count());
+ EXPECT_EQ(2 * arraysize(kEvents), event_recorder_.record_count());
+ EXPECT_EQ(arraysize(kEvents), message_recorder_.message_count());
for (size_t i = 0; i < arraysize(kEvents); ++i) {
- const IPC::Message& message = message_recorder.message_at(i);
+ const IPC::Message& message = message_recorder_.message_at(i);
- ASSERT_EQ(ViewMsg_HandleInputEvent::ID, message.type());
+ ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
const WebInputEvent* event = InputEventFilter::CrackMessage(message);
EXPECT_EQ(kEvents[i].size, event->size);
@@ -192,31 +213,84 @@
// Now reset everything, and test that DidHandleInputEvent is called.
- ipc_sink.ClearMessages();
- event_recorder.Clear();
- message_recorder.Clear();
+ ipc_sink_.ClearMessages();
+ event_recorder_.Clear();
+ message_recorder_.Clear();
- event_recorder.set_handle_events(true);
+ event_recorder_.set_handle_events(true);
- AddEventsToFilter(filter, kEvents, arraysize(kEvents));
- EXPECT_EQ(arraysize(kEvents), ipc_sink.message_count());
- EXPECT_EQ(arraysize(kEvents), event_recorder.record_count());
- EXPECT_EQ(0U, message_recorder.message_count());
+ AddEventsToFilter(filter_, kEvents, arraysize(kEvents));
+ EXPECT_EQ(arraysize(kEvents), ipc_sink_.message_count());
+ EXPECT_EQ(arraysize(kEvents), event_recorder_.record_count());
+ EXPECT_EQ(0U, message_recorder_.message_count());
for (size_t i = 0; i < arraysize(kEvents); ++i) {
- const IPC::Message* message = ipc_sink.GetMessageAt(i);
+ const IPC::Message* message = ipc_sink_.GetMessageAt(i);
EXPECT_EQ(kTestRoutingID, message->routing_id());
- EXPECT_EQ(ViewHostMsg_HandleInputEvent_ACK::ID, message->type());
+ EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
WebInputEvent::Type event_type = WebInputEvent::Undefined;
InputEventAckState ack_result = INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
- EXPECT_TRUE(ViewHostMsg_HandleInputEvent_ACK::Read(message, &event_type,
- &ack_result));
+ EXPECT_TRUE(InputHostMsg_HandleInputEvent_ACK::Read(message,
+ &event_type,
+ &ack_result));
EXPECT_EQ(kEvents[i].type, event_type);
EXPECT_EQ(ack_result, INPUT_EVENT_ACK_STATE_CONSUMED);
}
- filter->OnFilterRemoved();
+ filter_->OnFilterRemoved();
+}
+
+TEST_F(InputEventFilterTest, PreserveRelativeOrder) {
+ filter_->AddRoute(kTestRoutingID);
+ event_recorder_.set_send_to_widget(true);
+
+
+ WebMouseEvent mouse_down;
+ mouse_down.type = WebMouseEvent::MouseDown;
+ WebMouseEvent mouse_up;
+ mouse_up.type = WebMouseEvent::MouseUp;
+
+ std::vector<IPC::Message> messages;
+ messages.push_back(InputMsg_HandleInputEvent(kTestRoutingID,
+ &mouse_down,
+ false));
+ // Control where input events are delivered.
+ messages.push_back(InputMsg_MouseCaptureLost(kTestRoutingID));
+ messages.push_back(InputMsg_SetFocus(kTestRoutingID, true));
+
+ // Editing operations
+ messages.push_back(InputMsg_Undo(kTestRoutingID));
+ messages.push_back(InputMsg_Redo(kTestRoutingID));
+ messages.push_back(InputMsg_Cut(kTestRoutingID));
+ messages.push_back(InputMsg_Copy(kTestRoutingID));
+#if defined(OS_MACOSX)
+ messages.push_back(InputMsg_CopyToFindPboard(kTestRoutingID));
+#endif
+ messages.push_back(InputMsg_Paste(kTestRoutingID));
+ messages.push_back(InputMsg_PasteAndMatchStyle(kTestRoutingID));
+ messages.push_back(InputMsg_Delete(kTestRoutingID));
+ messages.push_back(InputMsg_Replace(kTestRoutingID, string16()));
+ messages.push_back(InputMsg_ReplaceMisspelling(kTestRoutingID,
+ string16()));
+ messages.push_back(InputMsg_Delete(kTestRoutingID));
+ messages.push_back(InputMsg_SelectAll(kTestRoutingID));
+ messages.push_back(InputMsg_Unselect(kTestRoutingID));
+ messages.push_back(InputMsg_SelectRange(kTestRoutingID,
+ gfx::Point(), gfx::Point()));
+ messages.push_back(InputMsg_MoveCaret(kTestRoutingID, gfx::Point()));
+
+ messages.push_back(InputMsg_HandleInputEvent(kTestRoutingID,
+ &mouse_up,
+ false));
+ AddMessagesToFilter(filter_, messages);
+
+ // We should have sent all messages back to the main thread and preserved
+ // their relative order.
+ ASSERT_EQ(message_recorder_.message_count(), messages.size());
+ for (size_t i = 0; i < messages.size(); ++i) {
+ EXPECT_EQ(message_recorder_.message_at(i).type(), messages[i].type()) << i;
+ }
}
} // namespace content
diff --git a/content/renderer/gpu/mailbox_output_surface.cc b/content/renderer/gpu/mailbox_output_surface.cc
index 6a35548..936f466 100644
--- a/content/renderer/gpu/mailbox_output_surface.cc
+++ b/content/renderer/gpu/mailbox_output_surface.cc
@@ -15,25 +15,39 @@
using cc::CompositorFrame;
using cc::GLFrameData;
using gpu::Mailbox;
-using WebKit::WebGraphicsContext3D;
namespace content {
MailboxOutputSurface::MailboxOutputSurface(
int32 routing_id,
- WebGraphicsContext3D* context3D,
+ WebGraphicsContext3DCommandBufferImpl* context3D,
cc::SoftwareOutputDevice* software_device)
: CompositorOutputSurface(routing_id, context3D, software_device),
fbo_(0),
is_backbuffer_discarded_(false) {
pending_textures_.push_back(TransferableFrame());
+ capabilities_.max_frames_pending = 1;
}
MailboxOutputSurface::~MailboxOutputSurface() {
DiscardBackbuffer();
+ DCHECK(!pending_textures_.empty());
+ bool cleared_errors = false;
while (!pending_textures_.empty()) {
- if (pending_textures_.front().texture_id)
+ TransferableFrame& frame = pending_textures_.front();
+ if (frame.texture_id) {
+ // TODO: crbug.com/230137 - make workaround obsolete with refcounting.
+ if (!cleared_errors) {
+ GLuint error;
+ while ((error = context3d_->getError()) != GL_NO_ERROR)
+ LOG(ERROR) << "Pending GL error during surface tear-down: " << error;
+ cleared_errors = true;
+ }
+ frame.sync_point = 0;
+ ConsumeTexture(frame); // Don't let the texture leak in the mailbox.
+ context3d_->getError(); // Clear error if mailbox was empty.
context3d_->deleteTexture(pending_textures_.front().texture_id);
+ }
pending_textures_.pop_front();
}
}
@@ -130,10 +144,7 @@
context3d_->framebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
-// TODO(sievers): Remove ifdef (crbug.com/222018)
-#ifndef NDEBUG
context3d_->bindFramebuffer(GL_FRAMEBUFFER, 0);
-#endif
context3d_->bindTexture(GL_TEXTURE_2D, current_backing_.texture_id);
context3d_->produceTextureCHROMIUM(
GL_TEXTURE_2D, current_backing_.mailbox.name);
@@ -186,15 +197,16 @@
CompositorOutputSurface::OnSwapAck(ack);
}
-void MailboxOutputSurface::SwapBuffers() {
+void MailboxOutputSurface::SwapBuffers(const cc::LatencyInfo&) {
}
-void MailboxOutputSurface::PostSubBuffer(gfx::Rect rect) {
+void MailboxOutputSurface::PostSubBuffer(gfx::Rect rect,
+ const cc::LatencyInfo&) {
NOTIMPLEMENTED()
<< "Partial swap not supported with composite-to-mailbox yet.";
// The browser only copies damage correctly for two buffers in use.
- DCHECK(GetNumAcksPending() < 3);
+ DCHECK(GetNumAcksPending() < 2);
}
void MailboxOutputSurface::ConsumeTexture(const TransferableFrame& frame) {
diff --git a/content/renderer/gpu/mailbox_output_surface.h b/content/renderer/gpu/mailbox_output_surface.h
index 1ad755f..7c159be 100644
--- a/content/renderer/gpu/mailbox_output_surface.h
+++ b/content/renderer/gpu/mailbox_output_surface.h
@@ -24,7 +24,7 @@
class MailboxOutputSurface : public CompositorOutputSurface {
public:
MailboxOutputSurface(int32 routing_id,
- WebKit::WebGraphicsContext3D* context3d,
+ WebGraphicsContext3DCommandBufferImpl* context3d,
cc::SoftwareOutputDevice* software);
virtual ~MailboxOutputSurface();
@@ -34,8 +34,8 @@
virtual void DiscardBackbuffer() OVERRIDE;
virtual void Reshape(gfx::Size size) OVERRIDE;
virtual void BindFramebuffer() OVERRIDE;
- virtual void PostSubBuffer(gfx::Rect rect) OVERRIDE;
- virtual void SwapBuffers() OVERRIDE;
+ virtual void PostSubBuffer(gfx::Rect rect, const cc::LatencyInfo&) OVERRIDE;
+ virtual void SwapBuffers(const cc::LatencyInfo&) OVERRIDE;
private:
// CompositorOutputSurface overrides.
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index b5f5f9d..6c59463 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -89,6 +89,9 @@
settings.accelerate_painting =
cmd->HasSwitch(switches::kEnableAcceleratedPainting);
settings.render_vsync_enabled = !cmd->HasSwitch(switches::kDisableGpuVsync);
+ settings.render_vsync_notification_enabled =
+ cmd->HasSwitch(switches::kEnableVsyncNotification);
+ settings.synchronously_disable_vsync = widget->SynchronouslyDisableVSync();
settings.per_tile_painting_enabled =
cmd->HasSwitch(cc::switches::kEnablePerTilePainting);
settings.accelerated_animation_enabled =
@@ -126,10 +129,8 @@
settings.right_aligned_scheduling_enabled =
cmd->HasSwitch(cc::switches::kEnableRightAlignedScheduling);
settings.impl_side_painting = cc::switches::IsImplSidePaintingEnabled();
- settings.use_cheapness_estimator =
- !cmd->HasSwitch(cc::switches::kDisableCheapnessEstimator);
settings.use_color_estimator =
- cmd->HasSwitch(cc::switches::kUseColorEstimator);
+ !cmd->HasSwitch(cc::switches::kDisableColorEstimator);
settings.prediction_benchmarking =
cmd->HasSwitch(cc::switches::kEnablePredictionBenchmarking);
@@ -180,6 +181,11 @@
settings.show_overdraw_in_tracing =
cmd->HasSwitch(cc::switches::kTraceOverdraw);
+#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS)
+ settings.use_pinch_zoom_scrollbars =
+ cmd->HasSwitch(cc::switches::kEnablePinchZoomScrollbars);
+#endif
+
// These flags should be mirrored by UI versions in ui/compositor/.
settings.initial_debug_state.show_debug_borders =
cmd->HasSwitch(cc::switches::kShowCompositedLayerBorders);
@@ -237,6 +243,30 @@
&settings.low_res_contents_scale_factor);
}
+ if (cmd->HasSwitch(cc::switches::kMaxTilesForInterestArea)) {
+ int max_tiles_for_interest_area;
+ if (GetSwitchValueAsInt(*cmd,
+ cc::switches::kMaxTilesForInterestArea,
+ 1, std::numeric_limits<int>::max(),
+ &max_tiles_for_interest_area))
+ settings.max_tiles_for_interest_area = max_tiles_for_interest_area;
+ }
+
+ if (cmd->HasSwitch(cc::switches::kMaxUnusedResourceMemoryUsagePercentage)) {
+ int max_unused_resource_memory_percentage;
+ if (GetSwitchValueAsInt(
+ *cmd,
+ cc::switches::kMaxUnusedResourceMemoryUsagePercentage,
+ 0, 100,
+ &max_unused_resource_memory_percentage)) {
+ settings.max_unused_resource_memory_percentage =
+ max_unused_resource_memory_percentage;
+ }
+ }
+
+ settings.strict_layer_property_change_checking =
+ cmd->HasSwitch(cc::switches::kStrictLayerPropertyChangeChecking);
+
#if defined(OS_ANDROID)
// TODO(danakj): Move these to the android code.
settings.can_use_lcd_text = false;
@@ -245,6 +275,7 @@
settings.solid_color_scrollbars = true;
settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128);
settings.solid_color_scrollbar_thickness_dip = 3;
+ settings.highp_threshold_min = 2048;
#endif
if (!compositor->initialize(settings))
@@ -281,6 +312,10 @@
layer_tree_host_->Composite(frame_begin_time);
}
+void RenderWidgetCompositor::SetNeedsDisplayOnAllLayers() {
+ layer_tree_host_->SetNeedsDisplayOnAllLayers();
+}
+
void RenderWidgetCompositor::GetRenderingStats(cc::RenderingStats* stats) {
layer_tree_host_->CollectRenderingStats(stats);
}
@@ -289,8 +324,12 @@
return layer_tree_host_->CapturePicture();
}
-void RenderWidgetCompositor::EnableHidingTopControls(bool enable) {
- layer_tree_host_->EnableHidingTopControls(enable);
+void RenderWidgetCompositor::UpdateTopControlsState(bool enable_hiding,
+ bool enable_showing,
+ bool animate) {
+ layer_tree_host_->UpdateTopControlsState(enable_hiding,
+ enable_showing,
+ animate);
}
void RenderWidgetCompositor::SetOverdrawBottomHeight(
@@ -298,6 +337,10 @@
layer_tree_host_->SetOverdrawBottomHeight(overdraw_bottom_height);
}
+void RenderWidgetCompositor::SetNeedsRedrawRect(gfx::Rect damage_rect) {
+ layer_tree_host_->SetNeedsRedrawRect(damage_rect);
+}
+
bool RenderWidgetCompositor::initialize(cc::LayerTreeSettings settings) {
scoped_ptr<cc::Thread> impl_thread;
scoped_refptr<base::MessageLoopProxy> compositor_message_loop_proxy =
@@ -327,13 +370,13 @@
}
void RenderWidgetCompositor::setViewportSize(
- const WebSize& layout_viewport_size,
+ const WebSize&,
const WebSize& device_viewport_size) {
- layer_tree_host_->SetViewportSize(layout_viewport_size, device_viewport_size);
+ layer_tree_host_->SetViewportSize(device_viewport_size);
}
WebSize RenderWidgetCompositor::layoutViewportSize() const {
- return layer_tree_host_->layout_viewport_size();
+ return layer_tree_host_->device_viewport_size();
}
WebSize RenderWidgetCompositor::deviceViewportSize() const {
@@ -479,8 +522,9 @@
widget_->webwidget()->didExitCompositingMode();
}
-scoped_ptr<cc::InputHandler> RenderWidgetCompositor::CreateInputHandler() {
- scoped_ptr<cc::InputHandler> ret;
+scoped_ptr<cc::InputHandlerClient>
+RenderWidgetCompositor::CreateInputHandlerClient() {
+ scoped_ptr<cc::InputHandlerClient> ret;
scoped_ptr<WebKit::WebInputHandler> web_handler(
widget_->webwidget()->createInputHandler());
if (web_handler)
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h
index de68d4a..ecb9f57 100644
--- a/content/renderer/gpu/render_widget_compositor.h
+++ b/content/renderer/gpu/render_widget_compositor.h
@@ -11,6 +11,7 @@
#include "cc/trees/layer_tree_settings.h"
#include "skia/ext/refptr.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebLayerTreeView.h"
+#include "ui/gfx/rect.h"
class SkPicture;
@@ -33,17 +34,21 @@
void SetSuppressScheduleComposite(bool suppress);
void Animate(base::TimeTicks time);
void Composite(base::TimeTicks frame_begin_time);
+ void SetNeedsDisplayOnAllLayers();
void GetRenderingStats(cc::RenderingStats* stats);
skia::RefPtr<SkPicture> CapturePicture();
- void EnableHidingTopControls(bool enable);
+ void UpdateTopControlsState(bool enable_hiding,
+ bool enable_showing,
+ bool animate);
void SetOverdrawBottomHeight(float overdraw_bottom_height);
+ void SetNeedsRedrawRect(gfx::Rect damage_rect);
// WebLayerTreeView implementation.
virtual void setSurfaceReady();
virtual void setRootLayer(const WebKit::WebLayer& layer);
virtual void clearRootLayer();
virtual void setViewportSize(
- const WebKit::WebSize& layout_viewport_size,
+ const WebKit::WebSize& unused_deprecated,
const WebKit::WebSize& device_viewport_size);
virtual WebKit::WebSize layoutViewportSize() const;
virtual WebKit::WebSize deviceViewportSize() const;
@@ -84,7 +89,8 @@
float page_scale) OVERRIDE;
virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface() OVERRIDE;
virtual void DidRecreateOutputSurface(bool success) OVERRIDE;
- virtual scoped_ptr<cc::InputHandler> CreateInputHandler() OVERRIDE;
+ virtual scoped_ptr<cc::InputHandlerClient> CreateInputHandlerClient()
+ OVERRIDE;
virtual void WillCommit() OVERRIDE;
virtual void DidCommit() OVERRIDE;
virtual void DidCommitAndDrawFrame() OVERRIDE;
@@ -109,4 +115,3 @@
} // namespace content
#endif // CONTENT_RENDERER_GPU_RENDER_WIDGET_COMPOSITOR_H_
-
diff --git a/content/renderer/gpu/stream_texture_host_android.cc b/content/renderer/gpu/stream_texture_host_android.cc
index a924ddc..f3de1f0 100644
--- a/content/renderer/gpu/stream_texture_host_android.cc
+++ b/content/renderer/gpu/stream_texture_host_android.cc
@@ -16,7 +16,7 @@
stream_id_(0),
listener_(NULL),
channel_(channel),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
+ weak_ptr_factory_(this) {
DCHECK(channel);
}
@@ -53,7 +53,7 @@
}
void StreamTextureHost::EstablishPeer(int32 primary_id, int32 secondary_id) {
- if (channel_.get()) {
+ if (channel_) {
channel_->Send(new GpuChannelMsg_EstablishStreamTexture(
stream_id_, primary_id, secondary_id));
}
diff --git a/content/renderer/hyphenator/hyphenator.cc b/content/renderer/hyphenator/hyphenator.cc
index ae60fd8..564fe46 100644
--- a/content/renderer/hyphenator/hyphenator.cc
+++ b/content/renderer/hyphenator/hyphenator.cc
@@ -24,7 +24,7 @@
// times. This class incrementally counts the number of converted UTF-16
// characters to avoid this problem.
//
-// scoped_array<size_t> position(new size_t[text.length()]);
+// scoped_ptr<size_t[]> position(new size_t[text.length()]);
// for (size_t i = 0; i < text.length(); ++i)
// position[i] = UTF8ToUTF16(text.substr(0, i)).length();
//
@@ -98,7 +98,7 @@
std::string word_utf8_;
// Return variables from the hyphen library.
- scoped_array<char> hyphen_vector_;
+ scoped_ptr<char[]> hyphen_vector_;
char** rep_;
int* pos_;
int* cut_;
diff --git a/content/renderer/idle_user_detector.cc b/content/renderer/idle_user_detector.cc
index 1831fa9..6d5200c 100644
--- a/content/renderer/idle_user_detector.cc
+++ b/content/renderer/idle_user_detector.cc
@@ -5,7 +5,7 @@
#include "content/renderer/idle_user_detector.h"
#include "base/logging.h"
-#include "content/common/view_messages.h"
+#include "content/common/input_messages.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/renderer/render_thread_impl.h"
@@ -20,7 +20,7 @@
bool IdleUserDetector::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(IdleUserDetector, message)
- IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent)
+ IPC_MESSAGE_HANDLER(InputMsg_HandleInputEvent, OnHandleInputEvent)
IPC_END_MESSAGE_MAP()
return false;
}
diff --git a/content/renderer/image_loading_helper.cc b/content/renderer/image_loading_helper.cc
new file mode 100644
index 0000000..ff6e2bd
--- /dev/null
+++ b/content/renderer/image_loading_helper.cc
@@ -0,0 +1,127 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/image_loading_helper.h"
+
+#include "base/bind.h"
+#include "base/message_loop.h"
+#include "content/common/image_messages.h"
+#include "content/public/common/url_constants.h"
+#include "content/public/renderer/render_view.h"
+#include "net/base/data_url.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebURLRequest.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
+#include "ui/gfx/favicon_size.h"
+#include "ui/gfx/size.h"
+#include "ui/gfx/skbitmap_operations.h"
+#include "webkit/glue/image_decoder.h"
+#include "webkit/glue/multi_resolution_image_resource_fetcher.h"
+#include "webkit/glue/webkit_glue.h"
+
+using WebKit::WebFrame;
+using WebKit::WebVector;
+using WebKit::WebURL;
+using WebKit::WebURLRequest;
+using webkit_glue::MultiResolutionImageResourceFetcher;
+
+namespace content {
+
+ImageLoadingHelper::ImageLoadingHelper(RenderView* render_view)
+ : RenderViewObserver(render_view) {
+}
+
+ImageLoadingHelper::~ImageLoadingHelper() {
+}
+
+void ImageLoadingHelper::OnDownloadImage(int id,
+ const GURL& image_url,
+ bool is_favicon,
+ int image_size) {
+ std::vector<SkBitmap> result_images;
+ if (image_url.SchemeIs(chrome::kDataScheme)) {
+ SkBitmap data_image = ImageFromDataUrl(image_url);
+ if (!data_image.empty())
+ result_images.push_back(data_image);
+ } else {
+ if (DownloadImage(id, image_url, is_favicon, image_size)) {
+ // Will complete asynchronously via ImageLoadingHelper::DidDownloadImage
+ return;
+ }
+ }
+
+ Send(new ImageHostMsg_DidDownloadImage(routing_id(),
+ id,
+ image_url,
+ image_size,
+ result_images));
+}
+
+bool ImageLoadingHelper::DownloadImage(int id,
+ const GURL& image_url,
+ bool is_favicon,
+ int image_size) {
+ // Make sure webview was not shut down.
+ if (!render_view()->GetWebView())
+ return false;
+ // Create an image resource fetcher and assign it with a call back object.
+ image_fetchers_.push_back(new MultiResolutionImageResourceFetcher(
+ image_url,
+ render_view()->GetWebView()->mainFrame(),
+ id,
+ is_favicon ? WebURLRequest::TargetIsFavicon :
+ WebURLRequest::TargetIsImage,
+ base::Bind(&ImageLoadingHelper::DidDownloadImage,
+ base::Unretained(this), image_size)));
+ return true;
+}
+
+void ImageLoadingHelper::DidDownloadImage(
+ int requested_size,
+ MultiResolutionImageResourceFetcher* fetcher,
+ const std::vector<SkBitmap>& images) {
+ // Notify requester of image download status.
+ Send(new ImageHostMsg_DidDownloadImage(routing_id(),
+ fetcher->id(),
+ fetcher->image_url(),
+ requested_size,
+ images));
+
+ // Remove the image fetcher from our pending list. We're in the callback from
+ // MultiResolutionImageResourceFetcher, best to delay deletion.
+ ImageResourceFetcherList::iterator iter =
+ std::find(image_fetchers_.begin(), image_fetchers_.end(), fetcher);
+ if (iter != image_fetchers_.end()) {
+ image_fetchers_.weak_erase(iter);
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, fetcher);
+ }
+}
+
+SkBitmap ImageLoadingHelper::ImageFromDataUrl(const GURL& url) const {
+ std::string mime_type, char_set, data;
+ if (net::DataURL::Parse(url, &mime_type, &char_set, &data) && !data.empty()) {
+ // Decode the image using WebKit's image decoder.
+ webkit_glue::ImageDecoder decoder(
+ gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize));
+ const unsigned char* src_data =
+ reinterpret_cast<const unsigned char*>(&data[0]);
+
+ return decoder.Decode(src_data, data.size());
+ }
+ return SkBitmap();
+}
+
+bool ImageLoadingHelper::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(ImageLoadingHelper, message)
+ IPC_MESSAGE_HANDLER(ImageMsg_DownloadImage, OnDownloadImage)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+
+ return handled;
+}
+
+} // namespace content
+
diff --git a/content/renderer/image_loading_helper.h b/content/renderer/image_loading_helper.h
new file mode 100644
index 0000000..6e2302d
--- /dev/null
+++ b/content/renderer/image_loading_helper.h
@@ -0,0 +1,77 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_IMAGE_LOADING_HELPER_H_
+#define CONTENT_RENDERER_IMAGE_LOADING_HELPER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/memory/scoped_vector.h"
+#include "content/public/renderer/render_view_observer.h"
+#include "googleurl/src/gurl.h"
+
+class SkBitmap;
+
+namespace webkit_glue {
+class MultiResolutionImageResourceFetcher;
+}
+
+namespace content {
+
+// This class deals with image downloading.
+// One instance of ImageLoadingHelper is owned by RenderView.
+class ImageLoadingHelper : public RenderViewObserver {
+ public:
+ explicit ImageLoadingHelper(RenderView* render_view);
+
+ private:
+ virtual ~ImageLoadingHelper();
+
+ // Message handler.
+ void OnDownloadImage(int id,
+ const GURL& image_url,
+ bool is_favicon,
+ int image_size);
+
+ // Requests to download an image. When done, the ImageLoadingHelper
+ // is notified by way of DidDownloadImage. Returns true if the
+ // request was successfully started, false otherwise. id is used to
+ // uniquely identify the request and passed back to the
+ // DidDownloadImage method. If the image is a favicon, cookies will not be
+ // sent nor accepted during download. If the image has multiple frames, the
+ // frame whose size is image_size is returned. If the image doesn't
+ // have a frame at the specified size, the first is returned.
+ bool DownloadImage(int id,
+ const GURL& image_url,
+ bool is_favicon,
+ int image_size);
+
+ // This callback is triggered when DownloadImage completes, either
+ // succesfully or with a failure. See DownloadImage for more
+ // details.
+ void DidDownloadImage(
+ int requested_size,
+ webkit_glue::MultiResolutionImageResourceFetcher* fetcher,
+ const std::vector<SkBitmap>& images);
+
+ // Decodes a data: URL image or returns an empty image in case of failure.
+ SkBitmap ImageFromDataUrl(const GURL&) const;
+
+ // RenderViewObserver implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+
+ typedef ScopedVector<webkit_glue::MultiResolutionImageResourceFetcher>
+ ImageResourceFetcherList;
+
+ // ImageResourceFetchers schedule via DownloadImage.
+ ImageResourceFetcherList image_fetchers_;
+
+ DISALLOW_COPY_AND_ASSIGN(ImageLoadingHelper);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_IMAGE_LOADING_HELPER_H_
+
diff --git a/content/renderer/internal_document_state_data.cc b/content/renderer/internal_document_state_data.cc
new file mode 100644
index 0000000..d5da984
--- /dev/null
+++ b/content/renderer/internal_document_state_data.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/internal_document_state_data.h"
+
+#include "content/public/common/password_form.h"
+#include "content/public/renderer/document_state.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
+#include "webkit/glue/alt_error_page_resource_fetcher.h"
+
+namespace content {
+
+namespace {
+
+// Key InternalDocumentStateData is stored under in DocumentState.
+const char kUserDataKey[] = "InternalDocumentStateData";
+
+}
+
+InternalDocumentStateData::InternalDocumentStateData()
+ : did_first_visually_non_empty_layout_(false),
+ did_first_visually_non_empty_paint_(false),
+ http_status_code_(0),
+ use_error_page_(false),
+ is_overriding_user_agent_(false),
+ must_reset_scroll_and_scale_state_(false),
+ cache_policy_override_set_(false),
+ cache_policy_override_(WebKit::WebURLRequest::UseProtocolCachePolicy),
+ referrer_policy_set_(false),
+ referrer_policy_(WebKit::WebReferrerPolicyDefault) {
+}
+
+// static
+InternalDocumentStateData* InternalDocumentStateData::FromDataSource(
+ WebKit::WebDataSource* ds) {
+ return FromDocumentState(static_cast<DocumentState*>(ds->extraData()));
+}
+
+// static
+InternalDocumentStateData* InternalDocumentStateData::FromDocumentState(
+ DocumentState* ds) {
+ if (!ds)
+ return NULL;
+ InternalDocumentStateData* data = static_cast<InternalDocumentStateData*>(
+ ds->GetUserData(&kUserDataKey));
+ if (!data) {
+ data = new InternalDocumentStateData;
+ ds->SetUserData(&kUserDataKey, data);
+ }
+ return data;
+}
+
+InternalDocumentStateData::~InternalDocumentStateData() {
+}
+
+void InternalDocumentStateData::set_alt_error_page_fetcher(
+ webkit_glue::AltErrorPageResourceFetcher* f) {
+ alt_error_page_fetcher_.reset(f);
+}
+
+} // namespace content
diff --git a/content/renderer/internal_document_state_data.h b/content/renderer/internal_document_state_data.h
new file mode 100644
index 0000000..08ca357
--- /dev/null
+++ b/content/renderer/internal_document_state_data.h
@@ -0,0 +1,154 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_INTERNAL_DOCUMENT_STATE_DATA_H_
+#define CONTENT_RENDERER_INTERNAL_DOCUMENT_STATE_DATA_H_
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/supports_user_data.h"
+#include "googleurl/src/gurl.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebReferrerPolicy.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebURLRequest.h"
+
+namespace webkit_glue {
+class AltErrorPageResourceFetcher;
+}
+
+namespace WebKit {
+class WebDataSource;
+}
+
+namespace content {
+
+class DocumentState;
+
+// Stores internal state per WebDataSource.
+class InternalDocumentStateData : public base::SupportsUserData::Data {
+ public:
+ InternalDocumentStateData();
+
+ static InternalDocumentStateData* FromDataSource(WebKit::WebDataSource* ds);
+ static InternalDocumentStateData* FromDocumentState(DocumentState* ds);
+
+ // Set to true once RenderViewImpl::didFirstVisuallyNonEmptyLayout() is
+ // invoked.
+ bool did_first_visually_non_empty_layout() const {
+ return did_first_visually_non_empty_layout_;
+ }
+ void set_did_first_visually_non_empty_layout(bool value) {
+ did_first_visually_non_empty_layout_ = value;
+ }
+
+ // Set to true once RenderViewImpl::DidFlushPaint() is inovked after
+ // RenderViewImpl::didFirstVisuallyNonEmptyLayout(). In other words after the
+ // page has painted something.
+ bool did_first_visually_non_empty_paint() const {
+ return did_first_visually_non_empty_paint_;
+ }
+ void set_did_first_visually_non_empty_paint(bool value) {
+ did_first_visually_non_empty_paint_ = value;
+ }
+
+ int http_status_code() const { return http_status_code_; }
+ void set_http_status_code(int http_status_code) {
+ http_status_code_ = http_status_code;
+ }
+
+ const GURL& searchable_form_url() const { return searchable_form_url_; }
+ void set_searchable_form_url(const GURL& url) { searchable_form_url_ = url; }
+ const std::string& searchable_form_encoding() const {
+ return searchable_form_encoding_;
+ }
+ void set_searchable_form_encoding(const std::string& encoding) {
+ searchable_form_encoding_ = encoding;
+ }
+
+ // True if an error page should be used, if the http status code also
+ // indicates an error.
+ bool use_error_page() const { return use_error_page_; }
+ void set_use_error_page(bool use_error_page) {
+ use_error_page_ = use_error_page;
+ }
+
+ // True if the user agent was overridden for this page.
+ bool is_overriding_user_agent() const { return is_overriding_user_agent_; }
+ void set_is_overriding_user_agent(bool state) {
+ is_overriding_user_agent_ = state;
+ }
+
+ // True if we have to reset the scroll and scale state of the page
+ // after the provisional load has been committed.
+ bool must_reset_scroll_and_scale_state() const {
+ return must_reset_scroll_and_scale_state_;
+ }
+ void set_must_reset_scroll_and_scale_state(bool state) {
+ must_reset_scroll_and_scale_state_ = state;
+ }
+
+ // Sets the cache policy. The cache policy is only used if explicitly set and
+ // by default is not set. You can mark a NavigationState as not having a cache
+ // state by way of clear_cache_policy_override.
+ void set_cache_policy_override(
+ WebKit::WebURLRequest::CachePolicy cache_policy) {
+ cache_policy_override_ = cache_policy;
+ cache_policy_override_set_ = true;
+ }
+ WebKit::WebURLRequest::CachePolicy cache_policy_override() const {
+ return cache_policy_override_;
+ }
+ void clear_cache_policy_override() {
+ cache_policy_override_set_ = false;
+ cache_policy_override_ = WebKit::WebURLRequest::UseProtocolCachePolicy;
+ }
+ bool is_cache_policy_override_set() const {
+ return cache_policy_override_set_;
+ }
+
+ // Sets the referrer policy to use. This is only used for browser initiated
+ // navigations, otherwise, the referrer policy is defined by the frame's
+ // document.
+ WebKit::WebReferrerPolicy referrer_policy() const {
+ return referrer_policy_;
+ }
+ void set_referrer_policy(WebKit::WebReferrerPolicy referrer_policy) {
+ referrer_policy_ = referrer_policy;
+ referrer_policy_set_ = true;
+ }
+ void clear_referrer_policy() {
+ referrer_policy_ = WebKit::WebReferrerPolicyDefault;
+ referrer_policy_set_ = false;
+ }
+ bool is_referrer_policy_set() const { return referrer_policy_set_; }
+
+ webkit_glue::AltErrorPageResourceFetcher* alt_error_page_fetcher() const {
+ return alt_error_page_fetcher_.get();
+ }
+ void set_alt_error_page_fetcher(webkit_glue::AltErrorPageResourceFetcher* f);
+
+ protected:
+ virtual ~InternalDocumentStateData();
+
+ private:
+ bool did_first_visually_non_empty_layout_;
+ bool did_first_visually_non_empty_paint_;
+ int http_status_code_;
+ GURL searchable_form_url_;
+ std::string searchable_form_encoding_;
+ bool use_error_page_;
+ bool is_overriding_user_agent_;
+ bool must_reset_scroll_and_scale_state_;
+ bool cache_policy_override_set_;
+ WebKit::WebURLRequest::CachePolicy cache_policy_override_;
+ bool referrer_policy_set_;
+ WebKit::WebReferrerPolicy referrer_policy_;
+ scoped_ptr<webkit_glue::AltErrorPageResourceFetcher> alt_error_page_fetcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(InternalDocumentStateData);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_INTERNAL_DOCUMENT_STATE_DATA_H_
diff --git a/content/renderer/java/java_bridge_dispatcher.cc b/content/renderer/java/java_bridge_dispatcher.cc
index 30039aa..04802df 100644
--- a/content/renderer/java/java_bridge_dispatcher.cc
+++ b/content/renderer/java/java_bridge_dispatcher.cc
@@ -22,7 +22,7 @@
}
bool JavaBridgeDispatcher::EnsureChannelIsSetUp() {
- if (channel_.get()) {
+ if (channel_) {
return true;
}
diff --git a/content/renderer/load_progress_tracker.cc b/content/renderer/load_progress_tracker.cc
index 0e7b07d..93b79ed 100644
--- a/content/renderer/load_progress_tracker.cc
+++ b/content/renderer/load_progress_tracker.cc
@@ -20,7 +20,7 @@
: render_view_(render_view),
tracked_frame_(NULL),
progress_(0.0),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ weak_factory_(this) {
}
LoadProgressTracker::~LoadProgressTracker() {
@@ -68,7 +68,7 @@
if (weak_factory_.HasWeakPtrs())
return;
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&LoadProgressTracker::SendChangeLoadProgress,
weak_factory_.GetWeakPtr()),
diff --git a/content/renderer/media/audio_device_factory.cc b/content/renderer/media/audio_device_factory.cc
index fae521e..927a85f 100644
--- a/content/renderer/media/audio_device_factory.cc
+++ b/content/renderer/media/audio_device_factory.cc
@@ -7,8 +7,8 @@
#include "base/logging.h"
#include "content/renderer/media/audio_input_message_filter.h"
#include "content/renderer/media/audio_message_filter.h"
-#include "content/renderer/media/renderer_audio_output_device.h"
#include "media/audio/audio_input_device.h"
+#include "media/audio/audio_output_device.h"
namespace content {
@@ -16,24 +16,33 @@
AudioDeviceFactory* AudioDeviceFactory::factory_ = NULL;
// static
-scoped_refptr<RendererAudioOutputDevice> AudioDeviceFactory::NewOutputDevice() {
- RendererAudioOutputDevice* device = NULL;
- if (factory_)
- device = factory_->CreateOutputDevice();
+scoped_refptr<media::AudioOutputDevice> AudioDeviceFactory::NewOutputDevice(
+ int render_view_id) {
+ if (factory_) {
+ media::AudioOutputDevice* const device =
+ factory_->CreateOutputDevice(render_view_id);
+ if (device)
+ return device;
+ }
- return device ? device : new RendererAudioOutputDevice(
- AudioMessageFilter::Get(), AudioMessageFilter::Get()->io_message_loop());
+ AudioMessageFilter* const filter = AudioMessageFilter::Get();
+ return new media::AudioOutputDevice(
+ filter->CreateAudioOutputIPC(render_view_id), filter->io_message_loop());
}
// static
-scoped_refptr<media::AudioInputDevice> AudioDeviceFactory::NewInputDevice() {
- media::AudioInputDevice* device = NULL;
- if (factory_)
- device = factory_->CreateInputDevice();
+scoped_refptr<media::AudioInputDevice> AudioDeviceFactory::NewInputDevice(
+ int render_view_id) {
+ if (factory_) {
+ media::AudioInputDevice* const device =
+ factory_->CreateInputDevice(render_view_id);
+ if (device)
+ return device;
+ }
- return device ? device : new media::AudioInputDevice(
- AudioInputMessageFilter::Get(),
- AudioInputMessageFilter::Get()->io_message_loop());
+ AudioInputMessageFilter* const filter = AudioInputMessageFilter::Get();
+ return new media::AudioInputDevice(
+ filter->CreateAudioInputIPC(render_view_id), filter->io_message_loop());
}
AudioDeviceFactory::AudioDeviceFactory() {
diff --git a/content/renderer/media/audio_device_factory.h b/content/renderer/media/audio_device_factory.h
index b06ace7..46bf5f9 100644
--- a/content/renderer/media/audio_device_factory.h
+++ b/content/renderer/media/audio_device_factory.h
@@ -10,22 +10,27 @@
namespace media {
class AudioInputDevice;
+class AudioOutputDevice;
}
namespace content {
-class RendererAudioOutputDevice;
-
-// A factory for creating RendererAudioOutputDevices. There is a global factory
-// function that can be installed for the purposes of testing to provide
-// a specialized AudioRendererSink class.
+// A factory for creating AudioOutputDevices and AudioInputDevices. There is a
+// global factory function that can be installed for the purposes of testing to
+// provide specialized implementations.
class AudioDeviceFactory {
public:
- // Creates a RendererAudioOutputDevice using the currently registered factory.
- static scoped_refptr<RendererAudioOutputDevice> NewOutputDevice();
+ // Creates an AudioOutputDevice using the currently registered factory.
+ // |render_view_id| refers to the render view containing the entity producing
+ // the audio.
+ static scoped_refptr<media::AudioOutputDevice> NewOutputDevice(
+ int render_view_id);
- // Creates an AudioInputDevice using the currently registered factory,
- static scoped_refptr<media::AudioInputDevice> NewInputDevice();
+ // Creates an AudioInputDevice using the currently registered factory.
+ // |render_view_id| refers to the render view containing the entity consuming
+ // the audio.
+ static scoped_refptr<media::AudioInputDevice> NewInputDevice(
+ int render_view_id);
protected:
AudioDeviceFactory();
@@ -35,8 +40,8 @@
// functions to provide alternate audio device implementations.
// If the return value of either of these function is NULL, we fall back
// on the default implementation.
- virtual RendererAudioOutputDevice* CreateOutputDevice() = 0;
- virtual media::AudioInputDevice* CreateInputDevice() = 0;
+ virtual media::AudioOutputDevice* CreateOutputDevice(int render_view_id) = 0;
+ virtual media::AudioInputDevice* CreateInputDevice(int render_view_id) = 0;
private:
// The current globally registered factory. This is NULL when we should
diff --git a/content/renderer/media/audio_input_message_filter.cc b/content/renderer/media/audio_input_message_filter.cc
index 038edf3..2b78e2c 100644
--- a/content/renderer/media/audio_input_message_filter.cc
+++ b/content/renderer/media/audio_input_message_filter.cc
@@ -11,24 +11,51 @@
namespace content {
-AudioInputMessageFilter* AudioInputMessageFilter::filter_ = NULL;
+namespace {
+const int kStreamIDNotSet = -1;
+}
+
+class AudioInputMessageFilter::AudioInputIPCImpl
+ : public NON_EXPORTED_BASE(media::AudioInputIPC) {
+ public:
+ AudioInputIPCImpl(const scoped_refptr<AudioInputMessageFilter>& filter,
+ int render_view_id);
+ virtual ~AudioInputIPCImpl();
+
+ // media::AudioInputIPC implementation.
+ virtual void CreateStream(media::AudioInputIPCDelegate* delegate,
+ int session_id,
+ const media::AudioParameters& params,
+ bool automatic_gain_control,
+ uint32 total_segments) OVERRIDE;
+ virtual void RecordStream() OVERRIDE;
+ virtual void SetVolume(double volume) OVERRIDE;
+ virtual void CloseStream() OVERRIDE;
+
+ private:
+ const scoped_refptr<AudioInputMessageFilter> filter_;
+ const int render_view_id_;
+ int stream_id_;
+};
+
+AudioInputMessageFilter* AudioInputMessageFilter::g_filter = NULL;
AudioInputMessageFilter::AudioInputMessageFilter(
const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
: channel_(NULL),
io_message_loop_(io_message_loop) {
- DCHECK(!filter_);
- filter_ = this;
+ DCHECK(!g_filter);
+ g_filter = this;
}
AudioInputMessageFilter::~AudioInputMessageFilter() {
- DCHECK_EQ(filter_, this);
- filter_ = NULL;
+ DCHECK_EQ(g_filter, this);
+ g_filter = NULL;
}
-// static.
+// static
AudioInputMessageFilter* AudioInputMessageFilter::Get() {
- return filter_;
+ return g_filter;
}
void AudioInputMessageFilter::Send(IPC::Message* message) {
@@ -134,43 +161,56 @@
delegate->OnStateChanged(state);
}
-int AudioInputMessageFilter::AddDelegate(
- media::AudioInputIPCDelegate* delegate) {
- DCHECK(io_message_loop_->BelongsToCurrentThread());
- return delegates_.Add(delegate);
+AudioInputMessageFilter::AudioInputIPCImpl::AudioInputIPCImpl(
+ const scoped_refptr<AudioInputMessageFilter>& filter, int render_view_id)
+ : filter_(filter),
+ render_view_id_(render_view_id),
+ stream_id_(kStreamIDNotSet) {}
+
+AudioInputMessageFilter::AudioInputIPCImpl::~AudioInputIPCImpl() {}
+
+scoped_ptr<media::AudioInputIPC> AudioInputMessageFilter::CreateAudioInputIPC(
+ int render_view_id) {
+ DCHECK_GT(render_view_id, 0);
+ return scoped_ptr<media::AudioInputIPC>(
+ new AudioInputIPCImpl(this, render_view_id));
}
-void AudioInputMessageFilter::RemoveDelegate(int id) {
- DCHECK(io_message_loop_->BelongsToCurrentThread());
- delegates_.Remove(id);
+void AudioInputMessageFilter::AudioInputIPCImpl::CreateStream(
+ media::AudioInputIPCDelegate* delegate,
+ int session_id,
+ const media::AudioParameters& params,
+ bool automatic_gain_control,
+ uint32 total_segments) {
+ DCHECK(filter_->io_message_loop_->BelongsToCurrentThread());
+ DCHECK(delegate);
+
+ stream_id_ = filter_->delegates_.Add(delegate);
+
+ AudioInputHostMsg_CreateStream_Config config;
+ config.params = params;
+ config.automatic_gain_control = automatic_gain_control;
+ config.shared_memory_count = total_segments;
+ filter_->Send(new AudioInputHostMsg_CreateStream(
+ stream_id_, render_view_id_, session_id, config));
}
-void AudioInputMessageFilter::CreateStream(int stream_id,
- int session_id,
- const media::AudioParameters& params,
- bool automatic_gain_control,
- uint32 total_segments) {
- Send(new AudioInputHostMsg_CreateStream(
- stream_id, session_id, params, automatic_gain_control, total_segments));
-
+void AudioInputMessageFilter::AudioInputIPCImpl::RecordStream() {
+ DCHECK_NE(stream_id_, kStreamIDNotSet);
+ filter_->Send(new AudioInputHostMsg_RecordStream(stream_id_));
}
-void AudioInputMessageFilter::AssociateStreamWithConsumer(int stream_id,
- int render_view_id) {
- Send(new AudioInputHostMsg_AssociateStreamWithConsumer(
- stream_id, render_view_id));
+void AudioInputMessageFilter::AudioInputIPCImpl::SetVolume(double volume) {
+ DCHECK_NE(stream_id_, kStreamIDNotSet);
+ filter_->Send(new AudioInputHostMsg_SetVolume(stream_id_, volume));
}
-void AudioInputMessageFilter::RecordStream(int stream_id) {
- Send(new AudioInputHostMsg_RecordStream(stream_id));
-}
-
-void AudioInputMessageFilter::CloseStream(int stream_id) {
- Send(new AudioInputHostMsg_CloseStream(stream_id));
-}
-
-void AudioInputMessageFilter::SetVolume(int stream_id, double volume) {
- Send(new AudioInputHostMsg_SetVolume(stream_id, volume));
+void AudioInputMessageFilter::AudioInputIPCImpl::CloseStream() {
+ DCHECK(filter_->io_message_loop_->BelongsToCurrentThread());
+ DCHECK_NE(stream_id_, kStreamIDNotSet);
+ filter_->Send(new AudioInputHostMsg_CloseStream(stream_id_));
+ filter_->delegates_.Remove(stream_id_);
+ stream_id_ = kStreamIDNotSet;
}
} // namespace content
diff --git a/content/renderer/media/audio_input_message_filter.h b/content/renderer/media/audio_input_message_filter.h
index bd6a0e1..fcba0a7 100644
--- a/content/renderer/media/audio_input_message_filter.h
+++ b/content/renderer/media/audio_input_message_filter.h
@@ -6,6 +6,7 @@
#define CONTENT_RENDERER_MEDIA_AUDIO_INPUT_MESSAGE_FILTER_H_
#include "base/id_map.h"
+#include "base/memory/scoped_ptr.h"
#include "base/shared_memory.h"
#include "base/sync_socket.h"
#include "content/common/content_export.h"
@@ -23,8 +24,7 @@
// IO thread (secondary thread of render process), it intercepts audio messages
// and process them on IO thread since these messages are time critical.
class CONTENT_EXPORT AudioInputMessageFilter
- : public IPC::ChannelProxy::MessageFilter,
- public NON_EXPORTED_BASE(media::AudioInputIPC) {
+ : public IPC::ChannelProxy::MessageFilter {
public:
explicit AudioInputMessageFilter(
const scoped_refptr<base::MessageLoopProxy>& io_message_loop);
@@ -32,29 +32,22 @@
// Getter for the one AudioInputMessageFilter object.
static AudioInputMessageFilter* Get();
- // Associates |render_view_id| as the destination of audio for a stream.
- void AssociateStreamWithConsumer(int stream_id, int render_view_id);
-
- // Implementation of AudioInputIPC. All methods must be called on the
- // provided |io_message_loop|.
- virtual int AddDelegate(
- media::AudioInputIPCDelegate* delegate) OVERRIDE;
- virtual void RemoveDelegate(int id) OVERRIDE;
- virtual void CreateStream(
- int stream_id,
- int session_id,
- const media::AudioParameters& params,
- bool automatic_gain_control,
- uint32 total_segments) OVERRIDE;
- virtual void RecordStream(int stream_id) OVERRIDE;
- virtual void CloseStream(int stream_id) OVERRIDE;
- virtual void SetVolume(int stream_id, double volume) OVERRIDE;
+ // Create an AudioInputIPC to be owned by one delegate. |render_view_id| is
+ // the render view containing the entity consuming the audio.
+ //
+ // The returned object is not thread-safe, and must be used on
+ // |io_message_loop|.
+ scoped_ptr<media::AudioInputIPC> CreateAudioInputIPC(int render_view_id);
scoped_refptr<base::MessageLoopProxy> io_message_loop() const {
return io_message_loop_;
}
private:
+ // Implementation of media::AudioInputIPC which augments IPC calls with
+ // stream_id and the destination render_view_id.
+ class AudioInputIPCImpl;
+
virtual ~AudioInputMessageFilter();
// Sends an IPC message using |channel_|.
@@ -91,12 +84,12 @@
// IPC channel for Send(), must only be accesed on |io_message_loop_|.
IPC::Channel* channel_;
- // The singleton instance for this filter.
- static AudioInputMessageFilter* filter_;
-
// Message loop on which IPC calls are driven.
const scoped_refptr<base::MessageLoopProxy> io_message_loop_;
+ // The singleton instance for this filter.
+ static AudioInputMessageFilter* g_filter;
+
DISALLOW_COPY_AND_ASSIGN(AudioInputMessageFilter);
};
diff --git a/content/renderer/media/audio_message_filter.cc b/content/renderer/media/audio_message_filter.cc
index 11de086..1cb5352 100644
--- a/content/renderer/media/audio_message_filter.cc
+++ b/content/renderer/media/audio_message_filter.cc
@@ -12,60 +12,99 @@
namespace content {
-AudioMessageFilter* AudioMessageFilter::filter_ = NULL;
-
-// static
-AudioMessageFilter* AudioMessageFilter::Get() {
- return filter_;
+namespace {
+const int kStreamIDNotSet = -1;
}
+class AudioMessageFilter::AudioOutputIPCImpl
+ : public NON_EXPORTED_BASE(media::AudioOutputIPC) {
+ public:
+ AudioOutputIPCImpl(const scoped_refptr<AudioMessageFilter>& filter,
+ int render_view_id);
+ virtual ~AudioOutputIPCImpl();
+
+ // media::AudioOutputIPC implementation.
+ virtual void CreateStream(media::AudioOutputIPCDelegate* delegate,
+ const media::AudioParameters& params) OVERRIDE;
+ virtual void PlayStream() OVERRIDE;
+ virtual void PauseStream() OVERRIDE;
+ virtual void CloseStream() OVERRIDE;
+ virtual void SetVolume(double volume) OVERRIDE;
+
+ private:
+ const scoped_refptr<AudioMessageFilter> filter_;
+ const int render_view_id_;
+ int stream_id_;
+};
+
+AudioMessageFilter* AudioMessageFilter::g_filter = NULL;
+
AudioMessageFilter::AudioMessageFilter(
const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
: channel_(NULL),
audio_hardware_config_(NULL),
io_message_loop_(io_message_loop) {
- DCHECK(!filter_);
- filter_ = this;
+ DCHECK(!g_filter);
+ g_filter = this;
}
-int AudioMessageFilter::AddDelegate(media::AudioOutputIPCDelegate* delegate) {
- DCHECK(io_message_loop_->BelongsToCurrentThread());
- return delegates_.Add(delegate);
+AudioMessageFilter::~AudioMessageFilter() {
+ DCHECK_EQ(g_filter, this);
+ g_filter = NULL;
}
-void AudioMessageFilter::RemoveDelegate(int id) {
- DCHECK(io_message_loop_->BelongsToCurrentThread());
- delegates_.Remove(id);
+// static
+AudioMessageFilter* AudioMessageFilter::Get() {
+ return g_filter;
}
-void AudioMessageFilter::CreateStream(int stream_id,
- const media::AudioParameters& params) {
- Send(new AudioHostMsg_CreateStream(stream_id, params));
+AudioMessageFilter::AudioOutputIPCImpl::AudioOutputIPCImpl(
+ const scoped_refptr<AudioMessageFilter>& filter, int render_view_id)
+ : filter_(filter),
+ render_view_id_(render_view_id),
+ stream_id_(kStreamIDNotSet) {}
+
+AudioMessageFilter::AudioOutputIPCImpl::~AudioOutputIPCImpl() {}
+
+scoped_ptr<media::AudioOutputIPC> AudioMessageFilter::CreateAudioOutputIPC(
+ int render_view_id) {
+ DCHECK_GT(render_view_id, 0);
+ return scoped_ptr<media::AudioOutputIPC>(
+ new AudioOutputIPCImpl(this, render_view_id));
}
-void AudioMessageFilter::AssociateStreamWithProducer(int stream_id,
- int render_view_id) {
- Send(new AudioHostMsg_AssociateStreamWithProducer(stream_id, render_view_id));
+void AudioMessageFilter::AudioOutputIPCImpl::CreateStream(
+ media::AudioOutputIPCDelegate* delegate,
+ const media::AudioParameters& params) {
+ DCHECK(filter_->io_message_loop_->BelongsToCurrentThread());
+ DCHECK(delegate);
+ DCHECK_EQ(stream_id_, kStreamIDNotSet);
+ stream_id_ = filter_->delegates_.Add(delegate);
+ filter_->Send(new AudioHostMsg_CreateStream(
+ stream_id_, render_view_id_, params));
}
-void AudioMessageFilter::PlayStream(int stream_id) {
- Send(new AudioHostMsg_PlayStream(stream_id));
+void AudioMessageFilter::AudioOutputIPCImpl::PlayStream() {
+ DCHECK_NE(stream_id_, kStreamIDNotSet);
+ filter_->Send(new AudioHostMsg_PlayStream(stream_id_));
}
-void AudioMessageFilter::PauseStream(int stream_id) {
- Send(new AudioHostMsg_PauseStream(stream_id));
+void AudioMessageFilter::AudioOutputIPCImpl::PauseStream() {
+ DCHECK_NE(stream_id_, kStreamIDNotSet);
+ filter_->Send(new AudioHostMsg_PauseStream(stream_id_));
}
-void AudioMessageFilter::FlushStream(int stream_id) {
- Send(new AudioHostMsg_FlushStream(stream_id));
+void AudioMessageFilter::AudioOutputIPCImpl::CloseStream() {
+ DCHECK(filter_->io_message_loop_->BelongsToCurrentThread());
+ DCHECK_NE(stream_id_, kStreamIDNotSet);
+ filter_->Send(new AudioHostMsg_CloseStream(stream_id_));
+ filter_->delegates_.Remove(stream_id_);
+ stream_id_ = kStreamIDNotSet;
}
-void AudioMessageFilter::CloseStream(int stream_id) {
- Send(new AudioHostMsg_CloseStream(stream_id));
-}
-
-void AudioMessageFilter::SetVolume(int stream_id, double volume) {
- Send(new AudioHostMsg_SetVolume(stream_id, volume));
+void AudioMessageFilter::AudioOutputIPCImpl::SetVolume(double volume) {
+ DCHECK_NE(stream_id_, kStreamIDNotSet);
+ filter_->Send(new AudioHostMsg_SetVolume(stream_id_, volume));
}
void AudioMessageFilter::Send(IPC::Message* message) {
@@ -117,11 +156,6 @@
}
}
-AudioMessageFilter::~AudioMessageFilter() {
- DCHECK_EQ(filter_, this);
- filter_ = NULL;
-}
-
void AudioMessageFilter::OnStreamCreated(
int stream_id,
base::SharedMemoryHandle handle,
diff --git a/content/renderer/media/audio_message_filter.h b/content/renderer/media/audio_message_filter.h
index 7c352d6..38deb80 100644
--- a/content/renderer/media/audio_message_filter.h
+++ b/content/renderer/media/audio_message_filter.h
@@ -7,6 +7,7 @@
#include "base/gtest_prod_util.h"
#include "base/id_map.h"
+#include "base/memory/scoped_ptr.h"
#include "base/shared_memory.h"
#include "base/sync_socket.h"
#include "base/synchronization/lock.h"
@@ -26,8 +27,7 @@
// IO thread (secondary thread of render process) it intercepts audio messages
// and process them on IO thread since these messages are time critical.
class CONTENT_EXPORT AudioMessageFilter
- : public IPC::ChannelProxy::MessageFilter,
- public NON_EXPORTED_BASE(media::AudioOutputIPC) {
+ : public IPC::ChannelProxy::MessageFilter {
public:
explicit AudioMessageFilter(
const scoped_refptr<base::MessageLoopProxy>& io_message_loop);
@@ -35,27 +35,12 @@
// Getter for the one AudioMessageFilter object.
static AudioMessageFilter* Get();
- // Associates |render_view_id| as the source of audio rendered for a stream.
- void AssociateStreamWithProducer(int stream_id, int render_view_id);
-
- // media::AudioOutputIPC implementation.
- virtual int AddDelegate(media::AudioOutputIPCDelegate* delegate) OVERRIDE;
- virtual void RemoveDelegate(int id) OVERRIDE;
-
- // Methods below must be called on the provided |io_message_loop|.
- virtual void CreateStream(int stream_id,
- const media::AudioParameters& params) OVERRIDE;
- virtual void PlayStream(int stream_id) OVERRIDE;
- virtual void PauseStream(int stream_id) OVERRIDE;
- virtual void FlushStream(int stream_id) OVERRIDE;
- virtual void CloseStream(int stream_id) OVERRIDE;
- virtual void SetVolume(int stream_id, double volume) OVERRIDE;
-
- // IPC::ChannelProxy::MessageFilter override. Called on |io_message_loop|.
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
- virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE;
- virtual void OnFilterRemoved() OVERRIDE;
- virtual void OnChannelClosing() OVERRIDE;
+ // Create an AudioOutputIPC to be owned by one delegate. |render_view_id| is
+ // the render view containing the entity producing the audio.
+ //
+ // The returned object is not thread-safe, and must be used on
+ // |io_message_loop|.
+ scoped_ptr<media::AudioOutputIPC> CreateAudioOutputIPC(int render_view_id);
// When set, AudioMessageFilter will update the AudioHardwareConfig with new
// configuration values as recieved by OnOutputDeviceChanged(). The provided
@@ -74,9 +59,19 @@
FRIEND_TEST_ALL_PREFIXES(AudioMessageFilterTest, Basic);
FRIEND_TEST_ALL_PREFIXES(AudioMessageFilterTest, Delegates);
+ // Implementation of media::AudioOutputIPC which augments IPC calls with
+ // stream_id and the source render_view_id.
+ class AudioOutputIPCImpl;
+
// Sends an IPC message using |channel_|.
void Send(IPC::Message* message);
+ // IPC::ChannelProxy::MessageFilter override. Called on |io_message_loop|.
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+ virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE;
+ virtual void OnFilterRemoved() OVERRIDE;
+ virtual void OnChannelClosing() OVERRIDE;
+
// Received when browser process has created an audio output stream.
void OnStreamCreated(int stream_id, base::SharedMemoryHandle handle,
#if defined(OS_WIN)
@@ -95,9 +90,6 @@
void OnOutputDeviceChanged(int stream_id, int new_buffer_size,
int new_sample_rate);
- // The singleton instance for this filter.
- static AudioMessageFilter* filter_;
-
// IPC channel for Send(); must only be accesed on |io_message_loop_|.
IPC::Channel* channel_;
@@ -113,6 +105,9 @@
// Message loop on which IPC calls are driven.
const scoped_refptr<base::MessageLoopProxy> io_message_loop_;
+ // The singleton instance for this filter.
+ static AudioMessageFilter* g_filter;
+
DISALLOW_COPY_AND_ASSIGN(AudioMessageFilter);
};
diff --git a/content/renderer/media/audio_message_filter_unittest.cc b/content/renderer/media/audio_message_filter_unittest.cc
index 4626a64..81db84e 100644
--- a/content/renderer/media/audio_message_filter_unittest.cc
+++ b/content/renderer/media/audio_message_filter_unittest.cc
@@ -11,6 +11,8 @@
namespace content {
namespace {
+const int kRenderViewId = 1;
+
class MockAudioDelegate : public media::AudioOutputIPCDelegate {
public:
MockAudioDelegate() {
@@ -69,13 +71,17 @@
} // namespace
TEST(AudioMessageFilterTest, Basic) {
- MessageLoop message_loop(MessageLoop::TYPE_IO);
+ base::MessageLoop message_loop(base::MessageLoop::TYPE_IO);
scoped_refptr<AudioMessageFilter> filter(new AudioMessageFilter(
message_loop.message_loop_proxy()));
MockAudioDelegate delegate;
- int stream_id = filter->AddDelegate(&delegate);
+ const scoped_ptr<media::AudioOutputIPC> ipc =
+ filter->CreateAudioOutputIPC(kRenderViewId);
+ ipc->CreateStream(&delegate, media::AudioParameters());
+ static const int kStreamId = 1;
+ EXPECT_EQ(&delegate, filter->delegates_.Lookup(kStreamId));
// AudioMsg_NotifyStreamCreated
#if defined(OS_WIN)
@@ -87,7 +93,7 @@
EXPECT_FALSE(delegate.created_received());
filter->OnMessageReceived(
AudioMsg_NotifyStreamCreated(
- stream_id, base::SharedMemory::NULLHandle(),
+ kStreamId, base::SharedMemory::NULLHandle(),
socket_handle, kLength));
EXPECT_TRUE(delegate.created_received());
EXPECT_FALSE(base::SharedMemory::IsHandleValid(delegate.handle()));
@@ -98,33 +104,43 @@
EXPECT_FALSE(delegate.state_changed_received());
filter->OnMessageReceived(
AudioMsg_NotifyStreamStateChanged(
- stream_id, media::AudioOutputIPCDelegate::kPlaying));
+ kStreamId, media::AudioOutputIPCDelegate::kPlaying));
EXPECT_TRUE(delegate.state_changed_received());
EXPECT_EQ(media::AudioOutputIPCDelegate::kPlaying, delegate.state());
delegate.Reset();
message_loop.RunUntilIdle();
- filter->RemoveDelegate(stream_id);
+
+ ipc->CloseStream();
+ EXPECT_EQ(static_cast<media::AudioOutputIPCDelegate*>(NULL),
+ filter->delegates_.Lookup(kStreamId));
}
TEST(AudioMessageFilterTest, Delegates) {
- MessageLoop message_loop(MessageLoop::TYPE_IO);
+ base::MessageLoop message_loop(base::MessageLoop::TYPE_IO);
scoped_refptr<AudioMessageFilter> filter(new AudioMessageFilter(
message_loop.message_loop_proxy()));
MockAudioDelegate delegate1;
MockAudioDelegate delegate2;
-
- int stream_id1 = filter->AddDelegate(&delegate1);
- int stream_id2 = filter->AddDelegate(&delegate2);
+ const scoped_ptr<media::AudioOutputIPC> ipc1 =
+ filter->CreateAudioOutputIPC(kRenderViewId);
+ const scoped_ptr<media::AudioOutputIPC> ipc2 =
+ filter->CreateAudioOutputIPC(kRenderViewId);
+ ipc1->CreateStream(&delegate1, media::AudioParameters());
+ ipc2->CreateStream(&delegate2, media::AudioParameters());
+ static const int kStreamId1 = 1;
+ static const int kStreamId2 = 2;
+ EXPECT_EQ(&delegate1, filter->delegates_.Lookup(kStreamId1));
+ EXPECT_EQ(&delegate2, filter->delegates_.Lookup(kStreamId2));
// Send an IPC message. Make sure the correct delegate gets called.
EXPECT_FALSE(delegate1.state_changed_received());
EXPECT_FALSE(delegate2.state_changed_received());
filter->OnMessageReceived(
AudioMsg_NotifyStreamStateChanged(
- stream_id1, media::AudioOutputIPCDelegate::kPlaying));
+ kStreamId1, media::AudioOutputIPCDelegate::kPlaying));
EXPECT_TRUE(delegate1.state_changed_received());
EXPECT_FALSE(delegate2.state_changed_received());
delegate1.Reset();
@@ -133,15 +149,19 @@
EXPECT_FALSE(delegate2.state_changed_received());
filter->OnMessageReceived(
AudioMsg_NotifyStreamStateChanged(
- stream_id2, media::AudioOutputIPCDelegate::kPlaying));
+ kStreamId2, media::AudioOutputIPCDelegate::kPlaying));
EXPECT_FALSE(delegate1.state_changed_received());
EXPECT_TRUE(delegate2.state_changed_received());
delegate2.Reset();
message_loop.RunUntilIdle();
- filter->RemoveDelegate(stream_id1);
- filter->RemoveDelegate(stream_id2);
+ ipc1->CloseStream();
+ ipc2->CloseStream();
+ EXPECT_EQ(static_cast<media::AudioOutputIPCDelegate*>(NULL),
+ filter->delegates_.Lookup(kStreamId1));
+ EXPECT_EQ(static_cast<media::AudioOutputIPCDelegate*>(NULL),
+ filter->delegates_.Lookup(kStreamId2));
}
} // namespace content
diff --git a/content/renderer/media/audio_renderer_mixer_manager.cc b/content/renderer/media/audio_renderer_mixer_manager.cc
index 2f2433f..7db67d1 100644
--- a/content/renderer/media/audio_renderer_mixer_manager.cc
+++ b/content/renderer/media/audio_renderer_mixer_manager.cc
@@ -7,7 +7,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/renderer_audio_output_device.h"
+#include "media/audio/audio_output_device.h"
#include "media/base/audio_hardware_config.h"
#include "media/base/audio_renderer_mixer.h"
#include "media/base/audio_renderer_mixer_input.h"
@@ -77,10 +77,9 @@
mixer = new media::AudioRendererMixer(
params, output_params, sink_for_testing_);
} else {
- scoped_refptr<RendererAudioOutputDevice> device =
- AudioDeviceFactory::NewOutputDevice();
- device->SetSourceRenderView(source_render_view_id);
- mixer = new media::AudioRendererMixer(params, output_params, device);
+ mixer = new media::AudioRendererMixer(
+ params, output_params, AudioDeviceFactory::NewOutputDevice(
+ source_render_view_id));
}
AudioRendererMixerReference mixer_reference = { mixer, 1 };
diff --git a/content/renderer/media/audio_renderer_mixer_manager.h b/content/renderer/media/audio_renderer_mixer_manager.h
index dd2575b..10901c1 100644
--- a/content/renderer/media/audio_renderer_mixer_manager.h
+++ b/content/renderer/media/audio_renderer_mixer_manager.h
@@ -50,6 +50,17 @@
// the returned input.
media::AudioRendererMixerInput* CreateInput(int source_render_view_id);
+ // Returns a mixer instance based on AudioParameters; an existing one if one
+ // with the provided AudioParameters exists or a new one if not.
+ media::AudioRendererMixer* GetMixer(int source_render_view_id,
+ const media::AudioParameters& params);
+
+ // Remove a mixer instance given a mixer if the only other reference is held
+ // by AudioRendererMixerManager. Every AudioRendererMixer owner must call
+ // this method when it's done with a mixer.
+ void RemoveMixer(int source_render_view_id,
+ const media::AudioParameters& params);
+
private:
friend class AudioRendererMixerManagerTest;
@@ -69,17 +80,6 @@
// Overrides the AudioRendererSink implementation for unit testing.
void SetAudioRendererSinkForTesting(media::AudioRendererSink* sink);
- // Returns a mixer instance based on AudioParameters; an existing one if one
- // with the provided AudioParameters exists or a new one if not.
- media::AudioRendererMixer* GetMixer(int source_render_view_id,
- const media::AudioParameters& params);
-
- // Remove a mixer instance given a mixer if the only other reference is held
- // by AudioRendererMixerManager. Every AudioRendererMixer owner must call
- // this method when it's done with a mixer.
- void RemoveMixer(int source_render_view_id,
- const media::AudioParameters& params);
-
// Active mixers.
AudioRendererMixerMap mixers_;
base::Lock mixers_lock_;
diff --git a/content/renderer/media/local_video_capture.cc b/content/renderer/media/local_video_capture.cc
deleted file mode 100644
index f4bc376..0000000
--- a/content/renderer/media/local_video_capture.cc
+++ /dev/null
@@ -1,155 +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/renderer/media/local_video_capture.h"
-
-#include "content/renderer/media/video_capture_impl_manager.h"
-#include "media/base/video_util.h"
-#include "media/video/capture/video_capture_proxy.h"
-
-using media::CopyYPlane;
-using media::CopyUPlane;
-using media::CopyVPlane;
-
-namespace content {
-
-LocalVideoCapture::LocalVideoCapture(
- media::VideoCaptureSessionId video_stream_id,
- VideoCaptureImplManager* vc_manager,
- const media::VideoCaptureCapability& capability,
- const base::Closure& error_cb,
- const RepaintCB& repaint_cb)
- : video_stream_id_(video_stream_id),
- vc_manager_(vc_manager),
- capability_(capability),
- error_cb_(error_cb),
- repaint_cb_(repaint_cb),
- capture_engine_(NULL),
- message_loop_proxy_(base::MessageLoopProxy::current()),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- handler_proxy_(new media::VideoCaptureHandlerProxy(
- this, message_loop_proxy_))),
- state_(VIDEO_CAPTURE_STATE_STOPPED) {
- DVLOG(3) << "LocalVideoCapture::ctor";
- DCHECK(vc_manager);
-}
-
-LocalVideoCapture::~LocalVideoCapture() {
- DVLOG(3) << "LocalVideoCapture::dtor";
-}
-
-void LocalVideoCapture::Start() {
- DVLOG(3) << "LocalVideoCapture::Start";
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED);
-
- capture_engine_ = vc_manager_->AddDevice(video_stream_id_, this);
- state_ = VIDEO_CAPTURE_STATE_STARTED;
- AddRef(); // Will be balanced in OnRemoved().
- capture_engine_->StartCapture(handler_proxy_.get(), capability_);
-}
-
-void LocalVideoCapture::Stop() {
- DVLOG(3) << "LocalVideoCapture::Stop";
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- if (capture_engine_) {
- state_ = VIDEO_CAPTURE_STATE_STOPPING;
- capture_engine_->StopCapture(handler_proxy_.get());
- capture_engine_ = NULL;
- }
-}
-
-void LocalVideoCapture::Play() {
- DVLOG(3) << "LocalVideoCapture::Play";
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- if (capture_engine_ && state_ == VIDEO_CAPTURE_STATE_PAUSED) {
- state_ = VIDEO_CAPTURE_STATE_STARTED;
- }
-}
-
-void LocalVideoCapture::Pause() {
- DVLOG(3) << "LocalVideoCapture::Pause";
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- if (capture_engine_ && state_ == VIDEO_CAPTURE_STATE_STARTED) {
- state_ = VIDEO_CAPTURE_STATE_PAUSED;
- }
-}
-
-void LocalVideoCapture::OnStarted(media::VideoCapture* capture) {
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- NOTIMPLEMENTED();
-}
-
-void LocalVideoCapture::OnStopped(media::VideoCapture* capture) {
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- NOTIMPLEMENTED();
-}
-
-void LocalVideoCapture::OnPaused(media::VideoCapture* capture) {
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- NOTIMPLEMENTED();
-}
-
-void LocalVideoCapture::OnError(media::VideoCapture* capture,
- int error_code) {
- DVLOG(3) << "LocalVideoCapture::OnError, " << error_code;
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- error_cb_.Run();
-}
-
-void LocalVideoCapture::OnRemoved(media::VideoCapture* capture) {
- DVLOG(3) << "LocalVideoCapture::OnRemoved";
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- // OnRemoved could be triggered by error.
- capture_engine_ = NULL;
- vc_manager_->RemoveDevice(video_stream_id_, this);
- Release(); // Balance the AddRef() in StartCapture().
-}
-
-void LocalVideoCapture::OnDeviceInfoReceived(
- media::VideoCapture* capture,
- const media::VideoCaptureParams& device_info) {
- DVLOG(3) << "LocalVideoCapture::OnDeviceInfoReceived";
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
-}
-
-void LocalVideoCapture::OnBufferReady(
- media::VideoCapture* capture,
- scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf) {
- DVLOG(3) << "LocalVideoCapture::OnBufferReady, state:" << state_;
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- DCHECK(buf);
-
- if (state_ != VIDEO_CAPTURE_STATE_STARTED) {
- capture->FeedBuffer(buf);
- return;
- }
-
- gfx::Size natural_size(buf->width, buf->height);
- scoped_refptr<media::VideoFrame> current_frame =
- media::VideoFrame::CreateFrame(media::VideoFrame::YV12, natural_size,
- gfx::Rect(natural_size), natural_size,
- buf->timestamp - base::Time());
- uint8* buffer = buf->memory_pointer;
-
- // Assume YV12 format.
- DCHECK_EQ(capability_.color, media::VideoCaptureCapability::kI420);
- if (capability_.color != media::VideoCaptureCapability::kI420)
- return;
-
- int y_width = buf->width;
- int y_height = buf->height;
- int uv_width = buf->width / 2;
- int uv_height = buf->height / 2;
- CopyYPlane(buffer, y_width, y_height, current_frame);
- buffer += y_width * y_height;
- CopyUPlane(buffer, uv_width, uv_height, current_frame);
- buffer += uv_width * uv_height;
- CopyVPlane(buffer, uv_width, uv_height, current_frame);
-
- capture->FeedBuffer(buf);
- repaint_cb_.Run(current_frame);
-}
-
-} // namespace content
diff --git a/content/renderer/media/local_video_capture.h b/content/renderer/media/local_video_capture.h
deleted file mode 100644
index 3babc44..0000000
--- a/content/renderer/media/local_video_capture.h
+++ /dev/null
@@ -1,78 +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_RENDERER_MEDIA_LOCAL_VIDEO_CAPTURE_H_
-#define CONTENT_RENDERER_MEDIA_LOCAL_VIDEO_CAPTURE_H_
-
-#include "content/common/content_export.h"
-#include "content/common/media/video_capture.h"
-#include "media/video/capture/video_capture.h"
-#include "webkit/media/video_frame_provider.h"
-
-namespace base {
-class MessageLoopProxy;
-}
-
-namespace media {
-class VideoCaptureHandlerProxy;
-}
-
-namespace content {
-class VideoCaptureImplManager;
-
-// This class takes raw frames from video capture engine via VideoCaptureProxy
-// and passes them to media player as a video frame provider.
-// This class lives on main thread.
-class CONTENT_EXPORT LocalVideoCapture
- : NON_EXPORTED_BASE(public webkit_media::VideoFrameProvider),
- public media::VideoCapture::EventHandler {
- public:
- LocalVideoCapture(
- media::VideoCaptureSessionId video_stream_id,
- VideoCaptureImplManager* vc_manager,
- const media::VideoCaptureCapability& capability,
- const base::Closure& error_cb,
- const RepaintCB& repaint_cb);
-
- // webkit_media::VideoFrameProvider implementation.
- virtual void Start() OVERRIDE;
- virtual void Stop() OVERRIDE;
- virtual void Play() OVERRIDE;
- virtual void Pause() OVERRIDE;
-
- // VideoCapture::EventHandler implementation.
- virtual void OnStarted(media::VideoCapture* capture) OVERRIDE;
- virtual void OnStopped(media::VideoCapture* capture) OVERRIDE;
- virtual void OnPaused(media::VideoCapture* capture) OVERRIDE;
- virtual void OnError(media::VideoCapture* capture, int error_code) OVERRIDE;
- virtual void OnRemoved(media::VideoCapture* capture) OVERRIDE;
- virtual void OnBufferReady(
- media::VideoCapture* capture,
- scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf) OVERRIDE;
- virtual void OnDeviceInfoReceived(
- media::VideoCapture* capture,
- const media::VideoCaptureParams& device_info) OVERRIDE;
-
- protected:
- virtual ~LocalVideoCapture();
-
- private:
- friend class LocalVideoCaptureTest;
-
- media::VideoCaptureSessionId video_stream_id_;
- scoped_refptr<VideoCaptureImplManager> vc_manager_;
- media::VideoCaptureCapability capability_;
- base::Closure error_cb_;
- RepaintCB repaint_cb_;
- media::VideoCapture* capture_engine_;
- scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
- scoped_ptr<media::VideoCaptureHandlerProxy> handler_proxy_;
- VideoCaptureState state_;
-
- DISALLOW_COPY_AND_ASSIGN(LocalVideoCapture);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_LOCAL_VIDEO_CAPTURE_H_
diff --git a/content/renderer/media/media_stream_center.cc b/content/renderer/media/media_stream_center.cc
index 29f2363..14b0327 100644
--- a/content/renderer/media/media_stream_center.cc
+++ b/content/renderer/media/media_stream_center.cc
@@ -32,7 +32,6 @@
return extra_data->stream();
}
-
static webrtc::MediaStreamTrackInterface* GetNativeMediaStreamTrack(
const WebKit::WebMediaStream& stream,
const WebKit::WebMediaStreamTrack& component) {
@@ -99,4 +98,22 @@
rtc_factory_->CreateNativeLocalMediaStream(&stream);
}
+bool MediaStreamCenter::didAddMediaStreamTrack(
+ const WebKit::WebMediaStream& stream,
+ const WebKit::WebMediaStreamTrack& track) {
+ if (!rtc_factory_)
+ return false;
+
+ return rtc_factory_->AddNativeMediaStreamTrack(stream, track);
+}
+
+bool MediaStreamCenter::didRemoveMediaStreamTrack(
+ const WebKit::WebMediaStream& stream,
+ const WebKit::WebMediaStreamTrack& track) {
+ if (!rtc_factory_)
+ return false;
+
+ return rtc_factory_->RemoveNativeMediaStreamTrack(stream, track);
+}
+
} // namespace content
diff --git a/content/renderer/media/media_stream_center.h b/content/renderer/media/media_stream_center.h
index bd125b5..de5f2e1 100644
--- a/content/renderer/media/media_stream_center.h
+++ b/content/renderer/media/media_stream_center.h
@@ -42,6 +42,14 @@
virtual void didCreateMediaStream(
WebKit::WebMediaStream& stream) OVERRIDE;
+ virtual bool didAddMediaStreamTrack(
+ const WebKit::WebMediaStream& stream,
+ const WebKit::WebMediaStreamTrack& track) OVERRIDE;
+
+ virtual bool didRemoveMediaStreamTrack(
+ const WebKit::WebMediaStream& stream,
+ const WebKit::WebMediaStreamTrack& track) OVERRIDE;
+
private:
// |rtc_factory_| is a weak pointer and is owned by the RenderThreadImpl.
// It is valid as long as RenderThreadImpl exist.
diff --git a/content/renderer/media/media_stream_dependency_factory.cc b/content/renderer/media/media_stream_dependency_factory.cc
index 06943a6..421bfac 100644
--- a/content/renderer/media/media_stream_dependency_factory.cc
+++ b/content/renderer/media/media_stream_dependency_factory.cc
@@ -15,6 +15,7 @@
#include "content/renderer/media/video_capture_impl_manager.h"
#include "content/renderer/media/webaudio_capturer_source.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
+#include "content/renderer/media/webrtc_local_audio_track.h"
#include "content/renderer/media/webrtc_uma_histograms.h"
#include "content/renderer/p2p/ipc_network_manager.h"
#include "content/renderer/p2p/ipc_socket_factory.h"
@@ -40,14 +41,14 @@
const char* key;
const char* value;
} const kWebAudioConstraints[] = {
- {webrtc::MediaConstraintsInterface::kEchoCancellation,
- webrtc::MediaConstraintsInterface::kValueFalse},
- {webrtc::MediaConstraintsInterface::kAutoGainControl,
- webrtc::MediaConstraintsInterface::kValueFalse},
- {webrtc::MediaConstraintsInterface::kNoiseSuppression,
- webrtc::MediaConstraintsInterface::kValueFalse},
- {webrtc::MediaConstraintsInterface::kHighpassFilter,
- webrtc::MediaConstraintsInterface::kValueFalse},
+ {webrtc::MediaConstraintsInterface::kEchoCancellation,
+ webrtc::MediaConstraintsInterface::kValueFalse},
+ {webrtc::MediaConstraintsInterface::kAutoGainControl,
+ webrtc::MediaConstraintsInterface::kValueFalse},
+ {webrtc::MediaConstraintsInterface::kNoiseSuppression,
+ webrtc::MediaConstraintsInterface::kValueFalse},
+ {webrtc::MediaConstraintsInterface::kHighpassFilter,
+ webrtc::MediaConstraintsInterface::kValueFalse},
};
class WebAudioConstraints : public RTCMediaConstraints {
@@ -65,7 +66,7 @@
}
}
- virtual ~WebAudioConstraints() {};
+ virtual ~WebAudioConstraints() {}
};
class P2PPortAllocatorFactory : public webrtc::PortAllocatorFactoryInterface {
@@ -227,6 +228,7 @@
}
void MediaStreamDependencyFactory::CreateNativeMediaSources(
+ int render_view_id,
const WebKit::WebMediaConstraints& audio_constraints,
const WebKit::WebMediaConstraints& video_constraints,
WebKit::WebMediaStream* description,
@@ -284,7 +286,7 @@
const StreamDeviceInfo device_info = source_data->device_info();
if (IsAudioMediaType(device_info.device.type)) {
- if (!InitializeAudioSource(device_info)) {
+ if (!InitializeAudioSource(render_view_id, device_info)) {
DLOG(WARNING) << "Unsupported audio source";
sources_created.Run(description, false);
return;
@@ -304,82 +306,30 @@
WebKit::WebMediaStream* description) {
DVLOG(1) << "MediaStreamDependencyFactory::CreateNativeLocalMediaStream()";
if (!EnsurePeerConnectionFactory()) {
- DVLOG(1) << "EnsurePeerConnectionFactory() failed!";
- return;
+ DVLOG(1) << "EnsurePeerConnectionFactory() failed!";
+ return;
}
std::string label = UTF16ToUTF8(description->label());
scoped_refptr<webrtc::MediaStreamInterface> native_stream =
CreateLocalMediaStream(label);
+ MediaStreamExtraData* extra_data = new MediaStreamExtraData(native_stream,
+ true);
+ description->setExtraData(extra_data);
// Add audio tracks.
WebKit::WebVector<WebKit::WebMediaStreamTrack> audio_tracks;
- description->audioSources(audio_tracks);
-
- bool start_stream = false;
+ description->audioTracks(audio_tracks);
for (size_t i = 0; i < audio_tracks.size(); ++i) {
- WebKit::WebMediaStreamSource source = audio_tracks[i].source();
-
- // See if we're adding a WebAudio MediaStream.
- if (source.requiresAudioConsumer()) {
- // TODO(crogers, xians): In reality we should be able to send a unique
- // audio stream to each PeerConnection separately. But currently WebRTC
- // is only able to handle a global audio stream sent to ALL peers.
-
- // Create a special source where default WebAudio constraints are used.
- if (!CreateWebAudioSource(&source)) {
- LOG(ERROR) << "Failed to create WebAudio source";
- continue;
- }
- }
-
- MediaStreamSourceExtraData* source_data =
- static_cast<MediaStreamSourceExtraData*>(source.extraData());
-
- if (!source_data) {
- // TODO(perkj): Implement support for sources from
- // remote MediaStreams.
- NOTIMPLEMENTED();
- continue;
- }
-
- scoped_refptr<webrtc::AudioTrackInterface> audio_track(
- CreateLocalAudioTrack(UTF16ToUTF8(audio_tracks[i].id()),
- source_data->local_audio_source()));
- native_stream->AddTrack(audio_track);
- audio_track->set_enabled(audio_tracks[i].isEnabled());
- start_stream = true;
- }
-
- if (start_stream && GetWebRtcAudioDevice()) {
- WebRtcAudioCapturer* capturer = GetWebRtcAudioDevice()->capturer();
- capturer->Start();
+ AddNativeMediaStreamTrack(*description, audio_tracks[i]);
}
// Add video tracks.
WebKit::WebVector<WebKit::WebMediaStreamTrack> video_tracks;
- description->videoSources(video_tracks);
+ description->videoTracks(video_tracks);
for (size_t i = 0; i < video_tracks.size(); ++i) {
- const WebKit::WebMediaStreamSource& source = video_tracks[i].source();
- MediaStreamSourceExtraData* source_data =
- static_cast<MediaStreamSourceExtraData*>(source.extraData());
- if (!source_data || !source_data->video_source()) {
- // TODO(perkj): Implement support for sources from remote MediaStreams.
- NOTIMPLEMENTED();
- continue;
- }
-
- scoped_refptr<webrtc::VideoTrackInterface> video_track(
- CreateLocalVideoTrack(UTF16ToUTF8(video_tracks[i].id()),
- source_data->video_source()));
-
- native_stream->AddTrack(video_track);
- video_track->set_enabled(video_tracks[i].isEnabled());
+ AddNativeMediaStreamTrack(*description, video_tracks[i]);
}
-
- MediaStreamExtraData* extra_data = new MediaStreamExtraData(native_stream,
- true);
- description->setExtraData(extra_data);
}
void MediaStreamDependencyFactory::CreateNativeLocalMediaStream(
@@ -392,16 +342,128 @@
extra_data->SetLocalStreamStopCallback(stream_stop);
}
+bool MediaStreamDependencyFactory::AddNativeMediaStreamTrack(
+ const WebKit::WebMediaStream& stream,
+ const WebKit::WebMediaStreamTrack& track) {
+ MediaStreamExtraData* extra_data =
+ static_cast<MediaStreamExtraData*>(stream.extraData());
+ webrtc::MediaStreamInterface* native_stream = extra_data->stream();
+ DCHECK(native_stream);
+
+ WebKit::WebMediaStreamSource source = track.source();
+ MediaStreamSourceExtraData* source_data =
+ static_cast<MediaStreamSourceExtraData*>(source.extraData());
+
+ if (!source_data) {
+ if (source.requiresAudioConsumer()) {
+ // We're adding a WebAudio MediaStream.
+ // TODO(crogers, xians): In reality we should be able to send a unique
+ // audio stream to each PeerConnection separately.
+ // Currently WebRTC is only able to handle a global audio stream sent to
+ // ALL peers. Create a special source where default WebAudio constraints
+ // are used.
+ if (CreateWebAudioSource(&source)) {
+ source_data =
+ static_cast<MediaStreamSourceExtraData*>(source.extraData());
+ } else {
+ LOG(ERROR) << "Failed to create WebAudio source";
+ return false;
+ }
+ } else {
+ // TODO(perkj): Implement support for sources from
+ // remote MediaStreams.
+ NOTIMPLEMENTED();
+ return false;
+ }
+ }
+
+ WebKit::WebMediaStreamSource::Type type = track.source().type();
+ DCHECK(type == WebKit::WebMediaStreamSource::TypeAudio ||
+ type == WebKit::WebMediaStreamSource::TypeVideo);
+
+ std::string track_id = UTF16ToUTF8(track.id());
+ if (source.type() == WebKit::WebMediaStreamSource::TypeAudio) {
+ // TODO(henrika,xians): Refactor how an audio track is created to harmonize
+ // with video tracks.
+ scoped_refptr<webrtc::AudioTrackInterface> audio_track(
+ CreateLocalAudioTrack(track_id, source_data->local_audio_source()));
+ audio_track->set_enabled(track.isEnabled());
+ if (GetWebRtcAudioDevice()) {
+ WebRtcAudioCapturer* capturer = GetWebRtcAudioDevice()->capturer();
+ if (!capturer->is_recording())
+ capturer->Start();
+ }
+ return native_stream->AddTrack(audio_track);
+ } else {
+ scoped_refptr<webrtc::VideoTrackInterface> video_track(
+ CreateLocalVideoTrack(track_id, source_data->video_source()));
+ video_track->set_enabled(track.isEnabled());
+ return native_stream->AddTrack(video_track);
+ }
+}
+
+bool MediaStreamDependencyFactory::AddNativeVideoMediaTrack(
+ const std::string& track_id,
+ WebKit::WebMediaStream* stream,
+ cricket::VideoCapturer* capturer) {
+ if (!stream) {
+ LOG(ERROR) << "AddNativeVideoMediaTrack called with null WebMediaStream.";
+ return false;
+ }
+
+ // Create native track from the source.
+ scoped_refptr<webrtc::VideoTrackInterface> native_track =
+ CreateLocalVideoTrack(track_id, capturer);
+
+ // Add the native track to native stream
+ MediaStreamExtraData* extra_data =
+ static_cast<MediaStreamExtraData*>(stream->extraData());
+ DCHECK(extra_data);
+ webrtc::MediaStreamInterface* native_stream = extra_data->stream();
+ native_stream->AddTrack(native_track);
+
+ // Create a new webkit video track.
+ WebKit::WebMediaStreamTrack webkit_track;
+ WebKit::WebMediaStreamSource webkit_source;
+ WebKit::WebString webkit_track_id(UTF8ToUTF16(track_id));
+ WebKit::WebMediaStreamSource::Type type =
+ WebKit::WebMediaStreamSource::TypeVideo;
+ webkit_source.initialize(webkit_track_id, type, webkit_track_id);
+ webkit_track.initialize(webkit_track_id, webkit_source);
+
+ // Add the track to WebMediaStream.
+ stream->addTrack(webkit_track);
+ return true;
+}
+
+bool MediaStreamDependencyFactory::RemoveNativeMediaStreamTrack(
+ const WebKit::WebMediaStream& stream,
+ const WebKit::WebMediaStreamTrack& track) {
+ MediaStreamExtraData* extra_data =
+ static_cast<MediaStreamExtraData*>(stream.extraData());
+ webrtc::MediaStreamInterface* native_stream = extra_data->stream();
+ DCHECK(native_stream);
+
+ WebKit::WebMediaStreamSource::Type type = track.source().type();
+ DCHECK(type == WebKit::WebMediaStreamSource::TypeAudio ||
+ type == WebKit::WebMediaStreamSource::TypeVideo);
+
+ std::string track_id = UTF16ToUTF8(track.id());
+ return type == WebKit::WebMediaStreamSource::TypeAudio ?
+ native_stream->RemoveTrack(native_stream->FindAudioTrack(track_id)) :
+ native_stream->RemoveTrack(native_stream->FindVideoTrack(track_id));
+}
+
bool MediaStreamDependencyFactory::CreatePeerConnectionFactory() {
DVLOG(1) << "MediaStreamDependencyFactory::CreatePeerConnectionFactory()";
- if (!pc_factory_.get()) {
+ if (!pc_factory_) {
DCHECK(!audio_device_);
audio_device_ = new WebRtcAudioDeviceImpl();
scoped_refptr<webrtc::PeerConnectionFactoryInterface> factory(
webrtc::CreatePeerConnectionFactory(worker_thread_,
signaling_thread_,
audio_device_));
- if (factory.get())
+ if (factory)
pc_factory_ = factory;
else
audio_device_ = NULL;
@@ -460,7 +522,8 @@
}
bool MediaStreamDependencyFactory::InitializeAudioSource(
- const StreamDeviceInfo& device_info) {
+ int render_view_id,
+ const StreamDeviceInfo& device_info) {
DVLOG(1) << "MediaStreamDependencyFactory::InitializeAudioSource()";
// TODO(henrika): the current design does not support a unique source
@@ -474,6 +537,7 @@
// TODO(henrika): refactor \content\public\common\media_stream_request.h
// to allow dependency of media::ChannelLayout and avoid static_cast.
if (!capturer->Initialize(
+ render_view_id,
static_cast<media::ChannelLayout>(device_info.device.channel_layout),
device_info.device.sample_rate, device_info.session_id))
return false;
@@ -524,11 +588,31 @@
return pc_factory_->CreateVideoTrack(id, source).get();
}
+scoped_refptr<webrtc::VideoTrackInterface>
+MediaStreamDependencyFactory::CreateLocalVideoTrack(
+ const std::string& id, cricket::VideoCapturer* capturer) {
+ if (!capturer) {
+ LOG(ERROR) << "CreateLocalVideoTrack called with null VideoCapturer.";
+ return NULL;
+ }
+
+ // Create video source from the |capturer|.
+ scoped_refptr<webrtc::VideoSourceInterface> source =
+ pc_factory_->CreateVideoSource(capturer, NULL).get();
+
+ // Create native track from the source.
+ return pc_factory_->CreateVideoTrack(id, source).get();
+}
+
scoped_refptr<webrtc::AudioTrackInterface>
MediaStreamDependencyFactory::CreateLocalAudioTrack(
const std::string& id,
webrtc::AudioSourceInterface* source) {
- return pc_factory_->CreateAudioTrack(id, source).get();
+ // TODO(xians): Merge |source| to the capturer(). We can't do this today
+ // because only one capturer() is supported while one |source| is created
+ // for each audio track.
+ return WebRtcLocalAudioTrack::Create(id, GetWebRtcAudioDevice()->capturer(),
+ source);
}
webrtc::SessionDescriptionInterface*
@@ -577,13 +661,13 @@
void MediaStreamDependencyFactory::CreateIpcNetworkManagerOnWorkerThread(
base::WaitableEvent* event) {
- DCHECK_EQ(MessageLoop::current(), chrome_worker_thread_.message_loop());
+ DCHECK_EQ(base::MessageLoop::current(), chrome_worker_thread_.message_loop());
network_manager_ = new IpcNetworkManager(p2p_socket_dispatcher_);
event->Signal();
}
void MediaStreamDependencyFactory::DeleteIpcNetworkManager() {
- DCHECK_EQ(MessageLoop::current(), chrome_worker_thread_.message_loop());
+ DCHECK_EQ(base::MessageLoop::current(), chrome_worker_thread_.message_loop());
delete network_manager_;
network_manager_ = NULL;
}
@@ -627,7 +711,7 @@
event.Wait();
}
- if (!socket_factory_.get()) {
+ if (!socket_factory_) {
socket_factory_.reset(
new IpcPacketSocketFactory(p2p_socket_dispatcher_));
}
diff --git a/content/renderer/media/media_stream_dependency_factory.h b/content/renderer/media/media_stream_dependency_factory.h
index 27e4f4a..a56177a 100644
--- a/content/renderer/media/media_stream_dependency_factory.h
+++ b/content/renderer/media/media_stream_dependency_factory.h
@@ -71,6 +71,7 @@
// WebMediaStreamSource.
// |audio_constraints| and |video_constraints| set parameters for the sources.
void CreateNativeMediaSources(
+ int render_view_id,
const WebKit::WebMediaConstraints& audio_constraints,
const WebKit::WebMediaConstraints& video_constraints,
WebKit::WebMediaStream* description,
@@ -89,6 +90,20 @@
WebKit::WebMediaStream* description,
const MediaStreamExtraData::StreamStopCallback& stream_stop);
+ // Adds a libjingle representation of a MediaStreamTrack to |stream| based
+ // on the source of |track|.
+ bool AddNativeMediaStreamTrack(const WebKit::WebMediaStream& stream,
+ const WebKit::WebMediaStreamTrack& track);
+
+ // Creates and adds libjingle representation of a MediaStreamTrack to |stream|
+ // based on the desired |track_id| and |capturer|.
+ bool AddNativeVideoMediaTrack(const std::string& track_id,
+ WebKit::WebMediaStream* stream,
+ cricket::VideoCapturer* capturer);
+
+ bool RemoveNativeMediaStreamTrack(const WebKit::WebMediaStream& stream,
+ const WebKit::WebMediaStreamTrack& track);
+
// Asks the libjingle PeerConnection factory to create a libjingle
// PeerConnection object.
// The PeerConnection object is owned by PeerConnectionHandler.
@@ -139,7 +154,8 @@
// Initializes the source using audio parameters for the selected
// capture device and specifies which capture device to use as capture
// source.
- virtual bool InitializeAudioSource(const StreamDeviceInfo& device_info);
+ virtual bool InitializeAudioSource(int render_view_id,
+ const StreamDeviceInfo& device_info);
// Creates a media::AudioCapturerSource with an implementation that is
// specific for a WebAudio source. The created WebAudioCapturerSource
@@ -157,6 +173,12 @@
CreateLocalVideoTrack(const std::string& id,
webrtc::VideoSourceInterface* source);
+ // Asks the PeerConnection factory to create a Local VideoTrack object with
+ // the video source using |capturer|.
+ virtual scoped_refptr<webrtc::VideoTrackInterface>
+ CreateLocalVideoTrack(const std::string& id,
+ cricket::VideoCapturer* capturer);
+
virtual bool EnsurePeerConnectionFactory();
virtual bool PeerConnectionFactoryCreated();
diff --git a/content/renderer/media/media_stream_dependency_factory_unittest.cc b/content/renderer/media/media_stream_dependency_factory_unittest.cc
index a44f134..0023bb9 100644
--- a/content/renderer/media/media_stream_dependency_factory_unittest.cc
+++ b/content/renderer/media/media_stream_dependency_factory_unittest.cc
@@ -49,10 +49,19 @@
dependency_factory_.reset(new MockMediaStreamDependencyFactory());
}
- WebKit::WebMediaStream CreateWebKitMediaStream(bool audio,
- bool video) {
+ virtual void TearDown() OVERRIDE {
+ // TODO(tommyw): Remove this once WebKit::MediaStreamSource::Owner has been
+ // implemented to fully avoid a circular dependency.
+ for (size_t i = 0; i < audio_sources_.size(); ++i)
+ audio_sources_[i].setExtraData(NULL);
+
+ for (size_t i = 0; i < video_sources_.size(); ++i)
+ video_sources_[i].setExtraData(NULL);
+ }
+
+ WebKit::WebMediaStream CreateWebKitMediaStream(bool audio, bool video) {
WebKit::WebVector<WebKit::WebMediaStreamSource> audio_sources(
- audio ? static_cast<size_t>(1) : 0);
+ audio ? static_cast<size_t>(1) : 0);
WebKit::WebVector<WebKit::WebMediaStreamSource> video_sources(
video ? static_cast<size_t>(1) : 0);
@@ -67,7 +76,8 @@
WebKit::WebMediaStreamSource::TypeAudio,
"audio");
audio_sources[0].setExtraData(
- new MediaStreamSourceExtraData(info));
+ new MediaStreamSourceExtraData(info, audio_sources[0]));
+ audio_sources_.assign(audio_sources);
}
if (video) {
StreamDeviceInfo info;
@@ -78,7 +88,8 @@
WebKit::WebMediaStreamSource::TypeVideo,
"video");
video_sources[0].setExtraData(
- new MediaStreamSourceExtraData(info));
+ new MediaStreamSourceExtraData(info, video_sources[0]));
+ video_sources_.assign(video_sources);
}
WebKit::WebMediaStream stream_desc;
stream_desc.initialize("media stream", audio_sources, video_sources);
@@ -87,9 +98,12 @@
}
void CreateNativeSources(WebKit::WebMediaStream* descriptor) {
+ static const int kRenderViewId = 1;
+
MediaSourceCreatedObserver observer;
WebKit::WebMediaConstraints audio_constraints;
dependency_factory_->CreateNativeMediaSources(
+ kRenderViewId,
WebKit::WebMediaConstraints(),
WebKit::WebMediaConstraints(),
descriptor,
@@ -108,8 +122,21 @@
EXPECT_TRUE(observer.description() == descriptor);
}
+ void VerifyMediaStream(const WebKit::WebMediaStream& stream_desc,
+ size_t num_audio_tracks,
+ size_t num_video_tracks) {
+ content::MediaStreamExtraData* extra_data =
+ static_cast<content::MediaStreamExtraData*>(stream_desc.extraData());
+ ASSERT_TRUE(extra_data && extra_data->stream());
+ EXPECT_TRUE(extra_data->is_local());
+ EXPECT_EQ(num_audio_tracks, extra_data->stream()->GetAudioTracks().size());
+ EXPECT_EQ(num_video_tracks, extra_data->stream()->GetVideoTracks().size());
+ }
+
protected:
scoped_ptr<MockMediaStreamDependencyFactory> dependency_factory_;
+ WebKit::WebVector<WebKit::WebMediaStreamSource> audio_sources_;
+ WebKit::WebVector<WebKit::WebMediaStreamSource> video_sources_;
};
TEST_F(MediaStreamDependencyFactoryTest, CreateRTCPeerConnectionHandler) {
@@ -124,13 +151,7 @@
CreateNativeSources(&stream_desc);
dependency_factory_->CreateNativeLocalMediaStream(&stream_desc);
-
- content::MediaStreamExtraData* extra_data =
- static_cast<content::MediaStreamExtraData*>(stream_desc.extraData());
- ASSERT_TRUE(extra_data && extra_data->stream());
- EXPECT_TRUE(extra_data->is_local());
- EXPECT_EQ(1u, extra_data->stream()->GetAudioTracks().size());
- EXPECT_EQ(1u, extra_data->stream()->GetVideoTracks().size());
+ VerifyMediaStream(stream_desc, 1, 1);
}
// Test that we don't crash if a MediaStream is created in WebKit with unknown
@@ -153,12 +174,35 @@
EXPECT_TRUE(dependency_factory_->EnsurePeerConnectionFactory());
dependency_factory_->CreateNativeLocalMediaStream(&stream_desc);
- MediaStreamExtraData* extra_data = static_cast<MediaStreamExtraData*>(
- stream_desc.extraData());
- ASSERT_TRUE(extra_data && extra_data->stream());
- EXPECT_TRUE(extra_data->is_local());
- EXPECT_EQ(0u, extra_data->stream()->GetVideoTracks().size());
- EXPECT_EQ(0u, extra_data->stream()->GetAudioTracks().size());
+ VerifyMediaStream(stream_desc, 0, 0);
+}
+
+TEST_F(MediaStreamDependencyFactoryTest, AddAndRemoveNativeTrack) {
+ WebKit::WebMediaStream stream_desc = CreateWebKitMediaStream(true, true);
+ CreateNativeSources(&stream_desc);
+
+ dependency_factory_->CreateNativeLocalMediaStream(&stream_desc);
+ VerifyMediaStream(stream_desc, 1, 1);
+
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> audio_tracks;
+ stream_desc.audioTracks(audio_tracks);
+ EXPECT_TRUE(dependency_factory_->RemoveNativeMediaStreamTrack(
+ stream_desc, audio_tracks[0]));
+ VerifyMediaStream(stream_desc, 0, 1);
+
+ EXPECT_TRUE(dependency_factory_->AddNativeMediaStreamTrack(
+ stream_desc, audio_tracks[0]));
+ VerifyMediaStream(stream_desc, 1, 1);
+
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> video_tracks;
+ stream_desc.videoTracks(video_tracks);
+ EXPECT_TRUE(dependency_factory_->RemoveNativeMediaStreamTrack(
+ stream_desc, video_tracks[0]));
+ VerifyMediaStream(stream_desc, 1, 0);
+
+ EXPECT_TRUE(dependency_factory_->AddNativeMediaStreamTrack(
+ stream_desc, video_tracks[0]));
+ VerifyMediaStream(stream_desc, 1, 1);
}
} // namespace content
diff --git a/content/renderer/media/media_stream_dispatcher.cc b/content/renderer/media/media_stream_dispatcher.cc
index d5eafe8..859022a 100644
--- a/content/renderer/media/media_stream_dispatcher.cc
+++ b/content/renderer/media/media_stream_dispatcher.cc
@@ -8,6 +8,7 @@
#include "base/message_loop_proxy.h"
#include "content/common/media/media_stream_messages.h"
#include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
+#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h"
#include "googleurl/src/gurl.h"
@@ -130,7 +131,7 @@
&audio_enumeration_state_ : &video_enumeration_state_);
state->requests.push_back(EnumerationRequest(event_handler, request_id));
- if (state->cached_devices.get()) {
+ if (state->cached_devices) {
event_handler->OnDevicesEnumerated(
request_id, state->cached_devices->devices);
} else if (state->ipc_id < 0) {
@@ -165,7 +166,7 @@
it != requests->end(); ++it) {
if (it->request_id == request_id && it->handler == event_handler) {
requests->erase(it);
- if (requests->empty() && state->cached_devices.get()) {
+ if (requests->empty() && state->cached_devices) {
// No more request and has a label, try to stop the label
// and invalidate the state.
Send(new MediaStreamHostMsg_StopGeneratedStream(
@@ -203,6 +204,15 @@
StopStream(label);
}
+bool MediaStreamDispatcher::Send(IPC::Message* message) {
+ if (!RenderThread::Get()) {
+ delete message;
+ return false;
+ }
+
+ return RenderThread::Get()->Send(message);
+}
+
bool MediaStreamDispatcher::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(MediaStreamDispatcher, message)
diff --git a/content/renderer/media/media_stream_dispatcher.h b/content/renderer/media/media_stream_dispatcher.h
index d5e48ef..e013864 100644
--- a/content/renderer/media/media_stream_dispatcher.h
+++ b/content/renderer/media/media_stream_dispatcher.h
@@ -122,6 +122,9 @@
EnumerationRequestList requests;
};
+ // RenderViewObserver OVERRIDE.
+ virtual bool Send(IPC::Message* message) OVERRIDE;
+
// Messages from the browser.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
void OnStreamGenerated(
diff --git a/content/renderer/media/media_stream_dispatcher_unittest.cc b/content/renderer/media/media_stream_dispatcher_unittest.cc
index d272f43..b9e055e 100644
--- a/content/renderer/media/media_stream_dispatcher_unittest.cc
+++ b/content/renderer/media/media_stream_dispatcher_unittest.cc
@@ -81,7 +81,7 @@
} // namespace
TEST(MediaStreamDispatcherTest, BasicStream) {
- scoped_ptr<MessageLoop> message_loop(new MessageLoop());
+ scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL));
scoped_ptr<MockMediaStreamDispatcherEventHandler>
handler(new MockMediaStreamDispatcherEventHandler);
@@ -157,7 +157,7 @@
TEST(MediaStreamDispatcherTest, BasicStreamForDevice) {
static const char kDeviceId[] = "/dev/video0";
- scoped_ptr<MessageLoop> message_loop(new MessageLoop());
+ scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL));
scoped_ptr<MockMediaStreamDispatcherEventHandler>
handler(new MockMediaStreamDispatcherEventHandler);
@@ -228,7 +228,7 @@
}
TEST(MediaStreamDispatcherTest, BasicVideoDevice) {
- scoped_ptr<MessageLoop> message_loop(new MessageLoop());
+ scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL));
scoped_ptr<MockMediaStreamDispatcherEventHandler>
handler1(new MockMediaStreamDispatcherEventHandler);
@@ -315,7 +315,7 @@
}
TEST(MediaStreamDispatcherTest, TestFailure) {
- scoped_ptr<MessageLoop> message_loop(new MessageLoop());
+ scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL));
scoped_ptr<MockMediaStreamDispatcherEventHandler>
handler(new MockMediaStreamDispatcherEventHandler);
@@ -367,7 +367,7 @@
}
TEST(MediaStreamDispatcherTest, CancelGenerateStream) {
- scoped_ptr<MessageLoop> message_loop(new MessageLoop());
+ scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL));
scoped_ptr<MockMediaStreamDispatcherEventHandler>
handler(new MockMediaStreamDispatcherEventHandler);
diff --git a/content/renderer/media/media_stream_impl.cc b/content/renderer/media/media_stream_impl.cc
index 85c8fde..518dc5b 100644
--- a/content/renderer/media/media_stream_impl.cc
+++ b/content/renderer/media/media_stream_impl.cc
@@ -15,7 +15,6 @@
#include "content/renderer/media/media_stream_extra_data.h"
#include "content/renderer/media/media_stream_source_extra_data.h"
#include "content/renderer/media/rtc_video_renderer.h"
-#include "content/renderer/media/video_capture_impl_manager.h"
#include "content/renderer/media/webrtc_audio_capturer.h"
#include "content/renderer/media/webrtc_audio_renderer.h"
#include "content/renderer/media/webrtc_local_audio_renderer.h"
@@ -27,7 +26,6 @@
#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/WebMediaStreamRegistry.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
#include "webkit/media/media_stream_audio_renderer.h"
namespace content {
@@ -92,7 +90,7 @@
type,
UTF8ToUTF16(devices[i].device.name));
webkit_sources[i].setExtraData(
- new content::MediaStreamSourceExtraData(devices[i]));
+ new content::MediaStreamSourceExtraData(devices[i], webkit_sources[i]));
webkit_sources[i].setDeviceId(UTF8ToUTF16(devices[i].device.id.c_str()));
}
}
@@ -111,12 +109,10 @@
MediaStreamImpl::MediaStreamImpl(
RenderView* render_view,
MediaStreamDispatcher* media_stream_dispatcher,
- VideoCaptureImplManager* vc_manager,
MediaStreamDependencyFactory* dependency_factory)
: RenderViewObserver(render_view),
dependency_factory_(dependency_factory),
- media_stream_dispatcher_(media_stream_dispatcher),
- vc_manager_(vc_manager) {
+ media_stream_dispatcher_(media_stream_dispatcher) {
}
MediaStreamImpl::~MediaStreamImpl() {
@@ -310,11 +306,13 @@
CreateWebKitSourceVector(label, audio_array,
WebKit::WebMediaStreamSource::TypeAudio,
audio_source_vector);
+ request_info->audio_sources.assign(audio_source_vector);
WebKit::WebVector<WebKit::WebMediaStreamSource> video_source_vector(
video_array.size());
CreateWebKitSourceVector(label, video_array,
WebKit::WebMediaStreamSource::TypeVideo,
video_source_vector);
+ request_info->video_sources.assign(video_source_vector);
WebKit::WebUserMediaRequest* request = &(request_info->request);
WebKit::WebString webkit_label = UTF8ToUTF16(label);
@@ -331,6 +329,7 @@
WebKit::WebMediaConstraints() : request->videoConstraints();
dependency_factory_->CreateNativeMediaSources(
+ RenderViewObserver::routing_id(),
audio_constraints, video_constraints, description,
base::Bind(&MediaStreamImpl::OnCreateNativeSourcesComplete, AsWeakPtr()));
}
@@ -476,6 +475,11 @@
NOTREACHED();
}
+void MediaStreamImpl::FrameDetached(WebKit::WebFrame* frame) {
+ // Do same thing as FrameWillClose.
+ FrameWillClose(frame);
+}
+
void MediaStreamImpl::FrameWillClose(WebKit::WebFrame* frame) {
// Loop through all UserMediaRequests and find the requests that belong to the
// frame that is being closed.
@@ -558,13 +562,16 @@
// Create a new WebRtcLocalAudioRenderer instance and connect it to the
// existing WebRtcAudioCapturer so that the renderer can use it as source.
- return new WebRtcLocalAudioRenderer(source, audio_track,
- RenderViewObserver::routing_id());
+ return new WebRtcLocalAudioRenderer(
+ static_cast<WebRtcLocalAudioTrack*>(audio_track),
+ RenderViewObserver::routing_id());
}
MediaStreamSourceExtraData::MediaStreamSourceExtraData(
- const StreamDeviceInfo& device_info)
- : device_info_(device_info) {
+ const StreamDeviceInfo& device_info,
+ const WebKit::WebMediaStreamSource& webkit_source)
+ : device_info_(device_info),
+ webkit_source_(webkit_source) {
}
MediaStreamSourceExtraData::MediaStreamSourceExtraData(
@@ -593,4 +600,35 @@
stream_stop_callback_.Run(stream_->label());
}
+MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo()
+ : request_id(0), generated(false), frame(NULL), request() {
+}
+
+MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo(
+ int request_id,
+ WebKit::WebFrame* frame,
+ const WebKit::WebUserMediaRequest& request)
+ : request_id(request_id), generated(false), frame(frame),
+ request(request) {
+}
+
+MediaStreamImpl::UserMediaRequestInfo::~UserMediaRequestInfo() {
+ // Release the extra data field of all sources created by
+ // MediaStreamImpl for this request. This breaks the circular reference to
+ // WebKit::MediaStreamSource.
+ // TODO(tommyw): Remove this once WebKit::MediaStreamSource::Owner has been
+ // implemented to fully avoid a circular dependency.
+ for (size_t i = 0; i < audio_sources.size(); ++i) {
+ audio_sources[i].setReadyState(
+ WebKit::WebMediaStreamSource::ReadyStateEnded);
+ audio_sources[i].setExtraData(NULL);
+ }
+
+ for (size_t i = 0; i < video_sources.size(); ++i) {
+ video_sources[i].setReadyState(
+ WebKit::WebMediaStreamSource::ReadyStateEnded);
+ video_sources[i].setExtraData(NULL);
+ }
+}
+
} // namespace content
diff --git a/content/renderer/media/media_stream_impl.h b/content/renderer/media/media_stream_impl.h
index 1845ca0..f088fa0 100644
--- a/content/renderer/media/media_stream_impl.h
+++ b/content/renderer/media/media_stream_impl.h
@@ -31,7 +31,6 @@
namespace content {
class MediaStreamDependencyFactory;
class MediaStreamDispatcher;
-class VideoCaptureImplManager;
class WebRtcAudioRenderer;
class WebRtcLocalAudioRenderer;
@@ -52,7 +51,6 @@
MediaStreamImpl(
RenderView* render_view,
MediaStreamDispatcher* media_stream_dispatcher,
- VideoCaptureImplManager* vc_manager,
MediaStreamDependencyFactory* dependency_factory);
virtual ~MediaStreamImpl();
@@ -98,6 +96,7 @@
virtual void OnDeviceOpenFailed(int request_id) OVERRIDE;
// RenderViewObserver OVERRIDE
+ virtual void FrameDetached(WebKit::WebFrame* frame) OVERRIDE;
virtual void FrameWillClose(WebKit::WebFrame* frame) OVERRIDE;
protected:
@@ -130,15 +129,11 @@
// Structure for storing information about a WebKit request to create a
// MediaStream.
struct UserMediaRequestInfo {
- UserMediaRequestInfo()
- : request_id(0), generated(false), frame(NULL), request() {
- }
+ UserMediaRequestInfo();
UserMediaRequestInfo(int request_id,
WebKit::WebFrame* frame,
- const WebKit::WebUserMediaRequest& request)
- : request_id(request_id), generated(false), frame(frame),
- request(request) {
- }
+ const WebKit::WebUserMediaRequest& request);
+ ~UserMediaRequestInfo();
int request_id;
// True if MediaStreamDispatcher has generated the stream, see
// OnStreamGenerated.
@@ -146,6 +141,8 @@
WebKit::WebFrame* frame; // WebFrame that requested the MediaStream.
WebKit::WebMediaStream descriptor;
WebKit::WebUserMediaRequest request;
+ WebKit::WebVector<WebKit::WebMediaStreamSource> audio_sources;
+ WebKit::WebVector<WebKit::WebMediaStreamSource> video_sources;
};
typedef ScopedVector<UserMediaRequestInfo> UserMediaRequests;
@@ -175,8 +172,6 @@
// valid for the lifetime of RenderView.
MediaStreamDispatcher* media_stream_dispatcher_;
- scoped_refptr<VideoCaptureImplManager> vc_manager_;
-
UserMediaRequests user_media_requests_;
DISALLOW_COPY_AND_ASSIGN(MediaStreamImpl);
diff --git a/content/renderer/media/media_stream_impl_unittest.cc b/content/renderer/media/media_stream_impl_unittest.cc
index 3cf0cc4..d1b2a20 100644
--- a/content/renderer/media/media_stream_impl_unittest.cc
+++ b/content/renderer/media/media_stream_impl_unittest.cc
@@ -28,10 +28,8 @@
};
MediaStreamImplUnderTest(MediaStreamDispatcher* media_stream_dispatcher,
- VideoCaptureImplManager* vc_manager,
MediaStreamDependencyFactory* dependency_factory)
- : MediaStreamImpl(NULL, media_stream_dispatcher, vc_manager,
- dependency_factory),
+ : MediaStreamImpl(NULL, media_stream_dispatcher, dependency_factory),
state_(REQUEST_NOT_STARTED) {
}
@@ -77,11 +75,8 @@
virtual void SetUp() {
// Create our test object.
ms_dispatcher_.reset(new MockMediaStreamDispatcher());
- scoped_refptr<VideoCaptureImplManager> vc_manager(
- new VideoCaptureImplManager());
dependency_factory_.reset(new MockMediaStreamDependencyFactory());
ms_impl_.reset(new MediaStreamImplUnderTest(ms_dispatcher_.get(),
- vc_manager.get(),
dependency_factory_.get()));
}
diff --git a/content/renderer/media/media_stream_registry_interface.h b/content/renderer/media/media_stream_registry_interface.h
new file mode 100644
index 0000000..cc309b9
--- /dev/null
+++ b/content/renderer/media/media_stream_registry_interface.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_MEDIA_STREAM_REGISTRY_INTERFACE_H_
+#define CONTENT_RENDERER_MEDIA_MEDIA_STREAM_REGISTRY_INTERFACE_H_
+
+#include <string>
+
+#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStream.h"
+
+namespace content {
+
+// Interface to get WebMediaStream from its url.
+class MediaStreamRegistryInterface {
+ public:
+ virtual WebKit::WebMediaStream GetMediaStream(const std::string& url) = 0;
+
+ protected:
+ virtual ~MediaStreamRegistryInterface() {}
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_MEDIA_STREAM_REGISTRY_INTERFACE_H_
diff --git a/content/renderer/media/media_stream_source_extra_data.h b/content/renderer/media/media_stream_source_extra_data.h
index a5fb9ad..85ed1af 100644
--- a/content/renderer/media/media_stream_source_extra_data.h
+++ b/content/renderer/media/media_stream_source_extra_data.h
@@ -8,6 +8,7 @@
#include "base/compiler_specific.h"
#include "content/common/content_export.h"
#include "content/common/media/media_stream_options.h"
+#include "content/renderer/media/media_stream_source_observer.h"
#include "media/base/audio_capturer_source.h"
#include "third_party/libjingle/source/talk/app/webrtc/videosourceinterface.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamSource.h"
@@ -17,13 +18,18 @@
class CONTENT_EXPORT MediaStreamSourceExtraData
: NON_EXPORTED_BASE(public WebKit::WebMediaStreamSource::ExtraData) {
public:
-
- explicit MediaStreamSourceExtraData(
- const StreamDeviceInfo& device_info);
+ MediaStreamSourceExtraData(
+ const StreamDeviceInfo& device_info,
+ const WebKit::WebMediaStreamSource& webkit_source);
explicit MediaStreamSourceExtraData(
media::AudioCapturerSource* source);
virtual ~MediaStreamSourceExtraData();
+ // Returns the WebMediaStreamSource object that owns this object.
+ const WebKit::WebMediaStreamSource& webkit_source() const {
+ return webkit_source_;
+ }
+
// Return device information about the camera or microphone.
const StreamDeviceInfo& device_info() const {
return device_info_;
@@ -31,10 +37,13 @@
void SetVideoSource(webrtc::VideoSourceInterface* source) {
video_source_ = source;
+ source_observer_.reset(new MediaStreamSourceObserver(source, this));
}
void SetLocalAudioSource(webrtc::AudioSourceInterface* source) {
local_audio_source_ = source;
+ // TODO(perkj): Implement a local source observer for audio.
+ // See |source_observer_|.
}
webrtc::VideoSourceInterface* video_source() { return video_source_; }
@@ -45,6 +54,16 @@
private:
StreamDeviceInfo device_info_;
+
+ // TODO(tommyw): Remove |webkit_source_| after WebMediaStreamSource::Owner()
+ // is implemented, which let us fetch the
+ // WebMediaStreamSource without increasing the reference count.
+ // |webkit_source_| will create a circular reference to WebMediaStreamSource.
+ // WebMediaStreamSource -> MediaStreamSourceExtraData -> WebMediaStreamSource
+ // Currently, we rely on manually releasing the MediaStreamSourceExtraData
+ // from WebMediaStreamSource like what
+ // MediaStreamImpl::~UserMediaRequestInfo() does.
+ WebKit::WebMediaStreamSource webkit_source_;
scoped_refptr<webrtc::VideoSourceInterface> video_source_;
scoped_refptr<media::AudioCapturerSource> audio_source_;
@@ -53,6 +72,7 @@
// TODO(hclam): This should be merged with |audio_source_| such that it
// carries audio options.
scoped_refptr<webrtc::AudioSourceInterface> local_audio_source_;
+ scoped_ptr<MediaStreamSourceObserver> source_observer_;
DISALLOW_COPY_AND_ASSIGN(MediaStreamSourceExtraData);
};
diff --git a/content/renderer/media/media_stream_source_observer.cc b/content/renderer/media/media_stream_source_observer.cc
new file mode 100644
index 0000000..a62c997
--- /dev/null
+++ b/content/renderer/media/media_stream_source_observer.cc
@@ -0,0 +1,63 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/media_stream_source_observer.h"
+
+#include "base/logging.h"
+#include "content/renderer/media/media_stream_source_extra_data.h"
+
+namespace content {
+
+MediaStreamSourceObserver::MediaStreamSourceObserver(
+ webrtc::MediaSourceInterface* webrtc_source,
+ MediaStreamSourceExtraData* extra_data)
+ : state_(webrtc_source->state()),
+ webrtc_source_(webrtc_source),
+ extra_data_(extra_data) {
+ webrtc_source_->RegisterObserver(this);
+}
+
+MediaStreamSourceObserver::~MediaStreamSourceObserver() {
+ DCHECK(CalledOnValidThread());
+ if (webrtc_source_)
+ webrtc_source_->UnregisterObserver(this);
+}
+
+void MediaStreamSourceObserver::OnChanged() {
+ DCHECK(CalledOnValidThread());
+ // There should be no more notification after kEnded.
+ DCHECK(webrtc_source_ != NULL);
+
+ webrtc::MediaSourceInterface::SourceState state = webrtc_source_->state();
+ if (state == state_)
+ return;
+ state_ = state;
+ WebKit::WebMediaStreamSource webkit_source(extra_data_->webkit_source());
+
+ switch (state) {
+ case webrtc::MediaSourceInterface::kInitializing:
+ // Ignore the kInitializing state since there is no match in
+ // WebMediaStreamSource::ReadyState.
+ break;
+ case webrtc::MediaSourceInterface::kLive:
+ webkit_source.setReadyState(
+ WebKit::WebMediaStreamSource::ReadyStateLive);
+ break;
+ case webrtc::MediaSourceInterface::kMuted:
+ webkit_source.setReadyState(
+ WebKit::WebMediaStreamSource::ReadyStateMuted);
+ break;
+ case webrtc::MediaSourceInterface::kEnded:
+ webkit_source.setReadyState(
+ WebKit::WebMediaStreamSource::ReadyStateEnded);
+ webrtc_source_->UnregisterObserver(this);
+ webrtc_source_ = NULL;
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+} // namespace content
diff --git a/content/renderer/media/media_stream_source_observer.h b/content/renderer/media/media_stream_source_observer.h
new file mode 100644
index 0000000..b8a363d
--- /dev/null
+++ b/content/renderer/media/media_stream_source_observer.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_MEDIA_STREAM_SOURCE_OBSERVER_H_
+#define CONTENT_RENDERER_MEDIA_MEDIA_STREAM_SOURCE_OBSERVER_H_
+
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "base/threading/non_thread_safe.h"
+#include "content/common/content_export.h"
+#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamSource.h"
+
+namespace content {
+
+class MediaStreamSourceExtraData;
+
+// MediaStreamSourceObserver listens to events on MediaSourceInterface and
+// notify WebKit. It will be owned by MediaStreamSourceExtraData.
+class CONTENT_EXPORT MediaStreamSourceObserver
+ : NON_EXPORTED_BASE(public webrtc::ObserverInterface),
+ NON_EXPORTED_BASE(public base::NonThreadSafe) {
+ public:
+ MediaStreamSourceObserver(webrtc::MediaSourceInterface* webrtc_source,
+ MediaStreamSourceExtraData* extra_data);
+ virtual ~MediaStreamSourceObserver();
+
+ private:
+ // webrtc::ObserverInterface implementation.
+ virtual void OnChanged() OVERRIDE;
+
+ webrtc::MediaSourceInterface::SourceState state_;
+ scoped_refptr<webrtc::MediaSourceInterface> webrtc_source_;
+ MediaStreamSourceExtraData* extra_data_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaStreamSourceObserver);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_MEDIA_STREAM_SOURCE_OBSERVER_H_
diff --git a/content/renderer/media/mock_media_stream_dependency_factory.cc b/content/renderer/media/mock_media_stream_dependency_factory.cc
index af3177f..c47ba26 100644
--- a/content/renderer/media/mock_media_stream_dependency_factory.cc
+++ b/content/renderer/media/mock_media_stream_dependency_factory.cc
@@ -5,9 +5,11 @@
#include "content/renderer/media/mock_media_stream_dependency_factory.h"
#include "base/logging.h"
+#include "base/utf_string_conversions.h"
#include "content/renderer/media/mock_peer_connection_impl.h"
#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
#include "third_party/libjingle/source/talk/base/scoped_ref_ptr.h"
+#include "third_party/libjingle/source/talk/media/base/videocapturer.h"
using webrtc::AudioSourceInterface;
using webrtc::AudioTrackInterface;
@@ -39,23 +41,40 @@
class MockMediaStream : public webrtc::MediaStreamInterface {
public:
explicit MockMediaStream(const std::string& label)
- : label_(label) {
+ : label_(label),
+ observer_(NULL) {
}
virtual bool AddTrack(AudioTrackInterface* track) OVERRIDE {
audio_track_vector_.push_back(track);
+ if (observer_)
+ observer_->OnChanged();
return true;
}
virtual bool AddTrack(VideoTrackInterface* track) OVERRIDE {
video_track_vector_.push_back(track);
+ if (observer_)
+ observer_->OnChanged();
return true;
}
virtual bool RemoveTrack(AudioTrackInterface* track) OVERRIDE {
- NOTIMPLEMENTED();
- return false;
+ AudioTrackVector::iterator it = FindTrack(&audio_track_vector_,
+ track->id());
+ if (it == audio_track_vector_.end())
+ return false;
+ audio_track_vector_.erase(it);
+ if (observer_)
+ observer_->OnChanged();
+ return true;
}
virtual bool RemoveTrack(VideoTrackInterface* track) OVERRIDE {
- NOTIMPLEMENTED();
- return false;
+ VideoTrackVector::iterator it = FindTrack(&video_track_vector_,
+ track->id());
+ if (it == video_track_vector_.end())
+ return false;
+ video_track_vector_.erase(it);
+ if (observer_)
+ observer_->OnChanged();
+ return true;
}
virtual std::string label() const OVERRIDE { return label_; }
virtual AudioTrackVector GetAudioTracks() OVERRIDE {
@@ -75,10 +94,12 @@
return it == video_track_vector_.end() ? NULL : *it;
}
virtual void RegisterObserver(ObserverInterface* observer) OVERRIDE {
- NOTIMPLEMENTED();
+ DCHECK(!observer_);
+ observer_ = observer;
}
virtual void UnregisterObserver(ObserverInterface* observer) OVERRIDE {
- NOTIMPLEMENTED();
+ DCHECK(observer_ == observer);
+ observer_ = NULL;
}
protected:
@@ -88,6 +109,7 @@
std::string label_;
AudioTrackVector audio_track_vector_;
VideoTrackVector video_track_vector_;
+ webrtc::ObserverInterface* observer_;
};
MockAudioSource::MockAudioSource(
@@ -128,15 +150,17 @@
}
MockVideoSource::MockVideoSource()
- : observer_(NULL),
- state_(MediaSourceInterface::kInitializing) {
+ : state_(MediaSourceInterface::kInitializing) {
}
MockVideoSource::~MockVideoSource() {}
+void MockVideoSource::SetVideoCapturer(cricket::VideoCapturer* capturer) {
+ capturer_.reset(capturer);
+}
+
cricket::VideoCapturer* MockVideoSource::GetVideoCapturer() {
- NOTIMPLEMENTED();
- return NULL;
+ return capturer_.get();
}
void MockVideoSource::AddSink(cricket::VideoRenderer* output) {
@@ -148,26 +172,37 @@
}
void MockVideoSource::RegisterObserver(webrtc::ObserverInterface* observer) {
- observer_ = observer;
+ observers_.push_back(observer);
}
void MockVideoSource::UnregisterObserver(webrtc::ObserverInterface* observer) {
- DCHECK(observer_ == observer);
- observer_ = NULL;
+ for (std::vector<ObserverInterface*>::iterator it = observers_.begin();
+ it != observers_.end(); ++it) {
+ if (*it == observer) {
+ observers_.erase(it);
+ break;
+ }
+ }
+}
+
+void MockVideoSource::FireOnChanged() {
+ std::vector<ObserverInterface*> observers(observers_);
+ for (std::vector<ObserverInterface*>::iterator it = observers.begin();
+ it != observers.end(); ++it) {
+ (*it)->OnChanged();
+ }
}
void MockVideoSource::SetLive() {
DCHECK_EQ(MediaSourceInterface::kInitializing, state_);
state_ = MediaSourceInterface::kLive;
- if (observer_)
- observer_->OnChanged();
+ FireOnChanged();
}
void MockVideoSource::SetEnded() {
DCHECK_NE(MediaSourceInterface::kEnded, state_);
state_ = MediaSourceInterface::kEnded;
- if (observer_)
- observer_->OnChanged();
+ FireOnChanged();
}
webrtc::MediaSourceInterface::SourceState MockVideoSource::state() const {
@@ -183,7 +218,9 @@
webrtc::VideoSourceInterface* source)
: enabled_(false),
id_(id),
- source_(source) {
+ state_(MediaStreamTrackInterface::kLive),
+ source_(source),
+ observer_(NULL) {
}
MockLocalVideoTrack::~MockLocalVideoTrack() {}
@@ -203,7 +240,7 @@
std::string MockLocalVideoTrack::kind() const {
NOTIMPLEMENTED();
- return "";
+ return std::string();
}
std::string MockLocalVideoTrack::id() const { return id_; }
@@ -211,8 +248,7 @@
bool MockLocalVideoTrack::enabled() const { return enabled_; }
MockLocalVideoTrack::TrackState MockLocalVideoTrack::state() const {
- NOTIMPLEMENTED();
- return kInitializing;
+ return state_;
}
bool MockLocalVideoTrack::set_enabled(bool enable) {
@@ -221,16 +257,19 @@
}
bool MockLocalVideoTrack::set_state(TrackState new_state) {
- NOTIMPLEMENTED();
- return false;
+ state_ = new_state;
+ if (observer_)
+ observer_->OnChanged();
+ return true;
}
void MockLocalVideoTrack::RegisterObserver(ObserverInterface* observer) {
- NOTIMPLEMENTED();
+ observer_ = observer;
}
void MockLocalVideoTrack::UnregisterObserver(ObserverInterface* observer) {
- NOTIMPLEMENTED();
+ DCHECK(observer_ == observer);
+ observer_ = NULL;
}
VideoSourceInterface* MockLocalVideoTrack::GetSource() const {
@@ -239,16 +278,15 @@
std::string MockLocalAudioTrack::kind() const {
NOTIMPLEMENTED();
- return "";
+ return std::string();
}
std::string MockLocalAudioTrack::id() const { return id_; }
bool MockLocalAudioTrack::enabled() const { return enabled_; }
-MockLocalVideoTrack::TrackState MockLocalAudioTrack::state() const {
- NOTIMPLEMENTED();
- return kInitializing;
+MockLocalAudioTrack::TrackState MockLocalAudioTrack::state() const {
+ return state_;
}
bool MockLocalAudioTrack::set_enabled(bool enable) {
@@ -257,16 +295,19 @@
}
bool MockLocalAudioTrack::set_state(TrackState new_state) {
- NOTIMPLEMENTED();
- return false;
+ state_ = new_state;
+ if (observer_)
+ observer_->OnChanged();
+ return true;
}
void MockLocalAudioTrack::RegisterObserver(ObserverInterface* observer) {
- NOTIMPLEMENTED();
+ observer_ = observer;
}
void MockLocalAudioTrack::UnregisterObserver(ObserverInterface* observer) {
- NOTIMPLEMENTED();
+ DCHECK(observer_ == observer);
+ observer_ = NULL;
}
AudioSourceInterface* MockLocalAudioTrack::GetSource() const {
@@ -292,11 +333,11 @@
}
virtual std::string session_id() const OVERRIDE {
NOTIMPLEMENTED();
- return "";
+ return std::string();
}
virtual std::string session_version() const OVERRIDE {
NOTIMPLEMENTED();
- return "";
+ return std::string();
}
virtual std::string type() const OVERRIDE {
return type_;
@@ -403,7 +444,8 @@
}
bool MockMediaStreamDependencyFactory::InitializeAudioSource(
- const StreamDeviceInfo& device_info) {
+ int render_view_id,
+ const StreamDeviceInfo& device_info) {
return true;
}
@@ -430,6 +472,19 @@
return track;
}
+scoped_refptr<webrtc::VideoTrackInterface>
+MockMediaStreamDependencyFactory::CreateLocalVideoTrack(
+ const std::string& id,
+ cricket::VideoCapturer* capturer) {
+ DCHECK(mock_pc_factory_created_);
+
+ scoped_refptr<MockVideoSource> source =
+ new talk_base::RefCountedObject<MockVideoSource>();
+ source->SetVideoCapturer(capturer);
+
+ return new talk_base::RefCountedObject<MockLocalVideoTrack>(id, source);
+}
+
scoped_refptr<webrtc::AudioTrackInterface>
MockMediaStreamDependencyFactory::CreateLocalAudioTrack(
const std::string& id,
diff --git a/content/renderer/media/mock_media_stream_dependency_factory.h b/content/renderer/media/mock_media_stream_dependency_factory.h
index e7c4221..7b44ac2 100644
--- a/content/renderer/media/mock_media_stream_dependency_factory.h
+++ b/content/renderer/media/mock_media_stream_dependency_factory.h
@@ -10,6 +10,7 @@
#include "base/compiler_specific.h"
#include "content/renderer/media/media_stream_dependency_factory.h"
+#include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface.h"
namespace content {
@@ -29,18 +30,24 @@
void SetLive();
// Changes the state of the source to ended and notifies the observer.
void SetEnded();
+ // Set the video capturer.
+ void SetVideoCapturer(cricket::VideoCapturer* capturer);
protected:
virtual ~MockVideoSource();
private:
- webrtc::ObserverInterface* observer_;
- MediaSourceInterface::SourceState state_;
+ void FireOnChanged();
+
+ std::vector<webrtc::ObserverInterface*> observers_;
+ MediaSourceInterface::SourceState state_;
+ scoped_ptr<cricket::VideoCapturer> capturer_;
};
class MockAudioSource : public webrtc::AudioSourceInterface {
public:
- MockAudioSource(const webrtc::MediaConstraintsInterface* constraints);
+ explicit MockAudioSource(
+ const webrtc::MediaConstraintsInterface* constraints);
virtual void RegisterObserver(webrtc::ObserverInterface* observer) OVERRIDE;
virtual void UnregisterObserver(webrtc::ObserverInterface* observer) OVERRIDE;
@@ -94,14 +101,18 @@
private:
bool enabled_;
std::string id_;
+ TrackState state_;
scoped_refptr<webrtc::VideoSourceInterface> source_;
+ webrtc::ObserverInterface* observer_;
};
class MockLocalAudioTrack : public webrtc::AudioTrackInterface {
public:
explicit MockLocalAudioTrack(const std::string& id)
: enabled_(false),
- id_(id) {
+ id_(id),
+ state_(MediaStreamTrackInterface::kLive),
+ observer_(NULL) {
}
virtual std::string kind() const OVERRIDE;
virtual std::string id() const OVERRIDE;
@@ -119,6 +130,8 @@
private:
bool enabled_;
std::string id_;
+ TrackState state_;
+ webrtc::ObserverInterface* observer_;
};
// A mock factory for creating different objects for
@@ -142,7 +155,7 @@
bool is_screencast,
const webrtc::MediaConstraintsInterface* constraints) OVERRIDE;
virtual bool InitializeAudioSource(
- const StreamDeviceInfo& device_info) OVERRIDE;
+ int render_view_id, const StreamDeviceInfo& device_info) OVERRIDE;
virtual bool CreateWebAudioSource(
WebKit::WebMediaStreamSource* source) OVERRIDE;
virtual scoped_refptr<webrtc::MediaStreamInterface>
@@ -150,6 +163,9 @@
virtual scoped_refptr<webrtc::VideoTrackInterface>
CreateLocalVideoTrack(const std::string& id,
webrtc::VideoSourceInterface* source) OVERRIDE;
+ virtual scoped_refptr<webrtc::VideoTrackInterface>
+ CreateLocalVideoTrack(const std::string& id,
+ cricket::VideoCapturer* capturer) OVERRIDE;
virtual scoped_refptr<webrtc::AudioTrackInterface>
CreateLocalAudioTrack(const std::string& id,
webrtc::AudioSourceInterface* source) OVERRIDE;
diff --git a/content/renderer/media/mock_media_stream_registry.cc b/content/renderer/media/mock_media_stream_registry.cc
new file mode 100644
index 0000000..964be2a
--- /dev/null
+++ b/content/renderer/media/mock_media_stream_registry.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/mock_media_stream_registry.h"
+
+#include <string>
+
+#include "base/utf_string_conversions.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamSource.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamTrack.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h"
+#include "third_party/libjingle/source/talk/media/base/videocapturer.h"
+
+namespace content {
+
+static const std::string kTestStreamLabel = "stream_label";
+
+MockMediaStreamRegistry::MockMediaStreamRegistry(
+ MockMediaStreamDependencyFactory* factory)
+ : factory_(factory) {
+}
+
+void MockMediaStreamRegistry::Init(const std::string& stream_url) {
+ stream_url_ = stream_url;
+ scoped_refptr<webrtc::MediaStreamInterface> stream(
+ factory_->CreateLocalMediaStream(kTestStreamLabel));
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> webkit_audio_tracks;
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> webkit_video_tracks;
+ WebKit::WebString webkit_stream_label(UTF8ToUTF16(stream->label()));
+ test_stream_.initialize(webkit_stream_label,
+ webkit_audio_tracks, webkit_video_tracks);
+ test_stream_.setExtraData(new MediaStreamExtraData(stream, false));
+}
+
+bool MockMediaStreamRegistry::AddVideoTrack(const std::string& track_id) {
+ cricket::VideoCapturer* capturer = NULL;
+ return factory_->AddNativeVideoMediaTrack(track_id, &test_stream_, capturer);
+}
+
+WebKit::WebMediaStream MockMediaStreamRegistry::GetMediaStream(
+ const std::string& url) {
+ if (url != stream_url_) {
+ return WebKit::WebMediaStream();
+ }
+ return test_stream_;
+}
+
+const WebKit::WebMediaStream MockMediaStreamRegistry::test_stream() const {
+ return test_stream_;
+}
+
+} // namespace content
diff --git a/content/renderer/media/mock_media_stream_registry.h b/content/renderer/media/mock_media_stream_registry.h
new file mode 100644
index 0000000..4d77395
--- /dev/null
+++ b/content/renderer/media/mock_media_stream_registry.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_MOCK_MEDIA_STREAM_REGISTRY_H_
+#define CONTENT_RENDERER_MEDIA_MOCK_MEDIA_STREAM_REGISTRY_H_
+
+#include <string>
+
+#include "content/renderer/media/media_stream_registry_interface.h"
+#include "content/renderer/media/mock_media_stream_dependency_factory.h"
+
+namespace content {
+
+class MockMediaStreamRegistry : public MediaStreamRegistryInterface {
+ public:
+ explicit MockMediaStreamRegistry(MockMediaStreamDependencyFactory* factory);
+
+ void Init(const std::string& stream_label);
+ bool AddVideoTrack(const std::string& track_id);
+ virtual WebKit::WebMediaStream GetMediaStream(const std::string& url)
+ OVERRIDE;
+ const WebKit::WebMediaStream test_stream() const;
+
+ private:
+ MockMediaStreamDependencyFactory* factory_;
+ WebKit::WebMediaStream test_stream_;
+ std::string stream_url_;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_MOCK_MEDIA_STREAM_REGISTRY_H_
diff --git a/content/renderer/media/mock_peer_connection_impl.cc b/content/renderer/media/mock_peer_connection_impl.cc
index 597d24f..db36c30 100644
--- a/content/renderer/media/mock_peer_connection_impl.cc
+++ b/content/renderer/media/mock_peer_connection_impl.cc
@@ -244,21 +244,21 @@
webrtc::StatsReport report;
report.id = "1234";
report.type = "ssrc";
- report.local.timestamp = 42;
- webrtc::StatsElement::Value value;
+ report.timestamp = 42;
+ webrtc::StatsReport::Value value;
value.name = "trackname";
value.value = "trackvalue";
- report.local.values.push_back(value);
+ report.values.push_back(value);
reports.push_back(report);
// If selector is given, we pass back one report.
// If selector is not given, we pass back two.
if (!track) {
report.id = "nontrack";
report.type = "generic";
- report.local.timestamp = 44;
+ report.timestamp = 44;
value.name = "somename";
value.value = "somevalue";
- report.local.values.push_back(value);
+ report.values.push_back(value);
reports.push_back(report);
}
// Note that the callback is synchronous, not asynchronous; it will
diff --git a/content/renderer/media/peer_connection_handler_base.cc b/content/renderer/media/peer_connection_handler_base.cc
index 1854a99..24585e0 100644
--- a/content/renderer/media/peer_connection_handler_base.cc
+++ b/content/renderer/media/peer_connection_handler_base.cc
@@ -51,43 +51,6 @@
DCHECK(native_stream);
}
-WebKit::WebMediaStream
-PeerConnectionHandlerBase::CreateRemoteWebKitMediaStream(
- webrtc::MediaStreamInterface* stream) {
- webrtc::AudioTrackVector audio_tracks = stream->GetAudioTracks();
- webrtc::VideoTrackVector video_tracks = stream->GetVideoTracks();
- WebKit::WebVector<WebKit::WebMediaStreamSource> audio_source_vector(
- audio_tracks.size());
- WebKit::WebVector<WebKit::WebMediaStreamSource> video_source_vector(
- video_tracks.size());
-
- // Add audio tracks.
- size_t i = 0;
- for (; i < audio_tracks.size(); ++i) {
- webrtc::AudioTrackInterface* audio_track = audio_tracks[i];
- DCHECK(audio_track);
- audio_source_vector[i].initialize(
- UTF8ToUTF16(audio_track->id()),
- WebKit::WebMediaStreamSource::TypeAudio,
- UTF8ToUTF16(audio_track->id()));
- }
-
- // Add video tracks.
- for (i = 0; i < video_tracks.size(); ++i) {
- webrtc::VideoTrackInterface* video_track = video_tracks[i];
- DCHECK(video_track);
- video_source_vector[i].initialize(
- UTF8ToUTF16(video_track->id()),
- WebKit::WebMediaStreamSource::TypeVideo,
- UTF8ToUTF16(video_track->id()));
- }
- WebKit::WebMediaStream descriptor;
- descriptor.initialize(UTF8ToUTF16(stream->label()),
- audio_source_vector, video_source_vector);
- descriptor.setExtraData(new MediaStreamExtraData(stream, false));
- return descriptor;
-}
-
webrtc::MediaStreamTrackInterface*
PeerConnectionHandlerBase::GetNativeMediaStreamTrack(
const WebKit::WebMediaStream& stream,
diff --git a/content/renderer/media/peer_connection_handler_base.h b/content/renderer/media/peer_connection_handler_base.h
index 824b5c5..f9c5cef 100644
--- a/content/renderer/media/peer_connection_handler_base.h
+++ b/content/renderer/media/peer_connection_handler_base.h
@@ -18,6 +18,7 @@
namespace content {
class MediaStreamDependencyFactory;
+class RemoteMediaStreamImpl;
// PeerConnectionHandlerBase is the base class of a delegate for the
// PeerConnection API messages going between WebKit and native
@@ -35,8 +36,6 @@
bool AddStream(const WebKit::WebMediaStream& stream,
const webrtc::MediaConstraintsInterface* constraints);
void RemoveStream(const WebKit::WebMediaStream& stream);
- WebKit::WebMediaStream CreateRemoteWebKitMediaStream(
- webrtc::MediaStreamInterface* stream);
webrtc::MediaStreamTrackInterface* GetNativeMediaStreamTrack(
const WebKit::WebMediaStream& stream,
const WebKit::WebMediaStreamTrack& component);
@@ -50,7 +49,7 @@
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_;
typedef std::map<webrtc::MediaStreamInterface*,
- WebKit::WebMediaStream> RemoteStreamMap;
+ content::RemoteMediaStreamImpl*> RemoteStreamMap;
RemoteStreamMap remote_streams_;
// The message loop we are created on and on which to make calls to WebKit.
diff --git a/content/renderer/media/peer_connection_tracker.cc b/content/renderer/media/peer_connection_tracker.cc
index 095d85f..3f2f23e 100644
--- a/content/renderer/media/peer_connection_tracker.cc
+++ b/content/renderer/media/peer_connection_tracker.cc
@@ -150,16 +150,19 @@
return result;
}
-// Builds a DictionaryValue from the StatsElement.
+// Builds a DictionaryValue from the StatsReport.
// The caller takes the ownership of the returned value.
-static DictionaryValue* GetDictValue(const webrtc::StatsElement& elem) {
- if (elem.values.empty())
+// Note:
+// The format must be consistent with what webrtc_internals.js expects.
+// If you change it here, you must change webrtc_internals.js as well.
+static DictionaryValue* GetDictValueStats(const webrtc::StatsReport& report) {
+ if (report.values.empty())
return NULL;
DictionaryValue* dict = new DictionaryValue();
if (!dict)
return NULL;
- dict->SetDouble("timestamp", elem.timestamp);
+ dict->SetDouble("timestamp", report.timestamp);
ListValue* values = new ListValue();
if (!values) {
@@ -168,9 +171,9 @@
}
dict->Set("values", values);
- for (size_t i = 0; i < elem.values.size(); ++i) {
- values->AppendString(elem.values[i].name);
- values->AppendString(elem.values[i].value);
+ for (size_t i = 0; i < report.values.size(); ++i) {
+ values->AppendString(report.values[i].name);
+ values->AppendString(report.values[i].value);
}
return dict;
}
@@ -178,21 +181,21 @@
// Builds a DictionaryValue from the StatsReport.
// The caller takes the ownership of the returned value.
static DictionaryValue* GetDictValue(const webrtc::StatsReport& report) {
- scoped_ptr<DictionaryValue> local, remote, result;
+ scoped_ptr<DictionaryValue> stats, result;
- local.reset(GetDictValue(report.local));
- remote.reset(GetDictValue(report.remote));
- if (!local.get() && !remote.get())
+ stats.reset(GetDictValueStats(report));
+ if (!stats)
return NULL;
result.reset(new DictionaryValue());
- if (!result.get())
+ if (!result)
return NULL;
- if (local.get())
- result->Set("local", local.release());
- if (remote.get())
- result->Set("remote", remote.release());
+ // Note:
+ // The format must be consistent with what webrtc_internals.js expects.
+ // If you change it here, you must change webrtc_internals.js as well.
+ if (stats)
+ result->Set("stats", stats.release());
result->SetString("id", report.id);
result->SetString("type", report.type);
@@ -310,12 +313,12 @@
void PeerConnectionTracker::TrackSetSessionDescription(
RTCPeerConnectionHandler* pc_handler,
- const webrtc::SessionDescriptionInterface* desc,
+ const WebKit::WebRTCSessionDescription& desc,
Source source) {
- string sdp;
- desc->ToString(&sdp);
+ string sdp = UTF16ToUTF8(desc.sdp());
+ string type = UTF16ToUTF8(desc.type());
- string value = "type: " + desc->type() + ", sdp: " + sdp;
+ string value = "type: " + type + ", sdp: " + sdp;
SendPeerConnectionUpdate(
pc_handler,
source == SOURCE_LOCAL ? "setLocalDescription" : "setRemoteDescription",
@@ -376,7 +379,7 @@
}
void PeerConnectionTracker::TrackStop(RTCPeerConnectionHandler* pc_handler) {
- SendPeerConnectionUpdate(pc_handler, "stop", "");
+ SendPeerConnectionUpdate(pc_handler, "stop", std::string());
}
void PeerConnectionTracker::TrackSignalingStateChange(
@@ -430,7 +433,7 @@
void PeerConnectionTracker::TrackOnRenegotiationNeeded(
RTCPeerConnectionHandler* pc_handler) {
- SendPeerConnectionUpdate(pc_handler, "onRenegotiationNeeded", "");
+ SendPeerConnectionUpdate(pc_handler, "onRenegotiationNeeded", std::string());
}
void PeerConnectionTracker::TrackCreateDTMFSender(
diff --git a/content/renderer/media/peer_connection_tracker.h b/content/renderer/media/peer_connection_tracker.h
index 9bd93fc..53e5369 100644
--- a/content/renderer/media/peer_connection_tracker.h
+++ b/content/renderer/media/peer_connection_tracker.h
@@ -11,12 +11,14 @@
#include "content/public/renderer/render_process_observer.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStream.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCPeerConnectionHandlerClient.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCSessionDescription.h"
#include "third_party/libjingle/source/talk/app/webrtc/peerconnectioninterface.h"
namespace WebKit {
class WebFrame;
class WebRTCICECandidate;
class WebString;
+class WebRTCSessionDescription;
} // namespace WebKit
namespace webrtc {
@@ -84,7 +86,7 @@
// Sends an update when setLocalDescription or setRemoteDescription is called.
virtual void TrackSetSessionDescription(
RTCPeerConnectionHandler* pc_handler,
- const webrtc::SessionDescriptionInterface* desc, Source source);
+ const WebKit::WebRTCSessionDescription& desc, Source source);
// Sends an update when Ice candidates are updated.
virtual void TrackUpdateIce(
diff --git a/content/renderer/media/pepper_platform_video_decoder_impl.cc b/content/renderer/media/pepper_platform_video_decoder_impl.cc
index ab444e8..d305ffa 100644
--- a/content/renderer/media/pepper_platform_video_decoder_impl.cc
+++ b/content/renderer/media/pepper_platform_video_decoder_impl.cc
@@ -26,7 +26,7 @@
bool PlatformVideoDecoderImpl::Initialize(media::VideoCodecProfile profile) {
// TODO(vrk): Support multiple decoders.
- if (decoder_.get())
+ if (decoder_)
return true;
RenderThreadImpl* render_thread = RenderThreadImpl::current();
@@ -43,8 +43,8 @@
DCHECK_EQ(channel->state(), GpuChannelHost::kConnected);
// Send IPC message to initialize decoder in GPU process.
- decoder_.reset(channel->CreateVideoDecoder(
- command_buffer_route_id_, profile, this));
+ decoder_ =
+ channel->CreateVideoDecoder(command_buffer_route_id_, profile, this);
return decoder_.get() != NULL;
}
@@ -76,7 +76,7 @@
}
void PlatformVideoDecoderImpl::Destroy() {
- if (decoder_.get())
+ if (decoder_)
decoder_.release()->Destroy();
client_ = NULL;
delete this;
diff --git a/content/renderer/media/remote_media_stream_impl.cc b/content/renderer/media/remote_media_stream_impl.cc
new file mode 100644
index 0000000..4242a92
--- /dev/null
+++ b/content/renderer/media/remote_media_stream_impl.cc
@@ -0,0 +1,217 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/remote_media_stream_impl.h"
+
+#include <string>
+
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "content/renderer/media/media_stream_extra_data.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
+
+namespace content {
+
+// RemoteMediaStreamTrackObserver is responsible for listening on change
+// notification on a remote webrtc MediaStreamTrack and notify WebKit.
+class RemoteMediaStreamTrackObserver
+ : NON_EXPORTED_BASE(public webrtc::ObserverInterface),
+ NON_EXPORTED_BASE(public base::NonThreadSafe) {
+ public:
+ RemoteMediaStreamTrackObserver(
+ webrtc::MediaStreamTrackInterface* webrtc_track,
+ const WebKit::WebMediaStreamTrack& webkit_track);
+ virtual ~RemoteMediaStreamTrackObserver();
+
+ webrtc::MediaStreamTrackInterface* observered_track() {
+ return webrtc_track_;
+ }
+ const WebKit::WebMediaStreamTrack& webkit_track() { return webkit_track_; }
+
+ private:
+ // webrtc::ObserverInterface implementation.
+ virtual void OnChanged() OVERRIDE;
+
+ webrtc::MediaStreamTrackInterface::TrackState state_;
+ scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track_;
+ WebKit::WebMediaStreamTrack webkit_track_;
+
+ DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackObserver);
+};
+
+} // namespace content
+
+namespace {
+
+void InitializeWebkitTrack(webrtc::MediaStreamTrackInterface* track,
+ WebKit::WebMediaStreamTrack* webkit_track,
+ WebKit::WebMediaStreamSource::Type type) {
+ WebKit::WebMediaStreamSource webkit_source;
+ WebKit::WebString webkit_track_id(UTF8ToUTF16(track->id()));
+
+ webkit_source.initialize(webkit_track_id, type, webkit_track_id);
+ webkit_track->initialize(webkit_track_id, webkit_source);
+}
+
+content::RemoteMediaStreamTrackObserver* FindTrackObserver(
+ webrtc::MediaStreamTrackInterface* track,
+ const ScopedVector<content::RemoteMediaStreamTrackObserver>& observers) {
+ ScopedVector<content::RemoteMediaStreamTrackObserver>::const_iterator it =
+ observers.begin();
+ for (; it != observers.end(); ++it) {
+ if ((*it)->observered_track() == track)
+ return *it;
+ }
+ return NULL;
+}
+
+} // namespace anonymous
+
+namespace content {
+
+RemoteMediaStreamTrackObserver::RemoteMediaStreamTrackObserver(
+ webrtc::MediaStreamTrackInterface* webrtc_track,
+ const WebKit::WebMediaStreamTrack& webkit_track)
+ : state_(webrtc_track->state()),
+ webrtc_track_(webrtc_track),
+ webkit_track_(webkit_track) {
+ webrtc_track->RegisterObserver(this);
+}
+
+RemoteMediaStreamTrackObserver::~RemoteMediaStreamTrackObserver() {
+ webrtc_track_->UnregisterObserver(this);
+}
+
+void RemoteMediaStreamTrackObserver::OnChanged() {
+ DCHECK(CalledOnValidThread());
+
+ webrtc::MediaStreamTrackInterface::TrackState state = webrtc_track_->state();
+ if (state == state_)
+ return;
+
+ state_ = state;
+ switch (state) {
+ case webrtc::MediaStreamTrackInterface::kInitializing:
+ // Ignore the kInitializing state since there is no match in
+ // WebMediaStreamSource::ReadyState.
+ break;
+ case webrtc::MediaStreamTrackInterface::kLive:
+ webkit_track_.source().setReadyState(
+ WebKit::WebMediaStreamSource::ReadyStateLive);
+ break;
+ case webrtc::MediaStreamTrackInterface::kEnded:
+ webkit_track_.source().setReadyState(
+ WebKit::WebMediaStreamSource::ReadyStateEnded);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+RemoteMediaStreamImpl::RemoteMediaStreamImpl(
+ webrtc::MediaStreamInterface* webrtc_stream)
+ : webrtc_stream_(webrtc_stream) {
+ webrtc_stream_->RegisterObserver(this);
+
+ webrtc::AudioTrackVector webrtc_audio_tracks =
+ webrtc_stream_->GetAudioTracks();
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> webkit_audio_tracks(
+ webrtc_audio_tracks.size());
+
+ // Initialize WebKit audio tracks.
+ size_t i = 0;
+ for (; i < webrtc_audio_tracks.size(); ++i) {
+ webrtc::AudioTrackInterface* audio_track = webrtc_audio_tracks[i];
+ DCHECK(audio_track);
+ InitializeWebkitTrack(audio_track, &webkit_audio_tracks[i],
+ WebKit::WebMediaStreamSource::TypeAudio);
+ audio_track_observers_.push_back(
+ new RemoteMediaStreamTrackObserver(audio_track,
+ webkit_audio_tracks[i]));
+ }
+
+ // Initialize WebKit video tracks.
+ webrtc::VideoTrackVector webrtc_video_tracks =
+ webrtc_stream_->GetVideoTracks();
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> webkit_video_tracks(
+ webrtc_video_tracks.size());
+ for (i = 0; i < webrtc_video_tracks.size(); ++i) {
+ webrtc::VideoTrackInterface* video_track = webrtc_video_tracks[i];
+ DCHECK(video_track);
+ InitializeWebkitTrack(video_track, &webkit_video_tracks[i],
+ WebKit::WebMediaStreamSource::TypeVideo);
+ video_track_observers_.push_back(
+ new RemoteMediaStreamTrackObserver(video_track,
+ webkit_video_tracks[i]));
+ }
+
+ webkit_stream_.initialize(UTF8ToUTF16(webrtc_stream->label()),
+ webkit_audio_tracks, webkit_video_tracks);
+ webkit_stream_.setExtraData(new MediaStreamExtraData(webrtc_stream, false));
+}
+
+RemoteMediaStreamImpl::~RemoteMediaStreamImpl() {
+ webrtc_stream_->UnregisterObserver(this);
+}
+
+void RemoteMediaStreamImpl::OnChanged() {
+ // Find removed audio tracks.
+ ScopedVector<RemoteMediaStreamTrackObserver>::iterator audio_it =
+ audio_track_observers_.begin();
+ while (audio_it != audio_track_observers_.end()) {
+ std::string track_id = (*audio_it)->observered_track()->id();
+ if (webrtc_stream_->FindAudioTrack(track_id) == NULL) {
+ webkit_stream_.removeTrack((*audio_it)->webkit_track());
+ audio_it = audio_track_observers_.erase(audio_it);
+ } else {
+ ++audio_it;
+ }
+ }
+
+ // Find removed video tracks.
+ ScopedVector<RemoteMediaStreamTrackObserver>::iterator video_it =
+ video_track_observers_.begin();
+ while (video_it != video_track_observers_.end()) {
+ std::string track_id = (*video_it)->observered_track()->id();
+ if (webrtc_stream_->FindVideoTrack(track_id) == NULL) {
+ webkit_stream_.removeTrack((*video_it)->webkit_track());
+ video_it = video_track_observers_.erase(video_it);
+ } else {
+ ++video_it;
+ }
+ }
+
+ // Find added audio tracks.
+ webrtc::AudioTrackVector webrtc_audio_tracks =
+ webrtc_stream_->GetAudioTracks();
+ for (webrtc::AudioTrackVector::iterator it = webrtc_audio_tracks.begin();
+ it != webrtc_audio_tracks.end(); ++it) {
+ if (!FindTrackObserver(*it, audio_track_observers_)) {
+ WebKit::WebMediaStreamTrack new_track;
+ InitializeWebkitTrack(*it, &new_track,
+ WebKit::WebMediaStreamSource::TypeAudio);
+ audio_track_observers_.push_back(
+ new RemoteMediaStreamTrackObserver(*it, new_track));
+ webkit_stream_.addTrack(new_track);
+ }
+ }
+
+ // Find added video tracks.
+ webrtc::VideoTrackVector webrtc_video_tracks =
+ webrtc_stream_->GetVideoTracks();
+ for (webrtc::VideoTrackVector::iterator it = webrtc_video_tracks.begin();
+ it != webrtc_video_tracks.end(); ++it) {
+ if (!FindTrackObserver(*it, video_track_observers_)) {
+ WebKit::WebMediaStreamTrack new_track;
+ InitializeWebkitTrack(*it, &new_track,
+ WebKit::WebMediaStreamSource::TypeVideo);
+ video_track_observers_.push_back(
+ new RemoteMediaStreamTrackObserver(*it, new_track));
+ webkit_stream_.addTrack(new_track);
+ }
+ }
+}
+
+} // namespace content
diff --git a/content/renderer/media/remote_media_stream_impl.h b/content/renderer/media/remote_media_stream_impl.h
new file mode 100644
index 0000000..361cc70
--- /dev/null
+++ b/content/renderer/media/remote_media_stream_impl.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_REMOTE_MEDIA_STREAM_IMPL_H_
+#define CONTENT_RENDERER_MEDIA_REMOTE_MEDIA_STREAM_IMPL_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_vector.h"
+#include "base/threading/non_thread_safe.h"
+#include "content/common/content_export.h"
+#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStream.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamSource.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamTrack.h"
+
+namespace content {
+
+class RemoteMediaStreamTrackObserver;
+
+// RemoteMediaStreamImpl serves as a container and glue between remote webrtc
+// MediaStreams and WebKit MediaStreams. For each remote MediaStream received
+// on a PeerConnection a RemoteMediaStreamImpl instance is created and
+// owned by RtcPeerConnection.
+class CONTENT_EXPORT RemoteMediaStreamImpl
+ : NON_EXPORTED_BASE(public webrtc::ObserverInterface),
+ NON_EXPORTED_BASE(public base::NonThreadSafe) {
+ public:
+ explicit RemoteMediaStreamImpl(
+ webrtc::MediaStreamInterface* webrtc_stream);
+ virtual ~RemoteMediaStreamImpl();
+
+ const WebKit::WebMediaStream& webkit_stream() { return webkit_stream_; }
+
+ private:
+ // webrtc::ObserverInterface implementation.
+ virtual void OnChanged() OVERRIDE;
+
+ scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream_;
+ ScopedVector<RemoteMediaStreamTrackObserver> audio_track_observers_;
+ ScopedVector<RemoteMediaStreamTrackObserver> video_track_observers_;
+ WebKit::WebMediaStream webkit_stream_;
+
+ DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_REMOTE_MEDIA_STREAM_IMPL_H_
diff --git a/content/renderer/media/render_media_log.cc b/content/renderer/media/render_media_log.cc
index 23ea4ee..8e4de53 100644
--- a/content/renderer/media/render_media_log.cc
+++ b/content/renderer/media/render_media_log.cc
@@ -5,26 +5,39 @@
#include "content/renderer/media/render_media_log.h"
#include "base/bind.h"
+#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "content/common/view_messages.h"
#include "content/renderer/render_thread_impl.h"
+using base::Time;
+using base::TimeDelta;
+
namespace content {
RenderMediaLog::RenderMediaLog()
- : render_loop_(base::MessageLoopProxy::current()) {
+ : render_loop_(base::MessageLoopProxy::current()),
+ last_ipc_send_time_(Time::Now()) {
DCHECK(RenderThreadImpl::current()) <<
"RenderMediaLog must be constructed on the render thread";
}
void RenderMediaLog::AddEvent(scoped_ptr<media::MediaLogEvent> event) {
- if (RenderThreadImpl::current()) {
- RenderThreadImpl::current()->Send(
- new ViewHostMsg_MediaLogEvent(*event));
- } else {
+ if (!RenderThreadImpl::current()) {
render_loop_->PostTask(FROM_HERE, base::Bind(
&RenderMediaLog::AddEvent, this, base::Passed(&event)));
+ return;
}
+ queued_media_events_.push_back(*event);
+ // Limit the send rate of high frequency events.
+ Time curr_time = Time::Now();
+ if ((curr_time - last_ipc_send_time_) < TimeDelta::FromSeconds(1))
+ return;
+ last_ipc_send_time_ = curr_time;
+ DVLOG(1) << "media log events array size " << queued_media_events_.size();
+ RenderThreadImpl::current()->Send(
+ new ViewHostMsg_MediaLogEvents(queued_media_events_));
+ queued_media_events_.clear();
}
RenderMediaLog::~RenderMediaLog() {}
diff --git a/content/renderer/media/render_media_log.h b/content/renderer/media/render_media_log.h
index 4c26cdf..70070b3 100644
--- a/content/renderer/media/render_media_log.h
+++ b/content/renderer/media/render_media_log.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_RENDERER_MEDIA_RENDER_MEDIA_LOG_H_
#define CONTENT_RENDERER_MEDIA_RENDER_MEDIA_LOG_H_
+#include <vector>
+#include "base/time.h"
#include "media/base/media_log.h"
namespace base {
@@ -14,7 +16,7 @@
namespace content {
// RenderMediaLog is an implementation of MediaLog that passes all events to the
-// browser process.
+// browser process, throttling as necessary.
class RenderMediaLog : public media::MediaLog {
public:
RenderMediaLog();
@@ -26,6 +28,8 @@
virtual ~RenderMediaLog();
scoped_refptr<base::MessageLoopProxy> render_loop_;
+ base::Time last_ipc_send_time_;
+ std::vector<media::MediaLogEvent> queued_media_events_;
DISALLOW_COPY_AND_ASSIGN(RenderMediaLog);
};
diff --git a/content/renderer/media/renderer_audio_output_device.cc b/content/renderer/media/renderer_audio_output_device.cc
deleted file mode 100644
index 678bbec..0000000
--- a/content/renderer/media/renderer_audio_output_device.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/renderer/media/renderer_audio_output_device.h"
-
-#include "base/bind.h"
-#include "base/message_loop_proxy.h"
-#include "content/renderer/media/audio_message_filter.h"
-
-namespace content {
-
-RendererAudioOutputDevice::RendererAudioOutputDevice(
- AudioMessageFilter* message_filter,
- const scoped_refptr<base::MessageLoopProxy>& io_loop)
- : AudioOutputDevice(message_filter, io_loop),
- source_render_view_id_(MSG_ROUTING_NONE),
- is_after_stream_created_(false) {
-}
-
-RendererAudioOutputDevice::~RendererAudioOutputDevice() {}
-
-void RendererAudioOutputDevice::Start() {
- AudioOutputDevice::Start();
- message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&RendererAudioOutputDevice::OnStart, this));
-}
-
-void RendererAudioOutputDevice::Stop() {
- AudioOutputDevice::Stop();
- message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&RendererAudioOutputDevice::OnStop, this));
-}
-
-void RendererAudioOutputDevice::SetSourceRenderView(int render_view_id) {
- message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&RendererAudioOutputDevice::OnSourceChange, this,
- render_view_id));
-}
-
-void RendererAudioOutputDevice::OnStart() {
- DCHECK(message_loop()->BelongsToCurrentThread());
- is_after_stream_created_ = true;
- OnSourceChange(source_render_view_id_);
-}
-
-void RendererAudioOutputDevice::OnStop() {
- DCHECK(message_loop()->BelongsToCurrentThread());
- is_after_stream_created_ = false;
-}
-
-void RendererAudioOutputDevice::OnSourceChange(int render_view_id) {
- DCHECK(message_loop()->BelongsToCurrentThread());
- source_render_view_id_ = render_view_id;
- if (is_after_stream_created_ && source_render_view_id_ != MSG_ROUTING_NONE) {
- AudioMessageFilter* const filter =
- static_cast<AudioMessageFilter*>(audio_output_ipc());
- if (filter)
- filter->AssociateStreamWithProducer(stream_id(), source_render_view_id_);
- }
-}
-
-} // namespace content
diff --git a/content/renderer/media/renderer_audio_output_device.h b/content/renderer/media/renderer_audio_output_device.h
deleted file mode 100644
index 601cca5..0000000
--- a/content/renderer/media/renderer_audio_output_device.h
+++ /dev/null
@@ -1,58 +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_RENDERER_MEDIA_RENDERER_AUDIO_OUTPUT_DEVICE_H_
-#define CONTENT_RENDERER_MEDIA_RENDERER_AUDIO_OUTPUT_DEVICE_H_
-
-#include "base/memory/ref_counted.h"
-#include "media/audio/audio_output_device.h"
-
-namespace base {
-class MessageLoopProxy;
-}
-
-namespace content {
-
-class AudioDeviceFactory;
-class AudioMessageFilter;
-
-// Subclass of media::AudioOutputDevice to support additional concepts within
-// the content component. Use AudioDeviceFactory to instantiate this class.
-class RendererAudioOutputDevice
- : NON_EXPORTED_BASE(public media::AudioOutputDevice) {
- public:
- // Set the source of the rendered audio data to the RenderView specified by
- // |render_view_id|. Callers should keep in mind that the RenderView which
- // caused the instantiation of RendererAudioOutputDevice might not necessarily
- // be same as the RenderView which actually renders the audio data.
- void SetSourceRenderView(int render_view_id);
-
- virtual void Start() OVERRIDE;
- virtual void Stop() OVERRIDE;
-
- protected:
- friend class AudioDeviceFactory;
-
- // Creates an uninitialized RendererAudioOutputDevice. Clients must call
- // Initialize() before using.
- RendererAudioOutputDevice(
- AudioMessageFilter* message_filter,
- const scoped_refptr<base::MessageLoopProxy>& io_loop);
-
- private:
- virtual ~RendererAudioOutputDevice();
-
- void OnStart();
- void OnStop();
- void OnSourceChange(int render_view_id);
-
- int source_render_view_id_;
- bool is_after_stream_created_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(RendererAudioOutputDevice);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_RENDERER_AUDIO_OUTPUT_DEVICE_H_
diff --git a/content/renderer/media/renderer_gpu_video_decoder_factories.cc b/content/renderer/media/renderer_gpu_video_decoder_factories.cc
index cdd5804..8aff387 100644
--- a/content/renderer/media/renderer_gpu_video_decoder_factories.cc
+++ b/content/renderer/media/renderer_gpu_video_decoder_factories.cc
@@ -8,12 +8,12 @@
#include <GLES2/gl2ext.h>
#include "base/bind.h"
-#include "base/synchronization/waitable_event.h"
#include "content/common/child_thread.h"
#include "content/common/gpu/client/gpu_channel_host.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/ipc/command_buffer_proxy.h"
+#include "third_party/skia/include/core/SkPixelRef.h"
namespace content {
@@ -23,13 +23,15 @@
const scoped_refptr<base::MessageLoopProxy>& message_loop,
WebGraphicsContext3DCommandBufferImpl* context)
: message_loop_(message_loop),
- gpu_channel_host_(gpu_channel_host) {
+ gpu_channel_host_(gpu_channel_host),
+ aborted_waiter_(true, false),
+ compositor_loop_async_waiter_(false, false),
+ render_thread_async_waiter_(false, false) {
if (message_loop_->BelongsToCurrentThread()) {
- AsyncGetContext(context, NULL);
+ AsyncGetContext(context);
return;
}
// Threaded compositor requires us to wait for the context to be acquired.
- base::WaitableEvent waiter(false, false);
message_loop_->PostTask(FROM_HERE, base::Bind(
&RendererGpuVideoDecoderFactories::AsyncGetContext,
// Unretained to avoid ref/deref'ing |*this|, which is not yet stored in a
@@ -40,14 +42,12 @@
// thread, and only as the result of a PostTask from the render thread
// which can only happen after this function returns, so our PostTask will
// run first.
- context,
- &waiter));
- waiter.Wait();
+ context));
+ compositor_loop_async_waiter_.Wait();
}
void RendererGpuVideoDecoderFactories::AsyncGetContext(
- WebGraphicsContext3DCommandBufferImpl* context,
- base::WaitableEvent* waiter) {
+ WebGraphicsContext3DCommandBufferImpl* context) {
context_ = context->AsWeakPtr();
if (context_) {
if (context_->makeContextCurrent()) {
@@ -56,8 +56,7 @@
context_->insertEventMarkerEXT("GpuVDAContext3D");
}
}
- if (waiter)
- waiter->Signal();
+ compositor_loop_async_waiter_.Signal();
}
media::VideoDecodeAccelerator*
@@ -65,29 +64,37 @@
media::VideoCodecProfile profile,
media::VideoDecodeAccelerator::Client* client) {
DCHECK(!message_loop_->BelongsToCurrentThread());
- media::VideoDecodeAccelerator* vda = NULL;
- base::WaitableEvent waiter(false, false);
+ // The VDA is returned in the vda_ member variable by the
+ // AsyncCreateVideoDecodeAccelerator() function.
message_loop_->PostTask(FROM_HERE, base::Bind(
&RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator,
- this, profile, client, &vda, &waiter));
- waiter.Wait();
- return vda;
+ this, profile, client));
+
+ base::WaitableEvent* objects[] = {&aborted_waiter_,
+ &compositor_loop_async_waiter_};
+ if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) {
+ // If we are aborting and the VDA is created by the
+ // AsyncCreateVideoDecodeAccelerator() function later we need to ensure
+ // that it is destroyed on the same thread.
+ message_loop_->PostTask(FROM_HERE, base::Bind(
+ &RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator,
+ this));
+ return NULL;
+ }
+ return vda_.release();
}
void RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator(
media::VideoCodecProfile profile,
- media::VideoDecodeAccelerator::Client* client,
- media::VideoDecodeAccelerator** vda,
- base::WaitableEvent* waiter) {
+ media::VideoDecodeAccelerator::Client* client) {
DCHECK(message_loop_->BelongsToCurrentThread());
+
if (context_ && context_->GetCommandBufferProxy()) {
- *vda = gpu_channel_host_->CreateVideoDecoder(
+ vda_ = gpu_channel_host_->CreateVideoDecoder(
context_->GetCommandBufferProxy()->GetRouteID(),
profile, client);
- } else {
- *vda = NULL;
}
- waiter->Signal();
+ compositor_loop_async_waiter_.Signal();
}
bool RendererGpuVideoDecoderFactories::CreateTextures(
@@ -95,31 +102,33 @@
std::vector<uint32>* texture_ids,
uint32 texture_target) {
DCHECK(!message_loop_->BelongsToCurrentThread());
- bool success = false;
- base::WaitableEvent waiter(false, false);
message_loop_->PostTask(FROM_HERE, base::Bind(
&RendererGpuVideoDecoderFactories::AsyncCreateTextures, this,
- count, size, texture_ids, texture_target, &success, &waiter));
- waiter.Wait();
- return success;
+ count, size, texture_target));
+
+ base::WaitableEvent* objects[] = {&aborted_waiter_,
+ &compositor_loop_async_waiter_};
+ if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
+ return false;
+ texture_ids->swap(created_textures_);
+ return true;
}
void RendererGpuVideoDecoderFactories::AsyncCreateTextures(
- int32 count, const gfx::Size& size, std::vector<uint32>* texture_ids,
- uint32 texture_target, bool* success, base::WaitableEvent* waiter) {
+ int32 count, const gfx::Size& size, uint32 texture_target) {
DCHECK(message_loop_->BelongsToCurrentThread());
DCHECK(texture_target);
+
if (!context_) {
- *success = false;
- waiter->Signal();
+ compositor_loop_async_waiter_.Signal();
return;
}
gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
- texture_ids->resize(count);
- gles2->GenTextures(count, &texture_ids->at(0));
+ created_textures_.resize(count);
+ gles2->GenTextures(count, &created_textures_[0]);
for (int i = 0; i < count; ++i) {
gles2->ActiveTexture(GL_TEXTURE0);
- uint32 texture_id = texture_ids->at(i);
+ uint32 texture_id = created_textures_[i];
gles2->BindTexture(texture_target, texture_id);
gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -135,8 +144,7 @@
// reused, this should not be unacceptably expensive.
gles2->Flush();
DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
- *success = true;
- waiter->Signal();
+ compositor_loop_async_waiter_.Signal();
}
void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) {
@@ -149,6 +157,7 @@
DCHECK(message_loop_->BelongsToCurrentThread());
if (!context_)
return;
+
gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
gles2->DeleteTextures(1, &texture_id);
DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
@@ -156,24 +165,34 @@
void RendererGpuVideoDecoderFactories::ReadPixels(
uint32 texture_id, uint32 texture_target, const gfx::Size& size,
- void* pixels) {
- base::WaitableEvent waiter(false, false);
+ const SkBitmap& pixels) {
+ // SkBitmaps use the SkPixelRef object to refcount the underlying pixels.
+ // Multiple SkBitmaps can share a SkPixelRef instance. We use this to
+ // ensure that the underlying pixels in the SkBitmap passed in remain valid
+ // until the AsyncReadPixels() call completes.
+ read_pixels_bitmap_.setPixelRef(pixels.pixelRef());
+
if (!message_loop_->BelongsToCurrentThread()) {
message_loop_->PostTask(FROM_HERE, base::Bind(
&RendererGpuVideoDecoderFactories::AsyncReadPixels, this,
- texture_id, texture_target, size, pixels, &waiter));
- waiter.Wait();
+ texture_id, texture_target, size));
+ base::WaitableEvent* objects[] = {&aborted_waiter_,
+ &compositor_loop_async_waiter_};
+ if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
+ return;
} else {
- AsyncReadPixels(texture_id, texture_target, size, pixels, &waiter);
+ AsyncReadPixels(texture_id, texture_target, size);
}
+ read_pixels_bitmap_.setPixelRef(NULL);
}
void RendererGpuVideoDecoderFactories::AsyncReadPixels(
- uint32 texture_id, uint32 texture_target, const gfx::Size& size,
- void* pixels, base::WaitableEvent* waiter) {
+ uint32 texture_id, uint32 texture_target, const gfx::Size& size) {
DCHECK(message_loop_->BelongsToCurrentThread());
- if (!context_)
+ if (!context_) {
+ compositor_loop_async_waiter_.Signal();
return;
+ }
gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
@@ -194,30 +213,35 @@
texture_target, tmp_texture, 0);
gles2->PixelStorei(GL_PACK_ALIGNMENT, 4);
gles2->ReadPixels(0, 0, size.width(), size.height(), GL_BGRA_EXT,
- GL_UNSIGNED_BYTE, pixels);
+ GL_UNSIGNED_BYTE, read_pixels_bitmap_.pixelRef()->pixels());
gles2->DeleteFramebuffers(1, &fb);
gles2->DeleteTextures(1, &tmp_texture);
DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
- waiter->Signal();
+ compositor_loop_async_waiter_.Signal();
}
base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory(
size_t size) {
- DCHECK_NE(MessageLoop::current(), ChildThread::current()->message_loop());
- base::SharedMemory* shm = NULL;
- base::WaitableEvent waiter(false, false);
+ DCHECK_NE(base::MessageLoop::current(),
+ ChildThread::current()->message_loop());
ChildThread::current()->message_loop()->PostTask(FROM_HERE, base::Bind(
&RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this,
- size, &shm, &waiter));
- waiter.Wait();
- return shm;
+ size));
+
+ base::WaitableEvent* objects[] = {&aborted_waiter_,
+ &render_thread_async_waiter_};
+ if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
+ return NULL;
+ return shared_memory_segment_.release();
}
-void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory(
- size_t size, base::SharedMemory** shm, base::WaitableEvent* waiter) {
- DCHECK_EQ(MessageLoop::current(), ChildThread::current()->message_loop());
- *shm = ChildThread::current()->AllocateSharedMemory(size);
- waiter->Signal();
+void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory(size_t size) {
+ DCHECK_EQ(base::MessageLoop::current(),
+ ChildThread::current()->message_loop());
+
+ shared_memory_segment_.reset(
+ ChildThread::current()->AllocateSharedMemory(size));
+ render_thread_async_waiter_.Signal();
}
scoped_refptr<base::MessageLoopProxy>
@@ -225,4 +249,18 @@
return message_loop_;
}
+void RendererGpuVideoDecoderFactories::Abort() {
+ aborted_waiter_.Signal();
+}
+
+bool RendererGpuVideoDecoderFactories::IsAborted() {
+ return aborted_waiter_.IsSignaled();
+}
+
+void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() {
+ // OK to release because Destroy() will delete the VDA instance.
+ if (vda_)
+ vda_.release()->Destroy();
+}
+
} // namespace content
diff --git a/content/renderer/media/renderer_gpu_video_decoder_factories.h b/content/renderer/media/renderer_gpu_video_decoder_factories.h
index 5512562..e05dd9a 100644
--- a/content/renderer/media/renderer_gpu_video_decoder_factories.h
+++ b/content/renderer/media/renderer_gpu_video_decoder_factories.h
@@ -5,11 +5,15 @@
#ifndef CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_DECODER_FACTORIES_H_
#define CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_DECODER_FACTORIES_H_
+#include <vector>
+
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/synchronization/waitable_event.h"
#include "content/common/content_export.h"
#include "media/filters/gpu_video_decoder.h"
+#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/size.h"
namespace base {
@@ -48,10 +52,14 @@
std::vector<uint32>* texture_ids,
uint32 texture_target) OVERRIDE;
virtual void DeleteTexture(uint32 texture_id) OVERRIDE;
- virtual void ReadPixels(uint32 texture_id, uint32 texture_target,
- const gfx::Size& size, void* pixels) OVERRIDE;
+ virtual void ReadPixels(uint32 texture_id,
+ uint32 texture_target,
+ const gfx::Size& size,
+ const SkBitmap& pixels) OVERRIDE;
virtual base::SharedMemory* CreateSharedMemory(size_t size) OVERRIDE;
virtual scoped_refptr<base::MessageLoopProxy> GetMessageLoop() OVERRIDE;
+ virtual void Abort() OVERRIDE;
+ virtual bool IsAborted() OVERRIDE;
protected:
friend class base::RefCountedThreadSafe<RendererGpuVideoDecoderFactories>;
@@ -60,32 +68,55 @@
private:
// Helper for the constructor to acquire the ContentGLContext on the
// compositor thread (when it is enabled).
- void AsyncGetContext(WebGraphicsContext3DCommandBufferImpl* context,
- base::WaitableEvent* waiter);
+ void AsyncGetContext(WebGraphicsContext3DCommandBufferImpl* context);
// Async versions of the public methods. They use output parameters instead
// of return values and each takes a WaitableEvent* param to signal completion
// (except for DeleteTexture, which is fire-and-forget).
// AsyncCreateSharedMemory runs on the renderer thread and the rest run on
// |message_loop_|.
+ // The AsyncCreateVideoDecodeAccelerator returns its output in the vda_
+ // member.
void AsyncCreateVideoDecodeAccelerator(
media::VideoCodecProfile profile,
- media::VideoDecodeAccelerator::Client* client,
- media::VideoDecodeAccelerator** vda,
- base::WaitableEvent* waiter);
- void AsyncCreateTextures(
- int32 count, const gfx::Size& size, std::vector<uint32>* texture_ids,
- uint32 texture_target, bool* success, base::WaitableEvent* waiter);
+ media::VideoDecodeAccelerator::Client* client);
+ void AsyncCreateTextures(int32 count, const gfx::Size& size,
+ uint32 texture_target);
void AsyncDeleteTexture(uint32 texture_id);
void AsyncReadPixels(uint32 texture_id, uint32 texture_target,
- const gfx::Size& size,
- void* pixels, base::WaitableEvent* waiter);
- void AsyncCreateSharedMemory(
- size_t size, base::SharedMemory** shm, base::WaitableEvent* waiter);
+ const gfx::Size& size);
+ void AsyncCreateSharedMemory(size_t size);
+ void AsyncDestroyVideoDecodeAccelerator();
scoped_refptr<base::MessageLoopProxy> message_loop_;
scoped_refptr<GpuChannelHost> gpu_channel_host_;
base::WeakPtr<WebGraphicsContext3DCommandBufferImpl> context_;
+
+ // This event is signaled if we have been asked to Abort().
+ base::WaitableEvent aborted_waiter_;
+
+ // This event is signaled by asynchronous tasks posted to the compositor
+ // message loop to indicate their completion.
+ // e.g. AsyncCreateVideoDecodeAccelerator()/AsyncCreateTextures() etc.
+ base::WaitableEvent compositor_loop_async_waiter_;
+
+ // This event is signaled by asynchronous tasks posted to the renderer thread
+ // message loop to indicate their completion. e.g. AsyncCreateSharedMemory.
+ base::WaitableEvent render_thread_async_waiter_;
+
+ // The vda returned by the CreateVideoAcclelerator function.
+ scoped_ptr<media::VideoDecodeAccelerator> vda_;
+
+ // Shared memory segment which is returned by the CreateSharedMemory()
+ // function.
+ scoped_ptr<base::SharedMemory> shared_memory_segment_;
+
+ // Bitmap returned by ReadPixels().
+ SkBitmap read_pixels_bitmap_;
+
+ // Textures returned by the CreateTexture() function.
+ std::vector<uint32> created_textures_;
+
DISALLOW_IMPLICIT_CONSTRUCTORS(RendererGpuVideoDecoderFactories);
};
diff --git a/content/renderer/media/renderer_webaudiodevice_impl.cc b/content/renderer/media/renderer_webaudiodevice_impl.cc
index ca32103..43a4a61 100644
--- a/content/renderer/media/renderer_webaudiodevice_impl.cc
+++ b/content/renderer/media/renderer_webaudiodevice_impl.cc
@@ -7,8 +7,8 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/renderer_audio_output_device.h"
#include "content/renderer/render_view_impl.h"
+#include "media/audio/audio_output_device.h"
#include "media/base/media_switches.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
@@ -38,9 +38,6 @@
if (output_device_)
return; // Already started.
- output_device_ = AudioDeviceFactory::NewOutputDevice();
- output_device_->Initialize(params_, this);
-
// Assumption: This method is being invoked within a V8 call stack. CHECKs
// will fail in the call to frameForCurrentContext() otherwise.
//
@@ -52,10 +49,9 @@
WebView* const web_view = web_frame ? web_frame->view() : NULL;
RenderViewImpl* const render_view =
web_view ? RenderViewImpl::FromWebView(web_view) : NULL;
- if (render_view) {
- output_device_->SetSourceRenderView(render_view->routing_id());
- }
-
+ output_device_ = AudioDeviceFactory::NewOutputDevice(
+ render_view ? render_view->routing_id() : MSG_ROUTING_NONE);
+ output_device_->Initialize(params_, this);
output_device_->Start();
// Note: Default behavior is to auto-play on start.
}
diff --git a/content/renderer/media/renderer_webaudiodevice_impl.h b/content/renderer/media/renderer_webaudiodevice_impl.h
index ca19d07..09c35d8 100644
--- a/content/renderer/media/renderer_webaudiodevice_impl.h
+++ b/content/renderer/media/renderer_webaudiodevice_impl.h
@@ -12,9 +12,11 @@
#include "third_party/WebKit/Source/Platform/chromium/public/WebAudioDevice.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h"
-namespace content {
+namespace media {
+class AudioOutputDevice;
+}
-class RendererAudioOutputDevice;
+namespace content {
class RendererWebAudioDeviceImpl
: public WebKit::WebAudioDevice,
@@ -50,7 +52,7 @@
base::ThreadChecker thread_checker_;
// When non-NULL, we are started. When NULL, we are stopped.
- scoped_refptr<RendererAudioOutputDevice> output_device_;
+ scoped_refptr<media::AudioOutputDevice> output_device_;
DISALLOW_COPY_AND_ASSIGN(RendererWebAudioDeviceImpl);
};
diff --git a/content/renderer/media/rtc_data_channel_handler.cc b/content/renderer/media/rtc_data_channel_handler.cc
index 4b0006a..6fcaa83 100644
--- a/content/renderer/media/rtc_data_channel_handler.cc
+++ b/content/renderer/media/rtc_data_channel_handler.cc
@@ -43,17 +43,15 @@
bool RtcDataChannelHandler::sendStringData(const WebKit::WebString& data) {
std::string utf8_buffer = UTF16ToUTF8(data);
- webrtc::DataBuffer buffer;
- buffer.binary = false;
- buffer.data.SetData(utf8_buffer.c_str(), utf8_buffer.length());
- return channel_->Send(buffer);
+ talk_base::Buffer buffer(utf8_buffer.c_str(), utf8_buffer.length());
+ webrtc::DataBuffer data_buffer(buffer, false);
+ return channel_->Send(data_buffer);
}
bool RtcDataChannelHandler::sendRawData(const char* data, size_t length) {
- webrtc::DataBuffer buffer;
- buffer.data.SetData(data, length);
- buffer.binary = true;
- return channel_->Send(buffer);
+ talk_base::Buffer buffer(data, length);
+ webrtc::DataBuffer data_buffer(buffer, true);
+ return channel_->Send(data_buffer);
}
void RtcDataChannelHandler::close() {
diff --git a/content/renderer/media/rtc_media_constraints.h b/content/renderer/media/rtc_media_constraints.h
index 5b654a8..24a92ee 100644
--- a/content/renderer/media/rtc_media_constraints.h
+++ b/content/renderer/media/rtc_media_constraints.h
@@ -6,7 +6,7 @@
#define CONTENT_RENDERER_MEDIA_RTC_MEDIA_CONSTRAINTS_H_
#include "base/compiler_specific.h"
-#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
+#include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface.h"
namespace WebKit {
class WebMediaConstraints;
diff --git a/content/renderer/media/rtc_peer_connection_handler.cc b/content/renderer/media/rtc_peer_connection_handler.cc
index 01838b4..30707ca 100644
--- a/content/renderer/media/rtc_peer_connection_handler.cc
+++ b/content/renderer/media/rtc_peer_connection_handler.cc
@@ -10,9 +10,11 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/stl_util.h"
#include "base/utf_string_conversions.h"
#include "content/renderer/media/media_stream_dependency_factory.h"
#include "content/renderer/media/peer_connection_tracker.h"
+#include "content/renderer/media/remote_media_stream_impl.h"
#include "content/renderer/media/rtc_data_channel_handler.h"
#include "content/renderer/media/rtc_dtmf_sender_handler.h"
#include "content/renderer/media/rtc_media_constraints.h"
@@ -129,6 +131,7 @@
webrtc::PeerConnectionInterface::IceServer server;
const WebKit::WebRTCICEServer& webkit_server =
server_configuration.server(i);
+ server.username = UTF16ToUTF8(webkit_server.username());
server.password = UTF16ToUTF8(webkit_server.credential());
server.uri = webkit_server.uri().spec();
servers->push_back(server);
@@ -231,27 +234,21 @@
const std::vector<webrtc::StatsReport>& reports) OVERRIDE {
for (std::vector<webrtc::StatsReport>::const_iterator it = reports.begin();
it != reports.end(); ++it) {
- // TODO(hta): Remove local/remote from libjingle API.
- if (it->local.values.size() > 0) {
- AddElement(it->id, it->type, it->local);
- }
- if (it->remote.values.size() > 0) {
- AddElement(it->id, it->type, it->remote);
+ if (it->values.size() > 0) {
+ AddReport(*it);
}
}
request_->requestSucceeded(response_);
}
private:
- void AddElement(const std::string& id,
- const std::string& type,
- const webrtc::StatsElement& element) {
- int idx = response_->addReport(WebKit::WebString::fromUTF8(id),
- WebKit::WebString::fromUTF8(type),
- element.timestamp);
- for (webrtc::StatsElement::Values::const_iterator value_it =
- element.values.begin();
- value_it != element.values.end(); ++value_it) {
+ void AddReport(const webrtc::StatsReport& report) {
+ int idx = response_->addReport(WebKit::WebString::fromUTF8(report.id),
+ WebKit::WebString::fromUTF8(report.type),
+ report.timestamp);
+ for (webrtc::StatsReport::Values::const_iterator value_it =
+ report.values.begin();
+ value_it != report.values.end(); ++value_it) {
AddStatistic(idx, value_it->name, value_it->value);
}
}
@@ -329,6 +326,7 @@
RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
if (peer_connection_tracker_)
peer_connection_tracker_->UnregisterPeerConnection(this);
+ STLDeleteValues(&remote_streams_);
}
void RTCPeerConnectionHandler::associateWithFrame(WebKit::WebFrame* frame) {
@@ -424,7 +422,7 @@
}
if (peer_connection_tracker_)
peer_connection_tracker_->TrackSetSessionDescription(
- this, native_desc, PeerConnectionTracker::SOURCE_LOCAL);
+ this, description, PeerConnectionTracker::SOURCE_LOCAL);
scoped_refptr<SetSessionDescriptionRequest> set_request(
new talk_base::RefCountedObject<SetSessionDescriptionRequest>(
@@ -449,7 +447,7 @@
}
if (peer_connection_tracker_)
peer_connection_tracker_->TrackSetSessionDescription(
- this, native_desc, PeerConnectionTracker::SOURCE_REMOTE);
+ this, description, PeerConnectionTracker::SOURCE_REMOTE);
scoped_refptr<SetSessionDescriptionRequest> set_request(
new talk_base::RefCountedObject<SetSessionDescriptionRequest>(
@@ -496,7 +494,7 @@
UTF16ToUTF8(candidate.sdpMid()),
candidate.sdpMLineIndex(),
UTF16ToUTF8(candidate.candidate())));
- if (!native_candidate.get()) {
+ if (!native_candidate) {
LOG(ERROR) << "Could not create native ICE candidate.";
return false;
}
@@ -666,17 +664,19 @@
webrtc::MediaStreamInterface* stream_interface) {
DCHECK(stream_interface);
DCHECK(remote_streams_.find(stream_interface) == remote_streams_.end());
- WebKit::WebMediaStream stream =
- CreateRemoteWebKitMediaStream(stream_interface);
+
+ RemoteMediaStreamImpl* remote_stream =
+ new RemoteMediaStreamImpl(stream_interface);
+ remote_streams_.insert(
+ std::pair<webrtc::MediaStreamInterface*, RemoteMediaStreamImpl*> (
+ stream_interface, remote_stream));
if (peer_connection_tracker_)
peer_connection_tracker_->TrackAddStream(
- this, stream, PeerConnectionTracker::SOURCE_REMOTE);
+ this, remote_stream->webkit_stream(),
+ PeerConnectionTracker::SOURCE_REMOTE);
- remote_streams_.insert(
- std::pair<webrtc::MediaStreamInterface*,
- WebKit::WebMediaStream>(stream_interface, stream));
- client_->didAddRemoteStream(stream);
+ client_->didAddRemoteStream(remote_stream->webkit_stream());
}
void RTCPeerConnectionHandler::OnRemoveStream(
@@ -687,15 +687,17 @@
NOTREACHED() << "Stream not found";
return;
}
- WebKit::WebMediaStream stream = it->second;
- DCHECK(!stream.isNull());
+
+ scoped_ptr<RemoteMediaStreamImpl> remote_stream(it->second);
+ const WebKit::WebMediaStream& webkit_stream = remote_stream->webkit_stream();
+ DCHECK(!webkit_stream.isNull());
remote_streams_.erase(it);
if (peer_connection_tracker_)
peer_connection_tracker_->TrackRemoveStream(
- this, stream, PeerConnectionTracker::SOURCE_REMOTE);
+ this, webkit_stream, PeerConnectionTracker::SOURCE_REMOTE);
- client_->didRemoveRemoteStream(stream);
+ client_->didRemoveRemoteStream(webkit_stream);
}
void RTCPeerConnectionHandler::OnIceCandidate(
diff --git a/content/renderer/media/rtc_peer_connection_handler_unittest.cc b/content/renderer/media/rtc_peer_connection_handler_unittest.cc
index e3e66df..a303893 100644
--- a/content/renderer/media/rtc_peer_connection_handler_unittest.cc
+++ b/content/renderer/media/rtc_peer_connection_handler_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <string>
+#include <vector>
#include "base/memory/scoped_ptr.h"
#include "base/utf_string_conversions.h"
@@ -38,6 +39,7 @@
using WebKit::WebRTCPeerConnectionHandlerClient;
using testing::NiceMock;
using testing::_;
+using testing::Ref;
namespace content {
@@ -125,7 +127,7 @@
public:
MOCK_METHOD1(UnregisterPeerConnection,
void(RTCPeerConnectionHandler* pc_handler));
- // TODO (jiayl): add coverage for the following methods
+ // TODO(jiayl): add coverage for the following methods
MOCK_METHOD2(TrackCreateOffer,
void(RTCPeerConnectionHandler* pc_handler,
const RTCMediaConstraints& constraints));
@@ -134,7 +136,7 @@
const RTCMediaConstraints& constraints));
MOCK_METHOD3(TrackSetSessionDescription,
void(RTCPeerConnectionHandler* pc_handler,
- const webrtc::SessionDescriptionInterface* desc,
+ const WebKit::WebRTCSessionDescription& desc,
Source source));
MOCK_METHOD3(
TrackUpdateIce,
@@ -175,7 +177,7 @@
MOCK_METHOD1(TrackOnRenegotiationNeeded,
void(RTCPeerConnectionHandler* pc_handler));
MOCK_METHOD2(TrackCreateDTMFSender,
- void (RTCPeerConnectionHandler* pc_handler,
+ void(RTCPeerConnectionHandler* pc_handler,
const WebKit::WebMediaStreamTrack& track));
};
@@ -246,9 +248,10 @@
WebKit::WebVector<WebKit::WebMediaStreamTrack> video_tracks;
local_stream.audioSources(video_tracks);
const std::string video_track_id = UTF16ToUTF8(video_tracks[0].id());
+ webrtc::VideoSourceInterface* source = NULL;
scoped_refptr<webrtc::VideoTrackInterface> video_track(
mock_dependency_factory_->CreateLocalVideoTrack(
- video_track_id, 0));
+ video_track_id, source));
native_stream->AddTrack(video_track);
local_stream.setExtraData(new MediaStreamExtraData(native_stream, true));
@@ -264,9 +267,10 @@
scoped_refptr<webrtc::MediaStreamInterface> stream(
mock_dependency_factory_->CreateLocalMediaStream(stream_label));
if (!video_track_label.empty()) {
+ webrtc::VideoSourceInterface* source = NULL;
scoped_refptr<webrtc::VideoTrackInterface> video_track(
mock_dependency_factory_->CreateLocalVideoTrack(
- video_track_label, 0));
+ video_track_label, source));
stream->AddTrack(video_track);
}
if (!audio_track_label.empty()) {
@@ -320,17 +324,17 @@
}
TEST_F(RTCPeerConnectionHandlerTest, setLocalDescription) {
+ WebKit::WebRTCVoidRequest request;
+ WebKit::WebRTCSessionDescription description;
+ description.initialize(kDummySdpType, kDummySdp);
// PeerConnectionTracker::TrackSetSessionDescription is expected to be called
// before |mock_peer_connection| is called.
testing::InSequence sequence;
EXPECT_CALL(*mock_tracker_.get(),
- TrackSetSessionDescription(pc_handler_.get(), testing::NotNull(),
+ TrackSetSessionDescription(pc_handler_.get(), Ref(description),
PeerConnectionTracker::SOURCE_LOCAL));
EXPECT_CALL(*mock_peer_connection_, SetLocalDescription(_, _));
- WebKit::WebRTCVoidRequest request;
- WebKit::WebRTCSessionDescription description;
- description.initialize(kDummySdpType, kDummySdp);
pc_handler_->setLocalDescription(request, description);
EXPECT_EQ(description.type(), pc_handler_->localDescription().type());
EXPECT_EQ(description.sdp(), pc_handler_->localDescription().sdp());
@@ -343,17 +347,18 @@
}
TEST_F(RTCPeerConnectionHandlerTest, setRemoteDescription) {
+ WebKit::WebRTCVoidRequest request;
+ WebKit::WebRTCSessionDescription description;
+ description.initialize(kDummySdpType, kDummySdp);
+
// PeerConnectionTracker::TrackSetSessionDescription is expected to be called
// before |mock_peer_connection| is called.
testing::InSequence sequence;
EXPECT_CALL(*mock_tracker_.get(),
- TrackSetSessionDescription(pc_handler_.get(), testing::NotNull(),
+ TrackSetSessionDescription(pc_handler_.get(), Ref(description),
PeerConnectionTracker::SOURCE_REMOTE));
EXPECT_CALL(*mock_peer_connection_, SetRemoteDescription(_, _));
- WebKit::WebRTCVoidRequest request;
- WebKit::WebRTCSessionDescription description;
- description.initialize(kDummySdpType, kDummySdp);
pc_handler_->setRemoteDescription(request, description);
EXPECT_EQ(description.type(), pc_handler_->remoteDescription().type());
EXPECT_EQ(description.sdp(), pc_handler_->remoteDescription().sdp());
@@ -654,6 +659,100 @@
pc_handler_->OnRemoveStream(remote_stream);
}
+// This test that WebKit is notified about remote track state changes.
+TEST_F(RTCPeerConnectionHandlerTest, RemoteTrackState) {
+ std::string remote_stream_label("remote_stream");
+ scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
+ AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
+
+ testing::InSequence sequence;
+ EXPECT_CALL(*mock_client_.get(), didAddRemoteStream(
+ testing::Property(&WebKit::WebMediaStream::label,
+ UTF8ToUTF16(remote_stream_label))));
+ pc_handler_->OnAddStream(remote_stream);
+ const WebKit::WebMediaStream& webkit_stream = mock_client_->remote_stream();
+
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> audio_tracks;
+ webkit_stream.audioTracks(audio_tracks);
+ EXPECT_EQ(WebKit::WebMediaStreamSource::ReadyStateLive,
+ audio_tracks[0].source().readyState());
+
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> video_tracks;
+ webkit_stream.videoTracks(video_tracks);
+ EXPECT_EQ(WebKit::WebMediaStreamSource::ReadyStateLive,
+ video_tracks[0].source().readyState());
+
+ remote_stream->GetAudioTracks()[0]->set_state(
+ webrtc::MediaStreamTrackInterface::kEnded);
+ EXPECT_EQ(WebKit::WebMediaStreamSource::ReadyStateEnded,
+ audio_tracks[0].source().readyState());
+
+ remote_stream->GetVideoTracks()[0]->set_state(
+ webrtc::MediaStreamTrackInterface::kEnded);
+ EXPECT_EQ(WebKit::WebMediaStreamSource::ReadyStateEnded,
+ video_tracks[0].source().readyState());
+}
+
+TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddAudioTrackFromRemoteStream) {
+ std::string remote_stream_label("remote_stream");
+ scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
+ AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
+
+ EXPECT_CALL(*mock_client_.get(), didAddRemoteStream(
+ testing::Property(&WebKit::WebMediaStream::label,
+ UTF8ToUTF16(remote_stream_label))));
+ pc_handler_->OnAddStream(remote_stream);
+ const WebKit::WebMediaStream& webkit_stream = mock_client_->remote_stream();
+
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> audio_tracks;
+ webkit_stream.audioTracks(audio_tracks);
+ EXPECT_EQ(1u, audio_tracks.size());
+
+ // Remove the Webrtc audio track from the Webrtc MediaStream.
+ scoped_refptr<webrtc::AudioTrackInterface> webrtc_track =
+ remote_stream->GetAudioTracks()[0].get();
+ remote_stream->RemoveTrack(webrtc_track);
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> modified_audio_tracks1;
+ webkit_stream.audioTracks(modified_audio_tracks1);
+ EXPECT_EQ(0u, modified_audio_tracks1.size());
+
+ // Add the WebRtc audio track again.
+ remote_stream->AddTrack(webrtc_track);
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> modified_audio_tracks2;
+ webkit_stream.audioTracks(modified_audio_tracks2);
+ EXPECT_EQ(1u, modified_audio_tracks2.size());
+}
+
+TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddVideoTrackFromRemoteStream) {
+ std::string remote_stream_label("remote_stream");
+ scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
+ AddRemoteMockMediaStream(remote_stream_label, "video", "video"));
+
+ EXPECT_CALL(*mock_client_.get(), didAddRemoteStream(
+ testing::Property(&WebKit::WebMediaStream::label,
+ UTF8ToUTF16(remote_stream_label))));
+ pc_handler_->OnAddStream(remote_stream);
+ const WebKit::WebMediaStream& webkit_stream = mock_client_->remote_stream();
+
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> video_tracks;
+ webkit_stream.videoTracks(video_tracks);
+ EXPECT_EQ(1u, video_tracks.size());
+
+ // Remove the Webrtc video track from the Webrtc MediaStream.
+ scoped_refptr<webrtc::VideoTrackInterface> webrtc_track =
+ remote_stream->GetVideoTracks()[0].get();
+ remote_stream->RemoveTrack(webrtc_track);
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> modified_video_tracks1;
+ webkit_stream.videoTracks(modified_video_tracks1);
+ EXPECT_EQ(0u, modified_video_tracks1.size());
+
+ // Add the WebRtc video track again.
+ remote_stream->AddTrack(webrtc_track);
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> modified_video_tracks2;
+ webkit_stream.videoTracks(modified_video_tracks2);
+ EXPECT_EQ(1u, modified_video_tracks2.size());
+}
+
TEST_F(RTCPeerConnectionHandlerTest, OnIceCandidate) {
testing::InSequence sequence;
EXPECT_CALL(*mock_tracker_.get(),
diff --git a/content/renderer/media/rtc_video_capture_delegate.cc b/content/renderer/media/rtc_video_capture_delegate.cc
index 33a1917..975cfde 100644
--- a/content/renderer/media/rtc_video_capture_delegate.cc
+++ b/content/renderer/media/rtc_video_capture_delegate.cc
@@ -14,7 +14,8 @@
: session_id_(id),
vc_manager_(vc_manager),
capture_engine_(NULL),
- got_first_frame_(false) {
+ got_first_frame_(false),
+ error_occured_(false) {
DVLOG(3) << " RtcVideoCaptureDelegate::ctor";
capture_engine_ = vc_manager_->AddDevice(session_id_, this);
}
@@ -32,6 +33,8 @@
message_loop_proxy_ = base::MessageLoopProxy::current();
captured_callback_ = captured_callback;
state_callback_ = state_callback;
+ got_first_frame_ = false;
+ error_occured_ = false;
// Increase the reference count to ensure we are not deleted until
// The we are unregistered in RtcVideoCaptureDelegate::OnRemoved.
@@ -59,14 +62,20 @@
void RtcVideoCaptureDelegate::OnError(media::VideoCapture* capture,
int error_code) {
+ DVLOG(3) << " RtcVideoCaptureDelegate::OnError";
message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&RtcVideoCaptureDelegate::OnErrorOnCaptureThread,
- this, capture, error_code));
+ this, capture));
}
void RtcVideoCaptureDelegate::OnRemoved(media::VideoCapture* capture) {
DVLOG(3) << " RtcVideoCaptureDelegate::OnRemoved";
+ message_loop_proxy_->PostTask(
+ FROM_HERE,
+ base::Bind(&RtcVideoCaptureDelegate::OnRemovedOnCaptureThread,
+ this, capture));
+
// Balance the AddRef in StartCapture.
// This means we are no longer registered as an event handler and can safely
// be deleted.
@@ -104,9 +113,17 @@
}
void RtcVideoCaptureDelegate::OnErrorOnCaptureThread(
- media::VideoCapture* capture, int error_code) {
+ media::VideoCapture* capture) {
+ error_occured_ = true;
if (!state_callback_.is_null())
- state_callback_.Run(got_first_frame_ ? CAPTURE_STOPPED : CAPTURE_FAILED);
+ state_callback_.Run(CAPTURE_FAILED);
+}
+
+
+void RtcVideoCaptureDelegate::OnRemovedOnCaptureThread(
+ media::VideoCapture* capture) {
+ if (!error_occured_ && !state_callback_.is_null())
+ state_callback_.Run(CAPTURE_STOPPED);
}
} // namespace content
diff --git a/content/renderer/media/rtc_video_capture_delegate.h b/content/renderer/media/rtc_video_capture_delegate.h
index 6482250..d8c3198 100644
--- a/content/renderer/media/rtc_video_capture_delegate.h
+++ b/content/renderer/media/rtc_video_capture_delegate.h
@@ -63,7 +63,8 @@
void OnBufferReadyOnCaptureThread(
media::VideoCapture* capture,
scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf);
- void OnErrorOnCaptureThread(media::VideoCapture* capture, int error_code);
+ void OnErrorOnCaptureThread(media::VideoCapture* capture);
+ void OnRemovedOnCaptureThread(media::VideoCapture* capture);
// The id identifies which video capture device is used for this video
// capture session.
@@ -74,6 +75,7 @@
// Accessed on the thread where StartCapture is called.
bool got_first_frame_;
+ bool error_occured_;
// |captured_callback_| is provided to this class in StartCapture and must be
// valid until StopCapture is called.
@@ -81,7 +83,7 @@
// |state_callback_| is provided to this class in StartCapture and must be
// valid until StopCapture is called.
StateChangeCallback state_callback_;
- // MessageLoop of the caller of StartCapture.
+ // Message loop of the caller of StartCapture.
scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
};
diff --git a/content/renderer/media/rtc_video_capturer.cc b/content/renderer/media/rtc_video_capturer.cc
index d6d665c..b1ebf22 100644
--- a/content/renderer/media/rtc_video_capturer.cc
+++ b/content/renderer/media/rtc_video_capturer.cc
@@ -5,6 +5,7 @@
#include "content/renderer/media/rtc_video_capturer.h"
#include "base/bind.h"
+#include "base/debug/trace_event.h"
namespace content {
@@ -100,11 +101,21 @@
// cricket::CapturedFrame time is in nanoseconds.
frame.elapsed_time = (buf.timestamp - start_time_).InMicroseconds() *
base::Time::kNanosecondsPerMicrosecond;
- frame.time_stamp = frame.elapsed_time;
+ frame.time_stamp =
+ (buf.timestamp - base::Time::UnixEpoch()).InMicroseconds() *
+ base::Time::kNanosecondsPerMicrosecond;
frame.data = buf.memory_pointer;
frame.pixel_height = 1;
frame.pixel_width = 1;
+ TRACE_EVENT_INSTANT2("rtc_video_capturer",
+ "OnFrameCaptured",
+ TRACE_EVENT_SCOPE_THREAD,
+ "elapsed time",
+ frame.elapsed_time,
+ "timestamp_ms",
+ frame.time_stamp / talk_base::kNumNanosecsPerMillisec);
+
// This signals to libJingle that a new VideoFrame is available.
// libJingle have no assumptions on what thread this signal come from.
SignalFrameCaptured(this, &frame);
@@ -113,6 +124,7 @@
void RtcVideoCapturer::OnStateChange(
RtcVideoCaptureDelegate::CaptureState state) {
cricket::CaptureState converted_state = cricket::CS_FAILED;
+ DVLOG(3) << " RtcVideoCapturer::OnStateChange " << state;
switch (state) {
case RtcVideoCaptureDelegate::CAPTURE_STOPPED:
converted_state = cricket::CS_STOPPED;
@@ -121,6 +133,10 @@
converted_state = cricket::CS_RUNNING;
break;
case RtcVideoCaptureDelegate::CAPTURE_FAILED:
+ // TODO(perkj): Update the comments in the the definition of
+ // cricket::CS_FAILED. According to the comments, cricket::CS_FAILED
+ // means that the capturer failed to start. But here and in libjingle it
+ // is also used if an error occur during capturing.
converted_state = cricket::CS_FAILED;
break;
default:
diff --git a/content/renderer/media/rtc_video_renderer.cc b/content/renderer/media/rtc_video_renderer.cc
index 6af00f9..8edef65 100644
--- a/content/renderer/media/rtc_video_renderer.cc
+++ b/content/renderer/media/rtc_video_renderer.cc
@@ -11,7 +11,6 @@
#include "base/message_loop_proxy.h"
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
-#include "third_party/libjingle/source/talk/base/timeutils.h"
#include "third_party/libjingle/source/talk/media/base/videoframe.h"
using media::CopyYPlane;
@@ -76,6 +75,15 @@
void RTCVideoRenderer::RenderFrame(const cricket::VideoFrame* frame) {
base::TimeDelta timestamp = base::TimeDelta::FromMilliseconds(
frame->GetTimeStamp() / talk_base::kNumNanosecsPerMillisec);
+
+ TRACE_EVENT_INSTANT2("rtc_video_renderer",
+ "RenderFrame",
+ TRACE_EVENT_SCOPE_THREAD,
+ "elapsed time",
+ frame->GetElapsedTime(),
+ "timestamp_ms",
+ timestamp.InMilliseconds());
+
gfx::Size size(frame->GetWidth(), frame->GetHeight());
scoped_refptr<media::VideoFrame> video_frame =
media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
diff --git a/content/renderer/media/stream_texture_factory_impl_android.cc b/content/renderer/media/stream_texture_factory_impl_android.cc
index c77700f..355519f 100644
--- a/content/renderer/media/stream_texture_factory_impl_android.cc
+++ b/content/renderer/media/stream_texture_factory_impl_android.cc
@@ -13,15 +13,10 @@
#include "content/common/gpu/gpu_messages.h"
#include "content/renderer/render_thread_impl.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebStreamTextureClient.h"
#include "ui/gfx/size.h"
namespace {
-static void DeleteStreamTextureHost(content::StreamTextureHost* host) {
- delete host;
-}
-
// Implementation of the StreamTextureProxy class. This class listens to all
// the stream texture updates and forward them to the
// cc::VideoFrameProvider::Client.
@@ -29,16 +24,14 @@
public content::StreamTextureHost::Listener {
public:
explicit StreamTextureProxyImpl(content::StreamTextureHost* host);
- virtual ~StreamTextureProxyImpl();
+ virtual ~StreamTextureProxyImpl() {}
// webkit_media::StreamTextureProxy implementation:
- virtual bool Initialize(int stream_id, int width, int height) OVERRIDE;
- virtual bool IsInitialized() OVERRIDE { return initialized_; }
-#ifndef REMOVE_WEBVIDEOFRAME
- virtual void SetClient(WebKit::WebStreamTextureClient* client) OVERRIDE;
-#else
+ virtual void BindToCurrentThread(
+ int stream_id, int width, int height) OVERRIDE;
+ virtual bool IsBoundToThread() OVERRIDE { return !!loop_.get(); }
virtual void SetClient(cc::VideoFrameProvider::Client* client) OVERRIDE;
-#endif
+ virtual void Release() OVERRIDE;
// StreamTextureHost::Listener implementation:
virtual void OnFrameAvailable() OVERRIDE;
@@ -49,12 +42,7 @@
scoped_refptr<base::MessageLoopProxy> loop_;
base::Lock client_lock_;
-#ifndef REMOVE_WEBVIDEOFRAME
- WebKit::WebStreamTextureClient* client_;
-#else
cc::VideoFrameProvider::Client* client_;
-#endif
- bool initialized_;
DISALLOW_COPY_AND_ASSIGN(StreamTextureProxyImpl);
};
@@ -62,57 +50,40 @@
StreamTextureProxyImpl::StreamTextureProxyImpl(
content::StreamTextureHost* host)
: host_(host),
- client_(NULL),
- initialized_(false) {
+ client_(NULL) {
DCHECK(host);
host->SetListener(this);
}
-StreamTextureProxyImpl::~StreamTextureProxyImpl() {
+void StreamTextureProxyImpl::Release() {
SetClient(NULL);
- // The StreamTextureHost instance needs to be deleted on the thread
- // it receives messages on (where it uses a WeakPtr).
- if (loop_.get()) {
- loop_->PostTask(FROM_HERE, base::Bind(&DeleteStreamTextureHost,
- host_.release()));
- }
+ if (loop_ && loop_ != base::MessageLoopProxy::current())
+ loop_->DeleteSoon(FROM_HERE, this);
+ else
+ delete this;
}
-#ifndef REMOVE_WEBVIDEOFRAME
-void StreamTextureProxyImpl::SetClient(WebKit::WebStreamTextureClient* client) {
-#else
void StreamTextureProxyImpl::SetClient(cc::VideoFrameProvider::Client* client) {
-#endif
base::AutoLock lock(client_lock_);
client_ = client;
}
-bool StreamTextureProxyImpl::Initialize(int stream_id, int width, int height) {
+void StreamTextureProxyImpl::BindToCurrentThread(
+ int stream_id, int width, int height) {
loop_ = base::MessageLoopProxy::current();
- initialized_ = true;
- return host_->Initialize(stream_id, gfx::Size(width, height));
+ host_->Initialize(stream_id, gfx::Size(width, height));
}
void StreamTextureProxyImpl::OnFrameAvailable() {
base::AutoLock lock(client_lock_);
-#ifndef REMOVE_WEBVIDEOFRAME
- if (client_)
- client_->didReceiveFrame();
-#else
if (client_)
client_->DidReceiveFrame();
-#endif
}
void StreamTextureProxyImpl::OnMatrixChanged(const float matrix[16]) {
base::AutoLock lock(client_lock_);
-#ifndef REMOVE_WEBVIDEOFRAME
- if (client_)
- client_->didUpdateMatrix(matrix);
-#else
if (client_)
client_->DidUpdateMatrix(matrix);
-#endif
}
} // anonymous namespace
diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc
index aa428d8..7ee2a2e 100644
--- a/content/renderer/media/video_capture_impl.cc
+++ b/content/renderer/media/video_capture_impl.cc
@@ -56,6 +56,7 @@
device_id_(0),
video_type_(media::VideoCaptureCapability::kI420),
device_info_available_(false),
+ suspended_(false),
state_(VIDEO_CAPTURE_STATE_STOPPED) {
DCHECK(filter);
memset(¤t_params_, 0, sizeof(current_params_));
@@ -138,6 +139,12 @@
base::Unretained(this), device_id));
}
+void VideoCaptureImpl::SuspendCapture(bool suspend) {
+ capture_message_loop_proxy_->PostTask(FROM_HERE,
+ base::Bind(&VideoCaptureImpl::DoSuspendCaptureOnCaptureThread,
+ base::Unretained(this), suspend));
+}
+
void VideoCaptureImpl::DoDeInitOnCaptureThread(base::Closure task) {
if (state_ == VIDEO_CAPTURE_STATE_STARTED)
Send(new VideoCaptureHostMsg_Stop(device_id_));
@@ -275,7 +282,7 @@
int buffer_id, base::Time timestamp) {
DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread());
- if (state_ != VIDEO_CAPTURE_STATE_STARTED) {
+ if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) {
Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id));
return;
}
@@ -321,6 +328,15 @@
clients_.clear();
state_ = VIDEO_CAPTURE_STATE_ERROR;
break;
+ case VIDEO_CAPTURE_STATE_ENDED:
+ DVLOG(1) << "OnStateChanged: ended!, device_id = " << device_id_;
+ for (ClientInfo::iterator it = clients_.begin();
+ it != clients_.end(); ++it) {
+ it->first->OnRemoved(this);
+ }
+ clients_.clear();
+ state_ = VIDEO_CAPTURE_STATE_ENDED;
+ break;
default:
break;
}
@@ -354,6 +370,13 @@
}
}
+void VideoCaptureImpl::DoSuspendCaptureOnCaptureThread(bool suspend) {
+ DVLOG(1) << "DoSuspendCapture: suspend " << (suspend ? "yes" : "no");
+ DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread());
+
+ suspended_ = suspend;
+}
+
void VideoCaptureImpl::StopDevice() {
DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread());
diff --git a/content/renderer/media/video_capture_impl.h b/content/renderer/media/video_capture_impl.h
index 4bb4c55..e47c35d 100644
--- a/content/renderer/media/video_capture_impl.h
+++ b/content/renderer/media/video_capture_impl.h
@@ -57,6 +57,9 @@
const media::VideoCaptureParams& device_info) OVERRIDE;
virtual void OnDelegateAdded(int32 device_id) OVERRIDE;
+ // Stop/resume delivering video frames to clients, based on flag |suspend|.
+ virtual void SuspendCapture(bool suspend);
+
private:
friend class VideoCaptureImplManager;
friend class VideoCaptureImplTest;
@@ -85,6 +88,8 @@
const media::VideoCaptureParams& device_info);
void DoDelegateAddedOnCaptureThread(int32 device_id);
+ void DoSuspendCaptureOnCaptureThread(bool suspend);
+
void Init();
void DeInit(base::Closure task);
void DoDeInitOnCaptureThread(base::Closure task);
@@ -124,6 +129,7 @@
media::VideoCaptureParams device_info_;
bool device_info_available_;
+ bool suspended_;
VideoCaptureState state_;
DISALLOW_COPY_AND_ASSIGN(VideoCaptureImpl);
diff --git a/content/renderer/media/video_capture_impl_manager.cc b/content/renderer/media/video_capture_impl_manager.cc
index 806ddf5..b270296 100644
--- a/content/renderer/media/video_capture_impl_manager.cc
+++ b/content/renderer/media/video_capture_impl_manager.cc
@@ -37,6 +37,12 @@
return it->second->vc;
}
+void VideoCaptureImplManager::SuspendDevices(bool suspend) {
+ base::AutoLock auto_lock(lock_);
+ for (Devices::iterator it = devices_.begin(); it != devices_.end(); ++it)
+ it->second->vc->SuspendCapture(suspend);
+}
+
void VideoCaptureImplManager::RemoveDevice(
media::VideoCaptureSessionId id,
media::VideoCapture::EventHandler* handler) {
diff --git a/content/renderer/media/video_capture_impl_manager.h b/content/renderer/media/video_capture_impl_manager.h
index 0a3baf4..c673960 100644
--- a/content/renderer/media/video_capture_impl_manager.h
+++ b/content/renderer/media/video_capture_impl_manager.h
@@ -42,6 +42,10 @@
virtual void RemoveDevice(media::VideoCaptureSessionId id,
media::VideoCapture::EventHandler* handler);
+ // Make all existing VideoCaptureImpl instances stop/resume delivering
+ // video frames to their clients, depends on flag |suspend|.
+ virtual void SuspendDevices(bool suspend);
+
VideoCaptureMessageFilter* video_capture_message_filter() const {
return filter_;
}
diff --git a/content/renderer/media/video_capture_impl_unittest.cc b/content/renderer/media/video_capture_impl_unittest.cc
index 4b181d8..2e2c739 100644
--- a/content/renderer/media/video_capture_impl_unittest.cc
+++ b/content/renderer/media/video_capture_impl_unittest.cc
@@ -103,7 +103,7 @@
};
VideoCaptureImplTest() {
- message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO));
+ message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO));
message_loop_proxy_ =
base::MessageLoopProxy::current().get();
child_process_.reset(new ChildProcess());
@@ -123,7 +123,7 @@
}
protected:
- scoped_ptr<MessageLoop> message_loop_;
+ scoped_ptr<base::MessageLoop> message_loop_;
scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
scoped_ptr<ChildProcess> child_process_;
scoped_refptr<MockVideoCaptureMessageFilter> message_filter_;
diff --git a/content/renderer/media/video_capture_message_filter_unittest.cc b/content/renderer/media/video_capture_message_filter_unittest.cc
index a2a4cd6..b0ffbc7 100644
--- a/content/renderer/media/video_capture_message_filter_unittest.cc
+++ b/content/renderer/media/video_capture_message_filter_unittest.cc
@@ -105,7 +105,7 @@
} // namespace
TEST(VideoCaptureMessageFilterTest, Basic) {
- MessageLoop message_loop(MessageLoop::TYPE_IO);
+ base::MessageLoop message_loop(base::MessageLoop::TYPE_IO);
scoped_refptr<VideoCaptureMessageFilter> filter(
new VideoCaptureMessageFilter());
@@ -169,7 +169,7 @@
}
TEST(VideoCaptureMessageFilterTest, Delegates) {
- MessageLoop message_loop(MessageLoop::TYPE_IO);
+ base::MessageLoop message_loop(base::MessageLoop::TYPE_IO);
scoped_refptr<VideoCaptureMessageFilter> filter(
new VideoCaptureMessageFilter());
diff --git a/content/renderer/media/video_destination_handler.cc b/content/renderer/media/video_destination_handler.cc
new file mode 100644
index 0000000..345525e
--- /dev/null
+++ b/content/renderer/media/video_destination_handler.cc
@@ -0,0 +1,199 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/video_destination_handler.h"
+
+#include <string>
+
+#include "base/logging.h"
+#include "content/renderer/media/media_stream_dependency_factory.h"
+#include "content/renderer/media/media_stream_registry_interface.h"
+#include "content/renderer/render_thread_impl.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamTrack.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamRegistry.h"
+#include "webkit/plugins/ppapi/ppb_image_data_impl.h"
+
+using cricket::CaptureState;
+using cricket::VideoFormat;
+using webkit::ppapi::PPB_ImageData_Impl;
+using webrtc::VideoTrackInterface;
+using webrtc::VideoTrackVector;
+
+static const cricket::FourCC kEffectColorFormat = cricket::FOURCC_BGRA;
+
+namespace content {
+
+PpFrameWriter::PpFrameWriter()
+ : started_(false) {}
+
+PpFrameWriter::~PpFrameWriter() {}
+
+CaptureState PpFrameWriter::Start(const VideoFormat& capture_format) {
+ base::AutoLock auto_lock(lock_);
+ if (started_) {
+ LOG(ERROR) << "PpFrameWriter::Start - "
+ << "Got a StartCapture when already started!";
+ return cricket::CS_FAILED;
+ }
+ started_ = true;
+ return cricket::CS_STARTING;
+}
+
+void PpFrameWriter::Stop() {
+ base::AutoLock auto_lock(lock_);
+ started_ = false;
+ SignalStateChange(this, cricket::CS_STOPPED);
+}
+
+bool PpFrameWriter::IsRunning() {
+ return started_;
+}
+
+bool PpFrameWriter::GetPreferredFourccs(std::vector<uint32>* fourccs) {
+ if (!fourccs) {
+ LOG(ERROR) << "PpFrameWriter::GetPreferredFourccs - "
+ << "fourccs is NULL.";
+ return false;
+ }
+ // The effects plugin output BGRA.
+ fourccs->push_back(kEffectColorFormat);
+ return true;
+}
+
+bool PpFrameWriter::GetBestCaptureFormat(const VideoFormat& desired,
+ VideoFormat* best_format) {
+ if (!best_format) {
+ LOG(ERROR) << "PpFrameWriter::GetBestCaptureFormat - "
+ << "best_format is NULL.";
+ return false;
+ }
+
+ // Use the desired format as the best format.
+ best_format->width = desired.width;
+ best_format->height = desired.height;
+ best_format->fourcc = kEffectColorFormat;
+ best_format->interval = desired.interval;
+ return true;
+}
+
+bool PpFrameWriter::IsScreencast() const {
+ return false;
+}
+
+void PpFrameWriter::PutFrame(PPB_ImageData_Impl* image_data,
+ int64 time_stamp_ns) {
+ base::AutoLock auto_lock(lock_);
+ // This assumes the handler of the SignalFrameCaptured won't call Start/Stop.
+ // TODO(ronghuawu): Avoid the using of lock. One way is to post this call to
+ // libjingle worker thread, which will require an extra copy of |image_data|.
+ // However if pepper host can hand over the ownership of |image_data|
+ // then we can avoid this extra copy.
+ if (!started_) {
+ LOG(ERROR) << "PpFrameWriter::PutFrame - "
+ << "Called when capturer is not started.";
+ return;
+ }
+ ASSERT(image_data != NULL);
+ webkit::ppapi::ImageDataAutoMapper mapper(image_data);
+ if (!mapper.is_valid()) {
+ LOG(ERROR) << "PpFrameWriter::PutFrame - "
+ << "The image could not be mapped and is unusable.";
+ return;
+ }
+ const SkBitmap* bitmap = image_data->GetMappedBitmap();
+ ASSERT(bitmap != NULL);
+
+ cricket::CapturedFrame frame;
+ frame.elapsed_time = 0;
+ frame.time_stamp = time_stamp_ns;
+ frame.pixel_height = 1;
+ frame.pixel_width = 1;
+ frame.width = bitmap->width();
+ frame.height = bitmap->height();
+ if (image_data->format() == PP_IMAGEDATAFORMAT_BGRA_PREMUL) {
+ frame.fourcc = cricket::FOURCC_BGRA;
+ } else {
+ LOG(ERROR) << "PpFrameWriter::PutFrame - Got RGBA which is not supported.";
+ ASSERT(false);
+ return;
+ }
+ frame.data_size = bitmap->getSize();
+ frame.data = bitmap->getPixels();
+
+ // This signals to libJingle that a new VideoFrame is available.
+ // libJingle have no assumptions on what thread this signal come from.
+ SignalFrameCaptured(this, &frame);
+}
+
+// PpFrameWriterProxy is a helper class to make sure the user won't use
+// PpFrameWriter after it is released (IOW its owner - WebMediaStreamTrack -
+// is released).
+class PpFrameWriterProxy : public FrameWriterInterface {
+ public:
+ PpFrameWriterProxy(VideoTrackInterface* track,
+ PpFrameWriter* writer)
+ : track_(track),
+ writer_(writer) {
+ ASSERT(writer_ != NULL);
+ }
+
+ virtual ~PpFrameWriterProxy() {}
+
+ virtual void PutFrame(webkit::ppapi::PPB_ImageData_Impl* image_data,
+ int64 time_stamp_ns) OVERRIDE {
+ writer_->PutFrame(image_data, time_stamp_ns);
+ }
+
+ private:
+ scoped_refptr<VideoTrackInterface> track_;
+ PpFrameWriter* writer_;
+
+ DISALLOW_COPY_AND_ASSIGN(PpFrameWriterProxy);
+};
+
+bool VideoDestinationHandler::Open(
+ MediaStreamDependencyFactory* factory,
+ MediaStreamRegistryInterface* registry,
+ const std::string& url,
+ FrameWriterInterface** frame_writer) {
+ if (!factory) {
+ factory = RenderThreadImpl::current()->GetMediaStreamDependencyFactory();
+ ASSERT(factory != NULL);
+ }
+ WebKit::WebMediaStream stream;
+ if (registry) {
+ stream = registry->GetMediaStream(url);
+ } else {
+ stream =
+ WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(GURL(url));
+ }
+ if (stream.isNull() || !stream.extraData()) {
+ LOG(ERROR) << "VideoDestinationHandler::Open - invalid url: " << url;
+ return false;
+ }
+
+ // Create a new native video track and add it to |stream|.
+ std::string track_id = talk_base::ToString(talk_base::CreateRandomId64());
+ PpFrameWriter* writer = new PpFrameWriter();
+ if (!factory->AddNativeVideoMediaTrack(track_id, &stream, writer)) {
+ delete writer;
+ return false;
+ }
+
+ // Gets a handler to the native video track, which owns the |writer|.
+ MediaStreamExtraData* extra_data =
+ static_cast<MediaStreamExtraData*>(stream.extraData());
+ DCHECK(extra_data);
+ webrtc::MediaStreamInterface* native_stream = extra_data->stream();
+ DCHECK(native_stream);
+ VideoTrackVector video_tracks = native_stream->GetVideoTracks();
+ // Currently one supports one video track per media stream.
+ ASSERT(video_tracks.size() == 1);
+
+ *frame_writer = new PpFrameWriterProxy(video_tracks[0].get(), writer);
+ return true;
+}
+
+} // namespace content
+
diff --git a/content/renderer/media/video_destination_handler.h b/content/renderer/media/video_destination_handler.h
new file mode 100644
index 0000000..68b1a6c
--- /dev/null
+++ b/content/renderer/media/video_destination_handler.h
@@ -0,0 +1,99 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_VIDEO_DESTINATION_HANDLER_H_
+#define CONTENT_RENDERER_MEDIA_VIDEO_DESTINATION_HANDLER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/synchronization/lock.h"
+#include "content/common/content_export.h"
+#include "third_party/libjingle/source/talk/media/base/videocapturer.h"
+
+namespace webkit {
+namespace ppapi {
+class PPB_ImageData_Impl;
+}
+}
+
+namespace content {
+
+class MediaStreamDependencyFactory;
+class MediaStreamRegistryInterface;
+
+// Interface used by the effects pepper plugin to output the processed frame
+// to the video track.
+class CONTENT_EXPORT FrameWriterInterface {
+ public:
+ // The ownership of the |image_data| deosn't transfer. So the implementation
+ // of this interface should make a copy of the |image_data| before return.
+ virtual void PutFrame(webkit::ppapi::PPB_ImageData_Impl* image_data,
+ int64 time_stamp_ns) = 0;
+ virtual ~FrameWriterInterface() {}
+};
+
+// PpFrameWriter implements cricket::VideoCapturer so that it can be used in
+// the native video track's video source. It also implements
+// FrameWriterInterface, which will be used by the effects pepper plugin to
+// inject the processed frame.
+class CONTENT_EXPORT PpFrameWriter
+ : public NON_EXPORTED_BASE(cricket::VideoCapturer),
+ public FrameWriterInterface {
+ public:
+ PpFrameWriter();
+ virtual ~PpFrameWriter();
+
+ // cricket::VideoCapturer implementation.
+ // These methods are accessed from a libJingle worker thread.
+ virtual cricket::CaptureState Start(
+ const cricket::VideoFormat& capture_format) OVERRIDE;
+ virtual void Stop() OVERRIDE;
+ virtual bool IsRunning() OVERRIDE;
+ virtual bool GetPreferredFourccs(std::vector<uint32>* fourccs) OVERRIDE;
+ virtual bool GetBestCaptureFormat(const cricket::VideoFormat& desired,
+ cricket::VideoFormat* best_format) OVERRIDE;
+ virtual bool IsScreencast() const OVERRIDE;
+
+ // FrameWriterInterface implementation.
+ // This method will be called by the Pepper host from render thread.
+ virtual void PutFrame(webkit::ppapi::PPB_ImageData_Impl* image_data,
+ int64 time_stamp_ns) OVERRIDE;
+
+ private:
+ bool started_;
+ // |lock_| is used to protect |started_| which will be accessed from different
+ // threads - libjingle worker thread and render thread.
+ base::Lock lock_;
+
+ DISALLOW_COPY_AND_ASSIGN(PpFrameWriter);
+};
+
+// VideoDestinationHandler is a glue class between the webrtc MediaStream and
+// the effects pepper plugin host.
+class CONTENT_EXPORT VideoDestinationHandler {
+ public:
+ // Instantiates and adds a new video track to the MediaStream specified by
+ // |url|. Returns a handler for delivering frames to the new video track as
+ // |frame_writer|.
+ // If |factory| is NULL the MediaStreamDependencyFactory owned by
+ // RenderThreadImpl::current() will be used.
+ // If |registry| is NULL the global WebKit::WebMediaStreamRegistry will be
+ // used to look up the media stream.
+ // The caller of the function takes the ownership of |frame_writer|.
+ // Returns true on success and false on failure.
+ static bool Open(MediaStreamDependencyFactory* factory,
+ MediaStreamRegistryInterface* registry,
+ const std::string& url,
+ FrameWriterInterface** frame_writer);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VideoDestinationHandler);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_VIDEO_DESTINATION_HANDLER_H_
+
diff --git a/content/renderer/media/video_destination_handler_unittest.cc b/content/renderer/media/video_destination_handler_unittest.cc
new file mode 100644
index 0000000..abdad6a
--- /dev/null
+++ b/content/renderer/media/video_destination_handler_unittest.cc
@@ -0,0 +1,127 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "base/utf_string_conversions.h"
+#include "content/renderer/media/media_stream_extra_data.h"
+#include "content/renderer/media/mock_media_stream_dependency_factory.h"
+#include "content/renderer/media/mock_media_stream_registry.h"
+#include "content/renderer/media/video_destination_handler.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamTrack.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
+
+using cricket::CapturedFrame;
+using cricket::CaptureState;
+using cricket::VideoCapturer;
+using cricket::VideoFormat;
+using cricket::VideoFormatPod;
+
+namespace content {
+
+static const std::string kTestStreamUrl = "stream_url";
+static const std::string kUnknownStreamUrl = "unknown_stream_url";
+static const VideoFormatPod kTestFormat = {
+ 640, 360, FPS_TO_INTERVAL(30), cricket::FOURCC_ANY
+};
+
+class PpFrameWriterTest
+ : public ::testing::Test,
+ public sigslot::has_slots<> {
+ public:
+ PpFrameWriterTest()
+ : last_capture_state_(cricket::CS_FAILED),
+ captured_frame_count_(0),
+ captured_frame_(NULL) {
+ writer_.SignalStateChange.connect(this, &PpFrameWriterTest::OnStateChange);
+ writer_.SignalFrameCaptured.connect(
+ this, &PpFrameWriterTest::OnFrameCaptured);
+ }
+
+ void OnStateChange(VideoCapturer* capturer, CaptureState state) {
+ last_capture_state_ = state;
+ }
+
+ void OnFrameCaptured(VideoCapturer* capturer, const CapturedFrame* frame) {
+ ++captured_frame_count_;
+ captured_frame_ = const_cast<CapturedFrame*>(frame);
+ }
+
+ protected:
+ PpFrameWriter writer_;
+ CaptureState last_capture_state_;
+ int captured_frame_count_;
+ CapturedFrame* captured_frame_;
+};
+
+class VideoDestinationHandlerTest : public ::testing::Test {
+ public:
+ VideoDestinationHandlerTest() : registry_(&factory_) {
+ factory_.EnsurePeerConnectionFactory();
+ registry_.Init(kTestStreamUrl);
+ }
+
+ protected:
+ MockMediaStreamDependencyFactory factory_;
+ MockMediaStreamRegistry registry_;
+};
+
+TEST_F(PpFrameWriterTest, StartStop) {
+ EXPECT_FALSE(writer_.IsRunning());
+ EXPECT_EQ(cricket::CS_STARTING, writer_.Start(VideoFormat(kTestFormat)));
+ EXPECT_TRUE(writer_.IsRunning());
+ EXPECT_EQ(cricket::CS_FAILED, writer_.Start(VideoFormat(kTestFormat)));
+ writer_.Stop();
+ EXPECT_EQ(cricket::CS_STOPPED, last_capture_state_);
+}
+
+TEST_F(PpFrameWriterTest, GetPreferredFourccs) {
+ std::vector<uint32> fourccs;
+ EXPECT_TRUE(writer_.GetPreferredFourccs(&fourccs));
+ EXPECT_EQ(1u, fourccs.size());
+ EXPECT_EQ(cricket::FOURCC_BGRA, fourccs[0]);
+}
+
+TEST_F(PpFrameWriterTest, GetBestCaptureFormat) {
+ VideoFormat desired(kTestFormat);
+ VideoFormat best_format;
+ EXPECT_FALSE(writer_.GetBestCaptureFormat(desired, NULL));
+ EXPECT_TRUE(writer_.GetBestCaptureFormat(desired, &best_format));
+ EXPECT_EQ(cricket::FOURCC_BGRA, best_format.fourcc);
+
+ desired.fourcc = best_format.fourcc;
+ EXPECT_EQ(desired, best_format);
+}
+
+TEST_F(VideoDestinationHandlerTest, Open) {
+ FrameWriterInterface* frame_writer = NULL;
+ // Unknow url will return false.
+ EXPECT_FALSE(VideoDestinationHandler::Open(&factory_, ®istry_,
+ kUnknownStreamUrl, &frame_writer));
+ EXPECT_TRUE(VideoDestinationHandler::Open(&factory_, ®istry_,
+ kTestStreamUrl, &frame_writer));
+ EXPECT_TRUE(frame_writer);
+
+ // Verify the video track has been added.
+ const WebKit::WebMediaStream test_stream = registry_.test_stream();
+ WebKit::WebVector<WebKit::WebMediaStreamTrack> video_tracks;
+ test_stream.videoSources(video_tracks);
+ EXPECT_EQ(1u, video_tracks.size());
+
+ // Verify the native video track has been added.
+ MediaStreamExtraData* extra_data =
+ static_cast<MediaStreamExtraData*>(test_stream.extraData());
+ DCHECK(extra_data);
+ webrtc::MediaStreamInterface* native_stream = extra_data->stream();
+ DCHECK(native_stream);
+ webrtc::VideoTrackVector native_video_tracks =
+ native_stream->GetVideoTracks();
+ EXPECT_EQ(1u, native_video_tracks.size());
+
+ delete frame_writer;
+}
+
+} // namespace content
diff --git a/content/renderer/media/video_source_handler.cc b/content/renderer/media/video_source_handler.cc
new file mode 100644
index 0000000..c4f875d
--- /dev/null
+++ b/content/renderer/media/video_source_handler.cc
@@ -0,0 +1,142 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/video_source_handler.h"
+
+#include <string>
+
+#include "base/logging.h"
+#include "content/renderer/media/media_stream_dependency_factory.h"
+#include "content/renderer/media/media_stream_registry_interface.h"
+#include "content/renderer/render_thread_impl.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStream.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamRegistry.h"
+#include "third_party/libjingle/source/talk/media/base/videoframe.h"
+#include "third_party/libjingle/source/talk/media/base/videorenderer.h"
+
+using cricket::VideoFrame;
+using cricket::VideoRenderer;
+using webrtc::VideoSourceInterface;
+
+namespace content {
+
+// PpFrameReceiver implements cricket::VideoRenderer so that it can be attached
+// to native video track's video source to receive the captured frame.
+// It can be attached to a FrameReaderInterface to output the received frame.
+class PpFrameReceiver : public cricket::VideoRenderer {
+ public:
+ PpFrameReceiver() : reader_(NULL) {}
+ virtual ~PpFrameReceiver() {}
+
+ // Implements VideoRenderer.
+ virtual bool SetSize(int width, int height, int reserved) OVERRIDE {
+ return true;
+ }
+ virtual bool RenderFrame(const cricket::VideoFrame* frame) OVERRIDE {
+ base::AutoLock auto_lock(lock_);
+ if (reader_) {
+ // Make a shallow copy of the frame as the |reader_| may need to queue it.
+ // Both frames will share a single reference-counted frame buffer.
+ reader_->GotFrame(frame->Copy());
+ }
+ return true;
+ }
+
+ void SetReader(FrameReaderInterface* reader) {
+ base::AutoLock auto_lock(lock_);
+ reader_ = reader;
+ }
+
+ private:
+ FrameReaderInterface* reader_;
+ base::Lock lock_;
+
+ DISALLOW_COPY_AND_ASSIGN(PpFrameReceiver);
+};
+
+VideoSourceHandler::VideoSourceHandler(
+ MediaStreamRegistryInterface* registry)
+ : registry_(registry) {
+}
+
+VideoSourceHandler::~VideoSourceHandler() {}
+
+bool VideoSourceHandler::Open(const std::string& url,
+ FrameReaderInterface* reader) {
+ scoped_refptr<webrtc::VideoSourceInterface> source = GetFirstVideoSource(url);
+ if (!source.get()) {
+ return false;
+ }
+ PpFrameReceiver* receiver = new PpFrameReceiver();
+ receiver->SetReader(reader);
+ source->AddSink(receiver);
+ reader_to_receiver_[reader] = receiver;
+ return true;
+}
+
+bool VideoSourceHandler::Close(const std::string& url,
+ FrameReaderInterface* reader) {
+ scoped_refptr<webrtc::VideoSourceInterface> source = GetFirstVideoSource(url);
+ if (!source.get()) {
+ LOG(ERROR) << "VideoSourceHandler::Close - Failed to get the video source "
+ << "from MediaStream with url: " << url;
+ return false;
+ }
+ PpFrameReceiver* receiver =
+ static_cast<PpFrameReceiver*>(GetReceiver(reader));
+ receiver->SetReader(NULL);
+ source->RemoveSink(receiver);
+ reader_to_receiver_.erase(reader);
+ return true;
+}
+
+scoped_refptr<VideoSourceInterface> VideoSourceHandler::GetFirstVideoSource(
+ const std::string& url) {
+ scoped_refptr<webrtc::VideoSourceInterface> source;
+ WebKit::WebMediaStream stream;
+ if (registry_) {
+ stream = registry_->GetMediaStream(url);
+ } else {
+ stream =
+ WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(GURL(url));
+ }
+ if (stream.isNull() || !stream.extraData()) {
+ LOG(ERROR) << "GetFirstVideoSource - invalid url: " << url;
+ return source;
+ }
+
+ // Get the first video track from the stream.
+ MediaStreamExtraData* extra_data =
+ static_cast<MediaStreamExtraData*>(stream.extraData());
+ if (!extra_data) {
+ LOG(ERROR) << "GetFirstVideoSource - MediaStreamExtraData is NULL.";
+ return source;
+ }
+ webrtc::MediaStreamInterface* native_stream = extra_data->stream();
+ if (!native_stream) {
+ LOG(ERROR) << "GetFirstVideoSource - native stream is NULL.";
+ return source;
+ }
+ webrtc::VideoTrackVector native_video_tracks =
+ native_stream->GetVideoTracks();
+ if (native_video_tracks.empty()) {
+ LOG(ERROR) << "GetFirstVideoSource - stream has no video track.";
+ return source;
+ }
+ source = native_video_tracks[0]->GetSource();
+ return source;
+}
+
+VideoRenderer* VideoSourceHandler::GetReceiver(
+ FrameReaderInterface* reader) {
+ std::map<FrameReaderInterface*, VideoRenderer*>::iterator it;
+ it = reader_to_receiver_.find(reader);
+ if (it == reader_to_receiver_.end()) {
+ return NULL;
+ }
+ return it->second;
+}
+
+} // namespace content
+
diff --git a/content/renderer/media/video_source_handler.h b/content/renderer/media/video_source_handler.h
new file mode 100644
index 0000000..3d3b4df
--- /dev/null
+++ b/content/renderer/media/video_source_handler.h
@@ -0,0 +1,73 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_VIDEO_SOURCE_HANDLER_H_
+#define CONTENT_RENDERER_MEDIA_VIDEO_SOURCE_HANDLER_H_
+
+#include <map>
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "content/common/content_export.h"
+#include "third_party/libjingle/source/talk/app/webrtc/videosourceinterface.h"
+
+namespace cricket {
+class VideoFrame;
+}
+
+namespace content {
+
+class MediaStreamDependencyFactory;
+class MediaStreamRegistryInterface;
+
+// Interface used by the effects pepper plugin to get captured frame
+// from the video track.
+class CONTENT_EXPORT FrameReaderInterface {
+ public:
+ // Got a new captured frame.
+ // The ownership of the |frame| is transfered to the caller. So the caller
+ // must delete |frame| when done with it.
+ virtual bool GotFrame(cricket::VideoFrame* frame) = 0;
+
+ protected:
+ virtual ~FrameReaderInterface() {}
+};
+
+// VideoSourceHandler is a glue class between the webrtc MediaStream and
+// the effects pepper plugin host.
+class CONTENT_EXPORT VideoSourceHandler {
+ public:
+ // |registry| is used to look up the media stream by url. If a NULL |registry|
+ // is given, the global WebKit::WebMediaStreamRegistry will be used.
+ explicit VideoSourceHandler(MediaStreamRegistryInterface* registry);
+ virtual ~VideoSourceHandler();
+ // Connects to the first video track in the MediaStream specified by |url| and
+ // the received frames will be delivered via |reader|.
+ // Returns true on success and false on failure.
+ bool Open(const std::string& url, FrameReaderInterface* reader);
+ // Closes |reader|'s connection with the first video track in
+ // the MediaStream specified by |url|, i.e. stops receiving frames from the
+ // video track.
+ // Returns true on success and false on failure.
+ bool Close(const std::string& url, FrameReaderInterface* reader);
+
+ // Gets the VideoRenderer associated with |reader|.
+ // Made it public only for testing purpose.
+ cricket::VideoRenderer* GetReceiver(FrameReaderInterface* reader);
+
+ private:
+ scoped_refptr<webrtc::VideoSourceInterface> GetFirstVideoSource(
+ const std::string& url);
+
+ MediaStreamRegistryInterface* registry_;
+ std::map<FrameReaderInterface*, cricket::VideoRenderer*> reader_to_receiver_;
+
+ DISALLOW_COPY_AND_ASSIGN(VideoSourceHandler);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_VIDEO_SOURCE_HANDLER_H_
+
diff --git a/content/renderer/media/video_source_handler_unittest.cc b/content/renderer/media/video_source_handler_unittest.cc
new file mode 100644
index 0000000..653d7a2
--- /dev/null
+++ b/content/renderer/media/video_source_handler_unittest.cc
@@ -0,0 +1,89 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "base/utf_string_conversions.h"
+#include "content/renderer/media/media_stream_extra_data.h"
+#include "content/renderer/media/media_stream_registry_interface.h"
+#include "content/renderer/media/mock_media_stream_dependency_factory.h"
+#include "content/renderer/media/mock_media_stream_registry.h"
+#include "content/renderer/media/video_source_handler.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamTrack.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
+#include "third_party/libjingle/source/talk/media/base/videorenderer.h"
+#include "third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.h"
+
+using cricket::VideoFrame;
+
+namespace content {
+
+static const std::string kTestStreamUrl = "stream_url";
+static const std::string kTestVideoTrackId = "video_track_id";
+static const std::string kUnknownStreamUrl = "unknown_stream_url";
+
+class FakeFrameReader : public FrameReaderInterface {
+ public:
+ virtual bool GotFrame(VideoFrame* frame) OVERRIDE {
+ last_frame_.reset(frame);
+ return true;
+ }
+
+ const VideoFrame* last_frame() {
+ return last_frame_.get();
+ }
+
+ private:
+ scoped_ptr<VideoFrame> last_frame_;
+};
+
+class VideoSourceHandlerTest : public ::testing::Test {
+ public:
+ VideoSourceHandlerTest() : registry_(&dependency_factory_) {
+ handler_.reset(new VideoSourceHandler(®istry_));
+ dependency_factory_.EnsurePeerConnectionFactory();
+ registry_.Init(kTestStreamUrl);
+ registry_.AddVideoTrack(kTestVideoTrackId);
+ }
+
+ protected:
+ scoped_ptr<VideoSourceHandler> handler_;
+ MockMediaStreamDependencyFactory dependency_factory_;
+ MockMediaStreamRegistry registry_;
+};
+
+TEST_F(VideoSourceHandlerTest, OpenClose) {
+ FakeFrameReader reader;
+ // Unknow url will return false.
+ EXPECT_FALSE(handler_->Open(kUnknownStreamUrl, &reader));
+ EXPECT_TRUE(handler_->Open(kTestStreamUrl, &reader));
+ cricket::WebRtcVideoFrame test_frame;
+ int width = 640;
+ int height = 360;
+ int64 et = 123456;
+ int64 ts = 789012;
+ test_frame.InitToBlack(width, height, 1, 1, et, ts);
+ cricket::VideoRenderer* receiver = handler_->GetReceiver(&reader);
+ ASSERT(receiver != NULL);
+ receiver->RenderFrame(&test_frame);
+
+ const VideoFrame* frame = reader.last_frame();
+ ASSERT_TRUE(frame != NULL);
+
+ // Compare |frame| to |test_frame|.
+ EXPECT_EQ(test_frame.GetWidth(), frame->GetWidth());
+ EXPECT_EQ(test_frame.GetHeight(), frame->GetHeight());
+ EXPECT_EQ(test_frame.GetElapsedTime(), frame->GetElapsedTime());
+ EXPECT_EQ(test_frame.GetTimeStamp(), frame->GetTimeStamp());
+ EXPECT_EQ(test_frame.GetYPlane(), frame->GetYPlane());
+ EXPECT_EQ(test_frame.GetUPlane(), frame->GetUPlane());
+ EXPECT_EQ(test_frame.GetVPlane(), frame->GetVPlane());
+
+ EXPECT_TRUE(handler_->Close(kTestStreamUrl, &reader));
+ EXPECT_TRUE(handler_->GetReceiver(&reader) == NULL);
+}
+
+} // namespace content
diff --git a/content/renderer/media/webmediaplayer_proxy_impl_android.cc b/content/renderer/media/webmediaplayer_proxy_impl_android.cc
index 875e4c1..652964a 100644
--- a/content/renderer/media/webmediaplayer_proxy_impl_android.cc
+++ b/content/renderer/media/webmediaplayer_proxy_impl_android.cc
@@ -7,7 +7,7 @@
#include "base/bind.h"
#include "base/message_loop.h"
#include "content/common/media/media_player_messages.h"
-#include "webkit/media/android/webmediaplayer_impl_android.h"
+#include "webkit/media/android/webmediaplayer_android.h"
#include "webkit/media/android/webmediaplayer_manager_android.h"
namespace content {
@@ -27,7 +27,8 @@
const IPC::Message& msg) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(WebMediaPlayerProxyImplAndroid, msg)
- IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaPrepared, OnMediaPrepared)
+ IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaMetadataChanged,
+ OnMediaMetadataChanged)
IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaPlaybackCompleted,
OnMediaPlaybackCompleted)
IPC_MESSAGE_HANDLER(MediaPlayerMsg_MediaBufferingUpdate,
@@ -43,15 +44,20 @@
IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidExitFullscreen, OnDidExitFullscreen)
IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidMediaPlayerPlay, OnPlayerPlay)
IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidMediaPlayerPause, OnPlayerPause)
+#if defined(GOOGLE_TV)
+ IPC_MESSAGE_HANDLER(MediaPlayerMsg_ReadFromDemuxer, OnReadFromDemuxer)
+#endif
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void WebMediaPlayerProxyImplAndroid::Initialize(
- int player_id, const GURL& url, const GURL& first_party_for_cookies) {
+ int player_id, const GURL& url,
+ bool is_media_source,
+ const GURL& first_party_for_cookies) {
Send(new MediaPlayerHostMsg_MediaPlayerInitialize(
- routing_id(), player_id, url, first_party_for_cookies));
+ routing_id(), player_id, url, is_media_source, first_party_for_cookies));
}
void WebMediaPlayerProxyImplAndroid::Start(int player_id) {
@@ -74,97 +80,88 @@
Send(new MediaPlayerHostMsg_DestroyMediaPlayer(routing_id(), player_id));
}
-void WebMediaPlayerProxyImplAndroid::OnMediaPrepared(
+void WebMediaPlayerProxyImplAndroid::OnMediaMetadataChanged(
int player_id,
- base::TimeDelta duration) {
- webkit_media::WebMediaPlayerImplAndroid* player =
- GetWebMediaPlayer(player_id);
+ base::TimeDelta duration,
+ int width,
+ int height,
+ bool success) {
+ webkit_media::WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id);
if (player)
- player->OnMediaPrepared(duration);
+ player->OnMediaMetadataChanged(duration, width, height, success);
}
void WebMediaPlayerProxyImplAndroid::OnMediaPlaybackCompleted(
int player_id) {
- webkit_media::WebMediaPlayerImplAndroid* player =
- GetWebMediaPlayer(player_id);
+ webkit_media::WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id);
if (player)
player->OnPlaybackComplete();
}
void WebMediaPlayerProxyImplAndroid::OnMediaBufferingUpdate(
int player_id, int percent) {
- webkit_media::WebMediaPlayerImplAndroid* player =
- GetWebMediaPlayer(player_id);
+ webkit_media::WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id);
if (player)
player->OnBufferingUpdate(percent);
}
void WebMediaPlayerProxyImplAndroid::OnMediaSeekCompleted(
int player_id, base::TimeDelta current_time) {
- webkit_media::WebMediaPlayerImplAndroid* player =
- GetWebMediaPlayer(player_id);
+ webkit_media::WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id);
if (player)
player->OnSeekComplete(current_time);
}
void WebMediaPlayerProxyImplAndroid::OnMediaError(
int player_id, int error) {
- webkit_media::WebMediaPlayerImplAndroid* player =
- GetWebMediaPlayer(player_id);
+ webkit_media::WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id);
if (player)
player->OnMediaError(error);
}
void WebMediaPlayerProxyImplAndroid::OnVideoSizeChanged(
int player_id, int width, int height) {
- webkit_media::WebMediaPlayerImplAndroid* player =
- GetWebMediaPlayer(player_id);
+ webkit_media::WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id);
if (player)
player->OnVideoSizeChanged(width, height);
}
void WebMediaPlayerProxyImplAndroid::OnTimeUpdate(
int player_id, base::TimeDelta current_time) {
- webkit_media::WebMediaPlayerImplAndroid* player =
- GetWebMediaPlayer(player_id);
+ webkit_media::WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id);
if (player)
player->OnTimeUpdate(current_time);
}
void WebMediaPlayerProxyImplAndroid::OnMediaPlayerReleased(
int player_id) {
- webkit_media::WebMediaPlayerImplAndroid* player =
- GetWebMediaPlayer(player_id);
+ webkit_media::WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id);
if (player)
player->OnPlayerReleased();
}
void WebMediaPlayerProxyImplAndroid::OnDidEnterFullscreen(
int player_id) {
- webkit_media::WebMediaPlayerImplAndroid* player =
- GetWebMediaPlayer(player_id);
+ webkit_media::WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id);
if (player)
player->OnDidEnterFullscreen();
}
void WebMediaPlayerProxyImplAndroid::OnDidExitFullscreen(
int player_id) {
- webkit_media::WebMediaPlayerImplAndroid* player =
- GetWebMediaPlayer(player_id);
+ webkit_media::WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id);
if (player)
player->OnDidExitFullscreen();
}
void WebMediaPlayerProxyImplAndroid::OnPlayerPlay(int player_id) {
- webkit_media::WebMediaPlayerImplAndroid* player =
- GetWebMediaPlayer(player_id);
+ webkit_media::WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id);
if (player)
player->OnMediaPlayerPlay();
}
void WebMediaPlayerProxyImplAndroid::OnPlayerPause(int player_id) {
- webkit_media::WebMediaPlayerImplAndroid* player =
- GetWebMediaPlayer(player_id);
+ webkit_media::WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id);
if (player)
player->OnMediaPlayerPause();
}
@@ -177,13 +174,47 @@
Send(new MediaPlayerHostMsg_ExitFullscreen(routing_id(), player_id));
}
+#if defined(GOOGLE_TV)
void WebMediaPlayerProxyImplAndroid::RequestExternalSurface(int player_id) {
Send(new MediaPlayerHostMsg_RequestExternalSurface(routing_id(), player_id));
}
-webkit_media::WebMediaPlayerImplAndroid*
+void WebMediaPlayerProxyImplAndroid::DidCommitCompositorFrame() {
+ std::map<int, gfx::RectF> geometry_change;
+ manager_->RetrieveGeometryChanges(&geometry_change);
+ for (std::map<int, gfx::RectF>::iterator it = geometry_change.begin();
+ it != geometry_change.end();
+ ++it) {
+ Send(new MediaPlayerHostMsg_NotifyGeometryChange(routing_id(),
+ it->first,
+ it->second));
+ }
+}
+
+void WebMediaPlayerProxyImplAndroid::DemuxerReady(
+ int player_id,
+ const media::MediaPlayerHostMsg_DemuxerReady_Params& params) {
+ Send(new MediaPlayerHostMsg_DemuxerReady(routing_id(), player_id, params));
+}
+
+void WebMediaPlayerProxyImplAndroid::ReadFromDemuxerAck(
+ int player_id,
+ const media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params& params) {
+ Send(new MediaPlayerHostMsg_ReadFromDemuxerAck(
+ routing_id(), player_id, params));
+
+}
+void WebMediaPlayerProxyImplAndroid::OnReadFromDemuxer(
+ int player_id, media::DemuxerStream::Type type, bool seek_done) {
+ webkit_media::WebMediaPlayerAndroid* player = GetWebMediaPlayer(player_id);
+ if (player)
+ player->OnReadFromDemuxer(type, seek_done);
+}
+#endif
+
+webkit_media::WebMediaPlayerAndroid*
WebMediaPlayerProxyImplAndroid::GetWebMediaPlayer(int player_id) {
- return static_cast<webkit_media::WebMediaPlayerImplAndroid*>(
+ return static_cast<webkit_media::WebMediaPlayerAndroid*>(
manager_->GetMediaPlayer(player_id));
}
diff --git a/content/renderer/media/webmediaplayer_proxy_impl_android.h b/content/renderer/media/webmediaplayer_proxy_impl_android.h
index d8eb51d..a990459 100644
--- a/content/renderer/media/webmediaplayer_proxy_impl_android.h
+++ b/content/renderer/media/webmediaplayer_proxy_impl_android.h
@@ -11,14 +11,14 @@
#include "webkit/media/android/webmediaplayer_proxy_android.h"
namespace webkit_media {
-class WebMediaPlayerImplAndroid;
+class WebMediaPlayerAndroid;
class WebMediaPlayerManagerAndroid;
}
namespace content {
// This class manages all the IPC communications between
-// WebMediaPlayerImplAndroid and the MediaPlayerManagerAndroid in the browser
+// WebMediaPlayerAndroid and the MediaPlayerManagerAndroid in the browser
// process.
class WebMediaPlayerProxyImplAndroid
: public RenderViewObserver,
@@ -26,7 +26,7 @@
public:
// Construct a WebMediaPlayerProxyImplAndroid object for the |render_view|.
// |manager| is passed to this class so that it can find the right
- // WebMediaPlayerImplAndroid using player IDs.
+ // WebMediaPlayerAndroid using player IDs.
WebMediaPlayerProxyImplAndroid(
RenderView* render_view,
webkit_media::WebMediaPlayerManagerAndroid* manager);
@@ -36,6 +36,7 @@
// Methods inherited from WebMediaPlayerProxyAndroid.
virtual void Initialize(int player_id, const GURL& url,
+ bool is_media_source,
const GURL& first_party_for_cookies) OVERRIDE;
virtual void Start(int player_id) OVERRIDE;
virtual void Pause(int player_id) OVERRIDE;
@@ -44,13 +45,25 @@
virtual void DestroyPlayer(int player_id) OVERRIDE;
virtual void EnterFullscreen(int player_id) OVERRIDE;
virtual void ExitFullscreen(int player_id) OVERRIDE;
+#if defined(GOOGLE_TV)
virtual void RequestExternalSurface(int player_id) OVERRIDE;
+ virtual void DemuxerReady(
+ int player_id,
+ const media::MediaPlayerHostMsg_DemuxerReady_Params& params) OVERRIDE;
+ virtual void ReadFromDemuxerAck(
+ int player_id,
+ const media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params&) OVERRIDE;
+
+ // Methods inherited from RenderViewObserver.
+ virtual void DidCommitCompositorFrame() OVERRIDE;
+#endif
private:
- webkit_media::WebMediaPlayerImplAndroid* GetWebMediaPlayer(int player_id);
+ webkit_media::WebMediaPlayerAndroid* GetWebMediaPlayer(int player_id);
// Message handlers.
- void OnMediaPrepared(int player_id, base::TimeDelta duration);
+ void OnMediaMetadataChanged(int player_id, base::TimeDelta duration,
+ int width, int height, bool success);
void OnMediaPlaybackCompleted(int player_id);
void OnMediaBufferingUpdate(int player_id, int percent);
void OnMediaSeekCompleted(int player_id, base::TimeDelta current_time);
@@ -62,6 +75,10 @@
void OnDidEnterFullscreen(int player_id);
void OnPlayerPlay(int player_id);
void OnPlayerPause(int player_id);
+#if defined(GOOGLE_TV)
+ void OnReadFromDemuxer(
+ int player_id, media::DemuxerStream::Type type, bool seek_done);
+#endif
webkit_media::WebMediaPlayerManagerAndroid* manager_;
diff --git a/content/renderer/media/webrtc_audio_capturer.cc b/content/renderer/media/webrtc_audio_capturer.cc
index e37df57..92951e2 100644
--- a/content/renderer/media/webrtc_audio_capturer.cc
+++ b/content/renderer/media/webrtc_audio_capturer.cc
@@ -10,6 +10,7 @@
#include "base/string_util.h"
#include "content/common/child_process.h"
#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/webrtc_audio_capturer_sink_owner.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
#include "media/audio/audio_util.h"
#include "media/audio/sample_rates.h"
@@ -65,77 +66,6 @@
return buffer_size;
}
-// Reference counted container of WebRtcAudioCapturerSink delegates.
-class WebRtcAudioCapturer::SinkOwner
- : public base::RefCounted<WebRtcAudioCapturer::SinkOwner>,
- public WebRtcAudioCapturerSink {
- public:
- explicit SinkOwner(WebRtcAudioCapturerSink* sink);
-
- virtual void CaptureData(const int16* audio_data,
- int number_of_channels,
- int number_of_frames,
- int audio_delay_milliseconds,
- double volume) OVERRIDE;
- virtual void SetCaptureFormat(const media::AudioParameters& params) OVERRIDE;
-
- bool IsEqual(const WebRtcAudioCapturerSink* other) const;
- void Reset();
-
- // Wrapper which allows to use std::find_if() when adding and removing
- // sinks to/from the list.
- struct WrapsSink {
- WrapsSink(WebRtcAudioCapturerSink* sink) : sink_(sink) {}
- bool operator()(
- const scoped_refptr<WebRtcAudioCapturer::SinkOwner>& owner) {
- return owner->IsEqual(sink_);
- }
- WebRtcAudioCapturerSink* sink_;
- };
-
- private:
- ~SinkOwner() {}
-
- friend class base::RefCounted<WebRtcAudioCapturer::SinkOwner>;
- WebRtcAudioCapturerSink* delegate_;
- mutable base::Lock lock_;
-
- DISALLOW_COPY_AND_ASSIGN(SinkOwner);
-};
-
-WebRtcAudioCapturer::SinkOwner::SinkOwner(
- WebRtcAudioCapturerSink* sink)
- : delegate_(sink) {
-}
-
-void WebRtcAudioCapturer::SinkOwner::CaptureData(
- const int16* audio_data, int number_of_channels, int number_of_frames,
- int audio_delay_milliseconds, double volume) {
- base::AutoLock lock(lock_);
- if (delegate_) {
- delegate_->CaptureData(audio_data, number_of_channels, number_of_frames,
- audio_delay_milliseconds, volume);
- }
-}
-
-void WebRtcAudioCapturer::SinkOwner::SetCaptureFormat(
- const media::AudioParameters& params) {
- base::AutoLock lock(lock_);
- if (delegate_)
- delegate_->SetCaptureFormat(params);
-}
-
-bool WebRtcAudioCapturer::SinkOwner::IsEqual(
- const WebRtcAudioCapturerSink* other) const {
- base::AutoLock lock(lock_);
- return (other == delegate_);
-}
-
-void WebRtcAudioCapturer::SinkOwner::Reset() {
- base::AutoLock lock(lock_);
- delegate_ = NULL;
-}
-
// This is a temporary audio buffer with parameters used to send data to
// callbacks.
class WebRtcAudioCapturer::ConfiguredBuffer :
@@ -179,7 +109,7 @@
// static
scoped_refptr<WebRtcAudioCapturer> WebRtcAudioCapturer::CreateCapturer() {
- scoped_refptr<WebRtcAudioCapturer> capturer = new WebRtcAudioCapturer();
+ scoped_refptr<WebRtcAudioCapturer> capturer = new WebRtcAudioCapturer();
return capturer;
}
@@ -189,26 +119,27 @@
if (!new_buffer->Initialize(sample_rate, channel_layout))
return false;
- SinkList sinks;
+ TrackList tracks;
{
base::AutoLock auto_lock(lock_);
buffer_ = new_buffer;
- sinks = sinks_;
+ tracks = tracks_;
}
- // Tell all sinks which format we use.
- for (SinkList::const_iterator it = sinks.begin(); it != sinks.end(); ++it)
+ // Tell all audio_tracks which format we use.
+ for (TrackList::const_iterator it = tracks.begin();
+ it != tracks.end(); ++it)
(*it)->SetCaptureFormat(new_buffer->params());
return true;
}
-bool WebRtcAudioCapturer::Initialize(media::ChannelLayout channel_layout,
+bool WebRtcAudioCapturer::Initialize(int render_view_id,
+ media::ChannelLayout channel_layout,
int sample_rate,
int session_id) {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!sinks_.empty());
DVLOG(1) << "WebRtcAudioCapturer::Initialize()";
DVLOG(1) << "Audio input hardware channel layout: " << channel_layout;
@@ -245,7 +176,7 @@
// Create and configure the default audio capturing source. The |source_|
// will be overwritten if an external client later calls SetCapturerSource()
// providing an alternative media::AudioCapturerSource.
- SetCapturerSource(AudioDeviceFactory::NewInputDevice(),
+ SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id),
channel_layout,
static_cast<float>(sample_rate));
@@ -262,39 +193,44 @@
WebRtcAudioCapturer::~WebRtcAudioCapturer() {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(sinks_.empty());
+ DCHECK(tracks_.empty());
DCHECK(!running_);
DVLOG(1) << "WebRtcAudioCapturer::~WebRtcAudioCapturer()";
}
-void WebRtcAudioCapturer::AddCapturerSink(WebRtcAudioCapturerSink* sink) {
+void WebRtcAudioCapturer::AddSink(
+ WebRtcAudioCapturerSink* track) {
DCHECK(thread_checker_.CalledOnValidThread());
- DVLOG(1) << "WebRtcAudioCapturer::AddCapturerSink()";
+ DVLOG(1) << "WebRtcAudioCapturer::AddSink()";
base::AutoLock auto_lock(lock_);
- // Verify that |sink| is not already added to the list.
+ // Verify that |track| is not already added to the list.
DCHECK(std::find_if(
- sinks_.begin(), sinks_.end(), SinkOwner::WrapsSink(sink)) ==
- sinks_.end());
- // Create (and add to the list) a new SinkOwner which owns the |sink|
- // and delagates all calls to the WebRtcAudioCapturerSink interface.
- sinks_.push_back(new WebRtcAudioCapturer::SinkOwner(sink));
+ tracks_.begin(), tracks_.end(),
+ WebRtcAudioCapturerSinkOwner::WrapsSink(track)) == tracks_.end());
+ // Create (and add to the list) a new WebRtcAudioCapturerSinkOwner which owns
+ // the |track| and delagates all calls to the WebRtcAudioCapturerSink
+ // interface.
+ tracks_.push_back(new WebRtcAudioCapturerSinkOwner(track));
+ // TODO(xians): should we call SetCapturerFormat() to each track?
}
-void WebRtcAudioCapturer::RemoveCapturerSink(WebRtcAudioCapturerSink* sink) {
+void WebRtcAudioCapturer::RemoveSink(
+ WebRtcAudioCapturerSink* track) {
DCHECK(thread_checker_.CalledOnValidThread());
- DVLOG(1) << "WebRtcAudioCapturer::RemoveCapturerSink()";
+ DVLOG(1) << "WebRtcAudioCapturer::RemoveSink()";
base::AutoLock auto_lock(lock_);
- // Get iterator to the first element for which WrapsSink(sink) returns true.
- SinkList::iterator it = std::find_if(sinks_.begin(), sinks_.end(),
- SinkOwner::WrapsSink(sink));
- if (it != sinks_.end()) {
+ // Get iterator to the first element for which WrapsSink(track) returns true.
+ TrackList::iterator it = std::find_if(
+ tracks_.begin(), tracks_.end(),
+ WebRtcAudioCapturerSinkOwner::WrapsSink(track));
+ if (it != tracks_.end()) {
// Clear the delegate to ensure that no more capture callbacks will
// be sent to this sink. Also avoids a possible crash which can happen
// if this method is called while capturing is active.
(*it)->Reset();
- sinks_.erase(it);
+ tracks_.erase(it);
}
}
@@ -315,6 +251,9 @@
source_.swap(old_source);
source_ = source;
current_buffer = buffer_;
+
+ // Reset the flag to allow calling Start() for the new source.
+ running_ = false;
}
const bool no_default_audio_source_exists = !current_buffer;
@@ -402,7 +341,7 @@
// This callback is driven by AudioInputDevice::AudioThreadCallback if
// |source_| is AudioInputDevice, otherwise it is driven by client's
// CaptureCallback.
- SinkList sinks;
+ TrackList tracks;
scoped_refptr<ConfiguredBuffer> buffer_ref_while_calling;
{
base::AutoLock auto_lock(lock_);
@@ -413,7 +352,7 @@
// a reference to the buffer so we can ensure it stays alive even if the
// buffer is reconfigured while we are calling back.
buffer_ref_while_calling = buffer_;
- sinks = sinks_;
+ tracks = tracks_;
}
int bytes_per_sample =
@@ -424,9 +363,9 @@
audio_source->ToInterleaved(audio_source->frames(), bytes_per_sample,
buffer_ref_while_calling->buffer());
- // Feed the data to the sinks.
- for (SinkList::const_iterator it = sinks.begin();
- it != sinks.end();
+ // Feed the data to the tracks.
+ for (TrackList::const_iterator it = tracks.begin();
+ it != tracks.end();
++it) {
(*it)->CaptureData(buffer_ref_while_calling->buffer(),
audio_source->channels(), audio_source->frames(),
diff --git a/content/renderer/media/webrtc_audio_capturer.h b/content/renderer/media/webrtc_audio_capturer.h
index 5d35604..12e0a34 100644
--- a/content/renderer/media/webrtc_audio_capturer.h
+++ b/content/renderer/media/webrtc_audio_capturer.h
@@ -23,10 +23,11 @@
namespace content {
class WebRtcAudioCapturerSink;
+class WebRtcAudioCapturerSinkOwner;
class WebRtcLocalAudioRenderer;
// This class manages the capture data flow by getting data from its
-// |source_|, and passing it to its |sink_|.
+// |source_|, and passing it to its |tracks_|.
// It allows clients to inject their own capture data source by calling
// SetCapturerSource().
// The threading model for this class is rather complex since it will be
@@ -43,24 +44,24 @@
static scoped_refptr<WebRtcAudioCapturer> CreateCapturer();
// Creates and configures the default audio capturing source using the
- // provided audio parameters, |session_id| is passed to the browser to
- // decide which device to use.
- // Called on the main render thread.
- bool Initialize(media::ChannelLayout channel_layout,
+ // provided audio parameters. |render_view_id| specifies the render view
+ // consuming audio for capture. |session_id| is passed to the browser to
+ // decide which device to use. Called on the main render thread.
+ bool Initialize(int render_view_id,
+ media::ChannelLayout channel_layout,
int sample_rate,
int session_id);
- // Called by the client on the sink side to add a sink.
+ // Add a audio track to the sinks of the capturer.
// WebRtcAudioDeviceImpl calls this method on the main render thread but
// other clients may call it from other threads. The current implementation
// does not support multi-thread calling.
// Called on the main render thread.
- void AddCapturerSink(WebRtcAudioCapturerSink* sink);
+ void AddSink(WebRtcAudioCapturerSink* track);
- // Called by the client on the sink side to remove a sink.
+ // Remove a audio track from the sinks of the capturer.
// Called on the main render thread.
- // Called on the main render thread.
- void RemoveCapturerSink(WebRtcAudioCapturerSink* sink);
+ void RemoveSink(WebRtcAudioCapturerSink* track);
// SetCapturerSource() is called if the client on the source side desires to
// provide their own captured audio data. Client is responsible for calling
@@ -97,6 +98,14 @@
// of this accessor and if we can remove it.
media::AudioParameters audio_parameters() const;
+ protected:
+ friend class base::RefCountedThreadSafe<WebRtcAudioCapturer>;
+ WebRtcAudioCapturer();
+ virtual ~WebRtcAudioCapturer();
+
+ private:
+ typedef std::list<scoped_refptr<WebRtcAudioCapturerSinkOwner> > TrackList;
+
// AudioCapturerSource::CaptureCallback implementation.
// Called on the AudioInputDevice audio thread.
virtual void Capture(media::AudioBus* audio_source,
@@ -104,16 +113,6 @@
double volume) OVERRIDE;
virtual void OnCaptureError() OVERRIDE;
- protected:
- friend class base::RefCountedThreadSafe<WebRtcAudioCapturer>;
- virtual ~WebRtcAudioCapturer();
-
- private:
- class SinkOwner;
- typedef std::list<scoped_refptr<SinkOwner> > SinkList;
-
- WebRtcAudioCapturer();
-
// Reconfigures the capturer with a new buffer size and capture parameters.
// Must be called without holding the lock. Returns true on success.
bool Reconfigure(int sample_rate, media::ChannelLayout channel_layout);
@@ -121,12 +120,12 @@
// Used to DCHECK that we are called on the correct thread.
base::ThreadChecker thread_checker_;
- // Protects |source_|, |sinks_|, |running_|, |loopback_fifo_|, |params_|,
- // |buffering_| and |agc_is_enabled_|.
+ // Protects |source_|, |audio_tracks_|, |running_|, |loopback_fifo_|,
+ // |params_|, |buffering_| and |agc_is_enabled_|.
mutable base::Lock lock_;
- // A list of sinks that the audio data is fed to.
- SinkList sinks_;
+ // A list of audio tracks that the audio data is fed to.
+ TrackList tracks_;
// The audio data source from the browser process.
scoped_refptr<media::AudioCapturerSource> source_;
diff --git a/content/renderer/media/webrtc_audio_capturer_sink_owner.cc b/content/renderer/media/webrtc_audio_capturer_sink_owner.cc
new file mode 100644
index 0000000..ab0c3d3
--- /dev/null
+++ b/content/renderer/media/webrtc_audio_capturer_sink_owner.cc
@@ -0,0 +1,42 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/webrtc_audio_capturer_sink_owner.h"
+
+namespace content {
+
+WebRtcAudioCapturerSinkOwner::WebRtcAudioCapturerSinkOwner(
+ WebRtcAudioCapturerSink* sink)
+ : delegate_(sink) {
+}
+
+void WebRtcAudioCapturerSinkOwner::CaptureData(
+ const int16* audio_data, int number_of_channels, int number_of_frames,
+ int audio_delay_milliseconds, double volume) {
+ base::AutoLock lock(lock_);
+ if (delegate_) {
+ delegate_->CaptureData(audio_data, number_of_channels, number_of_frames,
+ audio_delay_milliseconds, volume);
+ }
+}
+
+void WebRtcAudioCapturerSinkOwner::SetCaptureFormat(
+ const media::AudioParameters& params) {
+ base::AutoLock lock(lock_);
+ if (delegate_)
+ delegate_->SetCaptureFormat(params);
+}
+
+bool WebRtcAudioCapturerSinkOwner::IsEqual(
+ const WebRtcAudioCapturerSink* other) const {
+ base::AutoLock lock(lock_);
+ return (other == delegate_);
+}
+
+void WebRtcAudioCapturerSinkOwner::Reset() {
+ base::AutoLock lock(lock_);
+ delegate_ = NULL;
+}
+
+} // namespace content
diff --git a/content/renderer/media/webrtc_audio_capturer_sink_owner.h b/content/renderer/media/webrtc_audio_capturer_sink_owner.h
new file mode 100644
index 0000000..dd6264f
--- /dev/null
+++ b/content/renderer/media/webrtc_audio_capturer_sink_owner.h
@@ -0,0 +1,61 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_AUDIO_CAPTURER_SINK_OWNER_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_AUDIO_CAPTURER_SINK_OWNER_H_
+
+#include <list>
+
+#include "base/memory/ref_counted.h"
+#include "base/synchronization/lock.h"
+#include "content/renderer/media/webrtc_audio_device_impl.h"
+#include "media/audio/audio_parameters.h"
+
+namespace content {
+
+class WebRtcAudioCapturerSink;
+
+// Reference counted container of WebRtcAudioCapturerSink delegates.
+class WebRtcAudioCapturerSinkOwner
+ : public base::RefCountedThreadSafe<WebRtcAudioCapturerSinkOwner>,
+ public WebRtcAudioCapturerSink {
+ public:
+ explicit WebRtcAudioCapturerSinkOwner(WebRtcAudioCapturerSink* sink);
+
+ // WebRtcAudioCapturerSink implementation.
+ virtual void CaptureData(const int16* audio_data,
+ int number_of_channels,
+ int number_of_frames,
+ int audio_delay_milliseconds,
+ double volume) OVERRIDE;
+ virtual void SetCaptureFormat(const media::AudioParameters& params) OVERRIDE;
+
+ bool IsEqual(const WebRtcAudioCapturerSink* other) const;
+ void Reset();
+
+ // Wrapper which allows to use std::find_if() when adding and removing
+ // sinks to/from the list.
+ struct WrapsSink {
+ WrapsSink(WebRtcAudioCapturerSink* sink) : sink_(sink) {}
+ bool operator()(
+ const scoped_refptr<WebRtcAudioCapturerSinkOwner>& owner) {
+ return owner->IsEqual(sink_);
+ }
+ WebRtcAudioCapturerSink* sink_;
+ };
+
+ protected:
+ virtual ~WebRtcAudioCapturerSinkOwner() {}
+
+ private:
+ friend class base::RefCountedThreadSafe<WebRtcAudioCapturerSinkOwner>;
+ WebRtcAudioCapturerSink* delegate_;
+ mutable base::Lock lock_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcAudioCapturerSinkOwner);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_AUDIO_CAPTURER_SINK_OWNER_H_
diff --git a/content/renderer/media/webrtc_audio_device_impl.cc b/content/renderer/media/webrtc_audio_device_impl.cc
index 11091a6..f2763ca 100644
--- a/content/renderer/media/webrtc_audio_device_impl.cc
+++ b/content/renderer/media/webrtc_audio_device_impl.cc
@@ -226,8 +226,13 @@
DCHECK(!capturer_);
capturer_ = WebRtcAudioCapturer::CreateCapturer();
+ // Add itself as an audio track to the |capturer_|. This is because WebRTC
+ // supports only one ADM but multiple audio tracks, so the ADM can't be the
+ // sink of certain audio track now.
+ // TODO(xians): Register the ADM as the sink of the audio track if WebRTC
+ // supports one ADM for each audio track.
if (capturer_)
- capturer_->AddCapturerSink(this);
+ capturer_->AddSink(this);
// We need to return a success to continue the initialization of WebRtc VoE
// because failure on the capturer_ initialization should not prevent WebRTC
@@ -257,7 +262,7 @@
if (capturer_) {
// |capturer_| is stopped by the media stream, so do not need to
// call Stop() here.
- capturer_->RemoveCapturerSink(this);
+ capturer_->RemoveSink(this);
capturer_ = NULL;
}
diff --git a/content/renderer/media/webrtc_audio_device_impl.h b/content/renderer/media/webrtc_audio_device_impl.h
index e53bd09..56d256b 100644
--- a/content/renderer/media/webrtc_audio_device_impl.h
+++ b/content/renderer/media/webrtc_audio_device_impl.h
@@ -237,30 +237,6 @@
virtual int32_t AddRef() OVERRIDE;
virtual int32_t Release() OVERRIDE;
- // WebRtcAudioCapturerSink implementation.
-
- // Called on the AudioInputDevice worker thread.
- virtual void CaptureData(const int16* audio_data,
- int number_of_channels,
- int number_of_frames,
- int audio_delay_milliseconds,
- double volume) OVERRIDE;
-
- // Called on the main render thread.
- virtual void SetCaptureFormat(const media::AudioParameters& params) OVERRIDE;
-
- // WebRtcAudioRendererSource implementation.
-
- // Called on the AudioInputDevice worker thread.
- virtual void RenderData(uint8* audio_data,
- int number_of_channels,
- int number_of_frames,
- int audio_delay_milliseconds) OVERRIDE;
-
- // Called on the main render thread.
- virtual void SetRenderFormat(const media::AudioParameters& params) OVERRIDE;
- virtual void RemoveAudioRenderer(WebRtcAudioRenderer* renderer) OVERRIDE;
-
// webrtc::AudioDeviceModule implementation.
// All implemented methods are called on the main render thread unless
// anything else is stated.
@@ -338,6 +314,30 @@
// Make destructor private to ensure that we can only be deleted by Release().
virtual ~WebRtcAudioDeviceImpl();
+ // WebRtcAudioCapturerSink implementation.
+
+ // Called on the AudioInputDevice worker thread.
+ virtual void CaptureData(const int16* audio_data,
+ int number_of_channels,
+ int number_of_frames,
+ int audio_delay_milliseconds,
+ double volume) OVERRIDE;
+
+ // Called on the main render thread.
+ virtual void SetCaptureFormat(const media::AudioParameters& params) OVERRIDE;
+
+ // WebRtcAudioRendererSource implementation.
+
+ // Called on the AudioInputDevice worker thread.
+ virtual void RenderData(uint8* audio_data,
+ int number_of_channels,
+ int number_of_frames,
+ int audio_delay_milliseconds) OVERRIDE;
+
+ // Called on the main render thread.
+ virtual void SetRenderFormat(const media::AudioParameters& params) OVERRIDE;
+ virtual void RemoveAudioRenderer(WebRtcAudioRenderer* renderer) OVERRIDE;
+
// Used to DCHECK that we are called on the correct thread.
base::ThreadChecker thread_checker_;
diff --git a/content/renderer/media/webrtc_audio_device_unittest.cc b/content/renderer/media/webrtc_audio_device_unittest.cc
index 73c95fe..cc34bb2 100644
--- a/content/renderer/media/webrtc_audio_device_unittest.cc
+++ b/content/renderer/media/webrtc_audio_device_unittest.cc
@@ -18,6 +18,10 @@
#include "third_party/webrtc/voice_engine/include/voe_file.h"
#include "third_party/webrtc/voice_engine/include/voe_network.h"
+#if defined(OS_WIN)
+#include "base/win/windows_version.h"
+#endif
+
using media::AudioParameters;
using testing::_;
using testing::AnyNumber;
@@ -100,7 +104,7 @@
int sample_rate = hardware_config->GetInputSampleRate();
media::ChannelLayout channel_layout =
hardware_config->GetInputChannelLayout();
- if (!capturer->Initialize(channel_layout, sample_rate, 1))
+ if (!capturer->Initialize(kRenderViewId, channel_layout, sample_rate, 1))
return false;
return true;
@@ -122,7 +126,7 @@
// TODO(henrika): Refactor in WebRTC and convert to Chrome coding style.
virtual void Process(const int channel,
const webrtc::ProcessingTypes type,
- WebRtc_Word16 audio_10ms[],
+ int16_t audio_10ms[],
const int length,
const int sampling_freq,
const bool is_stereo) OVERRIDE {
@@ -216,6 +220,12 @@
// Basic test that instantiates and initializes an instance of
// WebRtcAudioDeviceImpl.
TEST_F(WebRTCAudioDeviceTest, Construct) {
+#if defined(OS_WIN)
+ // This test crashes on Win XP bots.
+ if (base::win::GetVersion() <= base::win::VERSION_XP)
+ return;
+#endif
+
AudioParameters input_params(
AudioParameters::AUDIO_PCM_LOW_LATENCY,
media::CHANNEL_LAYOUT_MONO,
@@ -473,7 +483,7 @@
// Play 2 seconds worth of audio and then quit.
message_loop_.PostDelayedTask(FROM_HERE,
- MessageLoop::QuitClosure(),
+ base::MessageLoop::QuitClosure(),
base::TimeDelta::FromSeconds(6));
message_loop_.Run();
@@ -567,7 +577,7 @@
LOG(INFO) << ">> You should now be able to hear yourself in loopback...";
message_loop_.PostDelayedTask(FROM_HERE,
- MessageLoop::QuitClosure(),
+ base::MessageLoop::QuitClosure(),
base::TimeDelta::FromSeconds(2));
message_loop_.Run();
diff --git a/content/renderer/media/webrtc_audio_renderer.cc b/content/renderer/media/webrtc_audio_renderer.cc
index d5591d0..c85b2df 100644
--- a/content/renderer/media/webrtc_audio_renderer.cc
+++ b/content/renderer/media/webrtc_audio_renderer.cc
@@ -8,9 +8,9 @@
#include "base/metrics/histogram.h"
#include "base/string_util.h"
#include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/renderer_audio_output_device.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
#include "content/renderer/render_thread_impl.h"
+#include "media/audio/audio_output_device.h"
#include "media/audio/audio_parameters.h"
#include "media/audio/sample_rates.h"
#include "media/base/audio_hardware_config.h"
@@ -111,9 +111,6 @@
DCHECK(!sink_);
DCHECK(!source_);
- sink_ = AudioDeviceFactory::NewOutputDevice();
- DCHECK(sink_);
-
// Use mono on all platforms but Windows for now.
// TODO(henrika): Tracking at http://crbug.com/166771.
media::ChannelLayout channel_layout = media::CHANNEL_LAYOUT_MONO;
@@ -126,6 +123,17 @@
RenderThreadImpl::current()->GetAudioHardwareConfig();
int sample_rate = hardware_config->GetOutputSampleRate();
DVLOG(1) << "Audio output hardware sample rate: " << sample_rate;
+
+ // WebRTC does not yet support higher rates than 96000 on the client side
+ // and 48000 is the preferred sample rate. Therefore, if 192000 is detected,
+ // we change the rate to 48000 instead. The consequence is that the native
+ // layer will be opened up at 192kHz but WebRTC will provide data at 48kHz
+ // which will then be resampled by the audio converted on the browser side
+ // to match the native audio layer.
+ if (sample_rate == 192000) {
+ DVLOG(1) << "Resampling from 48000 to 192000 is required";
+ sample_rate = 48000;
+ }
UMA_HISTOGRAM_ENUMERATION("WebRTC.AudioOutputSampleRate",
sample_rate, media::kUnexpectedAudioSampleRate);
@@ -208,8 +216,8 @@
source->SetRenderFormat(source_params);
// Configure the audio rendering client and start rendering.
+ sink_ = AudioDeviceFactory::NewOutputDevice(source_render_view_id_);
sink_->Initialize(sink_params, this);
- sink_->SetSourceRenderView(source_render_view_id_);
sink_->Start();
// User must call Play() before any audio can be heard.
diff --git a/content/renderer/media/webrtc_audio_renderer.h b/content/renderer/media/webrtc_audio_renderer.h
index e0b19c7..eb10256 100644
--- a/content/renderer/media/webrtc_audio_renderer.h
+++ b/content/renderer/media/webrtc_audio_renderer.h
@@ -14,9 +14,12 @@
#include "media/base/audio_renderer_sink.h"
#include "webkit/media/media_stream_audio_renderer.h"
+namespace media {
+class AudioOutputDevice;
+}
+
namespace content {
-class RendererAudioOutputDevice;
class WebRtcAudioRendererSource;
// This renderer handles calls from the pipeline and WebRtc ADM. It is used
@@ -71,14 +74,14 @@
const int source_render_view_id_;
// The sink (destination) for rendered audio.
- scoped_refptr<RendererAudioOutputDevice> sink_;
+ scoped_refptr<media::AudioOutputDevice> sink_;
// Audio data source from the browser process.
WebRtcAudioRendererSource* source_;
// Buffers used for temporary storage during render callbacks.
// Allocated during initialization.
- scoped_array<int16> buffer_;
+ scoped_ptr<int16[]> buffer_;
// Protects access to |state_|, |source_| and |sink_|.
base::Lock lock_;
diff --git a/content/renderer/media/webrtc_local_audio_renderer.cc b/content/renderer/media/webrtc_local_audio_renderer.cc
index cc5ba77..3689754 100644
--- a/content/renderer/media/webrtc_local_audio_renderer.cc
+++ b/content/renderer/media/webrtc_local_audio_renderer.cc
@@ -9,8 +9,8 @@
#include "base/message_loop_proxy.h"
#include "base/synchronization/lock.h"
#include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/renderer_audio_output_device.h"
#include "content/renderer/media/webrtc_audio_capturer.h"
+#include "media/audio/audio_output_device.h"
#include "media/base/audio_bus.h"
namespace content {
@@ -60,12 +60,11 @@
TRACE_EVENT0("audio", "WebRtcLocalAudioRenderer::CaptureData");
base::AutoLock auto_lock(thread_lock_);
- if (!playing_ || !track_is_enabled_) {
+ if (!playing_)
return;
- }
// Push captured audio to FIFO so it can be read by a local sink.
- if (loopback_fifo_ && track_is_enabled_) {
+ if (loopback_fifo_) {
if (loopback_fifo_->frames() + number_of_frames <=
loopback_fifo_->max_frames()) {
scoped_ptr<media::AudioBus> audio_source = media::AudioBus::Create(
@@ -82,27 +81,17 @@
void WebRtcLocalAudioRenderer::SetCaptureFormat(
const media::AudioParameters& params) {
- NOTIMPLEMENTED() << "WebRtcLocalAudioRenderer::SetCaptureFormat()";
-}
-
-// webrtc::ObserverInterface implementation
-void WebRtcLocalAudioRenderer::OnChanged() {
- DVLOG(1) << "WebRtcLocalAudioRenderer::OnChanged()";
- DCHECK(thread_checker_.CalledOnValidThread());
- base::AutoLock auto_lock(thread_lock_);
- track_is_enabled_ = audio_track_->enabled();
+ audio_params_ = params;
}
// WebRtcLocalAudioRenderer::WebRtcLocalAudioRenderer implementation.
WebRtcLocalAudioRenderer::WebRtcLocalAudioRenderer(
- const scoped_refptr<WebRtcAudioCapturer>& source,
- webrtc::AudioTrackInterface* audio_track,
+ WebRtcLocalAudioTrack* audio_track,
int source_render_view_id)
- : source_(source),
- audio_track_(audio_track),
+ : audio_track_(audio_track),
source_render_view_id_(source_render_view_id),
- playing_(false),
- track_is_enabled_(true) {
+ playing_(false) {
+ DCHECK(audio_track);
DVLOG(1) << "WebRtcLocalAudioRenderer::WebRtcLocalAudioRenderer()";
}
@@ -115,31 +104,14 @@
void WebRtcLocalAudioRenderer::Start() {
DVLOG(1) << "WebRtcLocalAudioRenderer::Start()";
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(source_);
-
- if (audio_track_) {
- audio_track_->RegisterObserver(this);
- track_is_enabled_ = audio_track_->enabled();
- }
+ // Add this class as sink to the audio track to ensure that we receive
+ // WebRtcAudioCapturerSink::CaptureData() callbacks for captured audio.
+ // |audio_params_| will be updated right after the AddCapturerAudioTrack().
+ audio_track_->AddSink(this);
base::AutoLock auto_lock(thread_lock_);
DCHECK(!sink_);
- // Add this class as sink to the capturer to ensure that we receive
- // WebRtcAudioCapturerSink::CaptureData() callbacks for captured audio.
- source_->AddCapturerSink(this);
-
- // Use the capturing source audio parameters when opening the output audio
- // device. Any mismatch will be compensated for by the audio output back-end.
- // Note that the buffer size is modified to make the full-duplex scheme less
- // resource intensive. By doubling the buffer size (compared to the capture
- // side), the callback frequency of browser side callbacks will be lower and
- // tests have shown that it resolves issues with audio glitches for some
- // cases where resampling is needed on the output side.
- // TODO(henrika): verify this scheme on as many different devices and
- // combinations of sample rates as possible
- media::AudioParameters source_params = source_->audio_parameters();
-
// TODO(henrika): we could add a more dynamic solution here but I prefer
// a fixed size combined with bad audio at overflow. The alternative is
// that we start to build up latency and that can be more difficult to
@@ -150,24 +122,22 @@
// the FIFO overflows.
DCHECK(!loopback_fifo_);
loopback_fifo_.reset(new media::AudioFifo(
- source_params.channels(),
- 10 * source_params.frames_per_buffer()));
+ audio_params_.channels(), 10 * audio_params_.frames_per_buffer()));
- media::AudioParameters sink_params(source_params.format(),
- source_params.channel_layout(),
- source_params.sample_rate(),
- source_params.bits_per_sample(),
- 2 * source_params.frames_per_buffer());
- sink_ = AudioDeviceFactory::NewOutputDevice();
+ media::AudioParameters sink_params(audio_params_.format(),
+ audio_params_.channel_layout(),
+ audio_params_.sample_rate(),
+ audio_params_.bits_per_sample(),
+ 2 * audio_params_.frames_per_buffer());
+ sink_ = AudioDeviceFactory::NewOutputDevice(source_render_view_id_);
+
// TODO(henrika): we could utilize the unified audio here instead and do
// sink_->InitializeIO(sink_params, 2, callback_.get());
// It would then be possible to avoid using the WebRtcAudioCapturer.
sink_->Initialize(sink_params, this);
- sink_->SetSourceRenderView(source_render_view_id_);
// Start the capturer and local rendering. Note that, the capturer is owned
// by the WebRTC ADM and might already bee running.
- source_->Start();
sink_->Start();
last_render_time_ = base::Time::Now();
@@ -198,13 +168,8 @@
// Ensure that the capturer stops feeding us with captured audio.
// Note that, we do not stop the capturer here since it may still be used by
// the WebRTC ADM.
- source_->RemoveCapturerSink(this);
- source_ = NULL;
-
- if (audio_track_) {
- audio_track_->UnregisterObserver(this);
- audio_track_ = NULL;
- }
+ audio_track_->RemoveSink(this);
+ audio_track_ = NULL;
}
void WebRtcLocalAudioRenderer::Play() {
diff --git a/content/renderer/media/webrtc_local_audio_renderer.h b/content/renderer/media/webrtc_local_audio_renderer.h
index 0bd310a..15d5116 100644
--- a/content/renderer/media/webrtc_local_audio_renderer.h
+++ b/content/renderer/media/webrtc_local_audio_renderer.h
@@ -11,28 +11,24 @@
#include "base/threading/thread_checker.h"
#include "content/common/content_export.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
-#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
+#include "content/renderer/media/webrtc_local_audio_track.h"
#include "webkit/media/media_stream_audio_renderer.h"
namespace media {
class AudioBus;
+class AudioOutputDevice;
class AudioParameters;
}
-namespace webrtc {
-class AudioTrackInterface;
-}
-
namespace content {
-class RendererAudioOutputDevice;
class WebRtcAudioCapturer;
// WebRtcLocalAudioRenderer is a webkit_media::MediaStreamAudioRenderer
// designed for rendering local audio media stream tracks,
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediastreamtrack
// It also implements media::AudioRendererSink::RenderCallback to render audio
-// data provided from a WebRtcAudioCapturer source which is set at construction.
+// data provided from a WebRtcLocalAudioTrack source.
// When the audio layer in the browser process asks for data to render, this
// class provides the data by implementing the WebRtcAudioCapturerSink
// interface, i.e., we are a sink seen from the WebRtcAudioCapturer perspective.
@@ -43,14 +39,12 @@
class CONTENT_EXPORT WebRtcLocalAudioRenderer
: NON_EXPORTED_BASE(public webkit_media::MediaStreamAudioRenderer),
NON_EXPORTED_BASE(public media::AudioRendererSink::RenderCallback),
- NON_EXPORTED_BASE(public WebRtcAudioCapturerSink),
- NON_EXPORTED_BASE(public webrtc::ObserverInterface) {
+ NON_EXPORTED_BASE(public WebRtcAudioCapturerSink) {
public:
// Creates a local renderer and registers a capturing |source| object.
// The |source| is owned by the WebRtcAudioDeviceImpl.
// Called on the main thread.
- WebRtcLocalAudioRenderer(const scoped_refptr<WebRtcAudioCapturer>& source,
- webrtc::AudioTrackInterface* audio_track,
+ WebRtcLocalAudioRenderer(WebRtcLocalAudioTrack* audio_track,
int source_render_view_id);
// webkit_media::MediaStreamAudioRenderer implementation.
@@ -63,6 +57,14 @@
virtual base::TimeDelta GetCurrentRenderTime() const OVERRIDE;
virtual bool IsLocalRenderer() const OVERRIDE;
+ const base::TimeDelta& total_render_time() const {
+ return total_render_time_;
+ }
+
+ protected:
+ virtual ~WebRtcLocalAudioRenderer();
+
+ private:
// content::WebRtcAudioCapturerSink implementation.
// Called on the AudioInputDevice worker thread.
@@ -82,30 +84,19 @@
int audio_delay_milliseconds) OVERRIDE;
virtual void OnRenderError() OVERRIDE;
- // webrtc::ObserverInterface implementation.
- // Called on the main render thread.
- virtual void OnChanged() OVERRIDE;
-
- base::TimeDelta total_render_time() const { return total_render_time_; }
-
- protected:
- virtual ~WebRtcLocalAudioRenderer();
-
- private:
- // The source of data to render. Given that this class implements local
- // loopback, the source is a capture instance reading data from the
- // selected microphone. The recorded data is stored in a FIFO and consumed
+ // The audio track which provides data to render. Given that this class
+ // implements local loopback, the audio track is getting data from a capture
+ // instance like a selected microphone and forwards the recorded data to its
+ // sinks. The recorded data is stored in a FIFO and consumed
// by this class when the sink asks for new data.
// The WebRtcAudioCapturer is today created by WebRtcAudioDeviceImpl.
- scoped_refptr<WebRtcAudioCapturer> source_;
-
- scoped_refptr<webrtc::AudioTrackInterface> audio_track_;
+ scoped_refptr<WebRtcLocalAudioTrack> audio_track_;
// The render view in which the audio is rendered into |sink_|.
const int source_render_view_id_;
// The sink (destination) for rendered audio.
- scoped_refptr<RendererAudioOutputDevice> sink_;
+ scoped_refptr<media::AudioOutputDevice> sink_;
// Used to DCHECK that we are called on the correct thread.
base::ThreadChecker thread_checker_;
@@ -121,12 +112,12 @@
// Keeps track of total time audio has been rendered.
base::TimeDelta total_render_time_;
+ // The audio parameters used by the renderer.
+ media::AudioParameters audio_params_;
+
// Set when playing, cleared when paused.
bool playing_;
- // Stores latest media track state for the enabled attribute.
- bool track_is_enabled_;
-
// Protects |loopback_fifo_|, |playing_| and |sink_|.
mutable base::Lock thread_lock_;
diff --git a/content/renderer/media/webrtc_local_audio_track.cc b/content/renderer/media/webrtc_local_audio_track.cc
new file mode 100644
index 0000000..b277cad
--- /dev/null
+++ b/content/renderer/media/webrtc_local_audio_track.cc
@@ -0,0 +1,123 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/webrtc_local_audio_track.h"
+
+#include "content/renderer/media/webrtc_audio_capturer.h"
+#include "content/renderer/media/webrtc_audio_capturer_sink_owner.h"
+
+namespace content {
+
+static const char kAudioTrackKind[] = "audio";
+
+scoped_refptr<WebRtcLocalAudioTrack> WebRtcLocalAudioTrack::Create(
+ const std::string& id,
+ const scoped_refptr<WebRtcAudioCapturer>& capturer,
+ webrtc::AudioSourceInterface* track_source) {
+ talk_base::RefCountedObject<WebRtcLocalAudioTrack>* track =
+ new talk_base::RefCountedObject<WebRtcLocalAudioTrack>(
+ id, capturer, track_source);
+ return track;
+}
+
+WebRtcLocalAudioTrack::WebRtcLocalAudioTrack(
+ const std::string& label,
+ const scoped_refptr<WebRtcAudioCapturer>& capturer,
+ webrtc::AudioSourceInterface* track_source)
+ : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(label),
+ capturer_(capturer),
+ track_source_(track_source) {
+ DCHECK(capturer);
+ capturer_->AddSink(this);
+ params_ = capturer_->audio_parameters();
+ DVLOG(1) << "WebRtcLocalAudioTrack::WebRtcLocalAudioTrack()";
+}
+
+WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(sinks_.empty());
+ capturer_->RemoveSink(this);
+ DVLOG(1) << "WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack()";
+}
+
+// Content::WebRtcAudioCapturerSink implementation.
+void WebRtcLocalAudioTrack::CaptureData(const int16* audio_data,
+ int number_of_channels,
+ int number_of_frames,
+ int audio_delay_milliseconds,
+ double volume) {
+ SinkList sinks;
+ {
+ base::AutoLock auto_lock(lock_);
+ // When the track is diabled, we simply return here.
+ // TODO(xians): Figure out if we should feed zero to sinks instead, in
+ // order to inject VAD data in such case.
+ if (!enabled())
+ return;
+
+ sinks = sinks_;
+ }
+
+ // Feed the data to the sinks.
+ for (SinkList::const_iterator it = sinks.begin();
+ it != sinks.end();
+ ++it) {
+ (*it)->CaptureData(audio_data, number_of_channels, number_of_frames,
+ audio_delay_milliseconds, volume);
+ }
+}
+
+void WebRtcLocalAudioTrack::SetCaptureFormat(
+ const media::AudioParameters& params) {
+ base::AutoLock auto_lock(lock_);
+ params_ = params;
+}
+
+// webrtc::AudioTrackInterface implementation.
+webrtc::AudioSourceInterface* WebRtcLocalAudioTrack::GetSource() const {
+ return track_source_;
+}
+
+std::string WebRtcLocalAudioTrack::kind() const {
+ return kAudioTrackKind;
+}
+
+void WebRtcLocalAudioTrack::AddSink(WebRtcAudioCapturerSink* sink) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DVLOG(1) << "WebRtcLocalAudioTrack::AddSink()";
+ base::AutoLock auto_lock(lock_);
+ sink->SetCaptureFormat(params_);
+
+ // Verify that |sink| is not already added to the list.
+ DCHECK(std::find_if(
+ sinks_.begin(), sinks_.end(),
+ WebRtcAudioCapturerSinkOwner::WrapsSink(sink)) == sinks_.end());
+
+ // Create (and add to the list) a new WebRtcAudioCapturerSinkOwner which owns
+ // the |sink| and delagates all calls to the WebRtcAudioCapturerSink
+ // interface.
+ sinks_.push_back(new WebRtcAudioCapturerSinkOwner(sink));
+}
+
+void WebRtcLocalAudioTrack::RemoveSink(
+ WebRtcAudioCapturerSink* sink) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DVLOG(1) << "WebRtcLocalAudioTrack::RemoveSink()";
+
+ base::AutoLock auto_lock(lock_);
+
+ // Get iterator to the first element for which WrapsSink(sink) returns true.
+ SinkList::iterator it = std::find_if(
+ sinks_.begin(), sinks_.end(),
+ WebRtcAudioCapturerSinkOwner::WrapsSink(sink));
+ if (it != sinks_.end()) {
+ // Clear the delegate to ensure that no more capture callbacks will
+ // be sent to this sink. Also avoids a possible crash which can happen
+ // if this method is called while capturing is active.
+ (*it)->Reset();
+ sinks_.erase(it);
+ }
+}
+
+} // namespace content
diff --git a/content/renderer/media/webrtc_local_audio_track.h b/content/renderer/media/webrtc_local_audio_track.h
new file mode 100644
index 0000000..660d696
--- /dev/null
+++ b/content/renderer/media/webrtc_local_audio_track.h
@@ -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.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_LOCAL_AUDIO_TRACK_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_LOCAL_AUDIO_TRACK_H_
+
+#include <list>
+#include <string>
+
+#include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
+#include "content/renderer/media/webrtc_audio_device_impl.h"
+#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
+#include "third_party/libjingle/source/talk/app/webrtc/mediastreamtrack.h"
+
+
+namespace content {
+
+class WebRtcAudioCapturer;
+class WebRtcAudioCapturerSinkOwner;
+
+// A WebRtcLocalAudioTrack instance contains the implementations of
+// MediaStreamTrack and WebRtcAudioCapturerSink.
+// When an instance is created, it will register itself as a track to the
+// WebRtcAudioCapturer to get the captured data, and forward the data to
+// its |sinks_|. The data flow can be stopped by disabling the audio track.
+class CONTENT_EXPORT WebRtcLocalAudioTrack
+ : NON_EXPORTED_BASE(public WebRtcAudioCapturerSink),
+ NON_EXPORTED_BASE(
+ public webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>) {
+ public:
+ static scoped_refptr<WebRtcLocalAudioTrack> Create(
+ const std::string& id,
+ const scoped_refptr<WebRtcAudioCapturer>& capturer,
+ webrtc::AudioSourceInterface* stream_source);
+
+ // Add a sink to the track. This function will trigger a SetCaptureFormat()
+ // call on the |sink|.
+ // Called on the main render thread.
+ void AddSink(WebRtcAudioCapturerSink* sink);
+
+ // Remove a sink from the track.
+ // Called on the main render thread.
+ void RemoveSink(WebRtcAudioCapturerSink* sink);
+
+ protected:
+ WebRtcLocalAudioTrack(const std::string& label,
+ const scoped_refptr<WebRtcAudioCapturer>& capturer,
+ webrtc::AudioSourceInterface* stream_source);
+ virtual ~WebRtcLocalAudioTrack();
+
+ private:
+ typedef std::list<scoped_refptr<WebRtcAudioCapturerSinkOwner> > SinkList;
+
+ // content::WebRtcAudioCapturerSink implementation.
+ // Called on the AudioInputDevice worker thread.
+ virtual void CaptureData(const int16* audio_data,
+ int number_of_channels,
+ int number_of_frames,
+ int audio_delay_milliseconds,
+ double volume) OVERRIDE;
+
+ // Can be called on different user threads.
+ virtual void SetCaptureFormat(const media::AudioParameters& params) OVERRIDE;
+
+ // webrtc::AudioTrackInterface implementation.
+ virtual webrtc::AudioSourceInterface* GetSource() const OVERRIDE;
+
+ // webrtc::MediaStreamTrack implementation.
+ virtual std::string kind() const OVERRIDE;
+
+ // The provider of captured data to render.
+ // The WebRtcAudioCapturer is today created by WebRtcAudioDeviceImpl.
+ scoped_refptr<WebRtcAudioCapturer> capturer_;
+
+ // The source of the audio track which handles the audio constraints.
+ // TODO(xians): merge |track_source_| to |capturer_|.
+ talk_base::scoped_refptr<webrtc::AudioSourceInterface> track_source_;
+
+ // A list of sinks that the audio data is fed to.
+ SinkList sinks_;
+
+ // Used to DCHECK that we are called on the correct thread.
+ base::ThreadChecker thread_checker_;
+
+ // Cached values of the audio parameters used by the |source_| and |sinks_|.
+ media::AudioParameters params_;
+
+ // Protects |params_| and |sinks_|.
+ mutable base::Lock lock_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcLocalAudioTrack);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_LOCAL_AUDIO_TRACK_H_
diff --git a/content/renderer/media/webrtc_local_audio_track_unittest.cc b/content/renderer/media/webrtc_local_audio_track_unittest.cc
new file mode 100644
index 0000000..7e2f473
--- /dev/null
+++ b/content/renderer/media/webrtc_local_audio_track_unittest.cc
@@ -0,0 +1,241 @@
+// 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/synchronization/waitable_event.h"
+#include "base/test/test_timeouts.h"
+#include "content/renderer/media/webrtc_audio_capturer.h"
+#include "content/renderer/media/webrtc_local_audio_track.h"
+#include "media/audio/audio_parameters.h"
+#include "media/base/audio_bus.h"
+#include "media/base/audio_capturer_source.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::AtLeast;
+using ::testing::Return;
+
+namespace content {
+
+namespace {
+
+ACTION_P(SignalEvent, event) {
+ event->Signal();
+}
+
+// A simple thread that we use to fake the audio thread which provides data to
+// the |WebRtcAudioCapturer|.
+class FakeAudioThread : public base::PlatformThread::Delegate {
+ public:
+ explicit FakeAudioThread(const scoped_refptr<WebRtcAudioCapturer>& capturer)
+ : capturer_(capturer),
+ thread_(base::kNullThreadHandle),
+ closure_(false, false) {
+ DCHECK(capturer);
+ audio_bus_ = media::AudioBus::Create(capturer_->audio_parameters());
+ }
+
+ virtual ~FakeAudioThread() { DCHECK(!thread_); }
+
+ // base::PlatformThread::Delegate:
+ virtual void ThreadMain() OVERRIDE {
+ while (true) {
+ if (closure_.IsSignaled())
+ return;
+
+ media::AudioCapturerSource::CaptureCallback* callback =
+ static_cast<media::AudioCapturerSource::CaptureCallback*>(capturer_);
+ audio_bus_->Zero();
+ callback->Capture(audio_bus_.get(), 0, 0);
+
+ // Sleep 1ms to yield the resource for the main thread.
+ base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
+ }
+ }
+
+ void Start() {
+ base::PlatformThread::CreateWithPriority(
+ 0, this, &thread_, base::kThreadPriority_RealtimeAudio);
+ CHECK(thread_ != base::kNullThreadHandle);
+ }
+
+ void Stop() {
+ closure_.Signal();
+ base::PlatformThread::Join(thread_);
+ thread_ = base::kNullThreadHandle;
+ }
+
+ private:
+ scoped_ptr<media::AudioBus> audio_bus_;
+ scoped_refptr<WebRtcAudioCapturer> capturer_;
+ base::PlatformThreadHandle thread_;
+ base::WaitableEvent closure_;
+ DISALLOW_COPY_AND_ASSIGN(FakeAudioThread);
+};
+
+class MockCapturerSource : public media::AudioCapturerSource {
+ public:
+ MockCapturerSource() {}
+ MOCK_METHOD3(Initialize, void(const media::AudioParameters& params,
+ CaptureCallback* callback,
+ int session_id));
+ MOCK_METHOD0(Start, void());
+ MOCK_METHOD0(Stop, void());
+ MOCK_METHOD1(SetVolume, void(double volume));
+ MOCK_METHOD1(SetAutomaticGainControl, void(bool enable));
+
+ protected:
+ virtual ~MockCapturerSource() {}
+};
+
+class MockWebRtcAudioCapturerSink : public WebRtcAudioCapturerSink {
+ public:
+ MockWebRtcAudioCapturerSink() {}
+ ~MockWebRtcAudioCapturerSink() {}
+ MOCK_METHOD5(CaptureData, void(const int16* audio_data,
+ int number_of_channels,
+ int number_of_frames,
+ int audio_delay_milliseconds,
+ double volume));
+ MOCK_METHOD1(SetCaptureFormat, void(const media::AudioParameters& params));
+};
+
+} // namespace
+
+class WebRtcLocalAudioTrackTest : public ::testing::Test {
+ protected:
+ virtual void SetUp() OVERRIDE {
+ capturer_ = WebRtcAudioCapturer::CreateCapturer();
+ capturer_source_ = new MockCapturerSource();
+ EXPECT_CALL(*capturer_source_, Initialize(_, capturer_.get(), 0))
+ .WillOnce(Return());
+ capturer_->SetCapturerSource(capturer_source_,
+ media::CHANNEL_LAYOUT_STEREO,
+ 48000);
+
+ EXPECT_CALL(*capturer_source_, Start()).WillOnce(Return());
+ EXPECT_CALL(*capturer_source_, SetAutomaticGainControl(false))
+ .WillOnce(Return());
+ capturer_->Start();
+ audio_thread_.reset(new FakeAudioThread(capturer_));
+ audio_thread_->Start();
+ }
+
+ virtual void TearDown() {
+ audio_thread_->Stop();
+ audio_thread_.reset();
+ EXPECT_CALL(*capturer_source_, Stop()).WillOnce(Return());
+ capturer_->Stop();
+ }
+
+ scoped_refptr<MockCapturerSource> capturer_source_;
+ scoped_refptr<WebRtcAudioCapturer> capturer_;
+ scoped_ptr<FakeAudioThread> audio_thread_;
+};
+
+// Creates a capturer and audio track, fakes its audio thread, and
+// connect/disconnect the sink to the audio track on the fly, the sink should
+// get data callback when the track is connected to the capturer but not when
+// the track is disconnected from the capturer.
+TEST_F(WebRtcLocalAudioTrackTest, ConnectAndDisconnectOneSink) {
+ scoped_refptr<WebRtcLocalAudioTrack> track =
+ WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL);
+ EXPECT_TRUE(track->enabled());
+ scoped_ptr<MockWebRtcAudioCapturerSink> sink(
+ new MockWebRtcAudioCapturerSink());
+ const media::AudioParameters params = capturer_->audio_parameters();
+ base::WaitableEvent event(false, false);
+ EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return());
+ EXPECT_CALL(*sink, CaptureData(
+ _, params.channels(), params.frames_per_buffer(), 0, 0))
+ .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event));
+ track->AddSink(sink.get());
+
+ EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
+ track->RemoveSink(sink.get());
+ track = NULL;
+}
+
+// The same setup as ConnectAndDisconnectOneSink, but enable and disable the
+// audio track on the fly. When the audio track is disabled, there is no data
+// callback to the sink; when the audio track is enabled, there comes data
+// callback.
+// TODO(xians): Enable this test after resolving the racing issue that TSAN
+// reports on MediaStreamTrack::enabled();
+TEST_F(WebRtcLocalAudioTrackTest, DISABLED_DisableEnableAudioTrack) {
+ scoped_refptr<WebRtcLocalAudioTrack> track =
+ WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL);
+ EXPECT_TRUE(track->enabled());
+ EXPECT_TRUE(track->set_enabled(false));
+ scoped_ptr<MockWebRtcAudioCapturerSink> sink(
+ new MockWebRtcAudioCapturerSink());
+ const media::AudioParameters params = capturer_->audio_parameters();
+ base::WaitableEvent event(false, false);
+ EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return());
+ EXPECT_CALL(*sink, CaptureData(
+ _, params.channels(), params.frames_per_buffer(), 0, 0))
+ .Times(0);
+ track->AddSink(sink.get());
+ EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout()));
+
+ event.Reset();
+ EXPECT_CALL(*sink, CaptureData(
+ _, params.channels(), params.frames_per_buffer(), 0, 0))
+ .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event));
+ EXPECT_TRUE(track->set_enabled(true));
+ EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
+ track->RemoveSink(sink.get());
+ track = NULL;
+}
+
+// Create multiple audio tracks and enable/disable them, verify that the audio
+// callbacks appear/disappear.
+// TODO(xians): Enable the test after the racing problem is resolved.
+TEST_F(WebRtcLocalAudioTrackTest, DISABLED_MultipleAudioTracks) {
+ scoped_refptr<WebRtcLocalAudioTrack> track_1 =
+ WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL);
+ EXPECT_TRUE(track_1->enabled());
+ scoped_ptr<MockWebRtcAudioCapturerSink> sink_1(
+ new MockWebRtcAudioCapturerSink());
+ const media::AudioParameters params = capturer_->audio_parameters();
+ base::WaitableEvent event_1(false, false);
+ EXPECT_CALL(*sink_1, SetCaptureFormat(_)).WillOnce(Return());
+ EXPECT_CALL(*sink_1, CaptureData(
+ _, params.channels(), params.frames_per_buffer(), 0, 0))
+ .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1));
+ track_1->AddSink(sink_1.get());
+
+ scoped_refptr<WebRtcLocalAudioTrack> track_2 =
+ WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL);
+ EXPECT_TRUE(track_2->set_enabled(false));
+ scoped_ptr<MockWebRtcAudioCapturerSink> sink_2(
+ new MockWebRtcAudioCapturerSink());
+ EXPECT_CALL(*sink_2, SetCaptureFormat(_)).WillOnce(Return());
+ EXPECT_CALL(*sink_2, CaptureData(
+ _, params.channels(), params.frames_per_buffer(), 0, 0))
+ .Times(0);
+ track_2->AddSink(sink_2.get());
+ EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout()));
+
+
+ // Enable |track_2|, and verify the data callback comes to |sink_2|;
+ event_1.Reset();
+ base::WaitableEvent event_2(false, false);
+ EXPECT_CALL(*sink_1, CaptureData(
+ _, params.channels(), params.frames_per_buffer(), 0, 0))
+ .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1));
+ EXPECT_CALL(*sink_2, CaptureData(
+ _, params.channels(), params.frames_per_buffer(), 0, 0))
+ .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_2));
+ EXPECT_TRUE(track_2->set_enabled(true));
+ EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout()));
+ EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout()));
+
+ track_1->RemoveSink(sink_1.get());
+ track_2->RemoveSink(sink_2.get());
+ track_1 = NULL;
+ track_2 = NULL;
+}
+
+} // namespace content
diff --git a/content/renderer/media/webrtc_logging_handler_impl.cc b/content/renderer/media/webrtc_logging_handler_impl.cc
new file mode 100644
index 0000000..6e3702e
--- /dev/null
+++ b/content/renderer/media/webrtc_logging_handler_impl.cc
@@ -0,0 +1,50 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/webrtc_logging_handler_impl.h"
+
+#include "base/logging.h"
+#include "base/message_loop_proxy.h"
+#include "content/renderer/media/webrtc_logging_message_filter.h"
+
+namespace content {
+
+WebRtcLoggingHandlerImpl::WebRtcLoggingHandlerImpl(
+ const scoped_refptr<WebRtcLoggingMessageFilter>& message_filter,
+ const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
+ : message_filter_(message_filter),
+ io_message_loop_(io_message_loop) {
+}
+
+WebRtcLoggingHandlerImpl::~WebRtcLoggingHandlerImpl() {
+}
+
+void WebRtcLoggingHandlerImpl::OnFilterRemoved() {
+ message_filter_ = NULL;
+}
+
+void WebRtcLoggingHandlerImpl::OpenLog() {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ // TODO(grunell): Check if already opened. (Could have been opened by another
+ // render view.)
+ if (message_filter_)
+ message_filter_->OpenLog();
+}
+
+void WebRtcLoggingHandlerImpl::OnLogOpened(
+ base::SharedMemoryHandle handle,
+ uint32 length) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ // TODO(grunell): Implement.
+ NOTIMPLEMENTED();
+}
+
+void WebRtcLoggingHandlerImpl::OnOpenLogFailed() {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ DLOG(ERROR) << "Could not open log.";
+ // TODO(grunell): Implement.
+ NOTIMPLEMENTED();
+}
+
+} // namespace content
diff --git a/content/renderer/media/webrtc_logging_handler_impl.h b/content/renderer/media/webrtc_logging_handler_impl.h
new file mode 100644
index 0000000..ca7b0ef
--- /dev/null
+++ b/content/renderer/media/webrtc_logging_handler_impl.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_LOGGING_HANDLER_IMPL_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_LOGGING_HANDLER_IMPL_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/shared_memory.h"
+#include "content/common/content_export.h"
+#include "ipc/ipc_channel_proxy.h"
+
+namespace base {
+class MessageLoopProxy;
+}
+
+namespace content {
+
+class WebRtcLoggingMessageFilter;
+
+// WebRtcLoggingHandlerImpl handles WebRTC logging. There is one object per
+// render thread. It communicates with WebRtcLoggingHandlerHost and receives
+// logging messages from libjingle and writes them to a shared memory buffer.
+class CONTENT_EXPORT WebRtcLoggingHandlerImpl
+ : public base::RefCounted<WebRtcLoggingHandlerImpl> {
+ public:
+ WebRtcLoggingHandlerImpl(
+ const scoped_refptr<WebRtcLoggingMessageFilter>& message_filter,
+ const scoped_refptr<base::MessageLoopProxy>& io_message_loop);
+
+ void OnFilterRemoved();
+
+ void OpenLog();
+
+ void OnLogOpened(base::SharedMemoryHandle handle, uint32 length);
+ void OnOpenLogFailed();
+
+ private:
+ friend class base::RefCounted<WebRtcLoggingHandlerImpl>;
+ virtual ~WebRtcLoggingHandlerImpl();
+
+ scoped_refptr<WebRtcLoggingMessageFilter> message_filter_;
+
+ scoped_refptr<base::MessageLoopProxy> io_message_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcLoggingHandlerImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_LOGGING_HANDLER_IMPL_H_
diff --git a/content/renderer/media/webrtc_logging_message_filter.cc b/content/renderer/media/webrtc_logging_message_filter.cc
new file mode 100644
index 0000000..db43d96
--- /dev/null
+++ b/content/renderer/media/webrtc_logging_message_filter.cc
@@ -0,0 +1,90 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/webrtc_logging_message_filter.h"
+
+#include "base/logging.h"
+#include "base/message_loop_proxy.h"
+#include "content/common/media/webrtc_logging_messages.h"
+#include "content/renderer/media/webrtc_logging_handler_impl.h"
+#include "ipc/ipc_logging.h"
+
+namespace content {
+
+WebRtcLoggingMessageFilter::WebRtcLoggingMessageFilter(
+ const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
+ : io_message_loop_(io_message_loop),
+ channel_(NULL) {
+}
+
+WebRtcLoggingMessageFilter::~WebRtcLoggingMessageFilter() {
+}
+
+bool WebRtcLoggingMessageFilter::OnMessageReceived(
+ const IPC::Message& message) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(WebRtcLoggingMessageFilter, message)
+ IPC_MESSAGE_HANDLER(WebRtcLoggingMsg_LogOpened, OnLogOpened)
+ IPC_MESSAGE_HANDLER(WebRtcLoggingMsg_OpenLogFailed, OnOpenLogFailed)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void WebRtcLoggingMessageFilter::OnFilterAdded(IPC::Channel* channel) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ channel_ = channel;
+}
+
+void WebRtcLoggingMessageFilter::OnFilterRemoved() {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ channel_ = NULL;
+ RemoveDelegate();
+}
+
+void WebRtcLoggingMessageFilter::OnChannelClosing() {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ channel_ = NULL;
+ RemoveDelegate();
+}
+
+void WebRtcLoggingMessageFilter::SetDelegate(
+ scoped_refptr<WebRtcLoggingHandlerImpl>& logging_handler) {
+ logging_handler_ = logging_handler;
+}
+
+void WebRtcLoggingMessageFilter::RemoveDelegate() {
+ logging_handler_ = NULL;
+}
+
+void WebRtcLoggingMessageFilter::OpenLog() {
+ Send(new WebRtcLoggingMsg_OpenLog());
+}
+
+void WebRtcLoggingMessageFilter::OnLogOpened(
+ base::SharedMemoryHandle handle,
+ uint32 length) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ if (logging_handler_)
+ logging_handler_->OnLogOpened(handle, length);
+}
+
+void WebRtcLoggingMessageFilter::OnOpenLogFailed() {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ if (logging_handler_)
+ logging_handler_->OnOpenLogFailed();
+}
+
+void WebRtcLoggingMessageFilter::Send(IPC::Message* message) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ if (!channel_) {
+ DLOG(ERROR) << "IPC channel not available.";
+ delete message;
+ } else {
+ channel_->Send(message);
+ }
+}
+
+} // namespace content
diff --git a/content/renderer/media/webrtc_logging_message_filter.h b/content/renderer/media/webrtc_logging_message_filter.h
new file mode 100644
index 0000000..33b5ccd
--- /dev/null
+++ b/content/renderer/media/webrtc_logging_message_filter.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_LOGGING_MESSAGE_FILTER_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_LOGGING_MESSAGE_FILTER_H_
+
+#include "base/shared_memory.h"
+#include "content/common/content_export.h"
+#include "ipc/ipc_channel_proxy.h"
+
+namespace base {
+class MessageLoopProxy;
+}
+
+namespace content {
+
+class WebRtcLoggingHandlerImpl;
+
+// Filter for WebRTC logging messages. Sits between WebRtcLoggingHandlerImpl
+// (renderer process) and WebRtcLoggingHandlerHost (browser process). Must be
+// called on the IO thread.
+class CONTENT_EXPORT WebRtcLoggingMessageFilter
+ : public IPC::ChannelProxy::MessageFilter {
+ public:
+ explicit WebRtcLoggingMessageFilter(
+ const scoped_refptr<base::MessageLoopProxy>& io_message_loop);
+
+ virtual void SetDelegate(
+ scoped_refptr<WebRtcLoggingHandlerImpl>& logging_handler);
+ virtual void RemoveDelegate();
+
+ virtual void OpenLog();
+
+ protected:
+ virtual ~WebRtcLoggingMessageFilter();
+
+ private:
+ // IPC::ChannelProxy::MessageFilter implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+ virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE;
+ virtual void OnFilterRemoved() OVERRIDE;
+ virtual void OnChannelClosing() OVERRIDE;
+
+ void OnLogOpened(base::SharedMemoryHandle handle, uint32 length);
+ void OnOpenLogFailed();
+
+ void Send(IPC::Message* message);
+
+ scoped_refptr<WebRtcLoggingHandlerImpl> logging_handler_;
+
+ scoped_refptr<base::MessageLoopProxy> io_message_loop_;
+
+ IPC::Channel* channel_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcLoggingMessageFilter);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_LOGGING_MESSAGE_FILTER_H_
diff --git a/content/renderer/p2p/ipc_network_manager.cc b/content/renderer/p2p/ipc_network_manager.cc
index 2ddc397..34a65c5 100644
--- a/content/renderer/p2p/ipc_network_manager.cc
+++ b/content/renderer/p2p/ipc_network_manager.cc
@@ -14,7 +14,7 @@
: socket_dispatcher_(socket_dispatcher),
start_count_(0),
network_list_received_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ weak_factory_(this) {
socket_dispatcher_->AddNetworkListObserver(this);
}
@@ -26,9 +26,10 @@
void IpcNetworkManager::StartUpdating() {
if (network_list_received_) {
// Post a task to avoid reentrancy.
- MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&IpcNetworkManager::SendNetworksChangedSignal,
- weak_factory_.GetWeakPtr()));
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&IpcNetworkManager::SendNetworksChangedSignal,
+ weak_factory_.GetWeakPtr()));
}
++start_count_;
}
diff --git a/content/renderer/p2p/ipc_socket_factory.cc b/content/renderer/p2p/ipc_socket_factory.cc
index ea53678..d1f5686 100644
--- a/content/renderer/p2p/ipc_socket_factory.cc
+++ b/content/renderer/p2p/ipc_socket_factory.cc
@@ -5,6 +5,7 @@
#include "content/renderer/p2p/ipc_socket_factory.h"
#include "base/compiler_specific.h"
+#include "base/debug/trace_event.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "content/renderer/p2p/socket_client.h"
@@ -16,6 +17,10 @@
namespace {
+// TODO(hclam): This shouldn't be a pre-defined value. Bug: crbug.com/181321.
+const int kMaxPendingPackets = 32;
+const int kWritableSignalThreshold = 0;
+
// IpcPacketSocket implements talk_base::AsyncPacketSocket interface
// using P2PSocketClient that works over IPC-channel. It must be used
// on the thread it was created.
@@ -47,6 +52,7 @@
virtual void OnOpen(const net::IPEndPoint& address) OVERRIDE;
virtual void OnIncomingTcpConnection(const net::IPEndPoint& address,
P2PSocketClient* client) OVERRIDE;
+ virtual void OnSendComplete() OVERRIDE;
virtual void OnError() OVERRIDE;
virtual void OnDataReceived(const net::IPEndPoint& address,
const std::vector<char>& data) OVERRIDE;
@@ -67,7 +73,7 @@
P2PSocketType type_;
// Message loop on which this socket was created and being used.
- MessageLoop* message_loop_;
+ base::MessageLoop* message_loop_;
// Corresponding P2P socket client.
scoped_refptr<P2PSocketClient> client_;
@@ -83,6 +89,14 @@
// Current state of the object.
InternalState state_;
+ // Number which have been sent to the browser, but for which we haven't
+ // received response.
+ int send_packets_pending_;
+
+ // Set to true once EWOULDBLOCK was returned from Send(). Indicates that the
+ // caller expects SignalWritable notification.
+ bool writable_signal_expected_;
+
// Current error code. Valid when state_ == IS_ERROR.
int error_;
@@ -91,10 +105,11 @@
IpcPacketSocket::IpcPacketSocket()
: type_(P2P_SOCKET_UDP),
- message_loop_(MessageLoop::current()),
+ message_loop_(base::MessageLoop::current()),
state_(IS_UNINITIALIZED),
- error_(0) {
-}
+ send_packets_pending_(0),
+ writable_signal_expected_(false),
+ error_(0) {}
IpcPacketSocket::~IpcPacketSocket() {
if (state_ == IS_OPENING || state_ == IS_OPEN ||
@@ -106,7 +121,7 @@
bool IpcPacketSocket::Init(P2PSocketType type, P2PSocketClient* client,
const talk_base::SocketAddress& local_address,
const talk_base::SocketAddress& remote_address) {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
DCHECK_EQ(state_, IS_UNINITIALIZED);
type_ = type;
@@ -135,7 +150,7 @@
P2PSocketClient* client,
const talk_base::SocketAddress& local_address,
const talk_base::SocketAddress& remote_address) {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
DCHECK_EQ(state_, IS_UNINITIALIZED);
client_ = client;
@@ -147,23 +162,23 @@
// talk_base::AsyncPacketSocket interface.
talk_base::SocketAddress IpcPacketSocket::GetLocalAddress() const {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
return local_address_;
}
talk_base::SocketAddress IpcPacketSocket::GetRemoteAddress() const {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
return remote_address_;
}
int IpcPacketSocket::Send(const void *data, size_t data_size) {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
return SendTo(data, data_size, remote_address_);
}
int IpcPacketSocket::SendTo(const void *data, size_t data_size,
const talk_base::SocketAddress& address) {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
switch (state_) {
case IS_UNINITIALIZED:
@@ -180,15 +195,24 @@
break;
}
+ if (send_packets_pending_ > kMaxPendingPackets) {
+ TRACE_EVENT_INSTANT1("p2p", "MaxPendingPacketsWouldBlock",
+ TRACE_EVENT_SCOPE_THREAD, "id", client_->socket_id());
+ writable_signal_expected_ = true;
+ error_ = EWOULDBLOCK;
+ return -1;
+ }
+
const char* data_char = reinterpret_cast<const char*>(data);
std::vector<char> data_vector(data_char, data_char + data_size);
net::IPEndPoint address_chrome;
if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) {
- // Just drop the packet if we failed to convert the address.
- return 0;
+ NOTREACHED();
+ return -1;
}
+ ++send_packets_pending_;
client_->Send(address_chrome, data_vector);
// Fake successful send. The caller ignores result anyway.
@@ -196,7 +220,7 @@
}
int IpcPacketSocket::Close() {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
client_->Close();
state_ = IS_CLOSED;
@@ -205,7 +229,7 @@
}
talk_base::AsyncPacketSocket::State IpcPacketSocket::GetState() const {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
switch (state_) {
case IS_UNINITIALIZED:
@@ -238,24 +262,21 @@
int IpcPacketSocket::SetOption(talk_base::Socket::Option opt, int value) {
// We don't support socket options for IPC sockets.
- //
- // TODO(sergeyu): Make sure we set proper socket options on the
- // browser side.
return -1;
}
int IpcPacketSocket::GetError() const {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
return error_;
}
void IpcPacketSocket::SetError(int error) {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
error_ = error;
}
void IpcPacketSocket::OnOpen(const net::IPEndPoint& address) {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
if (!jingle_glue::IPEndPointToSocketAddress(address, &local_address_)) {
// Always expect correct IPv4 address to be allocated.
@@ -274,7 +295,7 @@
void IpcPacketSocket::OnIncomingTcpConnection(
const net::IPEndPoint& address,
P2PSocketClient* client) {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
@@ -287,15 +308,28 @@
SignalNewConnection(this, socket.release());
}
+void IpcPacketSocket::OnSendComplete() {
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
+
+ --send_packets_pending_;
+ DCHECK_GE(send_packets_pending_, 0);
+
+ if (writable_signal_expected_ &&
+ send_packets_pending_ <= kWritableSignalThreshold) {
+ SignalReadyToSend(this);
+ writable_signal_expected_ = false;
+ }
+}
+
void IpcPacketSocket::OnError() {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
state_ = IS_ERROR;
error_ = ECONNABORTED;
}
void IpcPacketSocket::OnDataReceived(const net::IPEndPoint& address,
const std::vector<char>& data) {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+ DCHECK_EQ(base::MessageLoop::current(), message_loop_);
talk_base::SocketAddress address_lj;
if (!jingle_glue::IPEndPointToSocketAddress(address, &address_lj)) {
diff --git a/content/renderer/p2p/port_allocator.cc b/content/renderer/p2p/port_allocator.cc
index 7d06f6e..c8241e3 100644
--- a/content/renderer/p2p/port_allocator.cc
+++ b/content/renderer/p2p/port_allocator.cc
@@ -74,6 +74,9 @@
if (config_.disable_tcp_transport)
flags |= cricket::PORTALLOCATOR_DISABLE_TCP;
set_flags(flags);
+ // TODO(ronghuawu): crbug/138185 add ourselves to the firewall list in browser
+ // process and then remove below line.
+ set_allow_tcp_listen(false);
}
P2PPortAllocator::~P2PPortAllocator() {
@@ -199,7 +202,7 @@
relay_session_request_.reset(
allocator_->web_frame_->createAssociatedURLLoader(options));
- if (!relay_session_request_.get()) {
+ if (!relay_session_request_) {
LOG(ERROR) << "Failed to create URL loader.";
return;
}
@@ -282,8 +285,8 @@
}
void P2PPortAllocatorSession::AddConfig() {
- cricket::PortConfiguration* config =
- new cricket::PortConfiguration(stun_server_address_, "", "");
+ cricket::PortConfiguration* config = new cricket::PortConfiguration(
+ stun_server_address_, std::string(), std::string());
if (allocator_->config_.legacy_relay) {
// Passing empty credentials for legacy google relay.
diff --git a/content/renderer/p2p/socket_client.cc b/content/renderer/p2p/socket_client.cc
index e6f5a0f..ed3f211 100644
--- a/content/renderer/p2p/socket_client.cc
+++ b/content/renderer/p2p/socket_client.cc
@@ -134,6 +134,19 @@
}
}
+void P2PSocketClient::OnSendComplete() {
+ DCHECK(ipc_message_loop_->BelongsToCurrentThread());
+
+ delegate_message_loop_->PostTask(
+ FROM_HERE, base::Bind(&P2PSocketClient::DeliverOnSendComplete, this));
+}
+
+void P2PSocketClient::DeliverOnSendComplete() {
+ DCHECK(delegate_message_loop_->BelongsToCurrentThread());
+ if (delegate_)
+ delegate_->OnSendComplete();
+}
+
void P2PSocketClient::OnError() {
DCHECK(ipc_message_loop_->BelongsToCurrentThread());
state_ = STATE_ERROR;
diff --git a/content/renderer/p2p/socket_client.h b/content/renderer/p2p/socket_client.h
index d74107f..fd8537e 100644
--- a/content/renderer/p2p/socket_client.h
+++ b/content/renderer/p2p/socket_client.h
@@ -27,7 +27,8 @@
// thread which is specified in Init().
class P2PSocketClient : public base::RefCountedThreadSafe<P2PSocketClient> {
public:
- // Delegate is called on the the same thread on the delegate thread.
+ // Delegate is called on the the same thread on which P2PSocketCLient is
+ // created.
class Delegate {
public:
virtual ~Delegate() { }
@@ -35,6 +36,7 @@
virtual void OnOpen(const net::IPEndPoint& address) = 0;
virtual void OnIncomingTcpConnection(const net::IPEndPoint& address,
P2PSocketClient* client) = 0;
+ virtual void OnSendComplete() = 0;
virtual void OnError() = 0;
virtual void OnDataReceived(const net::IPEndPoint& address,
const std::vector<char>& data) = 0;
@@ -80,6 +82,8 @@
// Message handlers that run on IPC thread.
void OnSocketCreated(const net::IPEndPoint& address);
void OnIncomingTcpConnection(const net::IPEndPoint& address);
+ void OnSendComplete(int packet_id);
+ void OnSendComplete();
void OnError();
void OnDataReceived(const net::IPEndPoint& address,
const std::vector<char>& data);
@@ -89,6 +93,7 @@
void DeliverOnIncomingTcpConnection(
const net::IPEndPoint& address,
scoped_refptr<P2PSocketClient> new_client);
+ void DeliverOnSendComplete();
void DeliverOnError();
void DeliverOnDataReceived(const net::IPEndPoint& address,
const std::vector<char>& data);
diff --git a/content/renderer/p2p/socket_dispatcher.cc b/content/renderer/p2p/socket_dispatcher.cc
index c999e62..7fe71ee 100644
--- a/content/renderer/p2p/socket_dispatcher.cc
+++ b/content/renderer/p2p/socket_dispatcher.cc
@@ -63,6 +63,7 @@
IPC_MESSAGE_HANDLER(P2PMsg_GetHostAddressResult, OnGetHostAddressResult)
IPC_MESSAGE_HANDLER(P2PMsg_OnSocketCreated, OnSocketCreated)
IPC_MESSAGE_HANDLER(P2PMsg_OnIncomingTcpConnection, OnIncomingTcpConnection)
+ IPC_MESSAGE_HANDLER(P2PMsg_OnSendComplete, OnSendComplete)
IPC_MESSAGE_HANDLER(P2PMsg_OnError, OnError)
IPC_MESSAGE_HANDLER(P2PMsg_OnDataReceived, OnDataReceived)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -152,6 +153,13 @@
}
}
+void P2PSocketDispatcher::OnSendComplete(int socket_id) {
+ P2PSocketClient* client = GetClient(socket_id);
+ if (client) {
+ client->OnSendComplete();
+ }
+}
+
void P2PSocketDispatcher::OnError(int socket_id) {
P2PSocketClient* client = GetClient(socket_id);
if (client) {
diff --git a/content/renderer/p2p/socket_dispatcher.h b/content/renderer/p2p/socket_dispatcher.h
index e17a8c1..cbd8f2a 100644
--- a/content/renderer/p2p/socket_dispatcher.h
+++ b/content/renderer/p2p/socket_dispatcher.h
@@ -102,6 +102,7 @@
const net::IPAddressNumber& address);
void OnSocketCreated(int socket_id, const net::IPEndPoint& address);
void OnIncomingTcpConnection(int socket_id, const net::IPEndPoint& address);
+ void OnSendComplete(int socket_id);
void OnError(int socket_id);
void OnDataReceived(int socket_id, const net::IPEndPoint& address,
const std::vector<char>& data);
diff --git a/content/renderer/password_form_conversion_utils.cc b/content/renderer/password_form_conversion_utils.cc
index 68b1ee5..d173815 100644
--- a/content/renderer/password_form_conversion_utils.cc
+++ b/content/renderer/password_form_conversion_utils.cc
@@ -22,6 +22,11 @@
password_form->submit_element = web_password_form.submitElement;
password_form->username_element = web_password_form.userNameElement;
password_form->username_value = web_password_form.userNameValue;
+ password_form->possible_usernames.insert(
+ password_form->possible_usernames.begin(),
+ web_password_form.possibleUserNames.data(),
+ web_password_form.possibleUserNames.data() +
+ web_password_form.possibleUserNames.size());
password_form->password_element = web_password_form.passwordElement;
password_form->password_value = web_password_form.passwordValue;
password_form->password_autocomplete_set =
diff --git a/content/renderer/pepper/content_renderer_pepper_host_factory.cc b/content/renderer/pepper/content_renderer_pepper_host_factory.cc
index 0e7f380..a9c6f23 100644
--- a/content/renderer/pepper/content_renderer_pepper_host_factory.cc
+++ b/content/renderer/pepper/content_renderer_pepper_host_factory.cc
@@ -7,20 +7,24 @@
#include "base/logging.h"
#include "base/string_util.h"
#include "content/renderer/pepper/pepper_audio_input_host.h"
-#include "content/renderer/pepper/pepper_directory_reader_host.h"
#include "content/renderer/pepper/pepper_file_chooser_host.h"
#include "content/renderer/pepper/pepper_file_io_host.h"
+#include "content/renderer/pepper/pepper_file_system_host.h"
#include "content/renderer/pepper/pepper_graphics_2d_host.h"
#include "content/renderer/pepper/pepper_truetype_font_host.h"
#include "content/renderer/pepper/pepper_video_capture_host.h"
+#include "content/renderer/pepper/pepper_video_destination_host.h"
+#include "content/renderer/pepper/pepper_video_source_host.h"
#include "content/renderer/pepper/pepper_websocket_host.h"
#include "content/renderer/pepper/renderer_ppapi_host_impl.h"
#include "ppapi/host/resource_host.h"
+#include "ppapi/proxy/ppapi_message_utils.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/serialized_structs.h"
using ppapi::host::ResourceHost;
using ppapi::proxy::SerializedTrueTypeFontDesc;
+using ppapi::UnpackMessage;
namespace content {
@@ -45,23 +49,34 @@
// Public interfaces.
switch (message.type()) {
+ case PpapiHostMsg_FileIO_Create::ID:
+ return scoped_ptr<ResourceHost>(new PepperFileIOHost(
+ host_, instance, params.pp_resource()));
+ case PpapiHostMsg_FileSystem_Create::ID: {
+ PP_FileSystemType file_system_type;
+ if (!UnpackMessage<PpapiHostMsg_FileSystem_Create>(message,
+ &file_system_type)) {
+ NOTREACHED();
+ return scoped_ptr<ResourceHost>();
+ }
+ return scoped_ptr<ResourceHost>(new PepperFileSystemHost(
+ host_, instance, params.pp_resource(), file_system_type));
+ }
case PpapiHostMsg_Graphics2D_Create::ID: {
- PpapiHostMsg_Graphics2D_Create::Schema::Param msg_params;
- if (!PpapiHostMsg_Graphics2D_Create::Read(&message, &msg_params)) {
+ PP_Size size;
+ PP_Bool is_always_opaque;
+ if (!UnpackMessage<PpapiHostMsg_Graphics2D_Create>(message, &size,
+ &is_always_opaque)) {
NOTREACHED();
return scoped_ptr<ResourceHost>();
}
return scoped_ptr<ResourceHost>(
PepperGraphics2DHost::Create(host_, instance, params.pp_resource(),
- msg_params.a /* PP_Size */,
- msg_params.b /* PP_Bool */));
+ size, is_always_opaque));
}
case PpapiHostMsg_WebSocket_Create::ID:
return scoped_ptr<ResourceHost>(new PepperWebSocketHost(
host_, instance, params.pp_resource()));
- case PpapiHostMsg_FileIO_Create::ID:
- return scoped_ptr<ResourceHost>(new PepperFileIOHost(
- host_, instance, params.pp_resource()));
}
// Dev interfaces.
@@ -70,21 +85,18 @@
case PpapiHostMsg_AudioInput_Create::ID:
return scoped_ptr<ResourceHost>(new PepperAudioInputHost(
host_, instance, params.pp_resource()));
- case PpapiHostMsg_DirectoryReader_Create::ID:
- return scoped_ptr<ResourceHost>(new PepperDirectoryReaderHost(
- host_, instance, params.pp_resource()));
case PpapiHostMsg_FileChooser_Create::ID:
return scoped_ptr<ResourceHost>(new PepperFileChooserHost(
host_, instance, params.pp_resource()));
case PpapiHostMsg_TrueTypeFont_Create::ID: {
- PpapiHostMsg_TrueTypeFont_Create::Schema::Param msg_params;
- if (!PpapiHostMsg_TrueTypeFont_Create::Read(&message, &msg_params)) {
+ SerializedTrueTypeFontDesc desc;
+ if (!UnpackMessage<PpapiHostMsg_TrueTypeFont_Create>(message,
+ &desc)) {
NOTREACHED();
return scoped_ptr<ResourceHost>();
}
// Check that the family name is valid UTF-8 before passing it to the
// host OS.
- const SerializedTrueTypeFontDesc& desc = msg_params.a;
if (IsStringUTF8(desc.family)) {
return scoped_ptr<ResourceHost>(new PepperTrueTypeFontHost(
host_, instance, params.pp_resource(), desc));
@@ -103,6 +115,18 @@
}
}
+ // Private interfaces.
+ if (GetPermissions().HasPermission(ppapi::PERMISSION_PRIVATE)) {
+ switch (message.type()) {
+ case PpapiHostMsg_VideoDestination_Create::ID:
+ return scoped_ptr<ResourceHost>(new PepperVideoDestinationHost(
+ host_, instance, params.pp_resource()));
+ case PpapiHostMsg_VideoSource_Create::ID:
+ return scoped_ptr<ResourceHost>(new PepperVideoSourceHost(
+ host_, instance, params.pp_resource()));
+ }
+ }
+
return scoped_ptr<ResourceHost>();
}
diff --git a/content/renderer/pepper/null_file_system_callback_dispatcher.cc b/content/renderer/pepper/null_file_system_callback_dispatcher.cc
new file mode 100644
index 0000000..0c8d6a3
--- /dev/null
+++ b/content/renderer/pepper/null_file_system_callback_dispatcher.cc
@@ -0,0 +1,59 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/pepper/null_file_system_callback_dispatcher.h"
+
+#include "base/files/file_path.h"
+#include "base/files/file_util_proxy.h"
+#include "base/logging.h"
+#include "googleurl/src/gurl.h"
+
+namespace content {
+
+void NullFileSystemCallbackDispatcher::DidSucceed() {
+ NOTREACHED();
+}
+
+void NullFileSystemCallbackDispatcher::DidReadMetadata(
+ const base::PlatformFileInfo& /* file_info */,
+ const base::FilePath& /* platform_path */) {
+ NOTREACHED();
+}
+
+void NullFileSystemCallbackDispatcher::DidCreateSnapshotFile(
+ const base::PlatformFileInfo& /* file_info */,
+ const base::FilePath& /* platform_path */) {
+ NOTREACHED();
+}
+
+void NullFileSystemCallbackDispatcher::DidReadDirectory(
+ const std::vector<base::FileUtilProxy::Entry>& /* entries */,
+ bool /* has_more */) {
+ NOTREACHED();
+}
+
+void NullFileSystemCallbackDispatcher::DidOpenFileSystem(
+ const std::string& /* name */,
+ const GURL& /* root */) {
+ NOTREACHED();
+}
+
+void NullFileSystemCallbackDispatcher::DidWrite(int64 /* bytes */,
+ bool /* complete */) {
+ NOTREACHED();
+}
+
+void NullFileSystemCallbackDispatcher::DidOpenFile(
+ base::PlatformFile /* file */,
+ int /* file_open_id */,
+ quota::QuotaLimitType /* quota_policy */) {
+ NOTREACHED();
+}
+
+void NullFileSystemCallbackDispatcher::DidFail(
+ base::PlatformFileError /* platform_error */) {
+ NOTREACHED();
+}
+
+} // namespace content
diff --git a/content/renderer/pepper/null_file_system_callback_dispatcher.h b/content/renderer/pepper/null_file_system_callback_dispatcher.h
new file mode 100644
index 0000000..1031948
--- /dev/null
+++ b/content/renderer/pepper/null_file_system_callback_dispatcher.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_PEPPER_NULL_FILE_SYSTEM_CALLBACK_DISPATCHER_H_
+#define CONTENT_RENDERER_PEPPER_NULL_FILE_SYSTEM_CALLBACK_DISPATCHER_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/platform_file.h"
+#include "webkit/fileapi/file_system_callback_dispatcher.h"
+#include "webkit/quota/quota_types.h"
+
+class GURL;
+
+namespace base {
+class FilePath;
+class FileUtilProxy;
+struct PlatformFileInfo;
+} // namespace base
+
+namespace content {
+
+class NullFileSystemCallbackDispatcher
+ : public fileapi::FileSystemCallbackDispatcher {
+ public:
+ NullFileSystemCallbackDispatcher() {}
+
+ virtual ~NullFileSystemCallbackDispatcher(){}
+
+ virtual void DidSucceed() OVERRIDE;
+ virtual void DidReadMetadata(const base::PlatformFileInfo& file_info,
+ const base::FilePath& platform_path) OVERRIDE;
+ virtual void DidCreateSnapshotFile(
+ const base::PlatformFileInfo& file_info,
+ const base::FilePath& platform_path) OVERRIDE;
+ virtual void DidReadDirectory(
+ const std::vector<base::FileUtilProxy::Entry>& entries,
+ bool has_more) OVERRIDE;
+ virtual void DidOpenFileSystem(const std::string& name,
+ const GURL& root) OVERRIDE;
+ virtual void DidWrite(int64 bytes, bool complete) OVERRIDE;
+ virtual void DidOpenFile(base::PlatformFile file,
+ int file_open_id,
+ quota::QuotaLimitType quota_policy) OVERRIDE;
+ virtual void DidFail(base::PlatformFileError platform_error) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NullFileSystemCallbackDispatcher);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_PEPPER_NULL_FILE_SYSTEM_CALLBACK_DISPATCHER_H_
diff --git a/content/renderer/pepper/pepper_audio_input_host.cc b/content/renderer/pepper/pepper_audio_input_host.cc
index 413675a..7d494b1 100644
--- a/content/renderer/pepper/pepper_audio_input_host.cc
+++ b/content/renderer/pepper/pepper_audio_input_host.cc
@@ -44,8 +44,7 @@
: ResourceHost(host->GetPpapiHost(), instance, resource),
renderer_ppapi_host_(host),
audio_input_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- enumeration_helper_(this, this, PP_DEVICETYPE_DEV_AUDIOCAPTURE)) {
+ enumeration_helper_(this, this, PP_DEVICETYPE_DEV_AUDIOCAPTURE) {
}
PepperAudioInputHost::~PepperAudioInputHost() {
@@ -94,7 +93,7 @@
const std::string& device_id,
PP_AudioSampleRate sample_rate,
uint32_t sample_frame_count) {
- if (open_context_.get())
+ if (open_context_)
return PP_ERROR_INPROGRESS;
if (audio_input_)
return PP_ERROR_FAILED;
@@ -143,7 +142,7 @@
base::SyncSocket scoped_socket(socket_handle);
base::SharedMemory scoped_shared_memory(shared_memory_handle, false);
- if (!open_context_.get()) {
+ if (!open_context_) {
NOTREACHED();
return;
}
@@ -208,7 +207,7 @@
audio_input_->ShutDown();
audio_input_ = NULL;
- if (open_context_.get()) {
+ if (open_context_) {
open_context_->params.set_result(PP_ERROR_ABORTED);
host()->SendReply(*open_context_, PpapiPluginMsg_AudioInput_OpenReply());
open_context_.reset();
diff --git a/content/renderer/pepper/pepper_broker_impl.cc b/content/renderer/pepper/pepper_broker_impl.cc
index d814dda..550c3be 100644
--- a/content/renderer/pepper/pepper_broker_impl.cc
+++ b/content/renderer/pepper/pepper_broker_impl.cc
@@ -226,7 +226,7 @@
return;
}
- if (dispatcher_.get()) {
+ if (dispatcher_) {
ConnectPluginToBroker(client);
pending_connects_.erase(entry);
return;
diff --git a/content/renderer/pepper/pepper_broker_impl_unittest.cc b/content/renderer/pepper/pepper_broker_impl_unittest.cc
index aa61bf8..dc894a9 100644
--- a/content/renderer/pepper/pepper_broker_impl_unittest.cc
+++ b/content/renderer/pepper/pepper_broker_impl_unittest.cc
@@ -16,7 +16,7 @@
class PepperBrokerImplTest : public ::testing::Test {
protected:
- MessageLoopForIO message_loop_;
+ base::MessageLoopForIO message_loop_;
// We need a render process for ppapi::proxy::ProxyChannel to work.
MockRenderProcess mock_process_;
};
diff --git a/content/renderer/pepper/pepper_device_enumeration_event_handler.cc b/content/renderer/pepper/pepper_device_enumeration_event_handler.cc
index b23df8a..7a8dce6 100644
--- a/content/renderer/pepper/pepper_device_enumeration_event_handler.cc
+++ b/content/renderer/pepper/pepper_device_enumeration_event_handler.cc
@@ -78,7 +78,7 @@
}
void PepperDeviceEnumerationEventHandler::OnDeviceOpenFailed(int request_id) {
- NotifyDeviceOpened(request_id, false, "");
+ NotifyDeviceOpened(request_id, false, std::string());
}
// static
diff --git a/content/renderer/pepper/pepper_device_enumeration_host_helper.cc b/content/renderer/pepper/pepper_device_enumeration_host_helper.cc
index 4b21565..2352673 100644
--- a/content/renderer/pepper/pepper_device_enumeration_host_helper.cc
+++ b/content/renderer/pepper/pepper_device_enumeration_host_helper.cc
@@ -70,10 +70,13 @@
bool succeeded,
const std::vector<ppapi::DeviceRefData>& devices) {
if (sync_call_) {
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&ScopedRequest::EnumerateDevicesCallbackBody, AsWeakPtr(),
- request_id, succeeded, devices));
+ base::Bind(&ScopedRequest::EnumerateDevicesCallbackBody,
+ AsWeakPtr(),
+ request_id,
+ succeeded,
+ devices));
} else {
DCHECK_EQ(request_id_, request_id);
callback_.Run(request_id, succeeded, devices);
@@ -133,7 +136,7 @@
int32_t PepperDeviceEnumerationHostHelper::OnEnumerateDevices(
HostMessageContext* context) {
- if (enumerate_devices_context_.get())
+ if (enumerate_devices_context_)
return PP_ERROR_INPROGRESS;
enumerate_.reset(new ScopedRequest(
diff --git a/content/renderer/pepper/pepper_directory_reader_host.cc b/content/renderer/pepper/pepper_directory_reader_host.cc
deleted file mode 100644
index 2c3846c..0000000
--- a/content/renderer/pepper/pepper_directory_reader_host.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/pepper/pepper_directory_reader_host.h"
-
-#include "base/compiler_specific.h"
-#include "base/files/file_path.h"
-#include "base/utf_string_conversions.h"
-#include "content/public/renderer/renderer_ppapi_host.h"
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/host/dispatch_host_message.h"
-#include "ppapi/host/ppapi_host.h"
-#include "ppapi/proxy/ppapi_messages.h"
-#include "ppapi/shared_impl/file_type_conversion.h"
-#include "ppapi/shared_impl/ppb_file_ref_shared.h"
-#include "ppapi/thunk/enter.h"
-#include "webkit/fileapi/file_system_callback_dispatcher.h"
-#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
-#include "webkit/plugins/ppapi/ppb_file_system_impl.h"
-#include "webkit/plugins/ppapi/resource_helper.h"
-
-using ppapi::thunk::EnterResource;
-using ppapi::thunk::PPB_FileRef_API;
-using webkit::ppapi::PPB_FileRef_Impl;
-
-namespace content {
-
-namespace {
-
-std::string FilePathStringToUTF8String(const base::FilePath::StringType& str) {
-#if defined(OS_WIN)
- return WideToUTF8(str);
-#elif defined(OS_POSIX)
- return str;
-#else
-#error "Unsupported platform."
-#endif
-}
-
-base::FilePath::StringType UTF8StringToFilePathString(const std::string& str) {
-#if defined(OS_WIN)
- return UTF8ToWide(str);
-#elif defined(OS_POSIX)
- return str;
-#else
-#error "Unsupported platform."
-#endif
-}
-
-class ReadDirectoryCallback : public fileapi::FileSystemCallbackDispatcher {
- public:
- typedef base::Callback<void (const PepperDirectoryReaderHost::Entries&,
- bool, int32_t)>
- OnReadDirectoryCallback;
-
- explicit ReadDirectoryCallback(const OnReadDirectoryCallback& callback)
- : callback_(callback) {}
- virtual ~ReadDirectoryCallback() {}
-
- virtual void DidSucceed() OVERRIDE {
- NOTREACHED();
- }
-
- virtual void DidReadMetadata(const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path) OVERRIDE {
- NOTREACHED();
- }
-
- virtual void DidCreateSnapshotFile(
- const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path) OVERRIDE {
- NOTREACHED();
- }
-
- virtual void DidReadDirectory(
- const std::vector<base::FileUtilProxy::Entry>& entries,
- bool has_more) OVERRIDE {
- callback_.Run(entries, has_more, PP_OK);
- }
-
- virtual void DidOpenFileSystem(const std::string& name,
- const GURL& root) OVERRIDE {
- NOTREACHED();
- }
-
- virtual void DidFail(base::PlatformFileError error) OVERRIDE {
- callback_.Run(PepperDirectoryReaderHost::Entries(),
- false,
- ppapi::PlatformFileErrorToPepperError(error));
- }
-
- virtual void DidWrite(int64 bytes, bool complete) OVERRIDE {
- NOTREACHED();
- }
-
- virtual void DidOpenFile(base::PlatformFile file) OVERRIDE {
- NOTREACHED();
- }
-
- private:
- OnReadDirectoryCallback callback_;
-};
-
-} // namespace
-
-PepperDirectoryReaderHost::PepperDirectoryReaderHost(
- RendererPpapiHost* host,
- PP_Instance instance,
- PP_Resource resource)
- : ResourceHost(host->GetPpapiHost(), instance, resource),
- renderer_ppapi_host_(host),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
-}
-
-PepperDirectoryReaderHost::~PepperDirectoryReaderHost() {
-}
-
-int32_t PepperDirectoryReaderHost::OnResourceMessageReceived(
- const IPC::Message& msg,
- ppapi::host::HostMessageContext* context) {
- IPC_BEGIN_MESSAGE_MAP(PepperDirectoryReaderHost, msg)
- PPAPI_DISPATCH_HOST_RESOURCE_CALL(
- PpapiHostMsg_DirectoryReader_GetEntries, OnGetEntries)
- IPC_END_MESSAGE_MAP()
- return PP_ERROR_FAILED;
-}
-
-int32_t PepperDirectoryReaderHost::OnGetEntries(
- ppapi::host::HostMessageContext* host_context,
- const ppapi::HostResource& resource) {
- reply_context_ = host_context->MakeReplyMessageContext();
-
- EnterResource<PPB_FileRef_API> enter(resource.host_resource(), true);
- if (enter.failed())
- return PP_ERROR_FAILED;
- directory_ref_ = static_cast<PPB_FileRef_Impl*>(enter.object());
-
- if (directory_ref_->GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL)
- return PP_ERROR_FAILED;
-
- webkit::ppapi::PluginInstance* plugin_instance =
- renderer_ppapi_host_->GetPluginInstance(pp_instance());
- if (!plugin_instance)
- return PP_ERROR_FAILED;
-
- if (!plugin_instance->delegate()->ReadDirectory(
- directory_ref_->GetFileSystemURL(),
- new ReadDirectoryCallback(
- base::Bind(&PepperDirectoryReaderHost::OnReadDirectory,
- weak_factory_.GetWeakPtr()))))
- return PP_ERROR_FAILED;
- return PP_OK_COMPLETIONPENDING;
-}
-
-void PepperDirectoryReaderHost::OnReadDirectory(const Entries& entries,
- bool has_more,
- int32_t result) {
- // The current filesystem backend always returns false.
- DCHECK(!has_more);
- if (result == PP_OK && !AddNewEntries(entries))
- result = PP_ERROR_FAILED;
- SendGetEntriesReply(result);
-}
-
-bool PepperDirectoryReaderHost::AddNewEntries(const Entries& entries) {
- std::string dir_path = directory_ref_->GetCreateInfo().path;
- if (dir_path[dir_path.size() - 1] != '/')
- dir_path += '/';
- base::FilePath::StringType dir_file_path =
- UTF8StringToFilePathString(dir_path);
-
- for (Entries::const_iterator it = entries.begin();
- it != entries.end(); ++it) {
- EntryData data;
- data.file_ref = PPB_FileRef_Impl::CreateInternal(
- directory_ref_->file_system()->pp_resource(),
- FilePathStringToUTF8String(dir_file_path + it->name));
- if (!data.file_ref) {
- entry_data_.clear();
- return false;
- }
- data.file_type = it->is_directory ?
- PP_FILETYPE_DIRECTORY : PP_FILETYPE_REGULAR;
- entry_data_.push_back(data);
- }
-
- return true;
-}
-
-void PepperDirectoryReaderHost::SendGetEntriesReply(int32_t result) {
- std::vector<ppapi::PPB_FileRef_CreateInfo> host_resources;
- std::vector<PP_FileType> file_types;
-
- for (std::vector<EntryData>::iterator it = entry_data_.begin();
- it != entry_data_.end(); ++it) {
- // Add a ref count on behalf of the plugin side.
- it->file_ref->GetReference();
- host_resources.push_back(it->file_ref->GetCreateInfo());
- file_types.push_back(it->file_type);
- }
- entry_data_.clear();
-
- reply_context_.params.set_result(result);
- host()->SendReply(
- reply_context_,
- PpapiPluginMsg_DirectoryReader_GetEntriesReply(host_resources,
- file_types));
-}
-
-PepperDirectoryReaderHost::EntryData::EntryData() {
-}
-
-PepperDirectoryReaderHost::EntryData::~EntryData() {
-}
-
-} // namespace content
diff --git a/content/renderer/pepper/pepper_directory_reader_host.h b/content/renderer/pepper/pepper_directory_reader_host.h
deleted file mode 100644
index 3c57ee2..0000000
--- a/content/renderer/pepper/pepper_directory_reader_host.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_PEPPER_PEPPER_DIRECTORY_READER_HOST_H_
-#define CONTENT_RENDERER_PEPPER_PEPPER_DIRECTORY_READER_HOST_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/files/file_util_proxy.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "content/common/content_export.h"
-#include "ppapi/c/pp_file_info.h"
-#include "ppapi/host/host_message_context.h"
-#include "ppapi/host/resource_host.h"
-#include "webkit/plugins/ppapi/ppb_file_ref_impl.h"
-
-namespace ppapi {
-struct PPB_FileRef_CreateInfo;
-}
-
-namespace content {
-
-class RendererPpapiHost;
-
-class CONTENT_EXPORT PepperDirectoryReaderHost
- : public ppapi::host::ResourceHost {
- public:
- typedef std::vector<base::FileUtilProxy::Entry> Entries;
-
- PepperDirectoryReaderHost(RendererPpapiHost* host,
- PP_Instance instance,
- PP_Resource resource);
- virtual ~PepperDirectoryReaderHost();
-
- virtual int32_t OnResourceMessageReceived(
- const IPC::Message& msg,
- ppapi::host::HostMessageContext* context) OVERRIDE;
-
- private:
- struct EntryData {
- EntryData();
- ~EntryData();
- scoped_refptr<webkit::ppapi::PPB_FileRef_Impl> file_ref;
- PP_FileType file_type;
- };
-
- int32_t OnGetEntries(ppapi::host::HostMessageContext* host_context,
- const ppapi::HostResource& resource);
- void OnReadDirectory(const Entries& entries, bool has_more, int32_t result);
- bool AddNewEntries(const Entries& entries);
-
- void SendGetEntriesReply(int32_t result);
-
- RendererPpapiHost* renderer_ppapi_host_;
- ppapi::host::ReplyMessageContext reply_context_;
-
- scoped_refptr<webkit::ppapi::PPB_FileRef_Impl> directory_ref_;
-
- // Ensures that the resources are alive for as long as the host is.
- std::vector<EntryData> entry_data_;
-
- base::WeakPtrFactory<PepperDirectoryReaderHost> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(PepperDirectoryReaderHost);
-};
-
-}
-
-#endif // CONTENT_RENDERER_PEPPER_PEPPER_DIRECTORY_READER_HOST_H_
diff --git a/content/renderer/pepper/pepper_file_chooser_host_unittest.cc b/content/renderer/pepper/pepper_file_chooser_host_unittest.cc
index 8517220..b5d2f98 100644
--- a/content/renderer/pepper/pepper_file_chooser_host_unittest.cc
+++ b/content/renderer/pepper/pepper_file_chooser_host_unittest.cc
@@ -31,11 +31,9 @@
class PepperFileChooserHostTest : public RenderViewTest {
public:
PepperFileChooserHostTest()
- : pp_instance_(123456),
- old_content_client_(NULL) {}
+ : pp_instance_(123456) {}
virtual void SetUp() {
- old_content_client_ = GetContentClient();
SetContentClient(&client_);
RenderViewTest::SetUp();
@@ -45,7 +43,6 @@
globals_.GetResourceTracker()->DidDeleteInstance(pp_instance_);
RenderViewTest::TearDown();
- SetContentClient(old_content_client_);
}
PP_Instance pp_instance() const { return pp_instance_; }
@@ -55,9 +52,6 @@
ppapi::TestGlobals globals_;
TestContentClient client_;
-
- // Original value for the content client.
- ContentClient* old_content_client_;
};
// For testing to convert our hardcoded file paths to 8-bit.
diff --git a/content/renderer/pepper/pepper_file_io_host.cc b/content/renderer/pepper/pepper_file_io_host.cc
index d0fb617..cec0b3e 100644
--- a/content/renderer/pepper/pepper_file_io_host.cc
+++ b/content/renderer/pepper/pepper_file_io_host.cc
@@ -5,8 +5,13 @@
#include "content/renderer/pepper/pepper_file_io_host.h"
#include "base/bind.h"
+#include "base/callback.h"
#include "base/callback_helpers.h"
+#include "base/command_line.h"
#include "base/files/file_util_proxy.h"
+#include "content/public/common/content_client.h"
+#include "content/public/renderer/content_renderer_client.h"
+#include "content/renderer/pepper/null_file_system_callback_dispatcher.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/ppapi_host.h"
@@ -14,7 +19,6 @@
#include "ppapi/shared_impl/file_type_conversion.h"
#include "ppapi/shared_impl/time_conversion.h"
#include "ppapi/thunk/enter.h"
-#include "webkit/fileapi/file_system_callback_dispatcher.h"
#include "webkit/plugins/ppapi/file_callbacks.h"
#include "webkit/plugins/ppapi/host_globals.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
@@ -44,7 +48,7 @@
typedef base::Callback<void (base::PlatformFileError)> PlatformGeneralCallback;
class PlatformGeneralCallbackTranslator
- : public fileapi::FileSystemCallbackDispatcher {
+ : public NullFileSystemCallbackDispatcher {
public:
explicit PlatformGeneralCallbackTranslator(
const PlatformGeneralCallback& callback)
@@ -56,38 +60,8 @@
callback_.Run(base::PLATFORM_FILE_OK);
}
- virtual void DidReadMetadata(const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path) OVERRIDE {
- NOTREACHED();
- }
-
- virtual void DidCreateSnapshotFile(
- const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path) OVERRIDE {
- NOTREACHED();
- }
-
- virtual void DidReadDirectory(
- const std::vector<base::FileUtilProxy::Entry>& entries,
- bool has_more) OVERRIDE {
- NOTREACHED();
- }
-
- virtual void DidOpenFileSystem(const std::string& name,
- const GURL& root) OVERRIDE {
- NOTREACHED();
- }
-
- virtual void DidFail(base::PlatformFileError error_code) OVERRIDE {
- callback_.Run(error_code);
- }
-
- virtual void DidWrite(int64 bytes, bool complete) OVERRIDE {
- NOTREACHED();
- }
-
- virtual void DidOpenFile(base::PlatformFile file) OVERRIDE {
- NOTREACHED();
+ virtual void DidFail(base::PlatformFileError platform_error) OVERRIDE {
+ callback_.Run(platform_error);
}
private:
@@ -109,8 +83,9 @@
: ResourceHost(host->GetPpapiHost(), instance, resource),
file_(base::kInvalidPlatformFileValue),
file_system_type_(PP_FILESYSTEMTYPE_INVALID),
+ quota_policy_(quota::kQuotaLimitTypeUnknown),
is_running_in_process_(host->IsRunningInProcess()),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ weak_factory_(this) {
// TODO(victorhsieh): eliminate plugin_delegate_ as it's no longer needed.
webkit::ppapi::PluginInstance* plugin_instance =
webkit::ppapi::HostGlobals::Get()->GetInstance(instance);
@@ -147,6 +122,8 @@
OnHostMsgWillSetLength)
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_GetOSFileDescriptor,
OnHostMsgGetOSFileDescriptor)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_RequestOSFileHandle,
+ OnHostMsgRequestOSFileHandle)
IPC_END_MESSAGE_MAP()
return PP_ERROR_FAILED;
}
@@ -309,7 +286,7 @@
if (rv != PP_OK)
return rv;
- if (quota_file_io_.get()) {
+ if (quota_file_io_) {
if (!quota_file_io_->Write(
offset, buffer.c_str(), buffer.size(),
base::Bind(&PepperFileIOHost::ExecutePlatformWriteCallback,
@@ -410,12 +387,12 @@
if (rv != PP_OK)
return rv;
- if (!quota_file_io_.get())
+ if (!quota_file_io_)
return PP_OK;
if (!quota_file_io_->WillWrite(
offset, bytes_to_write,
- base::Bind(&PepperFileIOHost::ExecutePlatformWillWriteCallback,
+ base::Bind(&PepperFileIOHost::ExecutePlatformWriteCallback,
weak_factory_.GetWeakPtr(),
context->MakeReplyMessageContext())))
return PP_ERROR_FAILED;
@@ -432,7 +409,7 @@
if (rv != PP_OK)
return rv;
- if (!quota_file_io_.get())
+ if (!quota_file_io_)
return PP_OK;
if (!quota_file_io_->WillSetLength(
@@ -446,22 +423,44 @@
return PP_OK_COMPLETIONPENDING;
}
+int32_t PepperFileIOHost::OnHostMsgRequestOSFileHandle(
+ ppapi::host::HostMessageContext* context) {
+ if (!is_running_in_process_ &&
+ quota_policy_ != quota::kQuotaLimitTypeUnlimited)
+ return PP_ERROR_FAILED;
+
+ RendererPpapiHost* renderer_ppapi_host =
+ RendererPpapiHost::GetForPPInstance(pp_instance());
+
+ IPC::PlatformFileForTransit file =
+ renderer_ppapi_host->ShareHandleWithRemote(file_, false);
+ if (file == IPC::InvalidPlatformFileForTransit())
+ return PP_ERROR_FAILED;
+ ppapi::host::ReplyMessageContext reply_context =
+ context->MakeReplyMessageContext();
+ reply_context.params.AppendHandle(ppapi::proxy::SerializedHandle(
+ ppapi::proxy::SerializedHandle::FILE, file));
+ host()->SendReply(reply_context,
+ PpapiPluginMsg_FileIO_RequestOSFileHandleReply());
+ return PP_OK_COMPLETIONPENDING;
+}
+
int32_t PepperFileIOHost::OnHostMsgGetOSFileDescriptor(
ppapi::host::HostMessageContext* context) {
if (!is_running_in_process_)
return PP_ERROR_FAILED;
+
int32_t fd =
#if defined(OS_POSIX)
- file_;
+ file_;
#elif defined(OS_WIN)
- reinterpret_cast<uintptr_t>(file_);
+ reinterpret_cast<uintptr_t>(file_);
#else
- -1; // Platform not supported.
+ -1;
#endif
- // TODO(victorhsieh): Pass the file handle in the reply params once this works
- // in-process.
+
host()->SendReply(context->MakeReplyMessageContext(),
- PpapiPluginMsg_FileIO_GetOSFileDescriptorReply(fd));
+ PpapiPluginMsg_FileIO_GetOSFileDescriptorReply(fd));
return PP_OK_COMPLETIONPENDING;
}
@@ -502,9 +501,11 @@
ppapi::host::ReplyMessageContext reply_context,
base::PlatformFileError error_code,
base::PassPlatformFile file,
+ quota::QuotaLimitType quota_policy,
const PluginDelegate::NotifyCloseFileCallback& callback) {
if (error_code == base::PLATFORM_FILE_OK)
notify_close_file_callback_ = callback;
+ quota_policy_ = quota_policy;
ExecutePlatformOpenFileCallback(reply_context, error_code, file);
}
@@ -549,16 +550,6 @@
ppapi::host::ReplyMessageContext reply_context,
base::PlatformFileError error_code,
int bytes_written) {
- int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code);
- reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_written));
- host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply());
- state_manager_.SetOperationFinished();
-}
-
-void PepperFileIOHost::ExecutePlatformWillWriteCallback(
- ppapi::host::ReplyMessageContext reply_context,
- base::PlatformFileError error_code,
- int bytes_written) {
// On the plugin side, the callback expects a parameter with different meaning
// depends on whether is negative or not. It is the result here. We translate
// for the callback.
@@ -569,4 +560,3 @@
}
} // namespace content
-
diff --git a/content/renderer/pepper/pepper_file_io_host.h b/content/renderer/pepper/pepper_file_io_host.h
index b66cb6f..505af9c 100644
--- a/content/renderer/pepper/pepper_file_io_host.h
+++ b/content/renderer/pepper/pepper_file_io_host.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_RENDERER_PEPPER_PEPPER_FILE_IO_HOST_H_
#define CONTENT_RENDERER_PEPPER_PEPPER_FILE_IO_HOST_H_
+#include <set>
#include <string>
#include "base/basictypes.h"
@@ -58,6 +59,9 @@
int64_t length);
int32_t OnHostMsgClose(ppapi::host::HostMessageContext* context);
int32_t OnHostMsgFlush(ppapi::host::HostMessageContext* context);
+ // Private API.
+ int32_t OnHostMsgRequestOSFileHandle(
+ ppapi::host::HostMessageContext* context);
// Trusted API.
int32_t OnHostMsgGetOSFileDescriptor(
ppapi::host::HostMessageContext* context);
@@ -80,6 +84,7 @@
ReplyMessageContext reply_context,
base::PlatformFileError error_code,
base::PassPlatformFile file,
+ quota::QuotaLimitType quota_policy,
const PluginDelegate::NotifyCloseFileCallback& callback);
void ExecutePlatformQueryCallback(ReplyMessageContext reply_context,
base::PlatformFileError error_code,
@@ -90,9 +95,6 @@
void ExecutePlatformWriteCallback(ReplyMessageContext reply_context,
base::PlatformFileError error_code,
int bytes_written);
- void ExecutePlatformWillWriteCallback(ReplyMessageContext reply_context,
- base::PlatformFileError error_code,
- int bytes_written);
// TODO(victorhsieh): eliminate plugin_delegate_ as it's no longer needed.
webkit::ppapi::PluginDelegate* plugin_delegate_; // Not owned.
@@ -107,6 +109,9 @@
// Valid only for PP_FILESYSTEMTYPE_LOCAL{PERSISTENT,TEMPORARY}.
GURL file_system_url_;
+ // Used to check if we can pass file handle to plugins.
+ quota::QuotaLimitType quota_policy_;
+
// Callback function for notifying when the file handle is closed.
PluginDelegate::NotifyCloseFileCallback notify_close_file_callback_;
@@ -126,4 +131,3 @@
} // namespace content
#endif // CONTENT_RENDERER_PEPPER_PEPPER_FILE_IO_HOST_H_
-
diff --git a/content/renderer/pepper/pepper_file_system_host.cc b/content/renderer/pepper/pepper_file_system_host.cc
new file mode 100644
index 0000000..f29ef65
--- /dev/null
+++ b/content/renderer/pepper/pepper_file_system_host.cc
@@ -0,0 +1,132 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/pepper/pepper_file_system_host.h"
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "content/common/child_thread.h"
+#include "content/common/fileapi/file_system_dispatcher.h"
+#include "content/public/renderer/renderer_ppapi_host.h"
+#include "content/renderer/pepper/null_file_system_callback_dispatcher.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/host/dispatch_host_message.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/shared_impl/file_type_conversion.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
+#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
+
+namespace content {
+
+namespace {
+
+class PlatformCallbackAdaptor : public NullFileSystemCallbackDispatcher {
+ public:
+ explicit PlatformCallbackAdaptor(
+ const base::WeakPtr<PepperFileSystemHost>& weak_host)
+ : weak_host_(weak_host) {}
+
+ virtual ~PlatformCallbackAdaptor() {}
+
+ virtual void DidOpenFileSystem(const std::string& /* unused */,
+ const GURL& root) OVERRIDE {
+ if (weak_host_)
+ weak_host_->OpenFileSystemReply(PP_OK, root);
+ }
+
+ virtual void DidFail(base::PlatformFileError platform_error) OVERRIDE {
+ if (weak_host_) {
+ weak_host_->OpenFileSystemReply(
+ ppapi::PlatformFileErrorToPepperError(platform_error), GURL());
+ }
+ }
+
+ private:
+ base::WeakPtr<PepperFileSystemHost> weak_host_;
+};
+
+} // namespace
+
+PepperFileSystemHost::PepperFileSystemHost(RendererPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource,
+ PP_FileSystemType type)
+ : ResourceHost(host->GetPpapiHost(), instance, resource),
+ renderer_ppapi_host_(host),
+ weak_factory_(this),
+ type_(type),
+ opened_(false),
+ called_open_(false) {
+}
+
+PepperFileSystemHost::~PepperFileSystemHost() {
+}
+
+int32_t PepperFileSystemHost::OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context) {
+ IPC_BEGIN_MESSAGE_MAP(PepperFileSystemHost, msg)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileSystem_Open,
+ OnHostMsgOpen)
+ IPC_END_MESSAGE_MAP()
+ return PP_ERROR_FAILED;
+}
+
+void PepperFileSystemHost::OpenFileSystemReply(int32_t pp_error,
+ const GURL& root) {
+ opened_ = (pp_error == PP_OK);
+ root_url_ = root;
+ reply_context_.params.set_result(pp_error);
+ host()->SendReply(reply_context_,
+ PpapiPluginMsg_FileSystem_OpenReply());
+ reply_context_ = ppapi::host::ReplyMessageContext();
+}
+
+int32_t PepperFileSystemHost::OnHostMsgOpen(
+ ppapi::host::HostMessageContext* context,
+ int64_t expected_size) {
+ // Not allow multiple opens.
+ if (called_open_)
+ return PP_ERROR_INPROGRESS;
+ called_open_ = true;
+
+ fileapi::FileSystemType file_system_type;
+ switch (type_) {
+ case PP_FILESYSTEMTYPE_LOCALTEMPORARY:
+ file_system_type = fileapi::kFileSystemTypeTemporary;
+ break;
+ case PP_FILESYSTEMTYPE_LOCALPERSISTENT:
+ file_system_type = fileapi::kFileSystemTypePersistent;
+ break;
+ case PP_FILESYSTEMTYPE_EXTERNAL:
+ file_system_type = fileapi::kFileSystemTypeExternal;
+ break;
+ default:
+ return PP_ERROR_FAILED;
+ }
+
+ webkit::ppapi::PluginInstance* plugin_instance =
+ renderer_ppapi_host_->GetPluginInstance(pp_instance());
+ if (!plugin_instance)
+ return PP_ERROR_FAILED;
+
+ FileSystemDispatcher* file_system_dispatcher =
+ ChildThread::current()->file_system_dispatcher();
+ reply_context_ = context->MakeReplyMessageContext();
+ if (!file_system_dispatcher->OpenFileSystem(
+ GURL(plugin_instance->container()->element().document().url()).
+ GetOrigin(),
+ file_system_type, expected_size, true /* create */,
+ new PlatformCallbackAdaptor(weak_factory_.GetWeakPtr()))) {
+ return PP_ERROR_FAILED;
+ }
+
+ return PP_OK_COMPLETIONPENDING;
+}
+
+} // namespace content
diff --git a/content/renderer/pepper/pepper_file_system_host.h b/content/renderer/pepper/pepper_file_system_host.h
new file mode 100644
index 0000000..92f69a6
--- /dev/null
+++ b/content/renderer/pepper/pepper_file_system_host.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_PEPPER_PEPPER_FILE_SYSTEM_HOST_H_
+#define CONTENT_RENDERER_PEPPER_PEPPER_FILE_SYSTEM_HOST_H_
+
+#include "base/basictypes.h"
+#include "base/memory/weak_ptr.h"
+#include "googleurl/src/gurl.h"
+#include "ppapi/c/pp_file_info.h"
+#include "ppapi/host/host_message_context.h"
+#include "ppapi/host/resource_host.h"
+
+namespace content {
+
+class RendererPpapiHost;
+
+class PepperFileSystemHost :
+ public ppapi::host::ResourceHost,
+ public base::SupportsWeakPtr<PepperFileSystemHost> {
+ public:
+ PepperFileSystemHost(RendererPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource,
+ PP_FileSystemType type);
+ virtual ~PepperFileSystemHost();
+
+ // ppapi::host::ResourceHost override.
+ virtual int32_t OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context) OVERRIDE;
+
+ // Supports FileRefs direct access on the host side.
+ PP_FileSystemType GetType() const { return type_; }
+ bool IsOpened() const { return opened_; }
+ GURL GetRootUrl() const { return root_url_; }
+
+ // It's public only to allow PlatformCallbackAdaptor to access.
+ void OpenFileSystemReply(int32_t pp_error,
+ const GURL& root);
+
+ private:
+ int32_t OnHostMsgOpen(ppapi::host::HostMessageContext* context,
+ int64_t expected_size);
+
+ RendererPpapiHost* renderer_ppapi_host_;
+ ppapi::host::ReplyMessageContext reply_context_;
+ base::WeakPtrFactory<PepperFileSystemHost> weak_factory_;
+
+ PP_FileSystemType type_;
+ bool opened_; // whether open is successful.
+ GURL root_url_;
+ bool called_open_; // whether open has been called.
+
+ DISALLOW_COPY_AND_ASSIGN(PepperFileSystemHost);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_PEPPER_PEPPER_FILE_SYSTEM_HOST_H_
diff --git a/content/renderer/pepper/pepper_graphics_2d_host.cc b/content/renderer/pepper/pepper_graphics_2d_host.cc
index fc5e139..778f4f0 100644
--- a/content/renderer/pepper/pepper_graphics_2d_host.cc
+++ b/content/renderer/pepper/pepper_graphics_2d_host.cc
@@ -189,7 +189,7 @@
offscreen_flush_pending_(false),
is_always_opaque_(false),
scale_(1.0f),
- weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ weak_ptr_factory_(this),
is_running_in_process_(host->IsRunningInProcess()) {
}
@@ -725,7 +725,7 @@
void PepperGraphics2DHost::ScheduleOffscreenFlushAck() {
offscreen_flush_pending_ = true;
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&PepperGraphics2DHost::SendOffscreenFlushAck,
weak_ptr_factory_.GetWeakPtr()),
diff --git a/content/renderer/pepper/pepper_in_process_resource_creation.cc b/content/renderer/pepper/pepper_in_process_resource_creation.cc
index d9de4de..4ce8a08 100644
--- a/content/renderer/pepper/pepper_in_process_resource_creation.cc
+++ b/content/renderer/pepper/pepper_in_process_resource_creation.cc
@@ -17,6 +17,7 @@
#include "ppapi/proxy/browser_font_resource_trusted.h"
#include "ppapi/proxy/file_chooser_resource.h"
#include "ppapi/proxy/file_io_resource.h"
+#include "ppapi/proxy/file_system_resource.h"
#include "ppapi/proxy/graphics_2d_resource.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/printing_resource.h"
@@ -26,6 +27,7 @@
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
#include "ppapi/shared_impl/resource_tracker.h"
+#include "ppapi/shared_impl/var.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
// Note that the code in the creation functions in this file should generally
@@ -64,10 +66,13 @@
PP_Resource PepperInProcessResourceCreation::CreateFileChooser(
PP_Instance instance,
PP_FileChooserMode_Dev mode,
- const char* accept_types) {
+ const PP_Var& accept_types) {
+ scoped_refptr<ppapi::StringVar> string_var =
+ ppapi::StringVar::FromPPVar(accept_types);
+ std::string str = string_var ? string_var->value() : std::string();
return (new ppapi::proxy::FileChooserResource(
host_impl_->in_process_router()->GetPluginConnection(),
- instance, mode, accept_types))->GetReference();
+ instance, mode, str.c_str()))->GetReference();
}
PP_Resource PepperInProcessResourceCreation::CreateFileIO(
@@ -77,13 +82,21 @@
instance))->GetReference();
}
+PP_Resource PepperInProcessResourceCreation::CreateFileSystem(
+ PP_Instance instance,
+ PP_FileSystemType type) {
+ return (new ppapi::proxy::FileSystemResource(
+ host_impl_->in_process_router()->GetPluginConnection(),
+ instance, type))->GetReference();
+}
+
PP_Resource PepperInProcessResourceCreation::CreateGraphics2D(
PP_Instance instance,
- const PP_Size& size,
+ const PP_Size* size,
PP_Bool is_always_opaque) {
return (new ppapi::proxy::Graphics2DResource(
host_impl_->in_process_router()->GetPluginConnection(),
- instance, size, is_always_opaque))->GetReference();
+ instance, *size, is_always_opaque))->GetReference();
}
PP_Resource PepperInProcessResourceCreation::CreatePrinting(
@@ -95,17 +108,16 @@
PP_Resource PepperInProcessResourceCreation::CreateTrueTypeFont(
PP_Instance instance,
- const PP_TrueTypeFontDesc_Dev& desc) {
+ const PP_TrueTypeFontDesc_Dev* desc) {
NOTIMPLEMENTED();
return 0;
}
PP_Resource PepperInProcessResourceCreation::CreateURLRequestInfo(
- PP_Instance instance,
- const ::ppapi::URLRequestInfoData& data) {
+ PP_Instance instance) {
return (new ppapi::proxy::URLRequestInfoResource(
host_impl_->in_process_router()->GetPluginConnection(),
- instance, data))->GetReference();
+ instance, ::ppapi::URLRequestInfoData()))->GetReference();
}
PP_Resource PepperInProcessResourceCreation::CreateURLResponseInfo(
diff --git a/content/renderer/pepper/pepper_in_process_resource_creation.h b/content/renderer/pepper/pepper_in_process_resource_creation.h
index 4f0d5fa..847320b 100644
--- a/content/renderer/pepper/pepper_in_process_resource_creation.h
+++ b/content/renderer/pepper/pepper_in_process_resource_creation.h
@@ -48,20 +48,21 @@
virtual PP_Resource CreateFileChooser(
PP_Instance instance,
PP_FileChooserMode_Dev mode,
- const char* accept_types) OVERRIDE;
+ const PP_Var& accept_types) OVERRIDE;
virtual PP_Resource CreateFileIO(PP_Instance instance) OVERRIDE;
+ virtual PP_Resource CreateFileSystem(PP_Instance instance,
+ PP_FileSystemType type) OVERRIDE;
virtual PP_Resource CreateGraphics2D(
PP_Instance pp_instance,
- const PP_Size& size,
+ const PP_Size* size,
PP_Bool is_always_opaque) OVERRIDE;
virtual PP_Resource CreatePrinting(
PP_Instance instance) OVERRIDE;
virtual PP_Resource CreateTrueTypeFont(
PP_Instance instance,
- const struct PP_TrueTypeFontDesc_Dev& desc) OVERRIDE;
+ const struct PP_TrueTypeFontDesc_Dev* desc) OVERRIDE;
virtual PP_Resource CreateURLRequestInfo(
- PP_Instance instance,
- const ::ppapi::URLRequestInfoData& data) OVERRIDE;
+ PP_Instance instance) OVERRIDE;
virtual PP_Resource CreateURLResponseInfo(
PP_Instance instance,
const ::ppapi::URLResponseInfoData& data,
diff --git a/content/renderer/pepper/pepper_in_process_router.cc b/content/renderer/pepper/pepper_in_process_router.cc
index 1cdccc2..acd4226 100644
--- a/content/renderer/pepper/pepper_in_process_router.cc
+++ b/content/renderer/pepper/pepper_in_process_router.cc
@@ -35,7 +35,7 @@
: host_impl_(host_impl),
pending_message_id_(0),
reply_result_(false),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ weak_factory_(this) {
dummy_browser_channel_.reset(
new Channel(base::Bind(&PepperInProcessRouter::DummySendTo,
base::Unretained(this))));
@@ -94,11 +94,11 @@
} else {
CHECK(!pending_message_id_);
// Dispatch plugin messages from the message loop.
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&PepperInProcessRouter::DispatchPluginMsg,
- weak_factory_.GetWeakPtr(),
- base::Owned(message.release())));
+ weak_factory_.GetWeakPtr(),
+ base::Owned(message.release())));
}
return true;
}
diff --git a/content/renderer/pepper/pepper_platform_audio_input_impl.cc b/content/renderer/pepper/pepper_platform_audio_input_impl.cc
index f71b642..76afa17 100644
--- a/content/renderer/pepper/pepper_platform_audio_input_impl.cc
+++ b/content/renderer/pepper/pepper_platform_audio_input_impl.cc
@@ -9,7 +9,6 @@
#include "base/message_loop_proxy.h"
#include "build/build_config.h"
#include "content/common/child_process.h"
-#include "content/common/media/audio_messages.h"
#include "content/renderer/media/audio_input_message_filter.h"
#include "content/renderer/pepper/pepper_plugin_delegate_impl.h"
#include "content/renderer/render_thread_impl.h"
@@ -55,6 +54,10 @@
void PepperPlatformAudioInputImpl::ShutDown() {
DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
+ // Make sure we don't call shutdown more than once.
+ if (!client_)
+ return;
+
// Called on the main thread to stop all audio callbacks. We must only change
// the client on the main thread, and the delegates from the I/O thread.
client_ = NULL;
@@ -80,9 +83,8 @@
DCHECK_EQ(1, total_segments);
if (base::MessageLoopProxy::current() != main_message_loop_proxy_) {
- // No need to check |shutdown_called_| here. If shutdown has occurred,
- // |client_| will be NULL and the handles will be cleaned up on the main
- // thread.
+ // If shutdown has occurred, |client_| will be NULL and the handles will be
+ // cleaned up on the main thread.
main_message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&PepperPlatformAudioInputImpl::OnStreamCreated, this,
@@ -107,7 +109,7 @@
}
void PepperPlatformAudioInputImpl::OnIPCClosed() {
- ipc_ = NULL;
+ ipc_.reset();
}
PepperPlatformAudioInputImpl::~PepperPlatformAudioInputImpl() {
@@ -116,19 +118,14 @@
// Although these members should be accessed on a specific thread (either the
// main thread or the I/O thread), it should be fine to examine their value
// here.
- DCHECK_EQ(0, stream_id_);
+ DCHECK(!ipc_);
DCHECK(!client_);
DCHECK(label_.empty());
- DCHECK(shutdown_called_);
}
PepperPlatformAudioInputImpl::PepperPlatformAudioInputImpl()
: client_(NULL),
- stream_id_(0),
- render_view_id_(MSG_ROUTING_NONE),
- main_message_loop_proxy_(base::MessageLoopProxy::current()),
- shutdown_called_(false) {
- ipc_ = RenderThreadImpl::current()->audio_input_message_filter();
+ main_message_loop_proxy_(base::MessageLoopProxy::current()) {
}
bool PepperPlatformAudioInputImpl::Initialize(
@@ -142,8 +139,10 @@
if (!plugin_delegate || !client)
return false;
+ ipc_ = RenderThreadImpl::current()->audio_input_message_filter()->
+ CreateAudioInputIPC(plugin_delegate->GetRoutingID());
+
plugin_delegate_ = plugin_delegate;
- render_view_id_ = plugin_delegate_->GetRoutingID();
client_ = client;
params_.Reset(media::AudioParameters::AUDIO_PCM_LINEAR,
@@ -164,26 +163,19 @@
DCHECK(ChildProcess::current()->io_message_loop_proxy()->
BelongsToCurrentThread());
- if (shutdown_called_)
+ if (!ipc_)
return;
- // Make sure we don't call init more than once.
- DCHECK_EQ(0, stream_id_);
- stream_id_ = ipc_->AddDelegate(this);
- DCHECK_NE(0, stream_id_);
-
// We will be notified by OnStreamCreated().
- ipc_->CreateStream(stream_id_, session_id, params_, false, 1);
+ ipc_->CreateStream(this, session_id, params_, false, 1);
}
void PepperPlatformAudioInputImpl::StartCaptureOnIOThread() {
DCHECK(ChildProcess::current()->io_message_loop_proxy()->
BelongsToCurrentThread());
- if (stream_id_) {
- ipc_->AssociateStreamWithConsumer(stream_id_, render_view_id_);
- ipc_->RecordStream(stream_id_);
- }
+ if (ipc_)
+ ipc_->RecordStream();
}
void PepperPlatformAudioInputImpl::StopCaptureOnIOThread() {
@@ -191,24 +183,17 @@
BelongsToCurrentThread());
// TODO(yzshen): We cannot re-start capturing if the stream is closed.
- if (stream_id_)
- ipc_->CloseStream(stream_id_);
+ if (ipc_) {
+ ipc_->CloseStream();
+ ipc_.reset();
+ }
}
void PepperPlatformAudioInputImpl::ShutDownOnIOThread() {
DCHECK(ChildProcess::current()->io_message_loop_proxy()->
BelongsToCurrentThread());
- // Make sure we don't call shutdown more than once.
- if (shutdown_called_)
- return;
- shutdown_called_ = true;
-
- if (stream_id_) {
- ipc_->CloseStream(stream_id_);
- ipc_->RemoveDelegate(stream_id_);
- stream_id_ = 0;
- }
+ StopCaptureOnIOThread();
main_message_loop_proxy_->PostTask(
FROM_HERE,
diff --git a/content/renderer/pepper/pepper_platform_audio_input_impl.h b/content/renderer/pepper/pepper_platform_audio_input_impl.h
index 7d71347..0cfa92d 100644
--- a/content/renderer/pepper/pepper_platform_audio_input_impl.h
+++ b/content/renderer/pepper/pepper_platform_audio_input_impl.h
@@ -9,9 +9,9 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
-#include "content/renderer/media/audio_input_message_filter.h"
+#include "media/audio/audio_input_ipc.h"
#include "media/audio/audio_parameters.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
@@ -21,7 +21,6 @@
namespace content {
-class AudioInputMessageFilter;
class PepperPluginDelegateImpl;
// PepperPlatformAudioInputImpl is operated on two threads: the main thread (the
@@ -93,15 +92,8 @@
webkit::ppapi::PluginDelegate::PlatformAudioInputClient* client_;
// Used to send/receive IPC. THIS MUST ONLY BE ACCESSED ON THE
- // I/O thread except to send messages and get the message loop.
- scoped_refptr<AudioInputMessageFilter> ipc_;
-
- // Our ID on the MessageFilter. THIS MUST ONLY BE ACCESSED ON THE I/O THREAD
- // or else you could race with the initialize function which sets it.
- int32 stream_id_;
-
- // The render view into which the audio is sent.
- int render_view_id_;
+ // I/O THREAD.
+ scoped_ptr<media::AudioInputIPC> ipc_;
base::MessageLoopProxy* main_message_loop_proxy_;
@@ -112,10 +104,6 @@
// THE MAIN THREAD.
std::string label_;
- // Whether ShutDownOnIOThread() has been called. THIS MUST ONLY BE ACCESSED ON
- // THE I/O THREAD.
- bool shutdown_called_;
-
// Initialized on the main thread and accessed on the I/O thread afterwards.
media::AudioParameters params_;
diff --git a/content/renderer/pepper/pepper_platform_audio_output_impl.cc b/content/renderer/pepper/pepper_platform_audio_output_impl.cc
index 90ec7eb..e53dd6d 100644
--- a/content/renderer/pepper/pepper_platform_audio_output_impl.cc
+++ b/content/renderer/pepper/pepper_platform_audio_output_impl.cc
@@ -5,7 +5,6 @@
#include "content/renderer/pepper/pepper_platform_audio_output_impl.h"
#include "base/bind.h"
-#include "base/command_line.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "build/build_config.h"
@@ -14,7 +13,6 @@
#include "content/renderer/media/audio_message_filter.h"
#include "content/renderer/render_thread_impl.h"
#include "media/base/audio_hardware_config.h"
-#include "media/base/media_switches.h"
namespace content {
@@ -97,21 +95,19 @@
}
void PepperPlatformAudioOutputImpl::OnIPCClosed() {
- ipc_ = NULL;
+ ipc_.reset();
}
PepperPlatformAudioOutputImpl::~PepperPlatformAudioOutputImpl() {
// Make sure we have been shut down. Warning: this will usually happen on
// the I/O thread!
- DCHECK_EQ(0, stream_id_);
+ DCHECK(!ipc_);
DCHECK(!client_);
}
PepperPlatformAudioOutputImpl::PepperPlatformAudioOutputImpl()
: client_(NULL),
- stream_id_(0),
main_message_loop_proxy_(base::MessageLoopProxy::current()) {
- ipc_ = RenderThreadImpl::current()->audio_message_filter();
}
bool PepperPlatformAudioOutputImpl::Initialize(
@@ -122,66 +118,54 @@
DCHECK(client);
client_ = client;
- media::AudioParameters::Format format;
- const int kMaxFramesForLowLatency = 2047;
+ RenderThreadImpl* const render_thread = RenderThreadImpl::current();
+ ipc_ = render_thread->audio_message_filter()->
+ CreateAudioOutputIPC(source_render_view_id);
+ CHECK(ipc_);
- media::AudioHardwareConfig* hardware_config =
- RenderThreadImpl::current()->GetAudioHardwareConfig();
-
- const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
- if (!cmd_line->HasSwitch(switches::kDisableAudioOutputResampler)) {
- // Rely on AudioOutputResampler to handle any inconsistencies between the
- // hardware params required for low latency and the requested params.
- format = media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
- } else if (sample_rate == hardware_config->GetOutputSampleRate() &&
- frames_per_buffer <= kMaxFramesForLowLatency &&
- frames_per_buffer % hardware_config->GetOutputBufferSize() == 0) {
- // Use the low latency back end if the client request is compatible, and
- // the sample count is low enough to justify using AUDIO_PCM_LOW_LATENCY.
- format = media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
- } else {
- format = media::AudioParameters::AUDIO_PCM_LINEAR;
- }
-
- media::AudioParameters params(format, media::CHANNEL_LAYOUT_STEREO,
- sample_rate, 16, frames_per_buffer);
+ media::AudioParameters params(
+ media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
+ media::CHANNEL_LAYOUT_STEREO, sample_rate, 16, frames_per_buffer);
ChildProcess::current()->io_message_loop()->PostTask(
FROM_HERE,
base::Bind(&PepperPlatformAudioOutputImpl::InitializeOnIOThread,
- this, params, source_render_view_id));
+ this, params));
return true;
}
void PepperPlatformAudioOutputImpl::InitializeOnIOThread(
- const media::AudioParameters& params, int source_render_view_id) {
- // Make sure we don't call init more than once.
- DCHECK_EQ(0, stream_id_);
- stream_id_ = ipc_->AddDelegate(this);
- DCHECK_NE(0, stream_id_);
-
- ipc_->CreateStream(stream_id_, params);
- ipc_->AssociateStreamWithProducer(stream_id_, source_render_view_id);
+ const media::AudioParameters& params) {
+ DCHECK(ChildProcess::current()->io_message_loop_proxy()->
+ BelongsToCurrentThread());
+ if (ipc_)
+ ipc_->CreateStream(this, params);
}
void PepperPlatformAudioOutputImpl::StartPlaybackOnIOThread() {
- if (stream_id_)
- ipc_->PlayStream(stream_id_);
+ DCHECK(ChildProcess::current()->io_message_loop_proxy()->
+ BelongsToCurrentThread());
+ if (ipc_)
+ ipc_->PlayStream();
}
void PepperPlatformAudioOutputImpl::StopPlaybackOnIOThread() {
- if (stream_id_)
- ipc_->PauseStream(stream_id_);
+ DCHECK(ChildProcess::current()->io_message_loop_proxy()->
+ BelongsToCurrentThread());
+ if (ipc_)
+ ipc_->PauseStream();
}
void PepperPlatformAudioOutputImpl::ShutDownOnIOThread() {
+ DCHECK(ChildProcess::current()->io_message_loop_proxy()->
+ BelongsToCurrentThread());
+
// Make sure we don't call shutdown more than once.
- if (!stream_id_)
+ if (!ipc_)
return;
- ipc_->CloseStream(stream_id_);
- ipc_->RemoveDelegate(stream_id_);
- stream_id_ = 0;
+ ipc_->CloseStream();
+ ipc_.reset();
Release(); // Release for the delegate, balances out the reference taken in
// PepperPluginDelegateImpl::CreateAudio.
diff --git a/content/renderer/pepper/pepper_platform_audio_output_impl.h b/content/renderer/pepper/pepper_platform_audio_output_impl.h
index 0be7588..b8eb05d 100644
--- a/content/renderer/pepper/pepper_platform_audio_output_impl.h
+++ b/content/renderer/pepper/pepper_platform_audio_output_impl.h
@@ -7,6 +7,7 @@
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "media/audio/audio_output_ipc.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
@@ -20,8 +21,6 @@
namespace content {
-class AudioMessageFilter;
-
class PepperPlatformAudioOutputImpl
: public webkit::ppapi::PluginDelegate::PlatformAudioOutput,
public media::AudioOutputIPCDelegate,
@@ -63,8 +62,7 @@
webkit::ppapi::PluginDelegate::PlatformAudioOutputClient* client);
// I/O thread backends to above functions.
- void InitializeOnIOThread(const media::AudioParameters& params,
- int source_render_view_id);
+ void InitializeOnIOThread(const media::AudioParameters& params);
void StartPlaybackOnIOThread();
void StopPlaybackOnIOThread();
void ShutDownOnIOThread();
@@ -75,11 +73,7 @@
// Used to send/receive IPC. THIS MUST ONLY BE ACCESSED ON THE
// I/O thread except to send messages and get the message loop.
- scoped_refptr<AudioMessageFilter> ipc_;
-
- // Our ID on the MessageFilter. THIS MUST ONLY BE ACCESSED ON THE I/O THREAD
- // or else you could race with the initialize function which sets it.
- int32 stream_id_;
+ scoped_ptr<media::AudioOutputIPC> ipc_;
base::MessageLoopProxy* main_message_loop_proxy_;
diff --git a/content/renderer/pepper/pepper_platform_context_3d_impl.cc b/content/renderer/pepper/pepper_platform_context_3d_impl.cc
index 2a839ae..09e5935 100644
--- a/content/renderer/pepper/pepper_platform_context_3d_impl.cc
+++ b/content/renderer/pepper/pepper_platform_context_3d_impl.cc
@@ -24,7 +24,7 @@
: parent_texture_id_(0),
has_alpha_(false),
command_buffer_(NULL),
- weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ weak_ptr_factory_(this) {
}
PlatformContext3DImpl::~PlatformContext3DImpl() {
@@ -53,7 +53,7 @@
channel_ = render_thread->EstablishGpuChannelSync(
CAUSE_FOR_GPU_LAUNCH_PEPPERPLATFORMCONTEXT3DIMPL_INITIALIZE);
- if (!channel_.get())
+ if (!channel_)
return false;
DCHECK(channel_->state() == GpuChannelHost::kConnected);
diff --git a/content/renderer/pepper/pepper_platform_image_2d_impl.cc b/content/renderer/pepper/pepper_platform_image_2d_impl.cc
index dcad9ce..4a0b4f1 100644
--- a/content/renderer/pepper/pepper_platform_image_2d_impl.cc
+++ b/content/renderer/pepper/pepper_platform_image_2d_impl.cc
@@ -22,7 +22,7 @@
// On Mac, we have to tell the browser to free the transport DIB.
PepperPlatformImage2DImpl::~PepperPlatformImage2DImpl() {
#if defined(OS_MACOSX)
- if (dib_.get()) {
+ if (dib_) {
RenderThreadImpl::current()->Send(
new ViewHostMsg_FreeTransportDIB(dib_->id()));
}
diff --git a/content/renderer/pepper/pepper_platform_video_capture_impl.cc b/content/renderer/pepper/pepper_platform_video_capture_impl.cc
index 35bfd58..39ee609 100644
--- a/content/renderer/pepper/pepper_platform_video_capture_impl.cc
+++ b/content/renderer/pepper/pepper_platform_video_capture_impl.cc
@@ -21,9 +21,8 @@
: plugin_delegate_(plugin_delegate),
device_id_(device_id),
session_id_(0),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- handler_proxy_(new media::VideoCaptureHandlerProxy(
- this, base::MessageLoopProxy::current()))),
+ handler_proxy_(new media::VideoCaptureHandlerProxy(
+ this, base::MessageLoopProxy::current())),
handler_(handler),
video_capture_(NULL),
unbalanced_start_(false) {
diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.cc b/content/renderer/pepper/pepper_plugin_delegate_impl.cc
index d2be7cc..110e1bc 100644
--- a/content/renderer/pepper/pepper_plugin_delegate_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_delegate_impl.cc
@@ -43,6 +43,7 @@
#include "content/renderer/pepper/content_renderer_pepper_host_factory.h"
#include "content/renderer/pepper/pepper_broker_impl.h"
#include "content/renderer/pepper/pepper_device_enumeration_event_handler.h"
+#include "content/renderer/pepper/pepper_file_system_host.h"
#include "content/renderer/pepper/pepper_hung_plugin_filter.h"
#include "content/renderer/pepper/pepper_in_process_resource_creation.h"
#include "content/renderer/pepper/pepper_platform_audio_input_impl.h"
@@ -254,16 +255,18 @@
webkit::ppapi::PluginInstance* plugin_;
};
+void DoNotifyCloseFile(int file_open_id, base::PlatformFileError /* unused */) {
+ ChildThread::current()->file_system_dispatcher()->NotifyCloseFile(
+ file_open_id);
+}
+
class AsyncOpenFileSystemURLCallbackTranslator
: public fileapi::FileSystemCallbackDispatcher {
public:
AsyncOpenFileSystemURLCallbackTranslator(
const webkit::ppapi::PluginDelegate::AsyncOpenFileSystemURLCallback&
- callback,
- const webkit::ppapi::PluginDelegate::NotifyCloseFileCallback&
- close_file_callback)
- : callback_(callback),
- close_file_callback_(close_file_callback) {
+ callback)
+ : callback_(callback) {
}
virtual ~AsyncOpenFileSystemURLCallbackTranslator() {}
@@ -295,6 +298,7 @@
base::PlatformFile invalid_file = base::kInvalidPlatformFileValue;
callback_.Run(error_code,
base::PassPlatformFile(&invalid_file),
+ quota::kQuotaLimitTypeUnknown,
webkit::ppapi::PluginDelegate::NotifyCloseFileCallback());
}
@@ -302,27 +306,25 @@
NOTREACHED();
}
- virtual void DidOpenFile(base::PlatformFile file) OVERRIDE {
+ virtual void DidOpenFile(base::PlatformFile file,
+ int file_open_id,
+ quota::QuotaLimitType quota_policy) OVERRIDE {
callback_.Run(base::PLATFORM_FILE_OK,
base::PassPlatformFile(&file),
- close_file_callback_);
+ quota_policy,
+ base::Bind(&DoNotifyCloseFile, file_open_id));
// Make sure we won't leak file handle if the requester has died.
if (file != base::kInvalidPlatformFileValue) {
base::FileUtilProxy::Close(
RenderThreadImpl::current()->GetFileThreadMessageLoopProxy(), file,
- close_file_callback_);
+ base::Bind(&DoNotifyCloseFile, file_open_id));
}
}
private:
webkit::ppapi::PluginDelegate::AsyncOpenFileSystemURLCallback callback_;
- webkit::ppapi::PluginDelegate::NotifyCloseFileCallback close_file_callback_;
};
-void DoNotifyCloseFile(const GURL& path, base::PlatformFileError /* unused */) {
- ChildThread::current()->file_system_dispatcher()->NotifyCloseFile(path);
-}
-
void CreateHostForInProcessModule(RenderViewImpl* render_view,
webkit::ppapi::PluginModule* module,
const webkit::WebPluginInfo& webplugin_info) {
@@ -340,6 +342,16 @@
render_view->PpapiPluginCreated(host_impl);
}
+template <typename HostType>
+const HostType* GetRendererResourceHost(
+ PP_Instance instance, PP_Resource resource) {
+ const ppapi::host::PpapiHost* ppapi_host =
+ RendererPpapiHost::GetForPPInstance(instance)->GetPpapiHost();
+ if (!resource || !ppapi_host)
+ return NULL;
+ return static_cast<HostType*>(ppapi_host->GetResourceHost(resource));
+}
+
} // namespace
PepperPluginDelegateImpl::PepperPluginDelegateImpl(RenderViewImpl* render_view)
@@ -830,7 +842,7 @@
// If accelerated compositing of plugins is disabled, fail to create a 3D
// context, because it won't be visible. This allows graceful fallback in the
// modules.
- const webkit_glue::WebPreferences& prefs = render_view_->webkit_preferences();
+ const WebPreferences& prefs = render_view_->webkit_preferences();
if (!prefs.accelerated_compositing_for_plugins_enabled)
return NULL;
return new PlatformContext3DImpl;
@@ -915,9 +927,9 @@
scoped_refptr<PepperBrokerImpl> broker =
static_cast<PepperBrokerImpl*>(plugin_module->GetBroker());
- if (!broker.get()) {
+ if (!broker) {
broker = CreateBroker(plugin_module);
- if (!broker.get())
+ if (!broker)
return NULL;
}
@@ -1016,15 +1028,25 @@
last_mouse_event_target_ = NULL;
}
-bool PepperPluginDelegateImpl::OpenFileSystem(
- const GURL& origin_url,
- fileapi::FileSystemType type,
- long long size,
- fileapi::FileSystemCallbackDispatcher* dispatcher) {
- FileSystemDispatcher* file_system_dispatcher =
- ChildThread::current()->file_system_dispatcher();
- return file_system_dispatcher->OpenFileSystem(
- origin_url, type, size, true /* create */, dispatcher);
+bool PepperPluginDelegateImpl::IsFileSystemOpened(PP_Instance instance,
+ PP_Resource resource) const {
+ const PepperFileSystemHost* host =
+ GetRendererResourceHost<PepperFileSystemHost>(instance, resource);
+ return host && host->IsOpened();
+}
+
+PP_FileSystemType PepperPluginDelegateImpl::GetFileSystemType(
+ PP_Instance instance, PP_Resource resource) const {
+ const PepperFileSystemHost* host =
+ GetRendererResourceHost<PepperFileSystemHost>(instance, resource);
+ return host ? host->GetType() : PP_FILESYSTEMTYPE_INVALID;
+}
+
+GURL PepperPluginDelegateImpl::GetFileSystemRootUrl(
+ PP_Instance instance, PP_Resource resource) const {
+ const PepperFileSystemHost* host =
+ GetRendererResourceHost<PepperFileSystemHost>(instance, resource);
+ return host ? host->GetRootUrl() : GURL();
}
bool PepperPluginDelegateImpl::MakeDirectory(
@@ -1045,6 +1067,14 @@
return file_system_dispatcher->ReadMetadata(path, dispatcher);
}
+bool PepperPluginDelegateImpl::ReadDirectoryEntries(
+ const GURL& path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ FileSystemDispatcher* file_system_dispatcher =
+ ChildThread::current()->file_system_dispatcher();
+ return file_system_dispatcher->ReadDirectory(path, dispatcher);
+}
+
bool PepperPluginDelegateImpl::Touch(
const GURL& path,
const base::Time& last_access_time,
@@ -1115,8 +1145,7 @@
ChildThread::current()->file_system_dispatcher();
return file_system_dispatcher->OpenFile(path, flags,
new AsyncOpenFileSystemURLCallbackTranslator(
- callback,
- base::Bind(&DoNotifyCloseFile, path)));
+ callback));
}
void PepperPluginDelegateImpl::SyncGetFileSystemPlatformPath(
@@ -1355,7 +1384,7 @@
}
void PepperPluginDelegateImpl::SampleGamepads(WebKit::WebGamepads* data) {
- if (!gamepad_shared_memory_reader_.get())
+ if (!gamepad_shared_memory_reader_)
gamepad_shared_memory_reader_.reset(new GamepadSharedMemoryReader);
gamepad_shared_memory_reader_->SampleGamepads(*data);
}
@@ -1377,11 +1406,12 @@
PepperDeviceEnumerationEventHandler::FromPepperDeviceType(type),
GURL());
#else
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(
&PepperDeviceEnumerationEventHandler::OnDevicesEnumerationFailed,
- device_enumeration_event_handler_->AsWeakPtr(), request_id));
+ device_enumeration_event_handler_->AsWeakPtr(),
+ request_id));
#endif
return request_id;
@@ -1394,12 +1424,12 @@
#if defined(ENABLE_WEBRTC)
// Need to post task since this function might be called inside the callback
// of EnumerateDevices.
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(
- &MediaStreamDispatcher::StopEnumerateDevices,
- render_view_->media_stream_dispatcher()->AsWeakPtr(),
- request_id, device_enumeration_event_handler_.get()->AsWeakPtr()));
+ base::Bind(&MediaStreamDispatcher::StopEnumerateDevices,
+ render_view_->media_stream_dispatcher()->AsWeakPtr(),
+ request_id,
+ device_enumeration_event_handler_.get()->AsWeakPtr()));
#endif
}
@@ -1541,10 +1571,11 @@
PepperDeviceEnumerationEventHandler::FromPepperDeviceType(type),
GURL());
#else
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&PepperDeviceEnumerationEventHandler::OnDeviceOpenFailed,
- device_enumeration_event_handler_->AsWeakPtr(), request_id));
+ device_enumeration_event_handler_->AsWeakPtr(),
+ request_id));
#endif
return request_id;
@@ -1619,4 +1650,10 @@
should_close_source);
}
+bool PepperPluginDelegateImpl::IsRunningInProcess(PP_Instance instance) const {
+ RendererPpapiHostImpl* host =
+ RendererPpapiHostImpl::GetForPPInstance(instance);
+ return host && host->IsRunningInProcess();
+}
+
} // namespace content
diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.h b/content/renderer/pepper/pepper_plugin_delegate_impl.h
index d8b2e17..2f178ef 100644
--- a/content/renderer/pepper/pepper_plugin_delegate_impl.h
+++ b/content/renderer/pepper/pepper_plugin_delegate_impl.h
@@ -19,6 +19,7 @@
#include "content/public/renderer/render_view_observer.h"
#include "content/renderer/mouse_lock_dispatcher.h"
#include "content/renderer/render_view_pepper_helper.h"
+#include "ppapi/c/pp_file_info.h"
#include "ppapi/shared_impl/private/ppb_tcp_server_socket_shared.h"
#include "ppapi/shared_impl/private/tcp_socket_private_impl.h"
#include "ui/base/ime/text_input_type.h"
@@ -204,11 +205,13 @@
const GURL& path,
int flags,
const AsyncOpenFileSystemURLCallback& callback) OVERRIDE;
- virtual bool OpenFileSystem(
- const GURL& origin_url,
- fileapi::FileSystemType type,
- long long size,
- fileapi::FileSystemCallbackDispatcher* dispatcher) OVERRIDE;
+ virtual bool IsFileSystemOpened(PP_Instance instance,
+ PP_Resource resource) const OVERRIDE;
+ virtual PP_FileSystemType GetFileSystemType(
+ PP_Instance instance,
+ PP_Resource resource) const OVERRIDE;
+ virtual GURL GetFileSystemRootUrl(PP_Instance instance,
+ PP_Resource resource) const OVERRIDE;
virtual bool MakeDirectory(
const GURL& path,
bool recursive,
@@ -216,6 +219,9 @@
virtual bool Query(
const GURL& path,
fileapi::FileSystemCallbackDispatcher* dispatcher) OVERRIDE;
+ virtual bool ReadDirectoryEntries(
+ const GURL& path,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) OVERRIDE;
virtual bool Touch(
const GURL& path,
const base::Time& last_access_time,
@@ -393,6 +399,8 @@
base::ProcessId target_process_id,
bool should_close_source) const OVERRIDE;
+ virtual bool IsRunningInProcess(PP_Instance instance) const OVERRIDE;
+
// Pointer to the RenderView that owns us.
RenderViewImpl* render_view_;
diff --git a/content/renderer/pepper/pepper_truetype_font_host.cc b/content/renderer/pepper/pepper_truetype_font_host.cc
index c94c1f6..ea9bb12 100644
--- a/content/renderer/pepper/pepper_truetype_font_host.cc
+++ b/content/renderer/pepper/pepper_truetype_font_host.cc
@@ -26,7 +26,7 @@
: ResourceHost(host->GetPpapiHost(), instance, resource),
renderer_ppapi_host_(host),
font_(PepperTrueTypeFont::Create(desc)),
- weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ weak_factory_(this) {
}
PepperTrueTypeFontHost::~PepperTrueTypeFontHost() {
diff --git a/content/renderer/pepper/pepper_truetype_font_linux.cc b/content/renderer/pepper/pepper_truetype_font_linux.cc
index f59df68..2e3326a 100644
--- a/content/renderer/pepper/pepper_truetype_font_linux.cc
+++ b/content/renderer/pepper/pepper_truetype_font_linux.cc
@@ -2,15 +2,158 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/safe_numerics.h"
+#include "base/sys_byteorder.h"
+#include "content/public/common/child_process_sandbox_support_linux.h"
#include "content/renderer/pepper/pepper_truetype_font.h"
+#include "ppapi/c/dev/ppb_truetype_font_dev.h"
+#include "ppapi/c/pp_errors.h"
namespace content {
+namespace {
+
+class PepperTrueTypeFontLinux : public PepperTrueTypeFont {
+ public:
+ explicit PepperTrueTypeFontLinux(
+ const ppapi::proxy::SerializedTrueTypeFontDesc& desc);
+ virtual ~PepperTrueTypeFontLinux() OVERRIDE;
+
+ // PepperTrueTypeFont overrides.
+ virtual bool IsValid() OVERRIDE;
+ virtual int32_t Describe(
+ ppapi::proxy::SerializedTrueTypeFontDesc* desc) OVERRIDE;
+ virtual int32_t GetTableTags(std::vector<uint32_t>* tags) OVERRIDE;
+ virtual int32_t GetTable(uint32_t table_tag,
+ int32_t offset,
+ int32_t max_data_length,
+ std::string* data) OVERRIDE;
+ private:
+ // Save creation parameters here and use these to implement Describe.
+ // TODO(bbudge) Modify content API to return results of font matching and
+ // fallback.
+ ppapi::proxy::SerializedTrueTypeFontDesc desc_;
+ int fd_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperTrueTypeFontLinux);
+};
+
+PepperTrueTypeFontLinux::PepperTrueTypeFontLinux(
+ const ppapi::proxy::SerializedTrueTypeFontDesc& desc) :
+ desc_(desc) {
+ // If no face is provided, convert family to the platform defaults. These
+ // names should be mapped by FontConfig to an appropriate default font.
+ if (desc_.family.empty()) {
+ switch (desc_.generic_family) {
+ case PP_TRUETYPEFONTFAMILY_SERIF:
+ desc_.family = "serif";
+ break;
+ case PP_TRUETYPEFONTFAMILY_SANSSERIF:
+ desc_.family = "sans-serif";
+ break;
+ case PP_TRUETYPEFONTFAMILY_CURSIVE:
+ desc_.family = "cursive";
+ break;
+ case PP_TRUETYPEFONTFAMILY_FANTASY:
+ desc_.family = "fantasy";
+ break;
+ case PP_TRUETYPEFONTFAMILY_MONOSPACE:
+ desc_.family = "monospace";
+ break;
+ }
+ }
+
+ fd_ = content::MatchFontWithFallback(
+ desc_.family.c_str(),
+ desc_.weight >= PP_TRUETYPEFONTWEIGHT_BOLD,
+ desc_.style & PP_TRUETYPEFONTSTYLE_ITALIC,
+ desc_.charset);
+}
+
+PepperTrueTypeFontLinux::~PepperTrueTypeFontLinux() {
+}
+
+bool PepperTrueTypeFontLinux::IsValid() {
+ return fd_ != -1;
+}
+
+int32_t PepperTrueTypeFontLinux::Describe(
+ ppapi::proxy::SerializedTrueTypeFontDesc* desc) {
+ *desc = desc_;
+ return PP_OK;
+}
+
+int32_t PepperTrueTypeFontLinux::GetTableTags(std::vector<uint32_t>* tags) {
+ // Get the 2 byte numTables field at an offset of 4 in the font.
+ uint8_t num_tables_buf[2];
+ size_t output_length = sizeof(num_tables_buf);
+ if (!content::GetFontTable(fd_,
+ 0 /* tag */,
+ 4 /* offset */,
+ reinterpret_cast<uint8_t*>(&num_tables_buf),
+ &output_length))
+ return PP_ERROR_FAILED;
+ DCHECK(output_length == sizeof(num_tables_buf));
+ // Font data is stored in big-endian order.
+ uint16_t num_tables = (num_tables_buf[0] << 8) | num_tables_buf[1];
+
+ // The font has a header, followed by n table entries in its directory.
+ static const size_t kFontHeaderSize = 12;
+ static const size_t kTableEntrySize = 16;
+ output_length = num_tables * kTableEntrySize;
+ scoped_ptr<uint8_t[]> table_entries(new uint8_t[output_length]);
+ // Get the table directory entries, which follow the font header.
+ if (!content::GetFontTable(fd_,
+ 0 /* tag */,
+ kFontHeaderSize /* offset */,
+ table_entries.get(),
+ &output_length))
+ return PP_ERROR_FAILED;
+ DCHECK(output_length == num_tables * kTableEntrySize);
+
+ tags->resize(num_tables);
+ for (uint16_t i = 0; i < num_tables; i++) {
+ uint8_t* entry = table_entries.get() + i * kTableEntrySize;
+ uint32_t tag = static_cast<uint32_t>(entry[0]) << 24 |
+ static_cast<uint32_t>(entry[1]) << 16 |
+ static_cast<uint32_t>(entry[2]) << 8 |
+ static_cast<uint32_t>(entry[3]);
+ (*tags)[i] = tag;
+ }
+
+ return num_tables;
+}
+
+int32_t PepperTrueTypeFontLinux::GetTable(uint32_t table_tag,
+ int32_t offset,
+ int32_t max_data_length,
+ std::string* data) {
+ // Get the size of the font data first.
+ size_t table_size = 0;
+ // Tags are byte swapped on Linux.
+ table_tag = base::ByteSwap(table_tag);
+ if (!content::GetFontTable(fd_, table_tag, offset, NULL, &table_size))
+ return PP_ERROR_FAILED;
+ // Only retrieve as much as the caller requested.
+ table_size = std::min(table_size, static_cast<size_t>(max_data_length));
+ data->resize(table_size);
+ if (!content::GetFontTable(fd_, table_tag, offset,
+ reinterpret_cast<uint8_t*>(&(*data)[0]),
+ &table_size))
+ return PP_ERROR_FAILED;
+
+ return base::checked_numeric_cast<int32_t>(table_size);
+}
+
+} // namespace
+
// static
PepperTrueTypeFont* PepperTrueTypeFont::Create(
const ppapi::proxy::SerializedTrueTypeFontDesc& desc) {
- NOTIMPLEMENTED();
- return 0;
+ return new PepperTrueTypeFontLinux(desc);
}
} // namespace content
+
diff --git a/content/renderer/pepper/pepper_truetype_font_mac.mm b/content/renderer/pepper/pepper_truetype_font_mac.mm
index f59df68..b37c0fe 100644
--- a/content/renderer/pepper/pepper_truetype_font_mac.mm
+++ b/content/renderer/pepper/pepper_truetype_font_mac.mm
@@ -4,13 +4,408 @@
#include "content/renderer/pepper/pepper_truetype_font.h"
+#import <ApplicationServices/ApplicationServices.h>
+
+#include <stdio.h>
+
+#include "base/compiler_specific.h"
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "base/mac/scoped_nsautorelease_pool.h"
+#include "base/safe_numerics.h"
+#include "base/strings/sys_string_conversions.h"
+#include "base/sys_byteorder.h"
+#include "ppapi/c/dev/ppb_truetype_font_dev.h"
+#include "ppapi/c/pp_errors.h"
+
namespace content {
+namespace {
+
+static bool FindFloat(CFDictionaryRef dict, CFStringRef name, float* value) {
+ CFNumberRef num;
+ return
+ CFDictionaryGetValueIfPresent(dict, name,
+ reinterpret_cast<const void**>(&num)) &&
+ CFNumberIsFloatType(num) &&
+ CFNumberGetValue(num, kCFNumberFloatType, value);
+}
+
+float GetMacWeight(PP_TrueTypeFontWeight_Dev weight) {
+ // Map values from NORMAL (400) to HEAVY (900) to the range [0 .. 1], and
+ // values below NORMAL to the range [-0.6 .. 0]. NORMAL should map to 0.
+ float normal = PP_TRUETYPEFONTWEIGHT_NORMAL;
+ float heavy = PP_TRUETYPEFONTWEIGHT_HEAVY;
+ return (weight - normal) / (heavy - normal);
+}
+
+PP_TrueTypeFontWeight_Dev GetPepperWeight(float weight) {
+ // Perform the inverse mapping of GetMacWeight.
+ return static_cast<PP_TrueTypeFontWeight_Dev>(
+ weight * (PP_TRUETYPEFONTWEIGHT_HEAVY - PP_TRUETYPEFONTWEIGHT_NORMAL) +
+ PP_TRUETYPEFONTWEIGHT_NORMAL);
+}
+
+float GetMacWidth(PP_TrueTypeFontWidth_Dev width) {
+ // Map values from NORMAL (4) to ULTRA_EXPANDED (8) to the range [0 .. 1],
+ // and values below NORMAL to the range [-1 .. 0]. Normal should map to 0.
+ float normal = PP_TRUETYPEFONTWIDTH_NORMAL;
+ float ultra_expanded = PP_TRUETYPEFONTWIDTH_ULTRAEXPANDED;
+ return (width - normal) / (ultra_expanded - normal);
+}
+
+PP_TrueTypeFontWidth_Dev GetPepperWidth(float width) {
+ // Perform the inverse mapping of GetMacWeight.
+ return static_cast<PP_TrueTypeFontWidth_Dev>(
+ width *
+ (PP_TRUETYPEFONTWIDTH_ULTRAEXPANDED - PP_TRUETYPEFONTWIDTH_NORMAL) +
+ PP_TRUETYPEFONTWIDTH_NORMAL);
+}
+
+#define MAKE_TABLE_TAG(a, b, c, d) ((a) << 24) + ((b) << 16) + ((c) << 8) + (d)
+
+// TrueType font header and table entry structs. See
+// https://developer.apple.com/fonts/TTRefMan/RM06/Chap6.html
+struct FontHeader {
+ int32_t font_type;
+ uint16_t num_tables;
+ uint16_t search_range;
+ uint16_t entry_selector;
+ uint16_t range_shift;
+};
+static_assert(sizeof(FontHeader) == 12, "FontHeader wrong size");
+
+struct FontDirectoryEntry {
+ uint32_t tag;
+ uint32_t checksum;
+ uint32_t offset;
+ uint32_t logical_length;
+};
+static_assert(sizeof(FontDirectoryEntry) == 16,
+ "FontDirectoryEntry wrong size");
+
+uint32_t CalculateChecksum(char* table, int32_t table_length) {
+ uint32_t sum = 0;
+ uint32_t* current = reinterpret_cast<uint32_t*>(table);
+ uint32_t length = (table_length + 3) / 4;
+ // Raw font data is big-endian.
+ while (length-- > 0)
+ sum += base::NetToHost32(*current++);
+ return sum;
+}
+
+class PepperTrueTypeFontMac : public PepperTrueTypeFont {
+ public:
+ explicit PepperTrueTypeFontMac(
+ const ppapi::proxy::SerializedTrueTypeFontDesc& desc);
+ virtual ~PepperTrueTypeFontMac() OVERRIDE;
+
+ // PepperTrueTypeFont overrides.
+ virtual bool IsValid() OVERRIDE;
+ virtual int32_t Describe(
+ ppapi::proxy::SerializedTrueTypeFontDesc* desc) OVERRIDE;
+ virtual int32_t GetTableTags(std::vector<uint32_t>* tags) OVERRIDE;
+ virtual int32_t GetTable(uint32_t table_tag,
+ int32_t offset,
+ int32_t max_data_length,
+ std::string* data) OVERRIDE;
+ private:
+ virtual int32_t GetEntireFont(int32_t offset,
+ int32_t max_data_length,
+ std::string* data);
+
+ base::mac::ScopedCFTypeRef<CTFontRef> font_ref_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperTrueTypeFontMac);
+};
+
+PepperTrueTypeFontMac::PepperTrueTypeFontMac(
+ const ppapi::proxy::SerializedTrueTypeFontDesc& desc) {
+ // Create attributes and traits dictionaries.
+ base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> attributes_ref(
+ CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks));
+
+ base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> traits_ref(
+ CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks));
+ if (!attributes_ref || !traits_ref)
+ return;
+
+ CFDictionaryAddValue(attributes_ref, kCTFontTraitsAttribute, traits_ref);
+
+ // Use symbolic traits to specify traits when possible.
+ CTFontSymbolicTraits symbolic_traits = 0;
+ if (desc.style & PP_TRUETYPEFONTSTYLE_ITALIC)
+ symbolic_traits |= kCTFontItalicTrait;
+ if (desc.weight == PP_TRUETYPEFONTWEIGHT_BOLD)
+ symbolic_traits |= kCTFontBoldTrait;
+ if (desc.width == PP_TRUETYPEFONTWIDTH_CONDENSED)
+ symbolic_traits |= kCTFontCondensedTrait;
+ else if (desc.width == PP_TRUETYPEFONTWIDTH_EXPANDED)
+ symbolic_traits |= kCTFontExpandedTrait;
+
+ base::mac::ScopedCFTypeRef<CFNumberRef> symbolic_traits_ref(
+ CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberSInt32Type,
+ &symbolic_traits));
+ if (!symbolic_traits_ref)
+ return;
+ CFDictionaryAddValue(traits_ref, kCTFontSymbolicTrait, symbolic_traits_ref);
+
+ // Font family matching doesn't work using family classes in symbolic traits.
+ // Instead, map generic_family to font families that are always available.
+ std::string family(desc.family);
+ if (family.empty()) {
+ switch (desc.generic_family) {
+ case PP_TRUETYPEFONTFAMILY_SERIF:
+ family = "Times";
+ break;
+ case PP_TRUETYPEFONTFAMILY_SANSSERIF:
+ family = "Helvetica";
+ break;
+ case PP_TRUETYPEFONTFAMILY_CURSIVE:
+ family = "Apple Chancery";
+ break;
+ case PP_TRUETYPEFONTFAMILY_FANTASY:
+ family = "Papyrus";
+ break;
+ case PP_TRUETYPEFONTFAMILY_MONOSPACE:
+ family = "Courier";
+ break;
+ }
+ }
+
+ base::mac::ScopedCFTypeRef<CFStringRef> name_ref(
+ base::SysUTF8ToCFStringRef(family));
+ if (name_ref)
+ CFDictionaryAddValue(attributes_ref, kCTFontFamilyNameAttribute, name_ref);
+
+ if (desc.weight != PP_TRUETYPEFONTWEIGHT_NORMAL &&
+ desc.weight != PP_TRUETYPEFONTWEIGHT_BOLD) {
+ float weight = GetMacWeight(desc.weight);
+ base::mac::ScopedCFTypeRef<CFNumberRef> weight_trait_ref(
+ CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberFloat32Type,
+ &weight));
+ if (weight_trait_ref)
+ CFDictionaryAddValue(traits_ref, kCTFontWeightTrait, weight_trait_ref);
+ }
+
+ if (desc.width != PP_TRUETYPEFONTWIDTH_NORMAL &&
+ desc.width != PP_TRUETYPEFONTWIDTH_CONDENSED &&
+ desc.width != PP_TRUETYPEFONTWIDTH_EXPANDED) {
+ float width = GetMacWidth(desc.width);
+ base::mac::ScopedCFTypeRef<CFNumberRef> width_trait_ref(
+ CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberFloat32Type,
+ &width));
+ if (width_trait_ref)
+ CFDictionaryAddValue(traits_ref, kCTFontWidthTrait, width_trait_ref);
+ }
+
+ base::mac::ScopedCFTypeRef<CTFontDescriptorRef> desc_ref(
+ CTFontDescriptorCreateWithAttributes(attributes_ref));
+
+ if (desc_ref)
+ font_ref_.reset(CTFontCreateWithFontDescriptor(desc_ref, 0, NULL));
+}
+
+PepperTrueTypeFontMac::~PepperTrueTypeFontMac() {
+}
+
+bool PepperTrueTypeFontMac::IsValid() {
+ return font_ref_.get() != NULL;
+}
+
+int32_t PepperTrueTypeFontMac::Describe(
+ ppapi::proxy::SerializedTrueTypeFontDesc* desc) {
+ if (!IsValid())
+ return PP_ERROR_FAILED;
+
+ base::mac::ScopedCFTypeRef<CTFontDescriptorRef> desc_ref(
+ CTFontCopyFontDescriptor(font_ref_));
+
+ base::mac::ScopedCFTypeRef<CFStringRef> family_name_ref(
+ base::mac::CFCast<CFStringRef>(CTFontDescriptorCopyAttribute(
+ desc_ref, kCTFontFamilyNameAttribute)));
+ desc->family = base::SysCFStringRefToUTF8(family_name_ref);
+
+ base::mac::ScopedCFTypeRef<CFDictionaryRef> traits_ref(
+ base::mac::CFCast<CFDictionaryRef>(
+ CTFontDescriptorCopyAttribute(desc_ref, kCTFontTraitsAttribute)));
+
+ desc->style = PP_TRUETYPEFONTSTYLE_NORMAL;
+ CTFontSymbolicTraits symbolic_traits(CTFontGetSymbolicTraits(font_ref_));
+ if (symbolic_traits & kCTFontItalicTrait)
+ desc->style = static_cast<PP_TrueTypeFontStyle_Dev>(
+ desc->style | PP_TRUETYPEFONTSTYLE_ITALIC);
+ if (symbolic_traits & kCTFontBoldTrait) {
+ desc->weight = PP_TRUETYPEFONTWEIGHT_BOLD;
+ } else {
+ float weight;
+ if (FindFloat(traits_ref, kCTFontWeightTrait, &weight))
+ desc->weight = GetPepperWeight(weight);
+ }
+ if (symbolic_traits & kCTFontCondensedTrait) {
+ desc->width = PP_TRUETYPEFONTWIDTH_CONDENSED;
+ } else if (symbolic_traits & kCTFontExpandedTrait) {
+ desc->width = PP_TRUETYPEFONTWIDTH_EXPANDED;
+ } else {
+ float width;
+ if (FindFloat(traits_ref, kCTFontWidthTrait, &width))
+ desc->width = GetPepperWidth(width);
+ }
+
+ // Character set isn't supported on Mac.
+ desc->charset = PP_TRUETYPEFONTCHARSET_DEFAULT;
+ return PP_OK;
+}
+
+int32_t PepperTrueTypeFontMac::GetTableTags(std::vector<uint32_t>* tags) {
+ base::mac::ScopedCFTypeRef<CFArrayRef> tag_array(
+ CTFontCopyAvailableTables(font_ref_, kCTFontTableOptionNoOptions));
+ if (!tag_array)
+ return PP_ERROR_FAILED;
+
+ // Items returned by CTFontCopyAvailableTables are not boxed. Whose bright
+ // idea was this?
+ CFIndex length = CFArrayGetCount(tag_array);
+ tags->resize(length);
+ for (CFIndex i = 0; i < length; ++i) {
+ (*tags)[i] =
+ reinterpret_cast<uintptr_t>(CFArrayGetValueAtIndex(tag_array, i));
+ }
+ return length;
+}
+
+int32_t PepperTrueTypeFontMac::GetTable(uint32_t table_tag,
+ int32_t offset,
+ int32_t max_data_length,
+ std::string* data) {
+ if (!table_tag)
+ return GetEntireFont(offset, max_data_length, data);
+
+ base::mac::ScopedCFTypeRef<CFDataRef> table_ref(
+ CTFontCopyTable(font_ref_, static_cast<CTFontTableTag>(table_tag),
+ kCTFontTableOptionNoOptions));
+ if (!table_ref)
+ return PP_ERROR_FAILED;
+
+ CFIndex table_size = CFDataGetLength(table_ref);
+ CFIndex safe_offset =
+ std::min(base::checked_numeric_cast<CFIndex>(offset), table_size);
+ CFIndex safe_length =
+ std::min(table_size - safe_offset,
+ base::checked_numeric_cast<CFIndex>(max_data_length));
+ data->resize(safe_length);
+ CFDataGetBytes(table_ref, CFRangeMake(safe_offset, safe_length),
+ reinterpret_cast<UInt8*>(&(*data)[0]));
+
+ return safe_length;
+}
+
+int32_t PepperTrueTypeFontMac::GetEntireFont(int32_t offset,
+ int32_t max_data_length,
+ std::string* data) {
+ // Reconstruct the font header, table directory, and tables.
+ std::vector<uint32_t> table_tags;
+ int32_t table_count = GetTableTags(&table_tags);
+ if (table_count < 0)
+ return table_count; // PPAPI error code.
+
+ // Allocate enough room for the header and the table directory entries.
+ std::string font(sizeof(FontHeader) +
+ sizeof(FontDirectoryEntry) * table_count, 0);
+ // Map the OS X font type value to a TrueType scalar type.
+ base::mac::ScopedCFTypeRef<CFNumberRef> font_type_ref(
+ base::mac::CFCast<CFNumberRef>(
+ CTFontCopyAttribute(font_ref_, kCTFontFormatAttribute)));
+ int32_t font_type;
+ CFNumberGetValue(font_type_ref, kCFNumberSInt32Type, &font_type);
+ switch (font_type) {
+ case kCTFontFormatOpenTypePostScript:
+ font_type = MAKE_TABLE_TAG('O', 'T', 'T', 'O');
+ break;
+ case kCTFontFormatTrueType:
+ case kCTFontFormatBitmap:
+ font_type = MAKE_TABLE_TAG('t', 'r', 'u', 'e');
+ break;
+ case kCTFontFormatPostScript:
+ font_type = MAKE_TABLE_TAG('t', 'y', 'p', '1');
+ break;
+ case kCTFontFormatOpenTypeTrueType:
+ case kCTFontFormatUnrecognized:
+ default:
+ font_type = MAKE_TABLE_TAG(0, 1, 0, 0);
+ break;
+ }
+
+ // Calculate the rest of the header values.
+ uint16_t num_tables = base::checked_numeric_cast<uint16_t>(table_count);
+ uint16_t entry_selector = 0;
+ uint16_t search_range = 1;
+ while (search_range < num_tables >> 1) {
+ entry_selector++;
+ search_range <<= 1;
+ }
+ search_range <<= 4;
+ uint16_t range_shift = (num_tables << 4) - search_range;
+
+ // Write the header, with values in big-endian order.
+ FontHeader* font_header = reinterpret_cast<FontHeader*>(&font[0]);
+ font_header->font_type = base::HostToNet32(font_type);
+ font_header->num_tables = base::HostToNet16(num_tables);
+ font_header->search_range = base::HostToNet16(search_range);
+ font_header->entry_selector = base::HostToNet16(entry_selector);
+ font_header->range_shift = base::HostToNet16(range_shift);
+
+ for (int32_t i = 0; i < table_count; i++) {
+ // Get the table data.
+ std::string table;
+ int32_t table_size = GetTable(table_tags[i],
+ 0, std::numeric_limits<int32_t>::max(),
+ &table);
+ if (table_size < 0)
+ return table_size; // PPAPI error code.
+
+ // Append it to the font data so far, and zero pad so tables stay aligned.
+ size_t table_offset = font.size();
+ font.append(table);
+ size_t padding = font.size() & 0x3;
+ font.append(padding, 0);
+
+ // Fill in the directory entry for this table.
+ FontDirectoryEntry* entry = reinterpret_cast<FontDirectoryEntry*>(
+ &font[0] + sizeof(FontHeader) + i * sizeof(FontDirectoryEntry));
+ entry->tag = base::HostToNet32(table_tags[i]);
+ entry->checksum = base::HostToNet32(
+ CalculateChecksum(&font[table_offset], table_size));
+ entry->offset = base::HostToNet32(table_offset);
+ entry->logical_length = base::HostToNet32(table_size);
+ // TODO(bbudge) set the 'head' table checksumAdjustment.
+ }
+
+ // Extract a substring if the caller specified an offset or max data length.
+ int32_t font_size = base::checked_numeric_cast<int32_t>(font.size());
+ int32_t safe_offset = std::min(offset, font_size);
+ int32_t safe_length = std::min(font_size - safe_offset, max_data_length);
+ if (safe_offset || safe_length != font_size)
+ font = font.substr(safe_offset, safe_length);
+
+ data->clear();
+ data->swap(font);
+ return safe_length;
+}
+
+} // namespace
+
// static
PepperTrueTypeFont* PepperTrueTypeFont::Create(
const ppapi::proxy::SerializedTrueTypeFontDesc& desc) {
- NOTIMPLEMENTED();
- return 0;
+ return new PepperTrueTypeFontMac(desc);
}
} // namespace content
diff --git a/content/renderer/pepper/pepper_truetype_font_win.cc b/content/renderer/pepper/pepper_truetype_font_win.cc
index f59df68..9134c22 100644
--- a/content/renderer/pepper/pepper_truetype_font_win.cc
+++ b/content/renderer/pepper/pepper_truetype_font_win.cc
@@ -4,13 +4,239 @@
#include "content/renderer/pepper/pepper_truetype_font.h"
+#include <windows.h>
+#include <set>
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/sys_byteorder.h"
+#include "base/utf_string_conversions.h"
+#include "base/win/scoped_hdc.h"
+#include "base/win/scoped_select_object.h"
+#include "content/public/renderer/render_thread.h"
+#include "ppapi/c/dev/ppb_truetype_font_dev.h"
+#include "ppapi/c/pp_errors.h"
+
namespace content {
+namespace {
+
+class PepperTrueTypeFontWin : public PepperTrueTypeFont {
+ public:
+ explicit PepperTrueTypeFontWin(
+ const ppapi::proxy::SerializedTrueTypeFontDesc& desc);
+ virtual ~PepperTrueTypeFontWin();
+
+ // PepperTrueTypeFont overrides.
+ virtual bool IsValid() OVERRIDE;
+ virtual int32_t Describe(
+ ppapi::proxy::SerializedTrueTypeFontDesc* desc) OVERRIDE;
+ virtual int32_t GetTableTags(std::vector<uint32_t>* tags) OVERRIDE;
+ virtual int32_t GetTable(uint32_t table_tag,
+ int32_t offset,
+ int32_t max_data_length,
+ std::string* data) OVERRIDE;
+ private:
+ DWORD GetFontData(HDC hdc,
+ DWORD table,
+ DWORD offset,
+ LPVOID buffer,
+ DWORD length);
+
+ HFONT font_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperTrueTypeFontWin);
+};
+
+PepperTrueTypeFontWin::PepperTrueTypeFontWin(
+ const ppapi::proxy::SerializedTrueTypeFontDesc& desc) {
+ DWORD pitch_and_family = DEFAULT_PITCH;
+ switch (desc.generic_family) {
+ case PP_TRUETYPEFONTFAMILY_SERIF:
+ pitch_and_family |= FF_ROMAN;
+ break;
+ case PP_TRUETYPEFONTFAMILY_SANSSERIF:
+ pitch_and_family |= FF_SWISS;
+ break;
+ case PP_TRUETYPEFONTFAMILY_CURSIVE:
+ pitch_and_family |= FF_SCRIPT;
+ break;
+ case PP_TRUETYPEFONTFAMILY_FANTASY:
+ pitch_and_family |= FF_DECORATIVE;
+ break;
+ case PP_TRUETYPEFONTFAMILY_MONOSPACE:
+ pitch_and_family |= FF_MODERN;
+ break;
+ }
+ // TODO(bbudge) support widths (extended, condensed).
+
+ font_ = CreateFont(0 /* height */,
+ 0 /* width */,
+ 0 /* escapement */,
+ 0 /* orientation */,
+ desc.weight, // our weight enum matches Windows.
+ (desc.style & PP_TRUETYPEFONTSTYLE_ITALIC) ? 1 : 0,
+ 0 /* underline */,
+ 0 /* strikeout */,
+ desc.charset, // our charset enum matches Windows.
+ OUT_OUTLINE_PRECIS, // truetype and other outline fonts
+ CLIP_DEFAULT_PRECIS,
+ DEFAULT_QUALITY,
+ pitch_and_family,
+ UTF8ToUTF16(desc.family).c_str());
+}
+
+PepperTrueTypeFontWin::~PepperTrueTypeFontWin() {
+}
+
+bool PepperTrueTypeFontWin::IsValid() {
+ return font_ != NULL;
+}
+
+int32_t PepperTrueTypeFontWin::Describe(
+ ppapi::proxy::SerializedTrueTypeFontDesc* desc) {
+ LOGFONT font_desc;
+ if (!::GetObject(font_, sizeof(LOGFONT), &font_desc))
+ return PP_ERROR_FAILED;
+
+ switch (font_desc.lfPitchAndFamily & 0xF0) { // Top 4 bits are family.
+ case FF_ROMAN:
+ desc->generic_family = PP_TRUETYPEFONTFAMILY_SERIF;
+ break;
+ case FF_SWISS:
+ desc->generic_family = PP_TRUETYPEFONTFAMILY_SANSSERIF;
+ break;
+ case FF_SCRIPT:
+ desc->generic_family = PP_TRUETYPEFONTFAMILY_CURSIVE;
+ break;
+ case FF_DECORATIVE:
+ desc->generic_family = PP_TRUETYPEFONTFAMILY_FANTASY;
+ break;
+ case FF_MODERN:
+ desc->generic_family = PP_TRUETYPEFONTFAMILY_MONOSPACE;
+ break;
+ }
+
+ desc->style = font_desc.lfItalic ? PP_TRUETYPEFONTSTYLE_ITALIC :
+ PP_TRUETYPEFONTSTYLE_NORMAL;
+ desc->weight = static_cast<PP_TrueTypeFontWeight_Dev>(font_desc.lfWeight);
+ desc->width = PP_TRUETYPEFONTWIDTH_NORMAL;
+ desc->charset =
+ static_cast<PP_TrueTypeFontCharset_Dev>(font_desc.lfCharSet);
+
+ // To get the face name, select the font and query for the name. GetObject
+ // doesn't fill in the name field of the LOGFONT structure.
+ base::win::ScopedCreateDC hdc(::CreateCompatibleDC(NULL));
+ if (hdc) {
+ base::win::ScopedSelectObject select_object(hdc, font_);
+ WCHAR name[LF_FACESIZE];
+ GetTextFace(hdc, LF_FACESIZE, name);
+ desc->family = UTF16ToUTF8(name);
+ }
+ return PP_OK;
+}
+
+DWORD PepperTrueTypeFontWin::GetFontData(HDC hdc,
+ DWORD table,
+ DWORD offset,
+ void* buffer,
+ DWORD length) {
+ // If this is a zero byte read, return a successful result.
+ if (buffer && !length)
+ return 0;
+
+ DWORD result = ::GetFontData(hdc, table, offset, buffer, length);
+ if (result == GDI_ERROR) {
+ // The font may not be cached by the OS, causing an attempt to read it in
+ // the renderer process to fail. Attempt to pre-cache it.
+ LOGFONTW logfont;
+ if (!::GetObject(font_, sizeof(LOGFONTW), &logfont))
+ return GDI_ERROR;
+ content::RenderThread* render_thread = content::RenderThread::Get();
+ if (!render_thread)
+ return GDI_ERROR;
+ render_thread->PreCacheFont(logfont);
+
+ result = ::GetFontData(hdc, table, offset, buffer, length);
+ }
+ return result;
+}
+
+int32_t PepperTrueTypeFontWin::GetTableTags(std::vector<uint32_t>* tags) {
+ base::win::ScopedCreateDC hdc(::CreateCompatibleDC(NULL));
+ if (!hdc)
+ return PP_ERROR_FAILED;
+
+ base::win::ScopedSelectObject select_object(hdc, font_);
+
+ // Get the whole font header.
+ static const DWORD kFontHeaderSize = 12;
+ uint8_t header_buf[kFontHeaderSize];
+ if (GetFontData(hdc, 0, 0, header_buf, kFontHeaderSize) == GDI_ERROR)
+ return PP_ERROR_FAILED;
+
+ // The numTables follows a 4 byte scalerType tag. Font data is stored in
+ // big-endian order.
+ DWORD num_tables = (header_buf[4] << 8) | header_buf[5];
+
+ // The size in bytes of an entry in the table directory.
+ static const DWORD kDirectoryEntrySize = 16;
+ DWORD directory_size = num_tables * kDirectoryEntrySize;
+ scoped_ptr<uint8_t[]> directory(new uint8_t[directory_size]);
+ // Get the table directory entries after the font header.
+ if (GetFontData(hdc, 0 /* tag */, kFontHeaderSize,
+ directory.get(),
+ directory_size) == GDI_ERROR)
+ return PP_ERROR_FAILED;
+
+ tags->resize(num_tables);
+ for (DWORD i = 0; i < num_tables; i++) {
+ const uint8_t* entry = directory.get() + i * kDirectoryEntrySize;
+ uint32_t tag = static_cast<uint32_t>(entry[0]) << 24 |
+ static_cast<uint32_t>(entry[1]) << 16 |
+ static_cast<uint32_t>(entry[2]) << 8 |
+ static_cast<uint32_t>(entry[3]);
+ (*tags)[i] = tag;
+ }
+
+ return num_tables;
+}
+
+int32_t PepperTrueTypeFontWin::GetTable(uint32_t table_tag,
+ int32_t offset,
+ int32_t max_data_length,
+ std::string* data) {
+ base::win::ScopedCreateDC hdc(::CreateCompatibleDC(NULL));
+ if (!hdc)
+ return PP_ERROR_FAILED;
+
+ base::win::ScopedSelectObject select_object(hdc, font_);
+
+ // Tags are byte swapped on Windows.
+ table_tag = base::ByteSwap(table_tag);
+ // Get the size of the font table first.
+ DWORD table_size = GetFontData(hdc, table_tag, 0, NULL, 0);
+ if (table_size == GDI_ERROR)
+ return PP_ERROR_FAILED;
+
+ DWORD safe_offset = std::min(static_cast<DWORD>(offset), table_size);
+ DWORD safe_length = std::min(table_size - safe_offset,
+ static_cast<DWORD>(max_data_length));
+ data->resize(safe_length);
+ table_size = GetFontData(hdc, table_tag, safe_offset,
+ reinterpret_cast<uint8_t*>(&(*data)[0]),
+ safe_length);
+ if (table_size == GDI_ERROR)
+ return PP_ERROR_FAILED;
+ return static_cast<int32_t>(table_size);
+}
+
+} // namespace
+
// static
PepperTrueTypeFont* PepperTrueTypeFont::Create(
const ppapi::proxy::SerializedTrueTypeFontDesc& desc) {
- NOTIMPLEMENTED();
- return 0;
+ return new PepperTrueTypeFontWin(desc);
}
} // namespace content
diff --git a/content/renderer/pepper/pepper_video_capture_host.cc b/content/renderer/pepper/pepper_video_capture_host.cc
index f79a42e..de3642c 100644
--- a/content/renderer/pepper/pepper_video_capture_host.cc
+++ b/content/renderer/pepper/pepper_video_capture_host.cc
@@ -37,8 +37,7 @@
renderer_ppapi_host_(host),
buffer_count_hint_(0),
status_(PP_VIDEO_CAPTURE_STATUS_STOPPED),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- enumeration_helper_(this, this, PP_DEVICETYPE_DEV_VIDEOCAPTURE)) {
+ enumeration_helper_(this, this, PP_DEVICETYPE_DEV_VIDEOCAPTURE) {
}
PepperVideoCaptureHost::~PepperVideoCaptureHost() {
@@ -251,7 +250,7 @@
const std::string& device_id,
const PP_VideoCaptureDeviceInfo_Dev& requested_info,
uint32_t buffer_count) {
- if (platform_video_capture_.get())
+ if (platform_video_capture_)
return PP_ERROR_FAILED;
webkit::ppapi::PluginDelegate* plugin_delegate = GetPluginDelegate();
@@ -323,7 +322,7 @@
}
int32_t PepperVideoCaptureHost::Close() {
- if (!platform_video_capture_.get())
+ if (!platform_video_capture_)
return PP_OK;
StopCapture();
@@ -361,7 +360,7 @@
}
void PepperVideoCaptureHost::DetachPlatformVideoCapture() {
- if (platform_video_capture_.get()) {
+ if (platform_video_capture_) {
platform_video_capture_->DetachEventHandler();
platform_video_capture_ = NULL;
}
diff --git a/content/renderer/pepper/pepper_video_destination_host.cc b/content/renderer/pepper/pepper_video_destination_host.cc
new file mode 100644
index 0000000..13760d6
--- /dev/null
+++ b/content/renderer/pepper/pepper_video_destination_host.cc
@@ -0,0 +1,88 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/pepper/pepper_video_destination_host.h"
+
+#include "content/public/renderer/renderer_ppapi_host.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/host/dispatch_host_message.h"
+#include "ppapi/host/host_message_context.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/thunk/enter.h"
+#include "ppapi/thunk/ppb_image_data_api.h"
+#include "webkit/plugins/ppapi/ppb_image_data_impl.h"
+
+using ppapi::host::HostMessageContext;
+using ppapi::host::ReplyMessageContext;
+
+namespace content {
+
+PepperVideoDestinationHost::PepperVideoDestinationHost(
+ RendererPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource)
+ : ResourceHost(host->GetPpapiHost(), instance, resource),
+ renderer_ppapi_host_(host),
+ weak_factory_(this) {
+}
+
+PepperVideoDestinationHost::~PepperVideoDestinationHost() {
+}
+
+int32_t PepperVideoDestinationHost::OnResourceMessageReceived(
+ const IPC::Message& msg,
+ HostMessageContext* context) {
+ IPC_BEGIN_MESSAGE_MAP(PepperVideoDestinationHost, msg)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDestination_Open,
+ OnHostMsgOpen)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDestination_PutFrame,
+ OnHostMsgPutFrame)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoDestination_Close,
+ OnHostMsgClose)
+ IPC_END_MESSAGE_MAP()
+ return PP_ERROR_FAILED;
+}
+
+int32_t PepperVideoDestinationHost::OnHostMsgOpen(
+ HostMessageContext* context,
+ const std::string& stream_url) {
+ GURL gurl(stream_url);
+ if (!gurl.is_valid())
+ return PP_ERROR_BADARGUMENT;
+ // TODO(ronghuawu) Check that gurl is a valid MediaStream video track URL.
+ // TODO(ronghuawu) Open a MediaStream video track.
+ ReplyMessageContext reply_context = context->MakeReplyMessageContext();
+ reply_context.params.set_result(PP_OK);
+ host()->SendReply(reply_context,
+ PpapiPluginMsg_VideoDestination_OpenReply());
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t PepperVideoDestinationHost::OnHostMsgPutFrame(
+ HostMessageContext* context,
+ const ppapi::HostResource& image_data,
+ PP_TimeTicks timestamp) {
+ ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API> enter(
+ image_data.host_resource(), true);
+ if (enter.failed())
+ return PP_ERROR_BADRESOURCE;
+ webkit::ppapi::PPB_ImageData_Impl* image_resource =
+ static_cast<webkit::ppapi::PPB_ImageData_Impl*>(enter.object());
+
+ if (!webkit::ppapi::PPB_ImageData_Impl::IsImageDataFormatSupported(
+ image_resource->format()))
+ return PP_ERROR_BADARGUMENT;
+
+ // TODO(ronghuawu) write image data to MediaStream video track.
+ return PP_OK;
+}
+
+int32_t PepperVideoDestinationHost::OnHostMsgClose(
+ HostMessageContext* context) {
+ // TODO(ronghuawu) Close the video stream.
+ return PP_OK;
+}
+
+} // namespace content
diff --git a/content/renderer/pepper/pepper_video_destination_host.h b/content/renderer/pepper/pepper_video_destination_host.h
new file mode 100644
index 0000000..54941cb
--- /dev/null
+++ b/content/renderer/pepper/pepper_video_destination_host.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_DESTINATION_HOST_H_
+#define CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_DESTINATION_HOST_H_
+
+#include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/content_export.h"
+#include "ppapi/c/pp_time.h"
+#include "ppapi/host/resource_host.h"
+
+namespace content {
+
+class RendererPpapiHost;
+
+class CONTENT_EXPORT PepperVideoDestinationHost
+ : public ppapi::host::ResourceHost {
+ public:
+ PepperVideoDestinationHost(RendererPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource);
+
+ virtual ~PepperVideoDestinationHost();
+
+ virtual int32_t OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context) OVERRIDE;
+
+ private:
+ int32_t OnHostMsgOpen(ppapi::host::HostMessageContext* context,
+ const std::string& stream_url);
+ int32_t OnHostMsgPutFrame(ppapi::host::HostMessageContext* context,
+ const ppapi::HostResource& image_data,
+ PP_TimeTicks timestamp);
+ int32_t OnHostMsgClose(ppapi::host::HostMessageContext* context);
+
+ RendererPpapiHost* renderer_ppapi_host_;
+
+ base::WeakPtrFactory<PepperVideoDestinationHost> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperVideoDestinationHost);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_DESTINATION_HOST_H_
diff --git a/content/renderer/pepper/pepper_video_source_host.cc b/content/renderer/pepper/pepper_video_source_host.cc
new file mode 100644
index 0000000..1015ea0
--- /dev/null
+++ b/content/renderer/pepper/pepper_video_source_host.cc
@@ -0,0 +1,116 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/pepper/pepper_video_source_host.h"
+
+#include "base/bind.h"
+#include "content/public/renderer/renderer_ppapi_host.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/host/dispatch_host_message.h"
+#include "ppapi/host/host_message_context.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/ppb_image_data_proxy.h"
+#include "ppapi/shared_impl/scoped_pp_resource.h"
+#include "ppapi/thunk/enter.h"
+#include "ppapi/thunk/ppb_image_data_api.h"
+#include "skia/ext/platform_canvas.h"
+#include "webkit/plugins/ppapi/ppb_image_data_impl.h"
+
+using ppapi::host::HostMessageContext;
+using ppapi::host::ReplyMessageContext;
+
+namespace content {
+
+PepperVideoSourceHost::PepperVideoSourceHost(
+ RendererPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource)
+ : ResourceHost(host->GetPpapiHost(), instance, resource),
+ renderer_ppapi_host_(host),
+ weak_factory_(this),
+ last_timestamp_(0) {
+}
+
+PepperVideoSourceHost::~PepperVideoSourceHost() {
+}
+
+int32_t PepperVideoSourceHost::OnResourceMessageReceived(
+ const IPC::Message& msg,
+ HostMessageContext* context) {
+ IPC_BEGIN_MESSAGE_MAP(PepperVideoSourceHost, msg)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoSource_Open,
+ OnHostMsgOpen)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_GetFrame,
+ OnHostMsgGetFrame)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_Close,
+ OnHostMsgClose)
+ IPC_END_MESSAGE_MAP()
+ return PP_ERROR_FAILED;
+}
+
+int32_t PepperVideoSourceHost::OnHostMsgOpen(HostMessageContext* context,
+ const std::string& stream_url) {
+ GURL gurl(stream_url);
+ if (!gurl.is_valid())
+ return PP_ERROR_BADARGUMENT;
+ // TODO(ronghuawu) Check that gurl is a valid MediaStream video track URL.
+ // TODO(ronghuawu) Open a MediaStream video track.
+ ReplyMessageContext reply_context = context->MakeReplyMessageContext();
+ reply_context.params.set_result(PP_OK);
+ host()->SendReply(reply_context, PpapiPluginMsg_VideoSource_OpenReply());
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t PepperVideoSourceHost::OnHostMsgGetFrame(
+ HostMessageContext* context) {
+ ReplyMessageContext reply_context = context->MakeReplyMessageContext();
+ // TODO(ronghuawu) Wait until a frame with timestamp > last_timestamp_ is
+ // available.
+ // Create an image data resource to hold the frame pixels.
+ PP_ImageDataDesc desc;
+ IPC::PlatformFileForTransit image_handle;
+ uint32_t byte_count;
+ ppapi::ScopedPPResource resource(
+ ppapi::ScopedPPResource::PassRef(),
+ ppapi::proxy::PPB_ImageData_Proxy::CreateImageData(
+ pp_instance(),
+ webkit::ppapi::PPB_ImageData_Impl::GetNativeImageDataFormat(),
+ PP_MakeSize(0, 0),
+ false /* init_to_zero */,
+ false /* is_nacl_plugin */,
+ &desc, &image_handle, &byte_count));
+ if (!resource.get())
+ return PP_ERROR_FAILED;
+
+ ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API>
+ enter_resource(resource, false);
+ if (enter_resource.failed())
+ return PP_ERROR_FAILED;
+
+ webkit::ppapi::PPB_ImageData_Impl* image_data =
+ static_cast<webkit::ppapi::PPB_ImageData_Impl*>(enter_resource.object());
+ webkit::ppapi::ImageDataAutoMapper mapper(image_data);
+ if (!mapper.is_valid())
+ return PP_ERROR_FAILED;
+
+ // TODO(ronghuawu) Copy frame pixels to canvas.
+
+ ppapi::HostResource image_data_resource;
+ image_data_resource.SetHostResource(pp_instance(), resource.get());
+ double timestamp = 0;
+ reply_context.params.set_result(PP_OK);
+ host()->SendReply(
+ reply_context,
+ PpapiPluginMsg_VideoSource_GetFrameReply(image_data_resource, timestamp));
+ last_timestamp_ = timestamp;
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t PepperVideoSourceHost::OnHostMsgClose(HostMessageContext* context) {
+ // TODO(ronghuawu) Close the video stream.
+ return PP_OK;
+}
+
+} // namespace content
diff --git a/content/renderer/pepper/pepper_video_source_host.h b/content/renderer/pepper/pepper_video_source_host.h
new file mode 100644
index 0000000..c2a873f
--- /dev/null
+++ b/content/renderer/pepper/pepper_video_source_host.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_SOURCE_HOST_H_
+#define CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_SOURCE_HOST_H_
+
+#include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/content_export.h"
+#include "ppapi/c/pp_time.h"
+#include "ppapi/host/resource_host.h"
+
+namespace content {
+
+class RendererPpapiHost;
+
+class CONTENT_EXPORT PepperVideoSourceHost : public ppapi::host::ResourceHost {
+ public:
+ PepperVideoSourceHost(RendererPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource);
+
+ virtual ~PepperVideoSourceHost();
+
+ virtual int32_t OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context) OVERRIDE;
+
+ private:
+ int32_t OnHostMsgOpen(ppapi::host::HostMessageContext* context,
+ const std::string& stream_url);
+ int32_t OnHostMsgGetFrame(ppapi::host::HostMessageContext* context);
+ int32_t OnHostMsgClose(ppapi::host::HostMessageContext* context);
+
+ RendererPpapiHost* renderer_ppapi_host_;
+
+ base::WeakPtrFactory<PepperVideoSourceHost> weak_factory_;
+
+ PP_TimeTicks last_timestamp_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperVideoSourceHost);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_SOURCE_HOST_H_
diff --git a/content/renderer/pepper/pepper_websocket_host.cc b/content/renderer/pepper/pepper_websocket_host.cc
index d473e84..e2ab15a 100644
--- a/content/renderer/pepper/pepper_websocket_host.cc
+++ b/content/renderer/pepper/pepper_websocket_host.cc
@@ -43,7 +43,7 @@
}
PepperWebSocketHost::~PepperWebSocketHost() {
- if (websocket_.get())
+ if (websocket_)
websocket_->disconnect();
}
@@ -67,7 +67,7 @@
void PepperWebSocketHost::didConnect() {
std::string protocol;
- if (websocket_.get())
+ if (websocket_)
protocol = websocket_->subprotocol().utf8();
connecting_ = false;
connect_reply_.params.set_result(PP_OK);
@@ -169,7 +169,7 @@
}
// Disconnect.
- if (websocket_.get())
+ if (websocket_)
websocket_->disconnect();
}
@@ -233,7 +233,7 @@
WebDocument document = container->element().document();
websocket_.reset(WebSocket::create(document, this));
DCHECK(websocket_.get());
- if (!websocket_.get())
+ if (!websocket_)
return PP_ERROR_NOTSUPPORTED;
// Set receiving binary object type.
@@ -249,7 +249,7 @@
ppapi::host::HostMessageContext* context,
int32_t code,
const std::string& reason) {
- if (!websocket_.get())
+ if (!websocket_)
return PP_ERROR_FAILED;
close_reply_ = context->MakeReplyMessageContext();
initiating_close_ = true;
@@ -261,7 +261,7 @@
int32_t PepperWebSocketHost::OnHostMsgSendText(
ppapi::host::HostMessageContext* context,
const std::string& message) {
- if (websocket_.get()) {
+ if (websocket_) {
WebString web_message = WebString::fromUTF8(message);
websocket_->sendText(web_message);
}
@@ -282,7 +282,7 @@
int32_t PepperWebSocketHost::OnHostMsgFail(
ppapi::host::HostMessageContext* context,
const std::string& message) {
- if (websocket_.get())
+ if (websocket_)
websocket_->fail(WebString::fromUTF8(message));
return PP_OK;
}
diff --git a/content/renderer/pepper/renderer_ppapi_host_impl.cc b/content/renderer/pepper/renderer_ppapi_host_impl.cc
index 50b4fc7..4971d51 100644
--- a/content/renderer/pepper/renderer_ppapi_host_impl.cc
+++ b/content/renderer/pepper/renderer_ppapi_host_impl.cc
@@ -6,6 +6,8 @@
#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/process_util.h"
+#include "content/common/sandbox_util.h"
#include "content/renderer/pepper/pepper_graphics_2d_host.h"
#include "content/renderer/pepper/pepper_in_process_resource_creation.h"
#include "content/renderer/pepper/pepper_in_process_router.h"
@@ -245,9 +247,13 @@
base::PlatformFile handle,
bool should_close_source) {
if (!dispatcher_) {
- if (should_close_source)
- base::ClosePlatformFile(handle);
- return IPC::InvalidPlatformFileForTransit();
+ DCHECK(is_running_in_process_);
+ // Duplicate the file handle for in process mode so this function
+ // has the same semantics for both in process mode and out of
+ // process mode (i.e., the remote side must cloes the handle).
+ return BrokerGetFileHandleForProcess(handle,
+ base::GetCurrentProcId(),
+ should_close_source);
}
return dispatcher_->ShareHandleWithRemote(handle, should_close_source);
}
diff --git a/content/renderer/plugin_channel_host.cc b/content/renderer/plugin_channel_host.cc
index dfdffb0..f9b1829 100644
--- a/content/renderer/plugin_channel_host.cc
+++ b/content/renderer/plugin_channel_host.cc
@@ -29,7 +29,7 @@
#if defined(OS_MACOSX)
#include "base/debug/crash_logging.h"
#include "base/debug/stack_trace.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
namespace {
diff --git a/content/renderer/render_process_impl.cc b/content/renderer/render_process_impl.cc
index bbcb312..8256947 100644
--- a/content/renderer/render_process_impl.cc
+++ b/content/renderer/render_process_impl.cc
@@ -37,9 +37,9 @@
namespace content {
RenderProcessImpl::RenderProcessImpl()
- : ALLOW_THIS_IN_INITIALIZER_LIST(shared_mem_cache_cleaner_(
+ : shared_mem_cache_cleaner_(
FROM_HERE, base::TimeDelta::FromSeconds(5),
- this, &RenderProcessImpl::ClearTransportDIBCache)),
+ this, &RenderProcessImpl::ClearTransportDIBCache),
transport_dib_next_sequence_number_(0),
enabled_bindings_(0) {
in_process_plugins_ = InProcessPlugins();
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index c35a2c5..2896a54 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -84,7 +84,6 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDatabase.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/WebIDBFactory.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNetworkStateNotifier.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h"
@@ -180,7 +179,7 @@
return ".docs";
if (host == "plus.google.com")
return ".plus";
- return "";
+ return std::string();
}
void* CreateHistogram(
@@ -207,12 +206,12 @@
}
#if defined(ENABLE_WEBRTC)
-const unsigned char* GetCategoryEnabled(const char* name) {
- return TRACE_EVENT_API_GET_CATEGORY_ENABLED(name);
+const unsigned char* GetCategoryGroupEnabled(const char* category_group) {
+ return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group);
}
void AddTraceEvent(char phase,
- const unsigned char* category_enabled,
+ const unsigned char* category_group_enabled,
const char* name,
unsigned long long id,
int num_args,
@@ -220,8 +219,9 @@
const unsigned char* arg_types,
const unsigned long long* arg_values,
unsigned char flags) {
- TRACE_EVENT_API_ADD_TRACE_EVENT(phase, category_enabled, name, id, num_args,
- arg_names, arg_types, arg_values, flags);
+ TRACE_EVENT_API_ADD_TRACE_EVENT(phase, category_group_enabled, name, id,
+ num_args, arg_names, arg_types, arg_values,
+ NULL, flags);
}
#endif
@@ -363,7 +363,7 @@
AddFilter(db_message_filter_.get());
#if defined(ENABLE_WEBRTC)
- webrtc::SetupEventTracer(&GetCategoryEnabled, &AddTraceEvent);
+ webrtc::SetupEventTracer(&GetCategoryGroupEnabled, &AddTraceEvent);
peer_connection_tracker_.reset(new PeerConnectionTracker());
AddObserver(peer_connection_tracker_.get());
@@ -405,15 +405,18 @@
}
RenderThreadImpl::~RenderThreadImpl() {
+}
+
+void RenderThreadImpl::Shutdown() {
FOR_EACH_OBSERVER(
RenderProcessObserver, observers_, OnRenderProcessShutdown());
// Wait for all databases to be closed.
- if (web_database_observer_impl_.get())
+ if (web_database_observer_impl_)
web_database_observer_impl_->WaitForAllDatabasesToClose();
// Shutdown in reverse of the initialization order.
- if (devtools_agent_message_filter_.get()) {
+ if (devtools_agent_message_filter_) {
RemoveFilter(devtools_agent_message_filter_.get());
devtools_agent_message_filter_ = NULL;
}
@@ -430,20 +433,21 @@
db_message_filter_ = NULL;
// Shutdown the file thread if it's running.
- if (file_thread_.get())
+ if (file_thread_)
file_thread_->Stop();
- if (compositor_output_surface_filter_.get()) {
+ if (compositor_output_surface_filter_) {
RemoveFilter(compositor_output_surface_filter_.get());
compositor_output_surface_filter_ = NULL;
}
- if (input_handler_manager_.get()) {
+ compositor_thread_.reset();
+ if (input_handler_manager_) {
RemoveFilter(input_handler_manager_->GetMessageFilter());
input_handler_manager_.reset();
}
- if (webkit_platform_support_.get())
+ if (webkit_platform_support_)
WebKit::shutdown();
lazy_tls.Pointer()->Set(NULL);
@@ -501,10 +505,10 @@
if (notify_webkit_of_modal_loop)
WebView::willEnterModalLoop();
- RenderWidget* widget =
- static_cast<RenderWidget*>(ResolveRoute(msg->routing_id()));
- if (widget) {
- render_view_id = widget->routing_id();
+ RenderViewImpl* render_view =
+ RenderViewImpl::FromRoutingID(msg->routing_id());
+ if (render_view) {
+ render_view_id = msg->routing_id();
PluginChannelHost::Broadcast(
new PluginMsg_SignalModalDialogEvent(render_view_id));
}
@@ -618,8 +622,100 @@
ScheduleIdleHandler(kLongIdleHandlerDelayMs);
}
+static void AdjustRuntimeFeatureDefaultsForPlatform() {
+#if defined(OS_ANDROID) && !defined(GOOGLE_TV)
+ WebRuntimeFeatures::enableMediaSource(false);
+#endif
+
+#if defined(OS_ANDROID)
+ WebRuntimeFeatures::enableWebAudio(false);
+ // Web Speech API Speech recognition is not implemented on Android yet.
+ WebRuntimeFeatures::enableScriptedSpeech(false);
+ // Android does not support the Gamepad API.
+ WebRuntimeFeatures::enableGamepad(false);
+ // input[type=week] in Android is incomplete. crbug.com/135938
+ WebRuntimeFeatures::enableInputTypeWeek(false);
+#endif
+}
+
+static void AdjustRuntimeFeaturesFromArgs(const CommandLine& command_line) {
+ if (command_line.HasSwitch(switches::kDisableDatabases))
+ WebRuntimeFeatures::enableDatabase(false);
+
+ if (command_line.HasSwitch(switches::kDisableApplicationCache))
+ WebRuntimeFeatures::enableApplicationCache(false);
+
+ if (command_line.HasSwitch(switches::kDisableDesktopNotifications))
+ WebRuntimeFeatures::enableNotifications(false);
+
+ if (command_line.HasSwitch(switches::kDisableLocalStorage))
+ WebRuntimeFeatures::enableLocalStorage(false);
+
+ if (command_line.HasSwitch(switches::kDisableSessionStorage))
+ WebRuntimeFeatures::enableSessionStorage(false);
+
+ if (command_line.HasSwitch(switches::kDisableGeolocation))
+ WebRuntimeFeatures::enableGeolocation(false);
+
+#if !defined(OS_ANDROID) || defined(GOOGLE_TV)
+ if (command_line.HasSwitch(switches::kDisableMediaSource))
+ WebRuntimeFeatures::enableMediaSource(false);
+#endif
+
+#if defined(OS_ANDROID)
+ if (command_line.HasSwitch(switches::kDisableWebRTC))
+ WebRuntimeFeatures::enableMediaStream(false);
+#endif
+
+#if defined(OS_ANDROID)
+ if (command_line.HasSwitch(switches::kDisableWebRTC))
+ WebRuntimeFeatures::enablePeerConnection(false);
+#endif
+
+ if (command_line.HasSwitch(switches::kDisableFullScreen))
+ WebRuntimeFeatures::enableFullScreenAPI(false);
+
+ if (command_line.HasSwitch(switches::kDisableEncryptedMedia))
+ WebRuntimeFeatures::enableEncryptedMedia(false);
+
+#if defined(OS_ANDROID)
+ if (command_line.HasSwitch(switches::kEnableWebAudio))
+ WebRuntimeFeatures::enableWebAudio(true);
+#else
+ if (command_line.HasSwitch(switches::kDisableWebAudio))
+ WebRuntimeFeatures::enableWebAudio(false);
+#endif
+
+ if (command_line.HasSwitch(switches::kEnableWebMIDI))
+ WebRuntimeFeatures::enableWebMIDI(true);
+
+ if (command_line.HasSwitch(switches::kEnableDeviceMotion))
+ WebRuntimeFeatures::enableDeviceMotion(true);
+
+ if (command_line.HasSwitch(switches::kDisableDeviceOrientation))
+ WebRuntimeFeatures::enableDeviceOrientation(false);
+
+ if (command_line.HasSwitch(switches::kDisableSpeechInput))
+ WebRuntimeFeatures::enableSpeechInput(false);
+
+ if (command_line.HasSwitch(switches::kDisableFileSystem))
+ WebRuntimeFeatures::enableFileSystem(false);
+
+ if (command_line.HasSwitch(switches::kDisableJavaScriptI18NAPI))
+ WebRuntimeFeatures::enableJavaScriptI18NAPI(false);
+
+ if (command_line.HasSwitch(switches::kEnableExperimentalWebSocket))
+ WebRuntimeFeatures::enableExperimentalWebSocket(true);
+
+ if (command_line.HasSwitch(switches::kEnableExperimentalCanvasFeatures))
+ WebRuntimeFeatures::enableExperimentalCanvasFeatures(true);
+
+ if (command_line.HasSwitch(switches::kEnableSpeechSynthesis))
+ WebRuntimeFeatures::enableSpeechSynthesis(true);
+}
+
void RenderThreadImpl::EnsureWebKitInitialized() {
- if (webkit_platform_support_.get())
+ if (webkit_platform_support_)
return;
webkit_platform_support_.reset(new RendererWebKitPlatformSupportImpl);
@@ -633,7 +729,7 @@
bool enable = command_line.HasSwitch(switches::kEnableThreadedCompositing);
if (enable) {
- MessageLoop* override_loop =
+ base::MessageLoop* override_loop =
GetContentClient()->renderer()->OverrideCompositorMessageLoop();
if (override_loop) {
compositor_message_loop_proxy_ = override_loop->message_loop_proxy();
@@ -672,104 +768,24 @@
new WebDatabaseObserverImpl(sync_message_filter()));
WebKit::WebDatabase::setObserver(web_database_observer_impl_.get());
- WebRuntimeFeatures::enableSockets(
- !command_line.HasSwitch(switches::kDisableWebSockets));
+ WebRuntimeFeatures::enableStableFeatures(true);
- WebRuntimeFeatures::enableDatabase(
- !command_line.HasSwitch(switches::kDisableDatabases));
+ if (command_line.HasSwitch(switches::kEnableExperimentalWebKitFeatures))
+ WebRuntimeFeatures::enableExperimentalFeatures(true);
- WebRuntimeFeatures::enableDataTransferItems(
- !command_line.HasSwitch(switches::kDisableDataTransferItems));
+ AdjustRuntimeFeatureDefaultsForPlatform();
+ AdjustRuntimeFeaturesFromArgs(command_line);
- WebRuntimeFeatures::enableApplicationCache(
- !command_line.HasSwitch(switches::kDisableApplicationCache));
+ // Enabled by default for testing.
+ // TODO(urvang): Go back to using the command-line option after a few days.
+ // https://code.google.com/p/chromium/issues/detail?id=234437
+ WebRuntimeFeatures::enableWebPInAcceptHeader(true);
- WebRuntimeFeatures::enableNotifications(
- !command_line.HasSwitch(switches::kDisableDesktopNotifications));
-
- WebRuntimeFeatures::enableLocalStorage(
- !command_line.HasSwitch(switches::kDisableLocalStorage));
- WebRuntimeFeatures::enableSessionStorage(
- !command_line.HasSwitch(switches::kDisableSessionStorage));
-
- WebRuntimeFeatures::enableIndexedDatabase(true);
-
- WebRuntimeFeatures::enableGeolocation(
- !command_line.HasSwitch(switches::kDisableGeolocation));
-
- WebKit::WebRuntimeFeatures::enableMediaSource(
- !command_line.HasSwitch(switches::kDisableMediaSource));
-
- WebRuntimeFeatures::enableMediaPlayer(
- media::IsMediaLibraryInitialized());
-
-#if defined(OS_ANDROID)
- WebKit::WebRuntimeFeatures::enableMediaStream(
- !command_line.HasSwitch(switches::kDisableWebRTC));
- WebKit::WebRuntimeFeatures::enablePeerConnection(
- !command_line.HasSwitch(switches::kDisableWebRTC));
-#else
- WebKit::WebRuntimeFeatures::enableMediaStream(true);
- WebKit::WebRuntimeFeatures::enablePeerConnection(true);
-#endif
-
- WebKit::WebRuntimeFeatures::enableFullScreenAPI(
- !command_line.HasSwitch(switches::kDisableFullScreen));
-
- WebKit::WebRuntimeFeatures::enableEncryptedMedia(
- !command_line.HasSwitch(switches::kDisableEncryptedMedia));
-
-#if defined(OS_ANDROID)
- WebRuntimeFeatures::enableWebAudio(
- command_line.HasSwitch(switches::kEnableWebAudio) &&
- media::IsMediaLibraryInitialized());
-#else
- WebRuntimeFeatures::enableWebAudio(
- !command_line.HasSwitch(switches::kDisableWebAudio) &&
- media::IsMediaLibraryInitialized());
-#endif
-
- WebRuntimeFeatures::enableDeviceMotion(
- command_line.HasSwitch(switches::kEnableDeviceMotion));
-
- WebRuntimeFeatures::enableDeviceOrientation(
- !command_line.HasSwitch(switches::kDisableDeviceOrientation));
-
- WebRuntimeFeatures::enableSpeechInput(
- !command_line.HasSwitch(switches::kDisableSpeechInput));
-
-#if defined(OS_ANDROID)
- // Web Speech API Speech recognition is not implemented on Android yet.
- WebRuntimeFeatures::enableScriptedSpeech(false);
-#else
- WebRuntimeFeatures::enableScriptedSpeech(true);
-#endif
-
- WebRuntimeFeatures::enableFileSystem(
- !command_line.HasSwitch(switches::kDisableFileSystem));
-
- WebRuntimeFeatures::enableJavaScriptI18NAPI(
- !command_line.HasSwitch(switches::kDisableJavaScriptI18NAPI));
-
- WebRuntimeFeatures::enableGamepad(true);
-
- WebRuntimeFeatures::enableQuota(true);
-
- WebRuntimeFeatures::enableShadowDOM(true);
-
- if (command_line.HasSwitch(switches::kEnableExperimentalWebKitFeatures)) {
- WebRuntimeFeatures::enableStyleScoped(true);
- WebRuntimeFeatures::enableCustomDOMElements(true);
- WebRuntimeFeatures::enableCSSExclusions(true);
- WebRuntimeFeatures::enableExperimentalContentSecurityPolicyFeatures(true);
- WebRuntimeFeatures::enableCSSRegions(true);
- WebRuntimeFeatures::enableDialogElement(true);
- WebRuntimeFeatures::enableFontLoadEvents(true);
+ if (!media::IsMediaLibraryInitialized()) {
+ WebRuntimeFeatures::enableMediaPlayer(false);
+ WebRuntimeFeatures::enableWebAudio(false);
}
- WebRuntimeFeatures::enableSeamlessIFrames(
- command_line.HasSwitch(switches::kEnableExperimentalWebKitFeatures));
-
FOR_EACH_OBSERVER(RenderProcessObserver, observers_, WebKitInitialized());
devtools_agent_message_filter_ = new DevToolsAgentFilter();
@@ -802,7 +818,7 @@
new ChildProcessHostMsg_SyncAllocateSharedMemory(size, &handle);
// Allow calling this from the compositor thread.
- if (MessageLoop::current() == message_loop())
+ if (base::MessageLoop::current() == message_loop())
success = ChildThread::Send(message);
else
success = sync_message_filter()->Send(message);
@@ -923,7 +939,7 @@
void RenderThreadImpl::OnGpuVDAContextLoss() {
RenderThreadImpl* self = RenderThreadImpl::current();
DCHECK(self);
- if (!self->gpu_vda_context3d_.get())
+ if (!self->gpu_vda_context3d_)
return;
if (self->compositor_message_loop_proxy()) {
self->compositor_message_loop_proxy()->DeleteSoon(
@@ -935,12 +951,12 @@
WebGraphicsContext3DCommandBufferImpl*
RenderThreadImpl::GetGpuVDAContext3D() {
- if (!gpu_vda_context3d_.get()) {
+ if (!gpu_vda_context3d_) {
gpu_vda_context3d_.reset(
WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
this, WebKit::WebGraphicsContext3D::Attributes(),
GURL("chrome://gpu/RenderThreadImpl::GetGpuVDAContext3D")));
- if (gpu_vda_context3d_.get())
+ if (gpu_vda_context3d_)
gpu_vda_context3d_->setContextLostCallback(context_lost_cb_.get());
}
return gpu_vda_context3d_.get();
@@ -990,7 +1006,7 @@
}
AudioRendererMixerManager* RenderThreadImpl::GetAudioRendererMixerManager() {
- if (!audio_renderer_mixer_manager_.get()) {
+ if (!audio_renderer_mixer_manager_) {
audio_renderer_mixer_manager_.reset(new AudioRendererMixerManager(
GetAudioHardwareConfig()));
}
@@ -1045,7 +1061,8 @@
}
bool RenderThreadImpl::IsIOThread() {
- return MessageLoop::current() == ChildProcess::current()->io_message_loop();
+ return base::MessageLoop::current() ==
+ ChildProcess::current()->io_message_loop();
}
MessageLoop* RenderThreadImpl::GetMainLoop() {
@@ -1080,7 +1097,7 @@
&route_id);
// Allow calling this from the compositor thread.
- if (MessageLoop::current() == message_loop())
+ if (base::MessageLoop::current() == message_loop())
ChildThread::Send(message);
else
sync_message_filter()->Send(message);
@@ -1169,7 +1186,7 @@
CauseForGpuLaunch cause_for_gpu_launch) {
TRACE_EVENT0("gpu", "RenderThreadImpl::EstablishGpuChannelSync");
- if (gpu_channel_.get()) {
+ if (gpu_channel_) {
// Do nothing if we already have a GPU channel or are already
// establishing one.
if (gpu_channel_->state() == GpuChannelHost::kUnconnected ||
@@ -1231,7 +1248,7 @@
MediaStreamDependencyFactory*
RenderThreadImpl::GetMediaStreamDependencyFactory() {
#if defined(ENABLE_WEBRTC)
- if (!media_stream_factory_.get()) {
+ if (!media_stream_factory_) {
media_stream_factory_.reset(new MediaStreamDependencyFactory(
vc_manager_, p2p_socket_dispatcher_));
}
@@ -1240,7 +1257,7 @@
}
GpuChannelHost* RenderThreadImpl::GetGpuChannel() {
- if (!gpu_channel_.get())
+ if (!gpu_channel_)
return NULL;
if (gpu_channel_->state() != GpuChannelHost::kConnected)
@@ -1278,8 +1295,8 @@
scoped_refptr<base::MessageLoopProxy>
RenderThreadImpl::GetFileThreadMessageLoopProxy() {
- DCHECK(message_loop() == MessageLoop::current());
- if (!file_thread_.get()) {
+ DCHECK(message_loop() == base::MessageLoop::current());
+ if (!file_thread_) {
file_thread_.reset(new base::Thread("Renderer::FILE"));
file_thread_->Start();
}
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index 9eed9b8..be9b176 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -107,6 +107,7 @@
// Constructor that's used when running in single process mode.
explicit RenderThreadImpl(const std::string& channel_name);
virtual ~RenderThreadImpl();
+ virtual void Shutdown() OVERRIDE;
// When initializing WebKit, ensure that any schemes needed for the content
// module are registered properly. Static to allow sharing with tests.
@@ -114,7 +115,7 @@
// RenderThread implementation:
virtual bool Send(IPC::Message* msg) OVERRIDE;
- virtual MessageLoop* GetMessageLoop() OVERRIDE;
+ virtual base::MessageLoop* GetMessageLoop() OVERRIDE;
virtual IPC::SyncChannel* GetChannel() OVERRIDE;
virtual std::string GetLocale() OVERRIDE;
virtual IPC::SyncMessageFilter* GetSyncMessageFilter() OVERRIDE;
@@ -157,7 +158,7 @@
// GpuChannelHostFactory implementation:
virtual bool IsMainThread() OVERRIDE;
virtual bool IsIOThread() OVERRIDE;
- virtual MessageLoop* GetMainLoop() OVERRIDE;
+ virtual base::MessageLoop* GetMainLoop() OVERRIDE;
virtual scoped_refptr<base::MessageLoopProxy> GetIOLoopProxy() OVERRIDE;
virtual base::WaitableEvent* GetShutDownEvent() OVERRIDE;
virtual scoped_ptr<base::SharedMemory> AllocateSharedMemory(
diff --git a/content/renderer/render_thread_impl_browsertest.cc b/content/renderer/render_thread_impl_browsertest.cc
new file mode 100644
index 0000000..d8dc67b
--- /dev/null
+++ b/content/renderer/render_thread_impl_browsertest.cc
@@ -0,0 +1,62 @@
+// 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/command_line.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/renderer/content_renderer_client.h"
+#include "content/renderer/render_process_impl.h"
+#include "content/renderer/render_thread_impl.h"
+#include "content/test/mock_render_process.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+class RenderThreadImplBrowserTest : public testing::Test {
+ public:
+ virtual ~RenderThreadImplBrowserTest() {}
+};
+
+class DummyListener : public IPC::Listener {
+ public:
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
+ return true;
+ }
+};
+
+void CheckRenderThreadInputHandlerManager(RenderThreadImpl* thread) {
+ ASSERT_TRUE(thread->input_handler_manager());
+}
+
+// Check that InputHandlerManager outlives compositor thread because it uses
+// raw pointers to post tasks.
+TEST_F(RenderThreadImplBrowserTest,
+ InputHandlerManagerDestroyedAfterCompositorThread) {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableThreadedCompositing);
+
+ ContentRendererClient content_renderer_client;
+ SetRendererClientForTesting(&content_renderer_client);
+ base::MessageLoopForIO message_loop_;
+
+ std::string channel_id = IPC::Channel::GenerateVerifiedChannelID(
+ std::string());
+ DummyListener dummy_listener;
+ IPC::Channel channel(channel_id, IPC::Channel::MODE_SERVER, &dummy_listener);
+ ASSERT_TRUE(channel.Connect());
+
+ scoped_ptr<MockRenderProcess> mock_process(new MockRenderProcess);
+ // Owned by mock_process.
+ RenderThreadImpl* thread = new RenderThreadImpl(channel_id);
+ thread->EnsureWebKitInitialized();
+
+ ASSERT_TRUE(thread->input_handler_manager());
+
+ thread->compositor_message_loop_proxy()->PostTask(
+ FROM_HERE,
+ base::Bind(&CheckRenderThreadInputHandlerManager, thread));
+}
+
+} // namespace
+} // namespace content
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index 6e39cc0..35b784b 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -12,6 +12,8 @@
#include "content/public/browser/web_ui_controller_factory.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/url_constants.h"
+#include "content/public/renderer/document_state.h"
+#include "content/public/renderer/navigation_state.h"
#include "content/public/test/render_view_test.h"
#include "content/renderer/render_view_impl.h"
#include "content/shell/shell_content_browser_client.h"
@@ -315,13 +317,16 @@
WebUITestWebUIControllerFactory factory;
WebUIControllerFactory::RegisterFactory(&factory);
+ DocumentState state;
+ state.set_navigation_state(NavigationState::CreateContentInitiated());
+
// Navigations to normal HTTP URLs can be handled locally.
WebKit::WebURLRequest request(GURL("http://foo.com"));
WebKit::WebNavigationPolicy policy = view()->decidePolicyForNavigation(
GetMainFrame(),
+ &state,
request,
WebKit::WebNavigationTypeLinkClicked,
- WebKit::WebNode(),
WebKit::WebNavigationPolicyCurrentTab,
false);
EXPECT_EQ(WebKit::WebNavigationPolicyCurrentTab, policy);
@@ -331,9 +336,9 @@
form_request.setHTTPMethod("POST");
policy = view()->decidePolicyForNavigation(
GetMainFrame(),
+ &state,
form_request,
WebKit::WebNavigationTypeFormSubmitted,
- WebKit::WebNode(),
WebKit::WebNavigationPolicyCurrentTab,
false);
EXPECT_EQ(WebKit::WebNavigationPolicyIgnore, policy);
@@ -342,9 +347,9 @@
WebKit::WebURLRequest popup_request(GURL("chrome://foo"));
policy = view()->decidePolicyForNavigation(
GetMainFrame(),
+ &state,
popup_request,
WebKit::WebNavigationTypeLinkClicked,
- WebKit::WebNode(),
WebKit::WebNavigationPolicyNewForegroundTab,
false);
EXPECT_EQ(WebKit::WebNavigationPolicyIgnore, policy);
@@ -354,13 +359,16 @@
// Enable bindings to simulate a WebUI view.
view()->OnAllowBindings(BINDINGS_POLICY_WEB_UI);
+ DocumentState state;
+ state.set_navigation_state(NavigationState::CreateContentInitiated());
+
// Navigations to normal HTTP URLs will be sent to browser process.
WebKit::WebURLRequest request(GURL("http://foo.com"));
WebKit::WebNavigationPolicy policy = view()->decidePolicyForNavigation(
GetMainFrame(),
+ &state,
request,
WebKit::WebNavigationTypeLinkClicked,
- WebKit::WebNode(),
WebKit::WebNavigationPolicyCurrentTab,
false);
EXPECT_EQ(WebKit::WebNavigationPolicyIgnore, policy);
@@ -369,9 +377,9 @@
WebKit::WebURLRequest webui_request(GURL("chrome://foo"));
policy = view()->decidePolicyForNavigation(
GetMainFrame(),
+ &state,
webui_request,
WebKit::WebNavigationTypeLinkClicked,
- WebKit::WebNode(),
WebKit::WebNavigationPolicyCurrentTab,
false);
EXPECT_EQ(WebKit::WebNavigationPolicyIgnore, policy);
@@ -381,9 +389,9 @@
data_request.setHTTPMethod("POST");
policy = view()->decidePolicyForNavigation(
GetMainFrame(),
+ &state,
data_request,
WebKit::WebNavigationTypeFormSubmitted,
- WebKit::WebNode(),
WebKit::WebNavigationPolicyCurrentTab,
false);
EXPECT_EQ(WebKit::WebNavigationPolicyIgnore, policy);
@@ -398,9 +406,9 @@
RenderViewImpl* new_view = RenderViewImpl::FromWebView(new_web_view);
policy = new_view->decidePolicyForNavigation(
new_web_view->mainFrame(),
+ &state,
popup_request,
WebKit::WebNavigationTypeLinkClicked,
- WebKit::WebNode(),
WebKit::WebNavigationPolicyNewForegroundTab,
false);
EXPECT_EQ(WebKit::WebNavigationPolicyIgnore, policy);
@@ -1395,6 +1403,15 @@
error.reason = net::ERR_FILE_NOT_FOUND;
error.unreachableURL = GURL("http://foo");
WebFrame* web_frame = GetMainFrame();
+
+ // Start a load that will reach provisional state synchronously,
+ // but won't complete synchronously.
+ ViewMsg_Navigate_Params params;
+ params.page_id = -1;
+ params.navigation_type = ViewMsg_Navigate_Type::NORMAL;
+ params.url = GURL("data:text/html,test data");
+ view()->OnNavigate(params);
+
// An error occurred.
view()->didFailProvisionalLoad(web_frame, error);
// Frame should exit view-source mode.
@@ -1408,6 +1425,15 @@
error.reason = net::ERR_ABORTED;
error.unreachableURL = GURL("http://foo");
WebFrame* web_frame = GetMainFrame();
+
+ // Start a load that will reach provisional state synchronously,
+ // but won't complete synchronously.
+ ViewMsg_Navigate_Params params;
+ params.page_id = -1;
+ params.navigation_type = ViewMsg_Navigate_Type::NORMAL;
+ params.url = GURL("data:text/html,test data");
+ view()->OnNavigate(params);
+
// A cancellation occurred.
view()->didFailProvisionalLoad(web_frame, error);
// Frame should stay in view-source mode.
diff --git a/content/renderer/render_view_browsertest_mac.mm b/content/renderer/render_view_browsertest_mac.mm
index ed9908a..ab4af5d 100644
--- a/content/renderer/render_view_browsertest_mac.mm
+++ b/content/renderer/render_view_browsertest_mac.mm
@@ -8,6 +8,7 @@
#include "content/public/test/render_view_test.h"
#include "content/renderer/render_view_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/glue/webpreferences.h"
#include <Cocoa/Cocoa.h>
#include <Carbon/Carbon.h> // for the kVK_* constants.
@@ -83,7 +84,7 @@
);
#undef HTML
- webkit_glue::WebPreferences prefs;
+ WebPreferences prefs;
prefs.enable_scroll_animator = false;
RenderViewImpl* view = static_cast<RenderViewImpl*>(view_);
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index b1a51cf..2150615 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -13,7 +13,6 @@
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/debug/trace_event.h"
-#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
@@ -22,21 +21,21 @@
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/string_number_conversions.h"
-#include "base/string_piece.h"
#include "base/string_util.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "content/common/appcache/appcache_dispatcher.h"
#include "content/common/child_thread.h"
#include "content/common/clipboard_messages.h"
-#include "content/common/content_constants_internal.h"
#include "content/common/database_messages.h"
#include "content/common/drag_messages.h"
#include "content/common/fileapi/file_system_dispatcher.h"
#include "content/common/fileapi/webfilesystem_callback_dispatcher.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
+#include "content/common/input_messages.h"
#include "content/common/java_bridge_messages.h"
#include "content/common/pepper_messages.h"
#include "content/common/pepper_plugin_registry.h"
@@ -51,6 +50,7 @@
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/context_menu_params.h"
+#include "content/public/common/favicon_url.h"
#include "content/public/common/file_chooser_params.h"
#include "content/public/common/ssl_status.h"
#include "content/public/common/three_d_api_types.h"
@@ -71,16 +71,16 @@
#include "content/renderer/device_orientation_dispatcher.h"
#include "content/renderer/devtools/devtools_agent.h"
#include "content/renderer/disambiguation_popup_helper.h"
-#include "content/renderer/do_not_track_bindings.h"
#include "content/renderer/dom_automation_controller.h"
#include "content/renderer/dom_storage/webstoragenamespace_impl.h"
#include "content/renderer/external_popup_menu.h"
-#include "content/renderer/favicon_helper.h"
#include "content/renderer/geolocation_dispatcher.h"
#include "content/renderer/gpu/input_handler_manager.h"
#include "content/renderer/gpu/render_widget_compositor.h"
#include "content/renderer/idle_user_detector.h"
+#include "content/renderer/image_loading_helper.h"
#include "content/renderer/input_tag_speech_dispatcher.h"
+#include "content/renderer/internal_document_state_data.h"
#include "content/renderer/java/java_bridge_dispatcher.h"
#include "content/renderer/load_progress_tracker.h"
#include "content/renderer/media/audio_device_factory.h"
@@ -89,9 +89,9 @@
#include "content/renderer/media/media_stream_dispatcher.h"
#include "content/renderer/media/media_stream_impl.h"
#include "content/renderer/media/render_media_log.h"
-#include "content/renderer/media/renderer_audio_output_device.h"
#include "content/renderer/media/renderer_gpu_video_decoder_factories.h"
#include "content/renderer/media/rtc_peer_connection_handler.h"
+#include "content/renderer/media/video_capture_impl_manager.h"
#include "content/renderer/mhtml_generator.h"
#include "content/renderer/notification_provider.h"
#include "content/renderer/pepper/pepper_plugin_delegate_impl.h"
@@ -111,6 +111,7 @@
#include "content/renderer/web_ui_extension_data.h"
#include "content/renderer/webplugin_delegate_proxy.h"
#include "content/renderer/websharedworker_proxy.h"
+#include "media/audio/audio_output_device.h"
#include "media/base/audio_renderer_mixer_input.h"
#include "media/base/filter_collection.h"
#include "media/base/media_switches.h"
@@ -181,7 +182,7 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebWindowFeatures.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/default/WebRenderTheme.h"
-#include "ui/base/ui_base_switches.h"
+#include "ui/base/ui_base_switches_util.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
@@ -209,6 +210,8 @@
#include "webkit/plugins/npapi/webplugin_impl.h"
#if defined(OS_ANDROID)
+#include <cpu-features.h>
+
#include "content/common/android/device_telephony_info.h"
#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "content/renderer/android/address_detector.h"
@@ -221,9 +224,7 @@
#include "third_party/WebKit/Source/Platform/chromium/public/WebFloatRect.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebHitTestResult.h"
#include "ui/gfx/rect_f.h"
-#include "webkit/media/android/media_player_bridge_manager_impl.h"
#include "webkit/media/android/webmediaplayer_android.h"
-#include "webkit/media/android/webmediaplayer_impl_android.h"
#include "webkit/media/android/webmediaplayer_manager_android.h"
#elif defined(OS_WIN)
// TODO(port): these files are currently Windows only because they concern:
@@ -326,7 +327,6 @@
using webkit_glue::AltErrorPageResourceFetcher;
using webkit_glue::ResourceFetcher;
-using webkit_glue::WebPreferences;
using webkit_glue::WebURLResponseExtraDataImpl;
#if defined(OS_ANDROID)
@@ -375,14 +375,6 @@
static RenderViewImpl* (*g_create_render_view_impl)(RenderViewImplParams*) =
NULL;
-static WebKit::WebFrame* FindFrameByID(WebKit::WebFrame* root, int frame_id) {
- for (WebFrame* frame = root; frame; frame = frame->traverseNext(false)) {
- if (frame->identifier() == frame_id)
- return frame;
- }
- return NULL;
-}
-
static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) {
// Replace any occurrences of swappedout:// with about:blank.
const WebURL& blank_url = GURL(chrome::kAboutBlankURL);
@@ -397,13 +389,14 @@
}
}
-// If |data_source| is non-null and has a DocumentState associated with it,
-// the AltErrorPageResourceFetcher is reset.
+// If |data_source| is non-null and has an InternalDocumentStateData associated
+// with it, the AltErrorPageResourceFetcher is reset.
static void StopAltErrorPageFetcher(WebDataSource* data_source) {
if (data_source) {
- DocumentState* document_state = DocumentState::FromDataSource(data_source);
- if (document_state)
- document_state->set_alt_error_page_fetcher(NULL);
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDataSource(data_source);
+ if (internal_data)
+ internal_data->set_alt_error_page_fetcher(NULL);
}
}
@@ -542,8 +535,22 @@
switches::kEnableHighDpiCompositingForFixedPosition))
return true;
- // Default, when no switches are specified, is disabled.
- return false;
+ // Default, when no switch is specified, is to be enabled only for high-DPI.
+ return device_scale_factor > 1.0f;
+}
+
+static FaviconURL::IconType ToFaviconType(WebKit::WebIconURL::Type type) {
+ switch (type) {
+ case WebKit::WebIconURL::TypeFavicon:
+ return FaviconURL::FAVICON;
+ case WebKit::WebIconURL::TypeTouch:
+ return FaviconURL::TOUCH_ICON;
+ case WebKit::WebIconURL::TypeTouchPrecomposed:
+ return FaviconURL::TOUCH_PRECOMPOSED_ICON;
+ case WebKit::WebIconURL::TypeInvalid:
+ return FaviconURL::INVALID_ICON;
+ }
+ return FaviconURL::INVALID_ICON;
}
///////////////////////////////////////////////////////////////////////////////
@@ -595,6 +602,15 @@
return item.httpBody().identifier();
}
+bool TouchEnabled() {
+// Based on the definition of chrome::kEnableTouchIcon.
+#if defined(OS_ANDROID)
+ return true;
+#else
+ return false;
+#endif
+}
+
} // namespace
RenderViewImpl::RenderViewImpl(RenderViewImplParams* params)
@@ -621,7 +637,7 @@
cached_is_main_frame_pinned_to_right_(false),
cached_has_main_frame_horizontal_scrollbar_(false),
cached_has_main_frame_vertical_scrollbar_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(cookie_jar_(this)),
+ cookie_jar_(this),
notification_provider_(NULL),
geolocation_dispatcher_(NULL),
input_tag_speech_dispatcher_(NULL),
@@ -635,28 +651,23 @@
renderer_accessibility_(NULL),
java_bridge_dispatcher_(NULL),
mouse_lock_dispatcher_(NULL),
- favicon_helper_(NULL),
#if defined(OS_ANDROID)
body_background_color_(SK_ColorWHITE),
- update_frame_info_scheduled_(false),
expected_content_intent_id_(0),
media_player_proxy_(NULL),
+#endif
+#if defined(OS_WIN)
+ focused_plugin_id_(-1),
+#endif
enumeration_completion_id_(0),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- load_progress_tracker_(new LoadProgressTracker(this))),
+#if defined(OS_ANDROID)
+ load_progress_tracker_(new LoadProgressTracker(this)),
#endif
session_storage_namespace_id_(params->session_storage_namespace_id),
decrement_shared_popup_at_destruction_(false),
handling_select_range_(false),
next_snapshot_id_(0),
- allow_partial_swap_(params->allow_partial_swap),
-#if defined(OS_WIN)
- focused_plugin_id_(-1),
-#endif
- updating_frame_tree_(false),
- pending_frame_tree_update_(false),
- target_process_id_(0),
- target_routing_id_(0) {
+ allow_partial_swap_(params->allow_partial_swap) {
}
void RenderViewImpl::Initialize(RenderViewImplParams* params) {
@@ -729,12 +740,15 @@
webview()->settings()->setAcceleratedCompositingForFixedPositionEnabled(
ShouldUseFixedPositionCompositing(device_scale_factor_));
- webkit_preferences_.Apply(webview());
+ webkit_glue::ApplyWebPreferences(webkit_preferences_, webview());
webview()->initializeMainFrame(this);
- if (command_line.HasSwitch(switches::kEnableTouchDragDrop))
+ if (switches::IsTouchDragDropEnabled())
webview()->settings()->setTouchDragDropEnabled(true);
+ if (switches::IsTouchEditingEnabled())
+ webview()->settings()->setTouchEditingEnabled(true);
+
if (!params->frame_name.empty())
webview()->mainFrame()->setName(params->frame_name);
webview()->settings()->setMinimumTimerInterval(
@@ -762,7 +776,8 @@
// along with the RenderView automatically.
devtools_agent_ = new DevToolsAgent(this);
mouse_lock_dispatcher_ = new RenderViewMouseLockDispatcher(this);
- favicon_helper_ = new FaviconHelper(this);
+
+ new ImageLoadingHelper(this);
// Create renderer_accessibility_ if needed.
OnSetAccessibilityMode(params->accessibility_mode);
@@ -982,31 +997,35 @@
bool handled = true;
bool msg_is_ok = true;
IPC_BEGIN_MESSAGE_MAP_EX(RenderViewImpl, message, msg_is_ok)
+ IPC_MESSAGE_HANDLER(InputMsg_Copy, OnCopy)
+ IPC_MESSAGE_HANDLER(InputMsg_Cut, OnCut)
+ IPC_MESSAGE_HANDLER(InputMsg_Delete, OnDelete)
+ IPC_MESSAGE_HANDLER(InputMsg_ExecuteEditCommand, OnExecuteEditCommand)
+ IPC_MESSAGE_HANDLER(InputMsg_MoveCaret, OnMoveCaret)
+ IPC_MESSAGE_HANDLER(InputMsg_Paste, OnPaste)
+ IPC_MESSAGE_HANDLER(InputMsg_PasteAndMatchStyle, OnPasteAndMatchStyle)
+ IPC_MESSAGE_HANDLER(InputMsg_Redo, OnRedo)
+ IPC_MESSAGE_HANDLER(InputMsg_Replace, OnReplace)
+ IPC_MESSAGE_HANDLER(InputMsg_ReplaceMisspelling, OnReplaceMisspelling)
+ IPC_MESSAGE_HANDLER(InputMsg_ScrollFocusedEditableNodeIntoRect,
+ OnScrollFocusedEditableNodeIntoRect)
+ IPC_MESSAGE_HANDLER(InputMsg_SelectAll, OnSelectAll)
+ IPC_MESSAGE_HANDLER(InputMsg_SelectRange, OnSelectRange)
+ IPC_MESSAGE_HANDLER(InputMsg_SetEditCommandsForNextKeyEvent,
+ OnSetEditCommandsForNextKeyEvent)
+ IPC_MESSAGE_HANDLER(InputMsg_Undo, OnUndo)
+ IPC_MESSAGE_HANDLER(InputMsg_Unselect, OnUnselect)
IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)
IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)
IPC_MESSAGE_HANDLER(ViewMsg_ReloadFrame, OnReloadFrame)
- IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)
- IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)
- IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)
- IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)
- IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)
- IPC_MESSAGE_HANDLER(ViewMsg_PasteAndMatchStyle, OnPasteAndMatchStyle)
- IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)
- IPC_MESSAGE_HANDLER(ViewMsg_ReplaceMisspelling, OnReplaceMisspelling)
- IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)
IPC_MESSAGE_HANDLER(ViewMsg_SetName, OnSetName)
- IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)
- IPC_MESSAGE_HANDLER(ViewMsg_Unselect, OnUnselect)
IPC_MESSAGE_HANDLER(ViewMsg_SetEditableSelectionOffsets,
OnSetEditableSelectionOffsets)
IPC_MESSAGE_HANDLER(ViewMsg_SetCompositionFromExistingText,
OnSetCompositionFromExistingText)
IPC_MESSAGE_HANDLER(ViewMsg_ExtendSelectionAndDelete,
OnExtendSelectionAndDelete)
- IPC_MESSAGE_HANDLER(ViewMsg_SelectRange, OnSelectRange)
- IPC_MESSAGE_HANDLER(ViewMsg_MoveCaret, OnMoveCaret)
IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)
- IPC_MESSAGE_HANDLER(ViewMsg_ExecuteEditCommand, OnExecuteEditCommand)
IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)
IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)
IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
@@ -1029,8 +1048,6 @@
OnDragSourceSystemDragEnded)
IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)
IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)
- IPC_MESSAGE_HANDLER(ViewMsg_ScrollFocusedEditableNodeIntoRect,
- OnScrollFocusedEditableNodeIntoRect)
IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)
IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)
IPC_MESSAGE_HANDLER(ViewMsg_TimezoneChange, OnUpdateTimezone)
@@ -1059,10 +1076,6 @@
OnOrientationChangeEvent)
IPC_MESSAGE_HANDLER(ViewMsg_PluginActionAt, OnPluginActionAt)
IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
- IPC_MESSAGE_HANDLER(ViewMsg_SetNavigationStartTime,
- OnSetNavigationStartTime)
- IPC_MESSAGE_HANDLER(ViewMsg_SetEditCommandsForNextKeyEvent,
- OnSetEditCommandsForNextKeyEvent)
IPC_MESSAGE_HANDLER(ViewMsg_CustomContextMenuAction,
OnCustomContextMenuAction)
IPC_MESSAGE_HANDLER(ViewMsg_AsyncOpenFile_ACK, OnAsyncFileOpened)
@@ -1076,6 +1089,7 @@
ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,
OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)
IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed)
+ IPC_MESSAGE_HANDLER(ViewMsg_ShowContextMenu, OnShowContextMenu)
// TODO(viettrungluu): Move to a separate message filter.
IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune,
OnSetHistoryLengthAndPrune)
@@ -1083,18 +1097,17 @@
IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit)
IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode)
IPC_MESSAGE_HANDLER(ViewMsg_DisownOpener, OnDisownOpener)
- IPC_MESSAGE_HANDLER(ViewMsg_UpdateFrameTree, OnUpdatedFrameTree)
#if defined(OS_ANDROID)
- IPC_MESSAGE_HANDLER(ViewMsg_ActivateNearestFindResult,
+ IPC_MESSAGE_HANDLER(InputMsg_ActivateNearestFindResult,
OnActivateNearestFindResult)
IPC_MESSAGE_HANDLER(ViewMsg_FindMatchRects, OnFindMatchRects)
IPC_MESSAGE_HANDLER(ViewMsg_SelectPopupMenuItems, OnSelectPopupMenuItems)
IPC_MESSAGE_HANDLER(ViewMsg_UndoScrollFocusedEditableNodeIntoView,
OnUndoScrollFocusedEditableNodeIntoRect)
- IPC_MESSAGE_HANDLER(ViewMsg_EnableHidingTopControls,
- OnEnableHidingTopControls)
+ IPC_MESSAGE_HANDLER(ViewMsg_UpdateTopControlsState,
+ OnUpdateTopControlsState)
#elif defined(OS_MACOSX)
- IPC_MESSAGE_HANDLER(ViewMsg_CopyToFindPboard, OnCopyToFindPboard)
+ IPC_MESSAGE_HANDLER(InputMsg_CopyToFindPboard, OnCopyToFindPboard)
IPC_MESSAGE_HANDLER(ViewMsg_PluginImeCompositionCompleted,
OnPluginImeCompositionCompleted)
IPC_MESSAGE_HANDLER(ViewMsg_SelectPopupMenuItem, OnSelectPopupMenuItem)
@@ -1149,6 +1162,11 @@
SetSwappedOut(false);
}
+ if (params.should_clear_history_list) {
+ CHECK_EQ(params.pending_history_list_offset, -1);
+ CHECK_EQ(params.current_history_list_offset, -1);
+ CHECK_EQ(params.current_history_list_length, 0);
+ }
history_list_offset_ = params.current_history_list_offset;
history_list_length_ = params.current_history_list_length;
if (history_list_length_ >= 0)
@@ -1258,6 +1276,21 @@
}
frame->loadRequest(request);
+
+ // If this is a cross-process navigation, the browser process will send
+ // along the proper navigation start value.
+ if (!params.browser_navigation_start.is_null() &&
+ frame->provisionalDataSource()) {
+ // browser_navigation_start is likely before this process existed, so we
+ // can't use InterProcessTimeTicksConverter. Instead, the best we can do
+ // is just ensure we don't report a bogus value in the future.
+ base::TimeTicks navigation_start = std::min(
+ base::TimeTicks::Now(), params.browser_navigation_start);
+ double navigation_start_seconds =
+ (navigation_start - base::TimeTicks()).InSecondsF();
+ frame->provisionalDataSource()->setNavigationStartTime(
+ navigation_start_seconds);
+ }
}
// In case LoadRequest failed before DidCreateDataSource was called.
@@ -1329,15 +1362,6 @@
webview()->copyImageAt(WebPoint(x, y));
}
-void RenderViewImpl::OnExecuteEditCommand(const std::string& name,
- const std::string& value) {
- if (!webview() || !webview()->focusedFrame())
- return;
-
- webview()->focusedFrame()->executeCommand(
- WebString::fromUTF8(name), WebString::fromUTF8(value));
-}
-
void RenderViewImpl::OnUpdateTargetURLAck() {
// Check if there is a targeturl waiting to be sent.
if (target_url_status_ == TARGET_PENDING) {
@@ -1348,18 +1372,15 @@
target_url_status_ = TARGET_NONE;
}
-void RenderViewImpl::OnUndo() {
+void RenderViewImpl::OnCopy() {
if (!webview())
return;
- webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Undo"));
-}
-
-void RenderViewImpl::OnRedo() {
- if (!webview())
- return;
-
- webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Redo"));
+ base::AutoReset<bool> handling_select_range(&handling_select_range_, true);
+ WebNode current_node = context_menu_node_.isNull() ?
+ GetFocusedNode() : context_menu_node_;
+ webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Copy"),
+ current_node);
}
void RenderViewImpl::OnCut() {
@@ -1367,40 +1388,43 @@
return;
base::AutoReset<bool> handling_select_range(&handling_select_range_, true);
- webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Cut"));
+ webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Cut"),
+ GetFocusedNode());
}
-void RenderViewImpl::OnCopy() {
+void RenderViewImpl::OnDelete() {
if (!webview())
return;
- base::AutoReset<bool> handling_select_range(&handling_select_range_, true);
- webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Copy"),
- context_menu_node_);
+ webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Delete"),
+ GetFocusedNode());
}
-#if defined(OS_MACOSX)
-void RenderViewImpl::OnCopyToFindPboard() {
+void RenderViewImpl::OnExecuteEditCommand(const std::string& name,
+ const std::string& value) {
+ if (!webview() || !webview()->focusedFrame())
+ return;
+
+ webview()->focusedFrame()->executeCommand(
+ WebString::fromUTF8(name), WebString::fromUTF8(value));
+}
+
+void RenderViewImpl::OnMoveCaret(const gfx::Point& point) {
if (!webview())
return;
- // Since the find pasteboard supports only plain text, this can be simpler
- // than the |OnCopy()| case.
- WebFrame* frame = webview()->focusedFrame();
- if (frame->hasSelection()) {
- string16 selection = frame->selectionAsText();
- RenderThread::Get()->Send(
- new ClipboardHostMsg_FindPboardWriteStringAsync(selection));
- }
+ Send(new ViewHostMsg_MoveCaret_ACK(routing_id_));
+
+ webview()->focusedFrame()->moveCaretSelectionTowardsWindowPoint(point);
}
-#endif
void RenderViewImpl::OnPaste() {
if (!webview())
return;
base::AutoReset<bool> handling_select_range(&handling_select_range_, true);
- webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Paste"));
+ webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Paste"),
+ GetFocusedNode());
}
void RenderViewImpl::OnPasteAndMatchStyle() {
@@ -1409,7 +1433,15 @@
base::AutoReset<bool> handling_select_range(&handling_select_range_, true);
webview()->focusedFrame()->executeCommand(
- WebString::fromUTF8("PasteAndMatchStyle"));
+ WebString::fromUTF8("PasteAndMatchStyle"), GetFocusedNode());
+}
+
+void RenderViewImpl::OnRedo() {
+ if (!webview())
+ return;
+
+ webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Redo"),
+ GetFocusedNode());
}
void RenderViewImpl::OnReplace(const string16& text) {
@@ -1434,18 +1466,15 @@
frame->replaceMisspelledRange(text);
}
-void RenderViewImpl::OnDelete() {
- if (!webview())
- return;
-
- webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Delete"));
-}
-
-void RenderViewImpl::OnSetName(const std::string& name) {
- if (!webview())
- return;
-
- webview()->mainFrame()->setName(WebString::fromUTF8(name));
+void RenderViewImpl::OnScrollFocusedEditableNodeIntoRect(
+ const gfx::Rect& rect) {
+ WebKit::WebNode node = GetFocusedNode();
+ if (!node.isNull()) {
+ if (IsEditableNode(node)) {
+ webview()->saveScrollAndScaleState();
+ webview()->scrollFocusedNodeIntoRect(rect);
+ }
+ }
}
void RenderViewImpl::OnSelectAll() {
@@ -1454,7 +1483,31 @@
base::AutoReset<bool> handling_select_range(&handling_select_range_, true);
webview()->focusedFrame()->executeCommand(
- WebString::fromUTF8("SelectAll"));
+ WebString::fromUTF8("SelectAll"), GetFocusedNode());
+}
+
+void RenderViewImpl::OnSelectRange(const gfx::Point& start,
+ const gfx::Point& end) {
+ if (!webview())
+ return;
+
+ Send(new ViewHostMsg_SelectRange_ACK(routing_id_));
+
+ base::AutoReset<bool> handling_select_range(&handling_select_range_, true);
+ webview()->focusedFrame()->selectRange(start, end);
+}
+
+void RenderViewImpl::OnSetEditCommandsForNextKeyEvent(
+ const EditCommands& edit_commands) {
+ edit_commands_ = edit_commands;
+}
+
+void RenderViewImpl::OnUndo() {
+ if (!webview())
+ return;
+
+ webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Undo"),
+ GetFocusedNode());
}
void RenderViewImpl::OnUnselect() {
@@ -1462,7 +1515,31 @@
return;
base::AutoReset<bool> handling_select_range(&handling_select_range_, true);
- webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Unselect"));
+ webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Unselect"),
+ GetFocusedNode());
+}
+
+#if defined(OS_MACOSX)
+void RenderViewImpl::OnCopyToFindPboard() {
+ if (!webview())
+ return;
+
+ // Since the find pasteboard supports only plain text, this can be simpler
+ // than the |OnCopy()| case.
+ WebFrame* frame = webview()->focusedFrame();
+ if (frame->hasSelection()) {
+ string16 selection = frame->selectionAsText();
+ RenderThread::Get()->Send(
+ new ClipboardHostMsg_FindPboardWriteStringAsync(selection));
+ }
+}
+#endif
+
+void RenderViewImpl::OnSetName(const std::string& name) {
+ if (!webview())
+ return;
+
+ webview()->mainFrame()->setName(WebString::fromUTF8(name));
}
void RenderViewImpl::OnSetEditableSelectionOffsets(int start, int end) {
@@ -1496,26 +1573,6 @@
UpdateTextInputState(DO_NOT_SHOW_IME);
}
-void RenderViewImpl::OnSelectRange(const gfx::Point& start,
- const gfx::Point& end) {
- if (!webview())
- return;
-
- Send(new ViewHostMsg_SelectRange_ACK(routing_id_));
-
- base::AutoReset<bool> handling_select_range(&handling_select_range_, true);
- webview()->focusedFrame()->selectRange(start, end);
-}
-
-void RenderViewImpl::OnMoveCaret(const gfx::Point& point) {
- if (!webview())
- return;
-
- Send(new ViewHostMsg_MoveCaret_ACK(routing_id_));
-
- webview()->focusedFrame()->moveCaretSelectionTowardsWindowPoint(point);
-}
-
void RenderViewImpl::OnSetHistoryLengthAndPrune(int history_length,
int32 minimum_page_id) {
DCHECK_GE(history_length, 0);
@@ -1554,17 +1611,6 @@
}
#endif
-void RenderViewImpl::OnScrollFocusedEditableNodeIntoRect(
- const gfx::Rect& rect) {
- WebKit::WebNode node = GetFocusedNode();
- if (!node.isNull()) {
- if (IsEditableNode(node)) {
- webview()->saveScrollAndScaleState();
- webview()->scrollFocusedNodeIntoRect(rect);
- }
- }
-}
-
#if defined(OS_ANDROID)
void RenderViewImpl::OnUndoScrollFocusedEditableNodeIntoRect() {
const WebNode node = GetFocusedNode();
@@ -1586,6 +1632,8 @@
DocumentState* document_state = DocumentState::FromDataSource(ds);
NavigationState* navigation_state = document_state->navigation_state();
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDocumentState(document_state);
ViewHostMsg_FrameNavigate_Params params;
params.http_status_code = response.httpStatusCode();
@@ -1600,16 +1648,7 @@
params.was_fetched_via_proxy = extra_data->was_fetched_via_proxy();
}
params.was_within_same_page = navigation_state->was_within_same_page();
- if (!document_state->security_info().empty()) {
- // SSL state specified in the request takes precedence over the one in the
- // response.
- // So far this is only intended for error pages that are not expected to be
- // over ssl, so we should not get any clash.
- DCHECK(response.securityInfo().isEmpty());
- params.security_info = document_state->security_info();
- } else {
- params.security_info = response.securityInfo();
- }
+ params.security_info = response.securityInfo();
// Set the URL to be displayed in the browser UI to the user.
params.url = GetLoadingUrl(frame);
@@ -1622,12 +1661,10 @@
params.should_update_history = !ds->hasUnreachableURL() &&
!response.isMultipartPayload() && (response.httpStatusCode() != 404);
- params.searchable_form_url = document_state->searchable_form_url();
- params.searchable_form_encoding =
- document_state->searchable_form_encoding();
+ params.searchable_form_url = internal_data->searchable_form_url();
+ params.searchable_form_encoding = internal_data->searchable_form_encoding();
- const PasswordForm* password_form_data =
- document_state->password_form_data();
+ const PasswordForm* password_form_data = document_state->password_form_data();
if (password_form_data)
params.password_form = *password_form_data;
@@ -1715,12 +1752,14 @@
}
// Send the user agent override back.
- params.is_overriding_user_agent =
- document_state->is_overriding_user_agent();
+ params.is_overriding_user_agent = internal_data->is_overriding_user_agent();
// Track the URL of the original request.
params.original_request_url = original_request.url();
+ params.history_list_was_cleared =
+ navigation_state->history_list_was_cleared();
+
// Save some histogram data so we can compute the average memory used per
// page load of the glyphs.
UMA_HISTOGRAM_COUNTS_10000("Memory.GlyphPagesPerLoad",
@@ -1742,6 +1781,9 @@
else
params.transition = PAGE_TRANSITION_AUTO_SUBFRAME;
+ DCHECK(!navigation_state->history_list_was_cleared());
+ params.history_list_was_cleared = false;
+
Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
}
@@ -1839,7 +1881,7 @@
error_html = &html;
} else {
GetContentClient()->renderer()->GetNavigationErrorStrings(
- failed_request, error, &alt_html, NULL);
+ frame, failed_request, error, &alt_html, NULL);
error_html = &alt_html;
}
@@ -1934,7 +1976,7 @@
WebUserGestureIndicator::consumeUserGesture();
- webkit_glue::WebPreferences transferred_preferences = webkit_preferences_;
+ WebPreferences transferred_preferences = webkit_preferences_;
// Unless accelerated compositing has been explicitly disabled from the
// command line (e.g. via the blacklist or about:flags) re-enable it for
@@ -1990,7 +2032,7 @@
// By returning NULL in that case, we instruct WebKit to cancel that new
// popup. So from the user perspective, only the first one will show, and
// will have to close the first one before another one can be shown.
- if (external_popup_menu_.get())
+ if (external_popup_menu_)
return NULL;
external_popup_menu_.reset(
new ExternalPopupMenu(this, popup_menu_info, popup_menu_client));
@@ -2094,11 +2136,6 @@
is_loading_ = false;
- if (pending_frame_tree_update_) {
- pending_frame_tree_update_ = false;
- SendUpdatedFrameTree(NULL);
- }
-
// NOTE: For now we're doing the safest thing, and sending out notification
// when done loading. This currently isn't an issue as the favicon is only
// displayed when done loading. Ideally we would send notification when
@@ -2109,6 +2146,8 @@
if (load_progress_tracker_ != NULL)
load_progress_tracker_->DidStopLoading();
+ DidStopLoadingIcons();
+
FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStopLoading());
}
@@ -2419,10 +2458,6 @@
Send(new ViewHostMsg_DidChangeNumWheelEvents(routing_id_, num_handlers));
}
-void RenderViewImpl::hasTouchEventHandlers(bool has_handlers) {
- Send(new ViewHostMsg_HasTouchEventHandlers(routing_id_, has_handlers));
-}
-
void RenderViewImpl::didUpdateLayout() {
// We don't always want to set up a timer, only if we've been put in that
// mode by getting a |ViewMsg_EnablePreferredSizeChangedMode|
@@ -2602,7 +2637,7 @@
#if defined(ENABLE_PLUGINS)
if (UTF16ToASCII(params.mimeType) == kBrowserPluginMimeType) {
- return browser_plugin_manager()->CreateBrowserPlugin(this, frame, params);
+ return GetBrowserPluginManager()->CreateBrowserPlugin(this, frame, params);
}
webkit::WebPluginInfo info;
@@ -2655,6 +2690,11 @@
const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
#if defined(ENABLE_WEBRTC)
if (MediaStreamImpl::CheckMediaStream(url)) {
+#if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL)
+ bool found_neon =
+ (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
+ UMA_HISTOGRAM_BOOLEAN("Platform.WebRtcNEONFound", found_neon);
+#endif // defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL)
EnsureMediaStreamImpl();
return new webkit_media::WebMediaPlayerMS(
frame, client, AsWeakPtr(), media_stream_impl_, new RenderMediaLog());
@@ -2681,31 +2721,21 @@
media_player_proxy_ = new WebMediaPlayerProxyImplAndroid(
this, media_player_manager_.get());
}
- return new webkit_media::WebMediaPlayerImplAndroid(
+ return new webkit_media::WebMediaPlayerAndroid(
frame,
client,
media_player_manager_.get(),
media_player_proxy_,
new StreamTextureFactoryImpl(
- context_provider->Context3d(), gpu_channel_host, routing_id_));
+ context_provider->Context3d(), gpu_channel_host, routing_id_),
+ new RenderMediaLog());
#endif
scoped_refptr<media::AudioRendererSink> sink;
if (!cmd_line->HasSwitch(switches::kDisableAudio)) {
- if (!cmd_line->HasSwitch(switches::kDisableRendererSideMixing)) {
- sink = RenderThreadImpl::current()->GetAudioRendererMixerManager()->
- CreateInput(routing_id_);
- DVLOG(1) << "Using AudioRendererMixerManager-provided sink: " << sink;
- } else {
- scoped_refptr<RendererAudioOutputDevice> device =
- AudioDeviceFactory::NewOutputDevice();
- // The RenderView creating AudioRendererSink will be the source of
- // the audio (WebMediaPlayer is always associated with a document in a
- // frame at the time RenderAudioSourceProvider is instantiated).
- device->SetSourceRenderView(routing_id_);
- sink = device;
- DVLOG(1) << "Using AudioDeviceFactory-provided sink: " << sink;
- }
+ sink = RenderThreadImpl::current()->GetAudioRendererMixerManager()->
+ CreateInput(routing_id_);
+ DVLOG(1) << "Using AudioRendererMixerManager-provided sink: " << sink;
}
scoped_refptr<media::GpuVideoDecoder::Factories> gpu_factories;
@@ -2750,19 +2780,14 @@
}
void RenderViewImpl::didCreateFrame(WebFrame* parent, WebFrame* child) {
- if (!updating_frame_tree_)
- SendUpdatedFrameTree(NULL);
}
void RenderViewImpl::didDisownOpener(WebKit::WebFrame* frame) {
- // We should only hear this from the top-level frame, because subframes do not
- // have openers.
- CHECK(!frame->parent());
-
- // We only need to notify the browser if the active frame clears its opener.
- // We can ignore cases where a swapped out frame clears its opener after
- // hearing about it from the browser.
- if (is_swapped_out_)
+ // We only need to notify the browser if the active, top-level frame clears
+ // its opener. We can ignore cases where a swapped out frame clears its
+ // opener after hearing about it from the browser, and the browser does not
+ // (yet) care about subframe openers.
+ if (is_swapped_out_ || frame->parent())
return;
// Notify WebContents and all its swapped out RenderViews.
@@ -2772,15 +2797,6 @@
void RenderViewImpl::frameDetached(WebFrame* frame) {
Send(new ViewHostMsg_FrameDetached(routing_id_, frame->identifier()));
- if (is_loading_) {
- pending_frame_tree_update_ = true;
- // Make sure observers are notified, even if we return right away.
- FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame));
- return;
- }
- if (!updating_frame_tree_)
- SendUpdatedFrameTree(frame);
-
FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame));
}
@@ -2821,18 +2837,7 @@
}
SSLStatus RenderViewImpl::GetSSLStatusOfFrame(WebKit::WebFrame* frame) const {
- SSLStatus ssl_status;
-
- DocumentState* doc_state = DocumentState::FromDataSource(frame->dataSource());
- if (doc_state && !doc_state->security_info().empty()) {
- DeserializeSecurityInfo(doc_state->security_info(),
- &ssl_status.cert_id,
- &ssl_status.cert_status,
- &ssl_status.security_bits,
- &ssl_status.connection_status);
- }
-
- return ssl_status;
+ return SSLStatus();
}
void RenderViewImpl::loadURLExternally(
@@ -2851,8 +2856,9 @@
}
WebNavigationPolicy RenderViewImpl::decidePolicyForNavigation(
- WebFrame* frame, const WebURLRequest& request, WebNavigationType type,
- const WebNode&, WebNavigationPolicy default_policy, bool is_redirect) {
+ WebFrame* frame, WebDataSource::ExtraData* extraData,
+ const WebURLRequest& request, WebNavigationType type,
+ WebNavigationPolicy default_policy, bool is_redirect) {
if (request.url() != GURL(kSwappedOutURL) &&
GetContentClient()->renderer()->HandleNavigation(frame, request, type,
default_policy,
@@ -2894,8 +2900,7 @@
// A content initiated navigation may have originated from a link-click,
// script, drag-n-drop operation, etc.
- bool is_content_initiated =
- DocumentState::FromDataSource(frame->provisionalDataSource())->
+ bool is_content_initiated = static_cast<DocumentState*>(extraData)->
navigation_state()->is_content_initiated();
// Experimental:
@@ -3047,6 +3052,14 @@
return default_policy;
}
+WebNavigationPolicy RenderViewImpl::decidePolicyForNavigation(
+ WebFrame* frame, const WebURLRequest& request, WebNavigationType type,
+ WebNavigationPolicy default_policy, bool is_redirect) {
+ return decidePolicyForNavigation(frame,
+ frame->provisionalDataSource()->extraData(),
+ request, type, default_policy, is_redirect);
+}
+
bool RenderViewImpl::canHandleRequest(
WebFrame* frame, const WebURLRequest& request) {
// We allow WebKit to think that everything can be handled even though
@@ -3090,14 +3103,16 @@
DocumentState* document_state =
DocumentState::FromDataSource(frame->provisionalDataSource());
NavigationState* navigation_state = document_state->navigation_state();
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDocumentState(document_state);
if (navigation_state->transition_type() == PAGE_TRANSITION_LINK)
navigation_state->set_transition_type(PAGE_TRANSITION_FORM_SUBMIT);
// Save these to be processed when the ensuing navigation is committed.
WebSearchableFormData web_searchable_form_data(form);
- document_state->set_searchable_form_url(web_searchable_form_data.url());
- document_state->set_searchable_form_encoding(
+ internal_data->set_searchable_form_url(web_searchable_form_data.url());
+ internal_data->set_searchable_form_encoding(
web_searchable_form_data.encoding().utf8());
scoped_ptr<PasswordForm> password_form_data =
CreatePasswordForm(form);
@@ -3107,7 +3122,7 @@
// from the form contents already stored by |willSendSubmitEvent| into the
// dataSource's NavigationState (as opposed to the provisionalDataSource's,
// which is what we're storing into now.)
- if (password_form_data.get()) {
+ if (password_form_data) {
DocumentState* old_document_state =
DocumentState::FromDataSource(frame->dataSource());
if (old_document_state) {
@@ -3176,8 +3191,12 @@
DocumentState* old_document_state =
DocumentState::FromDataSource(webview()->mainFrame()->dataSource());
if (old_document_state) {
- document_state->set_is_overriding_user_agent(
- old_document_state->is_overriding_user_agent());
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDocumentState(document_state);
+ InternalDocumentStateData* old_internal_data =
+ InternalDocumentStateData::FromDocumentState(old_document_state);
+ internal_data->set_is_overriding_user_agent(
+ old_internal_data->is_overriding_user_agent());
}
}
@@ -3245,6 +3264,9 @@
const ViewMsg_Navigate_Params& params = *pending_navigation_params_.get();
document_state->set_request_time(params.request_time);
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDocumentState(document_state);
+
if (!params.url.SchemeIs(chrome::kJavaScriptScheme) &&
params.navigation_type == ViewMsg_Navigate_Type::RESTORE) {
// We're doing a load of a page that was restored from the last session. By
@@ -3252,7 +3274,7 @@
// can result in stale data for pages that are set to expire. We explicitly
// override that by setting the policy here so that as necessary we load
// from the network.
- document_state->set_cache_policy_override(
+ internal_data->set_cache_policy_override(
WebURLRequest::UseProtocolCachePolicy);
}
@@ -3263,9 +3285,9 @@
else
document_state->set_load_type(DocumentState::NORMAL_LOAD);
- document_state->set_referrer_policy(params.referrer.policy);
- document_state->set_is_overriding_user_agent(params.is_overriding_user_agent);
- document_state->set_must_reset_scroll_and_scale_state(
+ internal_data->set_referrer_policy(params.referrer.policy);
+ internal_data->set_is_overriding_user_agent(params.is_overriding_user_agent);
+ internal_data->set_must_reset_scroll_and_scale_state(
params.navigation_type ==
ViewMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL);
document_state->set_can_load_local_resources(params.can_load_local_resources);
@@ -3282,6 +3304,7 @@
navigation_state = NavigationState::CreateBrowserInitiated(
params.page_id,
params.pending_history_list_offset,
+ params.should_clear_history_list,
params.transition);
navigation_state->set_transferred_request_child_id(
params.transferred_request_child_id);
@@ -3321,11 +3344,9 @@
webview()->setFixedLayoutSize(WebSize(width, height));
}
}
-
- if (command_line.HasSwitch(switches::kEnablePinch))
- webview()->setPageScaleFactorLimits(1, 4);
- else
- webview()->setPageScaleFactorLimits(1, 1);
+ float maxPageScaleFactor =
+ command_line.HasSwitch(switches::kEnablePinch) ? 4.f : 1.f ;
+ webview()->setPageScaleFactorLimits(1, maxPageScaleFactor);
}
void RenderViewImpl::didStartProvisionalLoad(WebFrame* frame) {
@@ -3357,6 +3378,23 @@
navigation_gesture_ = WebUserGestureIndicator::isProcessingUserGesture() ?
NavigationGestureUser : NavigationGestureAuto;
+ // If the navigation is not triggered by a user gesture, e.g. by some ajax
+ // callback, then inherit the submitted password form from the previous
+ // state. This fixes the no password save issue for ajax login, tracked in
+ // [http://crbug/43219]. Note that there are still some sites that this
+ // fails for because they use some element other than a submit button to
+ // trigger submission.
+ if (navigation_gesture_ == NavigationGestureAuto) {
+ DocumentState* old_document_state = DocumentState::FromDataSource(
+ frame->dataSource());
+ const content::PasswordForm* old_password_form =
+ old_document_state->password_form_data();
+ if (old_password_form) {
+ document_state->set_password_form_data(
+ make_scoped_ptr(new content::PasswordForm(*old_password_form)));
+ }
+ }
+
// Make sure redirect tracking state is clear for the new load.
completed_client_redirect_src_ = Referrer();
} else if (frame->parent()->isLoading()) {
@@ -3419,6 +3457,7 @@
params.is_main_frame = !frame->parent();
params.error_code = error.reason;
GetContentClient()->renderer()->GetNavigationErrorStrings(
+ frame,
failed_request,
error,
NULL,
@@ -3463,6 +3502,8 @@
navigation_state->pending_page_id();
pending_navigation_params_->pending_history_list_offset =
navigation_state->pending_history_list_offset();
+ pending_navigation_params_->should_clear_history_list =
+ navigation_state->history_list_was_cleared();
pending_navigation_params_->transition =
navigation_state->transition_type();
pending_navigation_params_->request_time =
@@ -3480,9 +3521,9 @@
void RenderViewImpl::didReceiveDocumentData(
WebFrame* frame, const char* data, size_t data_len,
bool& prevent_default) {
- DocumentState* document_state =
- DocumentState::FromDataSource(frame->dataSource());
- document_state->set_use_error_page(false);
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDataSource(frame->dataSource());
+ internal_data->set_use_error_page(false);
}
void RenderViewImpl::didCommitProvisionalLoad(WebFrame* frame,
@@ -3490,13 +3531,15 @@
DocumentState* document_state =
DocumentState::FromDataSource(frame->dataSource());
NavigationState* navigation_state = document_state->navigation_state();
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDocumentState(document_state);
if (document_state->commit_load_time().is_null())
document_state->set_commit_load_time(Time::Now());
- if (document_state->must_reset_scroll_and_scale_state()) {
+ if (internal_data->must_reset_scroll_and_scale_state()) {
webview()->resetScrollAndScaleState();
- document_state->set_must_reset_scroll_and_scale_state(false);
+ internal_data->set_must_reset_scroll_and_scale_state(false);
}
if (is_new_navigation) {
@@ -3585,7 +3628,7 @@
DidClearWindowObject(frame));
if (enabled_bindings_ & BINDINGS_POLICY_DOM_AUTOMATION) {
- if (!dom_automation_controller_.get())
+ if (!dom_automation_controller_)
dom_automation_controller_.reset(new DomAutomationController());
dom_automation_controller_->set_message_sender(
static_cast<RenderView*>(this));
@@ -3593,8 +3636,6 @@
dom_automation_controller_->BindToJavascript(frame,
"domAutomationController");
}
-
- InjectDoNotTrackBindings(frame);
}
void RenderViewImpl::didCreateDocumentElement(WebFrame* frame) {
@@ -3617,8 +3658,21 @@
UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
}
-void RenderViewImpl::didChangeIcon(WebFrame* frame, WebIconURL::Type type) {
- favicon_helper_->DidChangeIcon(frame, type);
+void RenderViewImpl::didChangeIcon(WebFrame* frame,
+ WebIconURL::Type icon_type) {
+ if (frame->parent())
+ return;
+
+ if (!TouchEnabled() && icon_type != WebIconURL::TypeFavicon)
+ return;
+
+ WebVector<WebIconURL> icon_urls = frame->iconURLs(icon_type);
+ std::vector<FaviconURL> urls;
+ for (size_t i = 0; i < icon_urls.size(); i++) {
+ urls.push_back(FaviconURL(icon_urls[i].iconURL(),
+ ToFaviconType(icon_urls[i].iconType())));
+ }
+ SendUpdateFaviconURL(urls);
}
void RenderViewImpl::didFinishDocumentLoad(WebFrame* frame) {
@@ -3652,6 +3706,7 @@
const WebURLRequest& failed_request = ds->request();
string16 error_description;
GetContentClient()->renderer()->GetNavigationErrorStrings(
+ frame,
failed_request,
error,
NULL,
@@ -3728,6 +3783,8 @@
PageTransition transition_type = PAGE_TRANSITION_LINK;
DocumentState* document_state = DocumentState::FromDataSource(data_source);
DCHECK(document_state);
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDocumentState(document_state);
NavigationState* navigation_state = document_state->navigation_state();
transition_type = navigation_state->transition_type();
@@ -3742,13 +3799,13 @@
request.setURL(WebURL(new_url));
}
- if (document_state->is_cache_policy_override_set())
- request.setCachePolicy(document_state->cache_policy_override());
+ if (internal_data->is_cache_policy_override_set())
+ request.setCachePolicy(internal_data->cache_policy_override());
WebKit::WebReferrerPolicy referrer_policy;
- if (document_state && document_state->is_referrer_policy_set()) {
- referrer_policy = document_state->referrer_policy();
- document_state->clear_referrer_policy();
+ if (internal_data->is_referrer_policy_set()) {
+ referrer_policy = internal_data->referrer_policy();
+ internal_data->clear_referrer_policy();
} else {
referrer_policy = frame->document().referrerPolicy();
}
@@ -3841,18 +3898,20 @@
document_state->set_was_fetched_via_proxy(
extra_data->was_fetched_via_proxy());
}
- document_state->set_http_status_code(http_status_code);
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDocumentState(document_state);
+ internal_data->set_http_status_code(http_status_code);
// Whether or not the http status code actually corresponds to an error is
// only checked when the page is done loading, if |use_error_page| is
// still true.
- document_state->set_use_error_page(true);
+ internal_data->set_use_error_page(true);
}
void RenderViewImpl::didFinishResourceLoad(
WebFrame* frame, unsigned identifier) {
- DocumentState* document_state =
- DocumentState::FromDataSource(frame->dataSource());
- if (!document_state->use_error_page())
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDataSource(frame->dataSource());
+ if (!internal_data->use_error_page())
return;
// Do not show error page when DevTools is attached.
@@ -3860,7 +3919,7 @@
return;
// Display error page, if appropriate.
- int http_status_code = document_state->http_status_code();
+ int http_status_code = internal_data->http_status_code();
if (http_status_code == 404) {
// On 404s, try a remote search page as a fallback.
const GURL& document_url = frame->document().url();
@@ -3873,9 +3932,10 @@
original_error.reason = 404;
original_error.unreachableURL = document_url;
- document_state->set_alt_error_page_fetcher(
+ internal_data->set_alt_error_page_fetcher(
new AltErrorPageResourceFetcher(
- error_page_url, frame, original_error,
+ error_page_url, frame, frame->dataSource()->request(),
+ original_error,
base::Bind(&RenderViewImpl::AltErrorPageFinished,
base::Unretained(this))));
return;
@@ -3977,73 +4037,12 @@
preferred_size_));
}
-// The browser process needs to know the shape of the tree, as well as the names
-// and ids of all frames. This allows it to properly route JavaScript messages
-// across processes and frames. The serialization format is described in the
-// comments of the ViewMsg_FrameTreeUpdated message.
-// This function sends those updates to the browser and updates the RVH
-// corresponding to this object. It must be called on any events that modify
-// the tree structure or the names of any frames.
-void RenderViewImpl::SendUpdatedFrameTree(
- WebKit::WebFrame* exclude_frame_subtree) {
- // TODO(nasko): Frame tree updates are causing issues with postMessage, as
- // described in http://crbug.com/153701. Disable them until a proper fix is
- // in place.
-}
-
-BrowserPluginManager* RenderViewImpl::browser_plugin_manager() {
+BrowserPluginManager* RenderViewImpl::GetBrowserPluginManager() {
if (!browser_plugin_manager_)
browser_plugin_manager_ = BrowserPluginManager::Create(this);
return browser_plugin_manager_;
}
-void RenderViewImpl::CreateFrameTree(WebKit::WebFrame* frame,
- base::DictionaryValue* frame_tree) {
- // TODO(nasko): Remove once http://crbug.com/153701 is fixed.
- DCHECK(false);
- NavigateToSwappedOutURL(frame);
-
- string16 name;
- if (frame_tree->GetString(kFrameTreeNodeNameKey, &name) && !name.empty())
- frame->setName(name);
-
- int remote_id;
- if (frame_tree->GetInteger(kFrameTreeNodeIdKey, &remote_id))
- active_frame_id_map_.insert(std::pair<int, int>(frame->identifier(),
- remote_id));
-
- base::ListValue* children;
- if (!frame_tree->GetList(kFrameTreeNodeSubtreeKey, &children))
- return;
-
- // Create an invisible iframe tree in the swapped out page.
- base::DictionaryValue* child;
- for (size_t i = 0; i < children->GetSize(); ++i) {
- if (!children->GetDictionary(i, &child))
- continue;
- WebElement element = frame->document().createElement("iframe");
- element.setAttribute("width", "0");
- element.setAttribute("height", "0");
- element.setAttribute("frameBorder", "0");
- if (frame->document().body().appendChild(element)) {
- WebFrame* subframe = WebFrame::fromFrameOwnerElement(element);
- if (subframe)
- CreateFrameTree(subframe, child);
- } else {
- LOG(ERROR) << "Failed to append created iframe element.";
- }
- }
-}
-
-WebKit::WebFrame* RenderViewImpl::GetFrameByRemoteID(int remote_frame_id) {
- std::map<int, int>::const_iterator it = active_frame_id_map_.begin();
- for (; it != active_frame_id_map_.end(); ++it) {
- if (it->second == remote_frame_id)
- return FindFrameByID(webview()->mainFrame(), it->first);
- }
- return NULL;
-}
-
void RenderViewImpl::EnsureMediaStreamImpl() {
if (!RenderThreadImpl::current()) // Will be NULL during unit tests.
return;
@@ -4061,7 +4060,6 @@
media_stream_impl_ = new MediaStreamImpl(
this,
media_stream_dispatcher_,
- RenderThreadImpl::current()->video_capture_impl_manager(),
RenderThreadImpl::current()->GetMediaStreamDependencyFactory());
}
#endif
@@ -4124,11 +4122,15 @@
}
}
-#if defined(OS_ANDROID)
void RenderViewImpl::didFirstVisuallyNonEmptyLayout(WebFrame* frame) {
if (frame != webview()->mainFrame())
return;
+ InternalDocumentStateData* data =
+ InternalDocumentStateData::FromDataSource(frame->dataSource());
+ data->set_did_first_visually_non_empty_layout(true);
+
+#if defined(OS_ANDROID)
// Update body background color if necessary.
SkColor bg_color = webwidget_->backgroundColor();
@@ -4141,8 +4143,8 @@
body_background_color_ = bg_color;
Send(new ViewHostMsg_DidChangeBodyBackgroundColor(routing_id_, bg_color));
}
-}
#endif
+}
void RenderViewImpl::SendFindReply(int request_id,
int match_count,
@@ -4297,21 +4299,6 @@
RenderViewImpl* source_view = FromWebView(sourceFrame->view());
if (source_view)
params.source_routing_id = source_view->routing_id();
- params.source_frame_id = sourceFrame->identifier();
-
- // Include the process, route, and frame IDs of the target frame. This allows
- // the browser to detect races between this message being sent and the target
- // frame no longer being valid.
- params.target_process_id = target_process_id_;
- params.target_routing_id = target_routing_id_;
-
- std::map<int, int>::iterator it = active_frame_id_map_.find(
- targetFrame->identifier());
- if (it != active_frame_id_map_.end()) {
- params.target_frame_id = it->second;
- } else {
- params.target_frame_id = 0;
- }
Send(new ViewHostMsg_RouteMessageEvent(routing_id_, params));
return true;
@@ -4346,12 +4333,17 @@
else
data_source = main_frame->dataSource();
- DocumentState* document_state =
- data_source ? DocumentState::FromDataSource(data_source) : NULL;
- if (document_state && document_state->is_overriding_user_agent())
+ InternalDocumentStateData* internal_data = data_source ?
+ InternalDocumentStateData::FromDataSource(data_source) : NULL;
+ if (internal_data && internal_data->is_overriding_user_agent())
return WebString::fromUTF8(renderer_preferences_.user_agent_override);
- else
- return WebKit::WebString();
+ return WebKit::WebString();
+}
+
+WebString RenderViewImpl::doNotTrackValue(WebFrame* frame) {
+ if (renderer_preferences_.enable_do_not_track)
+ return WebString::fromUTF8("1");
+ return WebString();
}
bool RenderViewImpl::allowWebGL(WebFrame* frame, bool default_value) {
@@ -4695,6 +4687,7 @@
selection_range_ = range;
Send(new ViewHostMsg_SelectionChanged(routing_id_, text, offset, range));
}
+ UpdateSelectionBounds();
}
GURL RenderViewImpl::GetAlternateErrorPageURL(const GURL& failed_url,
@@ -4811,7 +4804,8 @@
if (!result) {
// don't leave text selected as you move to the next frame.
- search_frame->executeCommand(WebString::fromUTF8("Unselect"));
+ search_frame->executeCommand(WebString::fromUTF8("Unselect"),
+ GetFocusedNode());
// Find the next frame, but skip the invisible ones.
do {
@@ -4824,7 +4818,8 @@
search_frame != focused_frame);
// Make sure selection doesn't affect the search operation in new frame.
- search_frame->executeCommand(WebString::fromUTF8("Unselect"));
+ search_frame->executeCommand(WebString::fromUTF8("Unselect"),
+ GetFocusedNode());
// If we have multiple frames and we have wrapped back around to the
// focused frame, we need to search it once more allowing wrap within
@@ -4897,8 +4892,10 @@
}
bool clear_selection = action == STOP_FIND_ACTION_CLEAR_SELECTION;
- if (clear_selection)
- view->focusedFrame()->executeCommand(WebString::fromUTF8("Unselect"));
+ if (clear_selection) {
+ view->focusedFrame()->executeCommand(WebString::fromUTF8("Unselect"),
+ GetFocusedNode());
+ }
WebFrame* frame = view->mainFrame();
while (frame) {
@@ -5075,24 +5072,20 @@
const string16& jscript,
int id,
bool notify_result) {
- TRACE_EVENT_INSTANT0("test_tracing", "OnScriptEvalRequest");
+ TRACE_EVENT_INSTANT0("test_tracing", "OnScriptEvalRequest",
+ TRACE_EVENT_SCOPE_THREAD);
EvaluateScript(frame_xpath, jscript, id, notify_result);
}
void RenderViewImpl::OnPostMessageEvent(
const ViewMsg_PostMessage_Params& params) {
- // Find the target frame of this message. The source tags the message with
- // |target_frame_id|, so use it to locate the frame.
- // TODO(nasko): Lookup based on the frame id, once http://crbug.com/153701
- // is fixed and we can rely on having frame tree updates again.
+ // TODO(nasko): Support sending to subframes.
WebFrame* frame = webview()->mainFrame();
// Find the source frame if it exists.
WebFrame* source_frame = NULL;
if (params.source_routing_id != MSG_ROUTING_NONE) {
RenderViewImpl* source_view = FromRoutingID(params.source_routing_id);
- // TODO(nasko): Lookup based on the frame id, once http://crbug.com/153701
- // is fixed and we can rely on having frame tree updates again.
if (source_view)
source_frame = source_view->webview()->mainFrame();
}
@@ -5198,7 +5191,7 @@
void RenderViewImpl::OnUpdateWebPreferences(const WebPreferences& prefs) {
webkit_preferences_ = prefs;
- webkit_preferences_.Apply(webview());
+ webkit_glue::ApplyWebPreferences(webkit_preferences_, webview());
}
void RenderViewImpl::OnUpdateTimezone() {
@@ -5546,6 +5539,9 @@
if (!error_page_url.is_valid())
return false;
+ WebDataSource* ds = frame->provisionalDataSource();
+ const WebURLRequest& failed_request = ds->request();
+
// Load an empty page first so there is an immediate response to the error,
// and then kick off a request for the alternate error page.
frame->loadHTMLString(std::string(),
@@ -5556,23 +5552,24 @@
// Now, create a fetcher for the error page and associate it with the data
// source we just created via the LoadHTMLString call. That way if another
// navigation occurs, the fetcher will get destroyed.
- DocumentState* document_state =
- DocumentState::FromDataSource(frame->provisionalDataSource());
- document_state->set_alt_error_page_fetcher(
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDataSource(frame->provisionalDataSource());
+ internal_data->set_alt_error_page_fetcher(
new AltErrorPageResourceFetcher(
- error_page_url, frame, error,
+ error_page_url, frame, failed_request, error,
base::Bind(&RenderViewImpl::AltErrorPageFinished,
base::Unretained(this))));
return true;
}
void RenderViewImpl::AltErrorPageFinished(WebFrame* frame,
+ const WebURLRequest& original_request,
const WebURLError& original_error,
const std::string& html) {
// Here, we replace the blank page we loaded previously.
// If we failed to download the alternate error page, LoadNavigationErrorPage
// will simply display a default error page.
- LoadNavigationErrorPage(frame, WebURLRequest(), original_error, html, true);
+ LoadNavigationErrorPage(frame, original_request, original_error, html, true);
}
void RenderViewImpl::OnMoveOrResizeStarted() {
@@ -5627,6 +5624,14 @@
if (!main_frame->provisionalDataSource()) {
WebDataSource* ds = main_frame->dataSource();
DocumentState* document_state = DocumentState::FromDataSource(ds);
+ InternalDocumentStateData* data =
+ InternalDocumentStateData::FromDocumentState(document_state);
+ if (data->did_first_visually_non_empty_layout() &&
+ !data->did_first_visually_non_empty_paint()) {
+ data->set_did_first_visually_non_empty_paint(true);
+ Send(new ViewHostMsg_DidFirstVisuallyNonEmptyPaint(routing_id_,
+ page_id_));
+ }
// TODO(jar): The following code should all be inside a method, probably in
// NavigatorState.
@@ -5697,26 +5702,6 @@
#endif
}
-void RenderViewImpl::OnSetNavigationStartTime(
- const base::TimeTicks& browser_navigation_start) {
- // Only the initial navigation can be a cross-renderer navigation. If we've
- // already navigated away from that page, we can ignore this message.
- if (page_id_ != -1)
- return;
-
- if (!webview() || !webview()->mainFrame() ||
- !webview()->mainFrame()->provisionalDataSource())
- return;
-
- // browser_navigation_start is likely before this process existed, so we can't
- // use InterProcessTimeTicksConverter. Instead, the best we can do is just
- // ensure we don't report a bogus value in the future.
- base::TimeTicks navigation_start = std::min(base::TimeTicks::Now(),
- browser_navigation_start);
- webview()->mainFrame()->provisionalDataSource()->setNavigationStartTime(
- (navigation_start - base::TimeTicks()).InSecondsF());
-}
-
#if defined(OS_MACOSX)
void RenderViewImpl::OnSetWindowVisibility(bool visible) {
// Inform plugins that their container has changed visibility.
@@ -5749,11 +5734,6 @@
}
#endif // OS_MACOSX
-void RenderViewImpl::OnSetEditCommandsForNextKeyEvent(
- const EditCommands& edit_commands) {
- edit_commands_ = edit_commands;
-}
-
void RenderViewImpl::Close() {
// We need to grab a pointer to the doomed WebView before we destroy it.
WebView* doomed = webview();
@@ -5811,6 +5791,11 @@
// only be freed once the tab is destroyed or if the user navigates away
// via WebMediaPlayerAndroid::Destroy
media_player_manager_->ReleaseMediaResources();
+
+#if defined(ENABLE_WEBRTC)
+ RenderThreadImpl::current()->video_capture_impl_manager()->
+ SuspendDevices(true);
+#endif
#endif
if (webview()) {
@@ -5835,6 +5820,11 @@
void RenderViewImpl::OnWasShown(bool needs_repainting) {
RenderWidget::OnWasShown(needs_repainting);
+#if defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
+ RenderThreadImpl::current()->video_capture_impl_manager()->
+ SuspendDevices(false);
+#endif
+
if (webview()) {
webview()->settings()->setMinimumTimerInterval(
webkit_glue::kForegroundTabTimerInterval);
@@ -5887,7 +5877,7 @@
pepper_helper_->OnSetFocus(enable);
// Notify all BrowserPlugins of the RenderView's focus state.
if (browser_plugin_manager_)
- browser_plugin_manager()->UpdateFocusState();
+ browser_plugin_manager_->UpdateFocusState();
}
void RenderViewImpl::PpapiPluginFocusChanged() {
@@ -6030,6 +6020,9 @@
}
if (auto_resize_mode_)
AutoResizeCompositor();
+
+ if (browser_plugin_manager_)
+ browser_plugin_manager_->UpdateDeviceScaleFactor(device_scale_factor_);
}
ui::TextInputType RenderViewImpl::GetTextInputType() {
@@ -6293,10 +6286,12 @@
void RenderViewImpl::scheduleContentIntent(const WebURL& intent) {
// Introduce a short delay so that the user can notice the content.
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
- base::Bind(&RenderViewImpl::LaunchAndroidContentIntent, AsWeakPtr(),
- intent, expected_content_intent_id_),
+ base::Bind(&RenderViewImpl::LaunchAndroidContentIntent,
+ AsWeakPtr(),
+ intent,
+ expected_content_intent_id_),
base::TimeDelta::FromMilliseconds(kContentIntentDelayMilliseconds));
}
@@ -6372,7 +6367,7 @@
// a select faster than it takes for the show-select-popup IPC message to make
// it to the browser UI thread. Ignore the extra-messages.
// TODO(jcivelli): http:/b/5793321 Implement a better fix, as detailed in bug.
- if (!external_popup_menu_.get())
+ if (!external_popup_menu_)
return;
external_popup_menu_->DidSelectItems(canceled, selected_indices);
@@ -6396,6 +6391,11 @@
}
}
+void RenderViewImpl::OnShowContextMenu() {
+ if (webview())
+ webview()->showContextMenu();
+}
+
void RenderViewImpl::OnEnableViewSourceMode() {
if (!webview())
return;
@@ -6421,32 +6421,6 @@
main_frame->setOpener(NULL);
}
-void RenderViewImpl::OnUpdatedFrameTree(
- int process_id,
- int route_id,
- const std::string& frame_tree) {
- // TODO(nasko): Remove once http://crbug.com/153701 is fixed.
- DCHECK(false);
- // We should only act on this message if we are swapped out. It's possible
- // for this to happen due to races.
- if (!is_swapped_out_)
- return;
-
- base::DictionaryValue* frames = NULL;
- scoped_ptr<base::Value> tree(base::JSONReader::Read(frame_tree));
- if (tree.get() && tree->IsType(base::Value::TYPE_DICTIONARY))
- tree->GetAsDictionary(&frames);
-
- updating_frame_tree_ = true;
- active_frame_id_map_.clear();
-
- target_process_id_ = process_id;
- target_routing_id_ = route_id;
- CreateFrameTree(webview()->mainFrame(), frames);
-
- updating_frame_tree_ = false;
-}
-
#if defined(OS_ANDROID)
bool RenderViewImpl::didTapMultipleTargets(
const WebKit::WebGestureEvent& event,
@@ -6470,7 +6444,7 @@
scoped_ptr<skia::PlatformCanvas> canvas(
RenderProcess::current()->GetDrawingCanvas(&transport_dib,
gfx::Rect(canvas_size)));
- if (!canvas.get())
+ if (!canvas)
return false;
// TODO(trchen): Cleanup the device scale factor mess.
@@ -6537,4 +6511,28 @@
FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidCommitCompositorFrame());
}
+void RenderViewImpl::SendUpdateFaviconURL(const std::vector<FaviconURL>& urls) {
+ if (!urls.empty())
+ Send(new ViewHostMsg_UpdateFaviconURL(routing_id_, page_id_, urls));
+}
+
+void RenderViewImpl::DidStopLoadingIcons() {
+ int icon_types = WebIconURL::TypeFavicon;
+ if (TouchEnabled())
+ icon_types |= WebIconURL::TypeTouchPrecomposed | WebIconURL::TypeTouch;
+
+ WebVector<WebIconURL> icon_urls =
+ webview()->mainFrame()->iconURLs(icon_types);
+
+ std::vector<FaviconURL> urls;
+ for (size_t i = 0; i < icon_urls.size(); i++) {
+ WebURL url = icon_urls[i].iconURL();
+ if (!url.isEmpty())
+ urls.push_back(FaviconURL(url,
+ ToFaviconType(icon_urls[i].iconType())));
+ }
+ SendUpdateFaviconURL(urls);
+}
+
+
} // namespace content
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index a778fb4..09092c0 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -19,7 +19,6 @@
#include "base/observer_list.h"
#include "base/process.h"
#include "base/timer.h"
-#include "base/values.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/common/drag_event_source_info.h"
@@ -41,6 +40,7 @@
#include "third_party/WebKit/Source/Platform/chromium/public/WebFileSystem.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrameClient.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebHistoryItem.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebIconURL.h"
@@ -97,7 +97,6 @@
#if defined(OS_ANDROID)
namespace webkit_media {
-class MediaPlayerBridgeManagerImpl;
class WebMediaPlayerManagerAndroid;
}
#endif
@@ -169,6 +168,7 @@
class SpeechRecognitionDispatcher;
class WebPluginDelegateProxy;
struct CustomContextMenuContext;
+struct FaviconURL;
struct FileChooserParams;
struct RenderViewImplParams;
@@ -211,7 +211,7 @@
static RenderViewImpl* Create(
int32 opener_id,
const RendererPreferences& renderer_prefs,
- const webkit_glue::WebPreferences& webkit_prefs,
+ const WebPreferences& webkit_prefs,
SharedRenderViewCounter* counter,
int32 routing_id,
int32 surface_id,
@@ -240,14 +240,10 @@
int history_list_offset() const { return history_list_offset_; }
- const webkit_glue::WebPreferences& webkit_preferences() const {
+ const WebPreferences& webkit_preferences() const {
return webkit_preferences_;
}
- bool enable_do_not_track() const {
- return renderer_preferences_.enable_do_not_track;
- }
-
void set_send_content_state_immediately(bool value) {
send_content_state_immediately_ = value;
}
@@ -267,7 +263,7 @@
#endif
// Lazily initialize this view's BrowserPluginManager and return it.
- BrowserPluginManager* browser_plugin_manager();
+ BrowserPluginManager* GetBrowserPluginManager();
// Functions to add and remove observers for this object.
void AddObserver(RenderViewObserver* observer);
@@ -466,7 +462,6 @@
virtual void focusPrevious();
virtual void focusedNodeChanged(const WebKit::WebNode& node);
virtual void numberOfWheelEventHandlersChanged(unsigned num_handlers);
- virtual void hasTouchEventHandlers(bool has_handlers);
virtual void didUpdateLayout();
#if defined(OS_ANDROID)
virtual bool didTapMultipleTargets(
@@ -538,11 +533,20 @@
const WebKit::WebURLRequest& request,
WebKit::WebNavigationPolicy policy,
const WebKit::WebString& suggested_name);
+
+ // The WebDataSource::ExtraData* is assumed to be a DocumentState* subclass.
+ virtual WebKit::WebNavigationPolicy decidePolicyForNavigation(
+ WebKit::WebFrame* frame,
+ WebKit::WebDataSource::ExtraData* extraData,
+ const WebKit::WebURLRequest& request,
+ WebKit::WebNavigationType type,
+ WebKit::WebNavigationPolicy default_policy,
+ bool is_redirect);
+ // DEPRECATED.
virtual WebKit::WebNavigationPolicy decidePolicyForNavigation(
WebKit::WebFrame* frame,
const WebKit::WebURLRequest& request,
WebKit::WebNavigationType type,
- const WebKit::WebNode&,
WebKit::WebNavigationPolicy default_policy,
bool is_redirect);
virtual bool canHandleRequest(WebKit::WebFrame* frame,
@@ -629,9 +633,7 @@
int world_id);
virtual void didChangeScrollOffset(WebKit::WebFrame* frame);
virtual void willInsertBody(WebKit::WebFrame* frame) OVERRIDE;
-#if defined(OS_ANDROID)
virtual void didFirstVisuallyNonEmptyLayout(WebKit::WebFrame*) OVERRIDE;
-#endif
virtual void didChangeContentsSize(WebKit::WebFrame* frame,
const WebKit::WebSize& size);
virtual void reportFindInPageMatchCount(int request_id,
@@ -669,6 +671,7 @@
virtual WebKit::WebString userAgentOverride(
WebKit::WebFrame* frame,
const WebKit::WebURL& url) OVERRIDE;
+ virtual WebKit::WebString doNotTrackValue(WebKit::WebFrame* frame) OVERRIDE;
virtual bool allowWebGL(WebKit::WebFrame* frame, bool default_value) OVERRIDE;
virtual void didLoseWebGLContext(
WebKit::WebFrame* frame,
@@ -687,9 +690,8 @@
virtual int GetRoutingID() const OVERRIDE;
virtual int GetPageId() const OVERRIDE;
virtual gfx::Size GetSize() const OVERRIDE;
- virtual webkit_glue::WebPreferences& GetWebkitPreferences() OVERRIDE;
- virtual void SetWebkitPreferences(
- const webkit_glue::WebPreferences& preferences) OVERRIDE;
+ virtual WebPreferences& GetWebkitPreferences() OVERRIDE;
+ virtual void SetWebkitPreferences(const WebPreferences& preferences) OVERRIDE;
virtual WebKit::WebView* GetWebView() OVERRIDE;
virtual WebKit::WebNode GetFocusedNode() const OVERRIDE;
virtual WebKit::WebNode GetContextMenuNode() const OVERRIDE;
@@ -826,6 +828,10 @@
FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuTest, ShowPopupThenNavigate);
FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, DecideNavigationPolicyForWebUI);
FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest,
+ DidFailProvisionalLoadWithErrorForError);
+ FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest,
+ DidFailProvisionalLoadWithErrorForCancellation);
+ FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest,
DontIgnoreBackAfterNavEntryLimit);
FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, ImeComposition);
FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, InsertCharacters);
@@ -905,7 +911,24 @@
// IPC message handlers ------------------------------------------------------
//
// The documentation for these functions should be in
- // render_messages_internal.h for the message that the function is handling.
+ // content/common/*_messages.h for the message that the function is handling.
+
+ void OnCopy();
+ void OnCut();
+ void OnDelete();
+ void OnExecuteEditCommand(const std::string& name, const std::string& value);
+ void OnMoveCaret(const gfx::Point& point);
+ void OnPaste();
+ void OnPasteAndMatchStyle();
+ void OnRedo();
+ void OnReplace(const string16& text);
+ void OnReplaceMisspelling(const string16& text);
+ void OnScrollFocusedEditableNodeIntoRect(const gfx::Rect& rect);
+ void OnSelectAll();
+ void OnSelectRange(const gfx::Point& start, const gfx::Point& end);
+ void OnSetEditCommandsForNextKeyEvent(const EditCommands& edit_commands);
+ void OnUndo();
+ void OnUnselect();
void OnAllowBindings(int enabled_bindings_flags);
void OnAllowScriptToClose(bool script_can_close);
@@ -920,14 +943,12 @@
void OnClearFocusedNode();
void OnClosePage();
void OnContextMenuClosed(const CustomContextMenuContext& custom_context);
- void OnCopy();
+ void OnShowContextMenu();
void OnCopyImageAt(int x, int y);
- void OnCut();
void OnCSSInsertRequest(const string16& frame_xpath,
const std::string& css);
void OnCustomContextMenuAction(const CustomContextMenuContext& custom_context,
unsigned action);
- void OnDelete();
void OnSetName(const std::string& name);
void OnDeterminePageLanguage();
void OnDisableScrollbarsForSmallWindows(
@@ -956,7 +977,6 @@
void OnDisableAutoResize(const gfx::Size& new_size);
void OnEnumerateDirectoryResponse(int id,
const std::vector<base::FilePath>& paths);
- void OnExecuteEditCommand(const std::string& name, const std::string& value);
void OnExtendSelectionAndDelete(int before, int after);
void OnFileChooserResponse(
const std::vector<ui::SelectedFileInfo>& files);
@@ -976,22 +996,14 @@
const WebKit::WebPluginAction& action);
void OnMoveOrResizeStarted();
void OnNavigate(const ViewMsg_Navigate_Params& params);
- void OnPaste();
- void OnPasteAndMatchStyle();
void OnPostMessageEvent(const ViewMsg_PostMessage_Params& params);
- void OnRedo();
void OnReleaseDisambiguationPopupDIB(TransportDIB::Handle dib_handle);
void OnReloadFrame();
- void OnReplace(const string16& text);
- void OnReplaceMisspelling(const string16& text);
void OnResetPageEncodingToDefault();
void OnScriptEvalRequest(const string16& frame_xpath,
const string16& jscript,
int id,
bool notify_result);
- void OnSelectAll();
- void OnSelectRange(const gfx::Point& start, const gfx::Point& end);
- void OnMoveCaret(const gfx::Point& point);
void OnSetAccessibilityMode(AccessibilityMode new_mode);
void OnSetActive(bool active);
void OnSetAltErrorPageURL(const GURL& gurl);
@@ -999,29 +1011,23 @@
void OnSetCompositionFromExistingText(
int start, int end,
const std::vector<WebKit::WebCompositionUnderline>& underlines);
+ void OnExitFullscreen();
void OnSetEditableSelectionOffsets(int start, int end);
- void OnSetNavigationStartTime(
- const base::TimeTicks& browser_navigation_start);
- void OnSetWebUIProperty(const std::string& name, const std::string& value);
- void OnSetEditCommandsForNextKeyEvent(const EditCommands& edit_commands);
void OnSetHistoryLengthAndPrune(int history_length, int32 minimum_page_id);
void OnSetInitialFocus(bool reverse);
- void OnScrollFocusedEditableNodeIntoRect(const gfx::Rect& rect);
void OnSetPageEncoding(const std::string& encoding_name);
void OnSetRendererPrefs(const RendererPreferences& renderer_prefs);
+ void OnSetWebUIProperty(const std::string& name, const std::string& value);
void OnSetZoomLevel(double zoom_level);
void OnSetZoomLevelForLoadingURL(const GURL& url, double zoom_level);
- void OnExitFullscreen();
void OnShouldClose();
void OnStop();
void OnStopFinding(StopFindAction action);
void OnSwapOut(const ViewMsg_SwapOut_Params& params);
void OnThemeChanged();
- void OnUndo();
void OnUpdateTargetURLAck();
void OnUpdateTimezone();
- void OnUpdateWebPreferences(const webkit_glue::WebPreferences& prefs);
- void OnUnselect();
+ void OnUpdateWebPreferences(const WebPreferences& prefs);
void OnZoom(PageZoom zoom);
void OnZoomFactor(PageZoom zoom, int zoom_center_x, int zoom_center_y);
@@ -1031,9 +1037,6 @@
void OnJavaBridgeInit();
void OnDisownOpener();
- void OnUpdatedFrameTree(int process_id,
- int route_id,
- const std::string& frame_tree);
#if defined(OS_ANDROID)
void OnActivateNearestFindResult(int request_id, float x, float y);
@@ -1041,7 +1044,9 @@
void OnSelectPopupMenuItems(bool canceled,
const std::vector<int>& selected_indices);
void OnUndoScrollFocusedEditableNodeIntoRect();
- void OnEnableHidingTopControls(bool enable);
+ void OnUpdateTopControlsState(bool enable_hiding,
+ bool enable_showing,
+ bool animate);
#elif defined(OS_MACOSX)
void OnCopyToFindPboard();
void OnPluginImeCompositionCompleted(const string16& text, int plugin_id);
@@ -1064,34 +1069,13 @@
float scaling_increment);
void AltErrorPageFinished(WebKit::WebFrame* frame,
+ const WebKit::WebURLRequest& original_request,
const WebKit::WebURLError& original_error,
const std::string& html);
// Check whether the preferred size has changed.
void CheckPreferredSize();
- // This method walks the entire frame tree for this RenderView and sends an
- // update to the browser process as described in the
- // ViewHostMsg_FrameTreeUpdated comments. If |exclude_frame_subtree|
- // frame is non-NULL, the subtree starting at that frame not included in the
- // serialized form.
- // This is used when a frame is going to be removed from the tree.
- void SendUpdatedFrameTree(WebKit::WebFrame* exclude_frame_subtree);
-
- // Recursively creates a DOM frame tree starting with |frame|, based on
- // |frame_tree|. For each node, the frame is navigated to the swapped out URL,
- // the name (if present) is set on it, and all the subframes are created
- // and added to the DOM.
- void CreateFrameTree(WebKit::WebFrame* frame,
- base::DictionaryValue* frame_tree);
-
- // If this is a swapped out RenderView, which maintains a copy of the frame
- // tree of an active RenderView, we keep a map from frame ids in this view to
- // the frame ids of the active view for each corresponding frame.
- // This method returns the frame in this RenderView that corresponds to the
- // frame in the active RenderView specified by |remote_frame_id|.
- WebKit::WebFrame* GetFrameByRemoteID(int remote_frame_id);
-
void EnsureMediaStreamImpl();
// This callback is triggered when DownloadFavicon completes, either
@@ -1184,6 +1168,13 @@
// If |url| is empty, show |fallback_url|.
void UpdateTargetURL(const GURL& url, const GURL& fallback_url);
+ // Tells the browser what the new list of favicons for the webpage is.
+ void SendUpdateFaviconURL(const std::vector<FaviconURL>& urls);
+
+ // Invoked from DidStopLoading(). Sends the current list of loaded favicons to
+ // the browser.
+ void DidStopLoadingIcons();
+
// Coordinate conversion -----------------------------------------------------
gfx::RectF ClientRectToPhysicalWindowRect(const gfx::RectF& rect) const;
@@ -1195,7 +1186,7 @@
// Settings ------------------------------------------------------------------
- webkit_glue::WebPreferences webkit_preferences_;
+ WebPreferences webkit_preferences_;
RendererPreferences renderer_preferences_;
HostZoomLevels host_zoom_levels_;
@@ -1416,9 +1407,6 @@
// Mouse Lock dispatcher attached to this view.
MouseLockDispatcher* mouse_lock_dispatcher_;
- // Helper class to handle favicon changes.
- FaviconHelper* favicon_helper_;
-
#if defined(OS_ANDROID)
// Android Specific ---------------------------------------------------------
@@ -1427,9 +1415,6 @@
// have the actual content.
SkColor body_background_color_;
- // True if SendUpdateFrameInfo is pending.
- bool update_frame_info_scheduled_;
-
// Expected id of the next content intent launched. Used to prevent scheduled
// intents to be launched if aborted.
size_t expected_content_intent_id_;
@@ -1445,14 +1430,22 @@
// The media player manager for managing all the media players on this view.
scoped_ptr<webkit_media::WebMediaPlayerManagerAndroid> media_player_manager_;
- // Resource manager for all the android media player objects if they are
- // created in the renderer process.
- scoped_ptr<webkit_media::MediaPlayerBridgeManagerImpl> media_bridge_manager_;
-
// A date/time picker object for date and time related input elements.
scoped_ptr<RendererDateTimePicker> date_time_picker_client_;
#endif
+ // Plugins -------------------------------------------------------------------
+
+ // All the currently active plugin delegates for this RenderView; kept so
+ // that we can enumerate them to send updates about things like window
+ // location or tab focus and visibily. These are non-owning references.
+ std::set<WebPluginDelegateProxy*> plugin_delegates_;
+
+#if defined(OS_WIN)
+ // The ID of the focused NPAPI plug-in.
+ int focused_plugin_id_;
+#endif
+
// Misc ----------------------------------------------------------------------
// The current and pending file chooser completion objects. If the queue is
@@ -1499,7 +1492,7 @@
ObserverList<RenderViewObserver> observers_;
// Used to inform didChangeSelection() when it is called in the context
- // of handling a ViewMsg_SelectRange IPC.
+ // of handling a InputMsg_SelectRange IPC.
bool handling_select_range_;
// Wraps the |webwidget_| as a MouseLockDispatcher::LockTarget interface.
@@ -1511,52 +1504,14 @@
PendingSnapshotMap;
PendingSnapshotMap pending_snapshots_;
+ // Allows to selectively disable partial buffer swap for this renderer's
+ // compositor.
bool allow_partial_swap_;
- // Plugins -------------------------------------------------------------------
-
- // All the currently active plugin delegates for this RenderView; kept so
- // that we can enumerate them to send updates about things like window
- // location or tab focus and visibily. These are non-owning references.
- std::set<WebPluginDelegateProxy*> plugin_delegates_;
-
-#if defined(OS_WIN)
- // The ID of the focused NPAPI plug-in.
- int focused_plugin_id_;
-#endif
-
// Allows JS to access DOM automation. The JS object is only exposed when the
// DOM automation bindings are enabled.
scoped_ptr<DomAutomationController> dom_automation_controller_;
- // Boolean indicating whether we are in the process of creating the frame
- // tree for this renderer in response to ViewMsg_UpdateFrameTree. If true,
- // we won't be sending ViewHostMsg_FrameTreeUpdated messages back to the
- // browser, as those will be redundant.
- bool updating_frame_tree_;
-
- // Boolean indicating that the frame tree has changed, but a message has not
- // been sent to the browser because a page has been loading. This helps
- // avoid extra messages being sent to the browser when navigating away from a
- // page with subframes, which will be destroyed. Instead, a single message
- // is sent when the load is stopped with the final state of the frame tree.
- //
- // TODO(nasko): Relying on the is_loading_ means that frame tree updates will
- // not be sent until *all* subframes have completed loading. This can cause
- // JavaScript calls to fail, if they occur prior to the first update message
- // being sent. This will be fixed by bug http://crbug.com/145014.
- bool pending_frame_tree_update_;
-
- // If this render view is a swapped out "mirror" of an active render view in a
- // different process, we record the process id and route id for the active RV.
- // For further details, see the comments on ViewHostMsg_FrameTreeUpdated.
- int target_process_id_;
- int target_routing_id_;
-
- // A map of the current process's frame ids to ids in the remote active render
- // view, if this is a swapped out render view.
- std::map<int, int> active_frame_id_map_;
-
// This field stores drag/drop related info for the event that is currently
// being handled. If the current event results in starting a drag/drop
// session, this info is sent to the browser along with other drag/drop info.
diff --git a/content/renderer/render_view_impl_android.cc b/content/renderer/render_view_impl_android.cc
index bc061f2..0d5ade1 100644
--- a/content/renderer/render_view_impl_android.cc
+++ b/content/renderer/render_view_impl_android.cc
@@ -11,11 +11,14 @@
namespace content {
-void RenderViewImpl::OnEnableHidingTopControls(bool enable) {
- DCHECK(compositor_);
- if (compositor_) {
- compositor_->EnableHidingTopControls(enable);
- }
+void RenderViewImpl::OnUpdateTopControlsState(bool enable_hiding,
+ bool enable_showing,
+ bool animate) {
+ // TODO(tedchoc): Investigate why messages are getting here before the
+ // compositor has been initialized.
+ LOG_IF(WARNING, !compositor_) << "OnUpdateTopControlsState was unhandled.";
+ if (compositor_)
+ compositor_->UpdateTopControlsState(enable_hiding, enable_showing, animate);
}
} // namespace content
diff --git a/content/renderer/render_view_impl_params.cc b/content/renderer/render_view_impl_params.cc
index 5035b35..521778b 100644
--- a/content/renderer/render_view_impl_params.cc
+++ b/content/renderer/render_view_impl_params.cc
@@ -9,7 +9,7 @@
RenderViewImplParams::RenderViewImplParams(
int32 opener_id,
const RendererPreferences& renderer_prefs,
- const webkit_glue::WebPreferences& webkit_prefs,
+ const WebPreferences& webkit_prefs,
SharedRenderViewCounter* counter,
int32 routing_id,
int32 surface_id,
diff --git a/content/renderer/render_view_impl_params.h b/content/renderer/render_view_impl_params.h
index 7288ab1..da29fea 100644
--- a/content/renderer/render_view_impl_params.h
+++ b/content/renderer/render_view_impl_params.h
@@ -11,14 +11,12 @@
#include "content/common/content_export.h"
#include "content/common/view_message_enums.h"
+struct WebPreferences;
+
namespace WebKit {
struct WebScreenInfo;
}
-namespace webkit_glue {
-struct WebPreferences;
-}
-
namespace content {
struct RendererPreferences;
@@ -28,7 +26,7 @@
struct CONTENT_EXPORT RenderViewImplParams {
RenderViewImplParams(int32 opener_id,
const RendererPreferences& renderer_prefs,
- const webkit_glue::WebPreferences& webkit_prefs,
+ const WebPreferences& webkit_prefs,
SharedRenderViewCounter* counter,
int32 routing_id,
int32 surface_id,
@@ -44,7 +42,7 @@
int32 opener_id;
const RendererPreferences& renderer_prefs;
- const webkit_glue::WebPreferences& webkit_prefs;
+ const WebPreferences& webkit_prefs;
SharedRenderViewCounter* counter;
int32 routing_id;
int32 surface_id;
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 23511ac..a9069aa 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -20,11 +20,12 @@
#include "cc/output/output_surface.h"
#include "cc/trees/layer_tree_host.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
+#include "content/common/input_messages.h"
#include "content/common/swapped_out_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_switches.h"
#include "content/renderer/gpu/compositor_output_surface.h"
-#include "content/renderer/gpu/compositor_software_output_device_gl_adapter.h"
+#include "content/renderer/gpu/compositor_software_output_device.h"
#include "content/renderer/gpu/input_handler_manager.h"
#include "content/renderer/gpu/mailbox_output_surface.h"
#include "content/renderer/gpu/render_widget_compositor.h"
@@ -54,10 +55,13 @@
#include "ui/surface/transport_dib.h"
#include "webkit/compositor_bindings/web_rendering_stats_impl.h"
#include "webkit/glue/webkit_glue.h"
-#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"
#include "webkit/plugins/npapi/webplugin.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
+#if defined(OS_ANDROID)
+#include "content/renderer/android/synchronous_compositor_output_surface.h"
+#endif
+
#if defined(OS_POSIX)
#include "ipc/ipc_channel_posix.h"
#include "third_party/skia/include/core/SkMallocPixelRef.h"
@@ -171,9 +175,8 @@
screen_info_(screen_info),
device_scale_factor_(screen_info_.deviceScaleFactor),
throttle_input_events_(true),
- next_smooth_scroll_gesture_id_(0),
is_threaded_compositing_enabled_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
+ weak_ptr_factory_(this) {
if (!swapped_out)
RenderProcess::current()->AddRefProcess();
DCHECK(RenderThread::Get());
@@ -292,9 +295,24 @@
return true;
}
+bool RenderWidget::SynchronouslyDisableVSync() const {
+#if defined(OS_ANDROID)
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableSynchronousRendererCompositor)) {
+ return true;
+ }
+#endif
+ return false;
+}
+
bool RenderWidget::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderWidget, message)
+ IPC_MESSAGE_HANDLER(InputMsg_HandleInputEvent, OnHandleInputEvent)
+ IPC_MESSAGE_HANDLER(InputMsg_CursorVisibilityChange,
+ OnCursorVisibilityChange)
+ IPC_MESSAGE_HANDLER(InputMsg_MouseCaptureLost, OnMouseCaptureLost)
+ IPC_MESSAGE_HANDLER(InputMsg_SetFocus, OnSetFocus)
IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose)
IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck)
IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize)
@@ -305,9 +323,6 @@
IPC_MESSAGE_HANDLER(ViewMsg_UpdateRect_ACK, OnUpdateRectAck)
IPC_MESSAGE_HANDLER(ViewMsg_SwapBuffers_ACK,
OnViewContextSwapBuffersComplete)
- IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent)
- IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost)
- IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus)
IPC_MESSAGE_HANDLER(ViewMsg_SetInputMethodActive, OnSetInputMethodActive)
IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition)
IPC_MESSAGE_HANDLER(ViewMsg_ImeConfirmComposition, OnImeConfirmComposition)
@@ -423,7 +438,7 @@
// If there is a Send call on the stack, then it could be dangerous to close
// now. Post a task that only gets invoked when there are no nested message
// loops.
- MessageLoop::current()->PostNonNestableTask(
+ base::MessageLoop::current()->PostNonNestableTask(
FROM_HERE, base::Bind(&RenderWidget::Close, this));
// Balances the AddRef taken when we called AddRoute.
@@ -556,6 +571,13 @@
}
scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface() {
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ if (command_line.HasSwitch(switches::kEnableSoftwareCompositingGLAdapter)) {
+ return scoped_ptr<cc::OutputSurface>(
+ new CompositorOutputSurface(routing_id(), NULL,
+ new CompositorSoftwareOutputDevice()));
+ }
+
// Explicitly disable antialiasing for the compositor. As of the time of
// this writing, the only platform that supported antialiasing for the
// compositor was Mac OS X, because the on-screen OpenGL context creation
@@ -570,29 +592,30 @@
attributes.antialias = false;
attributes.shareResources = true;
attributes.noAutomaticFlushes = true;
- WebGraphicsContext3D* context = CreateGraphicsContext3D(attributes);
+ WebGraphicsContext3DCommandBufferImpl* context =
+ CreateGraphicsContext3D(attributes);
if (!context)
return scoped_ptr<cc::OutputSurface>();
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kEnableSoftwareCompositingGLAdapter)) {
- // In the absence of a software-based delegating renderer, use this
- // stopgap adapter class to present the software renderer output using a
- // 3d context.
- return scoped_ptr<cc::OutputSurface>(
- new CompositorOutputSurface(routing_id(), NULL,
- new CompositorSoftwareOutputDeviceGLAdapter(context)));
- } else {
- bool composite_to_mailbox =
- command_line.HasSwitch(cc::switches::kCompositeToMailbox);
- DCHECK(!composite_to_mailbox || command_line.HasSwitch(
- cc::switches::kEnableCompositorFrameMessage));
- // No swap throttling yet when compositing on the main thread.
- DCHECK(!composite_to_mailbox || is_threaded_compositing_enabled_);
- return scoped_ptr<cc::OutputSurface>(composite_to_mailbox ?
- new MailboxOutputSurface(routing_id(), context, NULL) :
- new CompositorOutputSurface(routing_id(), context, NULL));
+#if defined(OS_ANDROID)
+ if (command_line.HasSwitch(switches::kEnableSynchronousRendererCompositor)) {
+ // TODO(joth): Move above the |context| creation step above when the
+ // SynchronousCompositor no longer depends on externally created context.
+ return scoped_ptr<cc::OutputSurface>(
+ new SynchronousCompositorOutputSurface(routing_id(),
+ context));
}
+#endif
+
+ bool composite_to_mailbox =
+ command_line.HasSwitch(cc::switches::kCompositeToMailbox);
+ DCHECK(!composite_to_mailbox || command_line.HasSwitch(
+ cc::switches::kEnableCompositorFrameMessage));
+ // No swap throttling yet when compositing on the main thread.
+ DCHECK(!composite_to_mailbox || is_threaded_compositing_enabled_);
+ return scoped_ptr<cc::OutputSurface>(composite_to_mailbox ?
+ new MailboxOutputSurface(routing_id(), context, NULL) :
+ new CompositorOutputSurface(routing_id(), context, NULL));
}
void RenderWidget::OnViewContextSwapBuffersAborted() {
@@ -619,7 +642,7 @@
// pending_update_params_ can be NULL if the swap doesn't correspond to an
// DoDeferredUpdate compositing pass, hence doesn't require an UpdateRect
// message.
- if (pending_update_params_.get()) {
+ if (pending_update_params_) {
msg = new ViewHostMsg_UpdateRect(routing_id_, *pending_update_params_);
pending_update_params_.reset();
}
@@ -750,8 +773,8 @@
}
IPC::Message* response =
- new ViewHostMsg_HandleInputEvent_ACK(routing_id_, input_event->type,
- ack_result);
+ new InputHostMsg_HandleInputEvent_ACK(routing_id_, input_event->type,
+ ack_result);
bool event_type_gets_rate_limited =
input_event->type == WebInputEvent::MouseMove ||
input_event->type == WebInputEvent::MouseWheel ||
@@ -770,7 +793,7 @@
if (event_type_gets_rate_limited && is_input_throttled && !is_hidden_) {
// We want to rate limit the input events in this case, so we'll wait for
// painting to finish before ACKing this message.
- if (pending_input_event_ack_.get()) {
+ if (pending_input_event_ack_) {
// As two different kinds of events could cause us to postpone an ack
// we send it now, if we have one pending. The Browser should never
// send us the same kind of event we are delaying the ack for.
@@ -800,6 +823,11 @@
}
}
+void RenderWidget::OnCursorVisibilityChange(bool is_visible) {
+ if (webwidget_)
+ webwidget_->setCursorVisibilityState(is_visible);
+}
+
void RenderWidget::OnMouseCaptureLost() {
if (webwidget_)
webwidget_->mouseCaptureLost();
@@ -924,7 +952,6 @@
if (kEnableGpuBenchmarking) {
int64 num_pixels_processed = rect.width() * rect.height();
software_stats_.total_pixels_painted += num_pixels_processed;
- software_stats_.total_pixels_rasterized += num_pixels_processed;
}
}
@@ -1039,7 +1066,7 @@
void RenderWidget::DoDeferredUpdateAndSendInputAck() {
DoDeferredUpdate();
- if (pending_input_event_ack_.get())
+ if (pending_input_event_ack_)
Send(pending_input_event_ack_.release());
}
@@ -1198,7 +1225,7 @@
scoped_ptr<skia::PlatformCanvas> canvas(
RenderProcess::current()->GetDrawingCanvas(¤t_paint_buf_,
pixel_bounds));
- if (!canvas.get()) {
+ if (!canvas) {
NOTREACHED();
return;
}
@@ -1235,7 +1262,8 @@
// Software FPS tick for performance tests. The accelerated path traces the
// frame events in didCommitAndDrawCompositorFrame. See throughput_tests.cc.
// NOTE: Tests may break if this event is renamed or moved.
- UNSHIPPED_TRACE_EVENT_INSTANT0("test_fps", "TestFrameTickSW");
+ UNSHIPPED_TRACE_EVENT_INSTANT0("test_fps", "TestFrameTickSW",
+ TRACE_EVENT_SCOPE_THREAD);
} else { // Accelerated compositing path
// Begin painting.
// If painting is done via the gpu process then we don't set any damage
@@ -1253,14 +1281,14 @@
// UpdateReply message so we can receive another input event before the
// UpdateRect_ACK on platforms where the UpdateRect_ACK is sent from within
// the UpdateRect IPC message handler.
- if (pending_input_event_ack_.get())
+ if (pending_input_event_ack_)
Send(pending_input_event_ack_.release());
// If Composite() called SwapBuffers, pending_update_params_ will be reset (in
// OnSwapBuffersPosted), meaning a message has been added to the
// updates_pending_swap_ queue, that will be sent later. Otherwise, we send
// the message now.
- if (pending_update_params_.get()) {
+ if (pending_update_params_) {
// sending an ack to browser process that the paint is complete...
update_reply_pending_ = pending_update_params_->needs_ack;
Send(new ViewHostMsg_UpdateRect(routing_id_, *pending_update_params_));
@@ -1314,7 +1342,7 @@
// 2) Allows us to collect more damage rects before painting to help coalesce
// the work that we will need to do.
invalidation_task_posted_ = true;
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE, base::Bind(&RenderWidget::InvalidationCallback, this));
}
@@ -1355,7 +1383,7 @@
// 2) Allows us to collect more damage rects before painting to help coalesce
// the work that we will need to do.
invalidation_task_posted_ = true;
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE, base::Bind(&RenderWidget::InvalidationCallback, this));
}
@@ -1465,7 +1493,7 @@
void RenderWidget::didBecomeReadyForAdditionalInput() {
TRACE_EVENT0("renderer", "RenderWidget::didBecomeReadyForAdditionalInput");
- if (pending_input_event_ack_.get())
+ if (pending_input_event_ack_)
Send(pending_input_event_ack_.release());
}
@@ -1476,7 +1504,8 @@
TRACE_EVENT0("gpu", "RenderWidget::didCommitAndDrawCompositorFrame");
// Accelerated FPS tick for performance tests. See throughput_tests.cc.
// NOTE: Tests may break if this event is renamed or moved.
- UNSHIPPED_TRACE_EVENT_INSTANT0("test_fps", "TestFrameTickGPU");
+ UNSHIPPED_TRACE_EVENT_INSTANT0("test_fps", "TestFrameTickGPU",
+ TRACE_EVENT_SCOPE_THREAD);
// Notify subclasses that we initiated the paint operation.
DidInitiatePaint();
}
@@ -1598,7 +1627,7 @@
// could be closed before the JS finishes executing. So instead, post a
// message back to the message loop, which won't run until the JS is
// complete, and then the Close message can be sent.
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE, base::Bind(&RenderWidget::DoDeferredClose, this));
}
@@ -1796,7 +1825,7 @@
scoped_ptr<skia::PlatformCanvas> canvas(
paint_at_size_buffer->GetPlatformCanvas(canvas_size.width(),
canvas_size.height()));
- if (!canvas.get()) {
+ if (!canvas) {
NOTREACHED();
return;
}
@@ -1854,7 +1883,7 @@
true,
NULL,
skia::RETURN_NULL_ON_FAILURE));
- if (!canvas.get())
+ if (!canvas)
return false;
canvas->save();
@@ -1872,28 +1901,28 @@
return true;
}
-void RenderWidget::OnRepaint(const gfx::Size& size_to_paint) {
+void RenderWidget::OnRepaint(gfx::Size size_to_paint) {
// During shutdown we can just ignore this message.
if (!webwidget_)
return;
+ // Even if the browser provides an empty damage rect, it's still expecting to
+ // receive a repaint ack so just damage the entire widget bounds.
+ if (size_to_paint.IsEmpty()) {
+ size_to_paint = size_;
+ }
+
set_next_paint_is_repaint_ack();
- if (is_accelerated_compositing_active_) {
- if (compositor_)
- compositor_->setNeedsRedraw();
- scheduleComposite();
+ if (is_accelerated_compositing_active_ && compositor_) {
+ compositor_->SetNeedsRedrawRect(gfx::Rect(size_to_paint));
} else {
gfx::Rect repaint_rect(size_to_paint.width(), size_to_paint.height());
didInvalidateRect(repaint_rect);
}
}
-void RenderWidget::OnSmoothScrollCompleted(int gesture_id) {
- PendingSmoothScrollGestureMap::iterator it =
- pending_smooth_scroll_gestures_.find(gesture_id);
- DCHECK(it != pending_smooth_scroll_gestures_.end());
- it->second.Run();
- pending_smooth_scroll_gestures_.erase(it);
+void RenderWidget::OnSmoothScrollCompleted() {
+ pending_smooth_scroll_gesture_.Run();
}
void RenderWidget::OnSetTextDirection(WebTextDirection direction) {
@@ -2249,10 +2278,6 @@
software_stats_.total_paint_time;
stats.rendering_stats.total_pixels_painted +=
software_stats_.total_pixels_painted;
- stats.rendering_stats.total_rasterize_time +=
- software_stats_.total_rasterize_time;
- stats.rendering_stats.total_pixels_rasterized +=
- software_stats_.total_pixels_rasterized;
}
bool RenderWidget::GetGpuRenderingStats(GpuRenderingStats* stats) const {
@@ -2263,6 +2288,10 @@
return gpu_channel->CollectRenderingStatsForSurface(surface_id(), stats);
}
+RenderWidgetCompositor* RenderWidget::compositor() const {
+ return compositor_.get();
+}
+
void RenderWidget::BeginSmoothScroll(
bool down,
const SmoothScrollCompletionCallback& callback,
@@ -2270,7 +2299,6 @@
int mouse_event_x,
int mouse_event_y) {
DCHECK(!callback.is_null());
- int id = next_smooth_scroll_gesture_id_++;
ViewHostMsg_BeginSmoothScroll_Params params;
params.scroll_down = down;
@@ -2278,8 +2306,8 @@
params.mouse_event_x = mouse_event_x;
params.mouse_event_y = mouse_event_y;
- Send(new ViewHostMsg_BeginSmoothScroll(routing_id_, id, params));
- pending_smooth_scroll_gestures_.insert(std::make_pair(id, callback));
+ Send(new ViewHostMsg_BeginSmoothScroll(routing_id_, params));
+ pending_smooth_scroll_gesture_ = callback;
}
bool RenderWidget::WillHandleMouseEvent(const WebKit::WebMouseEvent& event) {
@@ -2291,12 +2319,16 @@
return false;
}
+void RenderWidget::hasTouchEventHandlers(bool has_handlers) {
+ Send(new ViewHostMsg_HasTouchEventHandlers(routing_id_, has_handlers));
+}
+
bool RenderWidget::HasTouchEventHandlersAt(const gfx::Point& point) const {
return true;
}
-WebGraphicsContext3D* RenderWidget::CreateGraphicsContext3D(
- const WebGraphicsContext3D::Attributes& attributes) {
+WebGraphicsContext3DCommandBufferImpl* RenderWidget::CreateGraphicsContext3D(
+ const WebKit::WebGraphicsContext3D::Attributes& attributes) {
if (!webwidget_)
return NULL;
scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index cb06e66..cf9f8fa 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -171,6 +171,8 @@
// This call is relatively expensive as it blocks on the GPU process
bool GetGpuRenderingStats(GpuRenderingStats*) const;
+ RenderWidgetCompositor* compositor() const;
+
virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface();
// Callback for use with BeginSmoothScroll.
@@ -207,6 +209,7 @@
virtual void InstrumentWillComposite() {}
virtual bool AllowPartialSwap() const;
+ bool SynchronouslyDisableVSync() const;
protected:
// Friend RefCounted so that the dtor can be non-public. Using this class
@@ -277,6 +280,11 @@
ResizeAck resize_ack);
// RenderWidget IPC message handlers
+ void OnHandleInputEvent(const WebKit::WebInputEvent* event,
+ bool keyboard_shortcut);
+ void OnCursorVisibilityChange(bool is_visible);
+ void OnMouseCaptureLost();
+ virtual void OnSetFocus(bool enable);
void OnClose();
void OnCreatingNewAck();
virtual void OnResize(const gfx::Size& new_size,
@@ -292,10 +300,6 @@
void OnCreateVideoAck(int32 video_id);
void OnUpdateVideoAck(int32 video_id);
void OnRequestMoveAck();
- void OnHandleInputEvent(const WebKit::WebInputEvent* event,
- bool keyboard_shortcut);
- void OnMouseCaptureLost();
- virtual void OnSetFocus(bool enable);
void OnSetInputMethodActive(bool is_active);
virtual void OnImeSetComposition(
const string16& text,
@@ -308,8 +312,8 @@
int tag,
const gfx::Size& page_size,
const gfx::Size& desired_size);
- void OnRepaint(const gfx::Size& size_to_paint);
- void OnSmoothScrollCompleted(int gesture_id);
+ void OnRepaint(gfx::Size size_to_paint);
+ void OnSmoothScrollCompleted();
void OnSetTextDirection(WebKit::WebTextDirection direction);
void OnGetFPS();
void OnScreenInfoChanged(const WebKit::WebScreenInfo& screen_info);
@@ -477,8 +481,11 @@
// at the given point.
virtual bool HasTouchEventHandlersAt(const gfx::Point& point) const;
+ // Check whether the WebWidget has any touch event handlers registered.
+ virtual void hasTouchEventHandlers(bool has_handlers);
+
// Creates a 3D context associated with this view.
- WebKit::WebGraphicsContext3D* CreateGraphicsContext3D(
+ WebGraphicsContext3DCommandBufferImpl* CreateGraphicsContext3D(
const WebKit::WebGraphicsContext3D::Attributes& attributes);
bool OnSnapshotHelper(const gfx::Rect& src_subrect, SkBitmap* bitmap);
@@ -680,10 +687,7 @@
bool throttle_input_events_;
// State associated with the BeginSmoothScroll synthetic scrolling function.
- int next_smooth_scroll_gesture_id_;
- typedef std::map<int, SmoothScrollCompletionCallback>
- PendingSmoothScrollGestureMap;
- PendingSmoothScrollGestureMap pending_smooth_scroll_gestures_;
+ SmoothScrollCompletionCallback pending_smooth_scroll_gesture_;
// Specified whether the compositor will run in its own thread.
bool is_threaded_compositing_enabled_;
diff --git a/content/renderer/render_widget_fullscreen_pepper.cc b/content/renderer/render_widget_fullscreen_pepper.cc
index b1eeecd..12b8b08 100644
--- a/content/renderer/render_widget_fullscreen_pepper.cc
+++ b/content/renderer/render_widget_fullscreen_pepper.cc
@@ -368,7 +368,7 @@
plugin_(plugin),
layer_(NULL),
mouse_lock_dispatcher_(new FullscreenMouseLockDispatcher(
- ALLOW_THIS_IN_INITIALIZER_LIST(this))) {
+ this)) {
}
RenderWidgetFullscreenPepper::~RenderWidgetFullscreenPepper() {
diff --git a/content/renderer/renderer_clipboard_client.cc b/content/renderer/renderer_clipboard_client.cc
index 57ddfac..b21db02 100644
--- a/content/renderer/renderer_clipboard_client.cc
+++ b/content/renderer/renderer_clipboard_client.cc
@@ -47,14 +47,14 @@
const void* pixels,
const gfx::Size& size) {
// Do not try to write a bitmap more than once
- if (shared_buf_.get())
+ if (shared_buf_)
return;
uint32 buf_size = 4 * size.width() * size.height();
// Allocate a shared memory buffer to hold the bitmap bits.
shared_buf_.reset(ChildThread::current()->AllocateSharedMemory(buf_size));
- if (!shared_buf_.get())
+ if (!shared_buf_)
return;
// Copy the bits into shared memory
@@ -80,7 +80,7 @@
// Flushes the objects to the clipboard with an IPC.
void RendererClipboardWriteContext::Flush(
const ui::Clipboard::ObjectMap& objects) {
- if (shared_buf_.get()) {
+ if (shared_buf_) {
RenderThreadImpl::current()->Send(
new ClipboardHostMsg_WriteObjectsSync(objects, shared_buf_->handle()));
} else {
diff --git a/content/renderer/renderer_main.cc b/content/renderer/renderer_main.cc
index 7cfd127..cc8e584 100644
--- a/content/renderer/renderer_main.cc
+++ b/content/renderer/renderer_main.cc
@@ -17,9 +17,9 @@
#include "base/metrics/stats_counters.h"
#include "base/path_service.h"
#include "base/pending_task.h"
+#include "base/power_monitor/power_monitor.h"
#include "base/process_util.h"
#include "base/string_util.h"
-#include "base/system_monitor/system_monitor.h"
#include "base/threading/platform_thread.h"
#include "base/time.h"
#include "content/common/pepper_plugin_registry.h"
@@ -30,6 +30,7 @@
#include "content/renderer/render_process_impl.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/renderer_main_platform_delegate.h"
+#include "third_party/libjingle/overrides/init_webrtc.h"
#include "ui/base/ui_base_switches.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/plugins/ppapi/ppapi_interface_factory.h"
@@ -63,7 +64,7 @@
// This is a simplified version of the browser Jankometer, which measures
// the processing time of tasks on the render thread.
-class RendererMessageLoopObserver : public MessageLoop::TaskObserver {
+class RendererMessageLoopObserver : public base::MessageLoop::TaskObserver {
public:
RendererMessageLoopObserver()
: process_times_(base::Histogram::FactoryGet(
@@ -87,7 +88,7 @@
};
// For measuring memory usage after each task. Behind a command line flag.
-class MemoryObserver : public MessageLoop::TaskObserver {
+class MemoryObserver : public base::MessageLoop::TaskObserver {
public:
MemoryObserver() {}
virtual ~MemoryObserver() {}
@@ -144,12 +145,13 @@
#if defined(OS_MACOSX)
// As long as we use Cocoa in the renderer (for the forseeable future as of
// now; see http://crbug.com/13890 for info) we need to have a UI loop.
- MessageLoop main_message_loop(MessageLoop::TYPE_UI);
+ base::MessageLoop main_message_loop(base::MessageLoop::TYPE_UI);
#else
// The main message loop of the renderer services doesn't have IO or UI tasks,
// unless in-process-plugins is used.
- MessageLoop main_message_loop(RenderProcessImpl::InProcessPlugins() ?
- MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT);
+ base::MessageLoop main_message_loop(RenderProcessImpl::InProcessPlugins()
+ ? base::MessageLoop::TYPE_UI
+ : base::MessageLoop::TYPE_DEFAULT);
#endif
main_message_loop.AddTaskObserver(&task_observer);
@@ -161,7 +163,7 @@
base::PlatformThread::SetName("CrRendererMain");
- base::SystemMonitor system_monitor;
+ base::PowerMonitor power_monitor;
HighResolutionTimerManager hi_res_timer_manager;
platform.PlatformInitialize();
@@ -188,6 +190,13 @@
// Load pepper plugins before engaging the sandbox.
PepperPluginRegistry::GetInstance();
#endif
+#if defined(ENABLE_WEBRTC)
+ // Initialize WebRTC before engaging the sandbox.
+ // NOTE: On linux, this call could already have been made from
+ // zygote_main_linux.cc. However, calling multiple times from the same thread
+ // is OK.
+ InitializeWebRtcModule();
+#endif
{
#if defined(OS_WIN) || defined(OS_MACOSX)
@@ -223,7 +232,7 @@
pool->Recycle();
#endif
TRACE_EVENT_BEGIN_ETW("RendererMain.START_MSG_LOOP", 0, 0);
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
TRACE_EVENT_END_ETW("RendererMain.START_MSG_LOOP", 0, 0);
}
}
diff --git a/content/renderer/renderer_main_platform_delegate_linux.cc b/content/renderer/renderer_main_platform_delegate_linux.cc
index a653bfe..dd8281d 100644
--- a/content/renderer/renderer_main_platform_delegate_linux.cc
+++ b/content/renderer/renderer_main_platform_delegate_linux.cc
@@ -40,9 +40,8 @@
// The setuid sandbox is started in the zygote process: zygote_main_linux.cc
// http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox
//
- // The seccomp sandbox mode 1 (sandbox/linux/seccomp-legacy) and mode 2
- // (sandbox/linux/seccomp-bpf) are started in InitializeSandbox().
- InitializeSandbox();
+ // Anything else is started in InitializeSandbox().
+ LinuxSandbox::InitializeSandbox();
return true;
}
diff --git a/content/renderer/renderer_main_platform_delegate_mac.mm b/content/renderer/renderer_main_platform_delegate_mac.mm
index 42f8abc..c128cf0 100644
--- a/content/renderer/renderer_main_platform_delegate_mac.mm
+++ b/content/renderer/renderer_main_platform_delegate_mac.mm
@@ -13,7 +13,7 @@
#import "base/mac/foundation_util.h"
#import "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "content/common/sandbox_mac.h"
#include "content/public/common/content_switches.h"
#import "content/public/common/injection_test_mac.h"
diff --git a/content/renderer/renderer_main_platform_delegate_win.cc b/content/renderer/renderer_main_platform_delegate_win.cc
index 8732ac8..1af746d 100644
--- a/content/renderer/renderer_main_platform_delegate_win.cc
+++ b/content/renderer/renderer_main_platform_delegate_win.cc
@@ -47,6 +47,15 @@
base::win::SetAbortBehaviorForCrashReporting();
}
+#if !defined(NDEBUG)
+LRESULT CALLBACK WindowsHookCBT(int code, WPARAM w_param, LPARAM l_param) {
+ CHECK_NE(code, HCBT_CREATEWND)
+ << "Should not be creating windows in the renderer!";
+ return CallNextHookEx(NULL, code, w_param, l_param);
+}
+#endif // !NDEBUG
+
+
} // namespace
RendererMainPlatformDelegate::RendererMainPlatformDelegate(
@@ -59,6 +68,15 @@
}
void RendererMainPlatformDelegate::PlatformInitialize() {
+#if !defined(NDEBUG)
+ // Install a check that we're not creating windows in the renderer. See
+ // http://crbug.com/230122 for background. TODO(scottmg): Ideally this would
+ // check all threads in the renderer, but it currently only checks the main
+ // thread.
+ PCHECK(
+ SetWindowsHookEx(WH_CBT, WindowsHookCBT, NULL, ::GetCurrentThreadId()));
+#endif // !NDEBUG
+
InitExitInterceptions();
// Be mindful of what resources you acquire here. They can be used by
diff --git a/content/renderer/renderer_webapplicationcachehost_impl.cc b/content/renderer/renderer_webapplicationcachehost_impl.cc
index 78418ff..6404053 100644
--- a/content/renderer/renderer_webapplicationcachehost_impl.cc
+++ b/content/renderer/renderer_webapplicationcachehost_impl.cc
@@ -58,8 +58,7 @@
}
RenderViewImpl* RendererWebApplicationCacheHostImpl::GetRenderView() {
- return static_cast<RenderViewImpl*>
- (RenderThreadImpl::current()->ResolveRoute(routing_id_));
+ return RenderViewImpl::FromRoutingID(routing_id_);
}
// static
diff --git a/content/renderer/renderer_webkitplatformsupport_impl.cc b/content/renderer/renderer_webkitplatformsupport_impl.cc
index 33f9707..f21400e 100644
--- a/content/renderer/renderer_webkitplatformsupport_impl.cc
+++ b/content/renderer/renderer_webkitplatformsupport_impl.cc
@@ -54,7 +54,6 @@
#include "webkit/glue/webclipboard_impl.h"
#include "webkit/glue/webfileutilities_impl.h"
#include "webkit/glue/webkit_glue.h"
-#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"
#if defined(OS_WIN)
#include "content/common/child_process_messages.h"
@@ -229,7 +228,7 @@
WebKit::WebFileUtilities*
RendererWebKitPlatformSupportImpl::fileUtilities() {
- if (!file_utilities_.get()) {
+ if (!file_utilities_) {
file_utilities_.reset(new FileUtilities(thread_safe_sender_));
file_utilities_->set_sandbox_enabled(sandboxEnabled());
}
@@ -358,7 +357,7 @@
//------------------------------------------------------------------------------
WebIDBFactory* RendererWebKitPlatformSupportImpl::idbFactory() {
- if (!web_idb_factory_.get()) {
+ if (!web_idb_factory_) {
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess))
web_idb_factory_.reset(WebIDBFactory::create());
else
@@ -370,7 +369,7 @@
//------------------------------------------------------------------------------
WebFileSystem* RendererWebKitPlatformSupportImpl::fileSystem() {
- if (!web_file_system_.get())
+ if (!web_file_system_)
web_file_system_.reset(new WebFileSystemImpl());
return web_file_system_.get();
}
@@ -471,9 +470,9 @@
// Create a hyphenator object and attach it to the render thread so it can
// receive a dictionary file opened by a browser.
- if (!hyphenator_.get()) {
+ if (!hyphenator_) {
hyphenator_.reset(new content::Hyphenator(base::kInvalidPlatformFileValue));
- if (!hyphenator_.get())
+ if (!hyphenator_)
return false;
return hyphenator_->Attach(RenderThreadImpl::current(), locale);
}
@@ -633,23 +632,7 @@
double RendererWebKitPlatformSupportImpl::audioHardwareSampleRate() {
RenderThreadImpl* thread = RenderThreadImpl::current();
- int sample_rate = thread->GetAudioHardwareConfig()->GetOutputSampleRate();
-
- // In some rare cases it has been found that Windows returns
- // a sample-rate of 0.
- // Let's make sure to return a sane fallback sample-rate.
- // http://crbug.com/222718
- static const int kMinSampleRate = 22050;
- static const int kMaxSampleRate = 192000;
-#if defined(OS_MACOSX)
- static const int kFallbackSampleRate = 44100;
-#else
- static const int kFallbackSampleRate = 48000;
-#endif
- if (sample_rate < kMinSampleRate || sample_rate > kMaxSampleRate)
- sample_rate = kFallbackSampleRate;
-
- return sample_rate;
+ return thread->GetAudioHardwareConfig()->GetOutputSampleRate();
}
size_t RendererWebKitPlatformSupportImpl::audioHardwareBufferSize() {
@@ -776,7 +759,7 @@
WebBlobRegistry* RendererWebKitPlatformSupportImpl::blobRegistry() {
// thread_safe_sender_ can be NULL when running some tests.
- if (!blob_registry_.get() && thread_safe_sender_.get())
+ if (!blob_registry_.get() && thread_safe_sender_)
blob_registry_.reset(new WebBlobRegistryImpl(thread_safe_sender_));
return blob_registry_.get();
}
@@ -785,7 +768,7 @@
void RendererWebKitPlatformSupportImpl::sampleGamepads(WebGamepads& gamepads) {
if (g_test_gamepads == 0) {
- if (!gamepad_shared_memory_reader_.get())
+ if (!gamepad_shared_memory_reader_)
gamepad_shared_memory_reader_.reset(new GamepadSharedMemoryReader);
gamepad_shared_memory_reader_->SampleGamepads(gamepads);
} else {
@@ -872,6 +855,14 @@
//------------------------------------------------------------------------------
+WebKit::WebSpeechSynthesizer*
+RendererWebKitPlatformSupportImpl::createSpeechSynthesizer(
+ WebKit::WebSpeechSynthesizerClient* client) {
+ return GetContentClient()->renderer()->OverrideSpeechSynthesizer(client);
+}
+
+//------------------------------------------------------------------------------
+
bool RendererWebKitPlatformSupportImpl::processMemorySizesInBytes(
size_t* private_bytes, size_t* shared_bytes) {
content::RenderThread::Get()->Send(
diff --git a/content/renderer/renderer_webkitplatformsupport_impl.h b/content/renderer/renderer_webkitplatformsupport_impl.h
index de19386..3a89860 100644
--- a/content/renderer/renderer_webkitplatformsupport_impl.h
+++ b/content/renderer/renderer_webkitplatformsupport_impl.h
@@ -11,7 +11,7 @@
#include "content/common/content_export.h"
#include "content/common/webkitplatformsupport_impl.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBFactory.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBFactory.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSharedWorkerRepository.h"
namespace cc {
@@ -46,6 +46,8 @@
virtual WebKit::WebCookieJar* cookieJar();
virtual WebKit::WebHyphenator* hyphenator();
virtual WebKit::WebThemeEngine* themeEngine();
+ virtual WebKit::WebSpeechSynthesizer* createSpeechSynthesizer(
+ WebKit::WebSpeechSynthesizerClient* client);
virtual bool sandboxEnabled();
virtual unsigned long long visitedLinkHash(
const char* canonicalURL, size_t length);
diff --git a/content/renderer/resource_fetcher_browsertest.cc b/content/renderer/resource_fetcher_browsertest.cc
new file mode 100644
index 0000000..e7e0c36
--- /dev/null
+++ b/content/renderer/resource_fetcher_browsertest.cc
@@ -0,0 +1,284 @@
+// 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 "webkit/glue/resource_fetcher.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/command_line.h"
+#include "base/message_loop.h"
+#include "base/timer.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/renderer/render_view.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/shell.h"
+#include "content/test/content_browser_test.h"
+#include "content/test/content_browser_test_utils.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebURLResponse.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
+
+using WebKit::WebFrame;
+using WebKit::WebURLRequest;
+using WebKit::WebURLResponse;
+using webkit_glue::ResourceFetcher;
+using webkit_glue::ResourceFetcherWithTimeout;
+
+namespace content {
+
+static const int kMaxWaitTimeMs = 5000;
+
+class FetcherDelegate {
+ public:
+ FetcherDelegate()
+ : completed_(false),
+ timed_out_(false) {
+ // Start a repeating timer waiting for the download to complete. The
+ // callback has to be a static function, so we hold on to our instance.
+ FetcherDelegate::instance_ = this;
+ StartTimer();
+ }
+
+ virtual ~FetcherDelegate() {}
+
+ ResourceFetcher::Callback NewCallback() {
+ return base::Bind(&FetcherDelegate::OnURLFetchComplete,
+ base::Unretained(this));
+ }
+
+ virtual void OnURLFetchComplete(const WebURLResponse& response,
+ const std::string& data) {
+ response_ = response;
+ data_ = data;
+ completed_ = true;
+ timer_.Stop();
+ if (!timed_out_)
+ quit_task_.Run();
+ }
+
+ bool completed() const { return completed_; }
+ bool timed_out() const { return timed_out_; }
+
+ std::string data() const { return data_; }
+ const WebURLResponse& response() const { return response_; }
+
+ // Wait for the request to complete or timeout.
+ void WaitForResponse() {
+ scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
+ quit_task_ = runner->QuitClosure();
+ runner->Run();
+ }
+
+ void StartTimer() {
+ timer_.Start(FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kMaxWaitTimeMs),
+ this,
+ &FetcherDelegate::TimerFired);
+ }
+
+ void TimerFired() {
+ ASSERT_FALSE(completed_);
+
+ timed_out_ = true;
+ if (!completed_)
+ quit_task_.Run();
+ FAIL() << "fetch timed out";
+ }
+
+ static FetcherDelegate* instance_;
+
+ private:
+ base::OneShotTimer<FetcherDelegate> timer_;
+ bool completed_;
+ bool timed_out_;
+ WebURLResponse response_;
+ std::string data_;
+ base::Closure quit_task_;
+};
+
+FetcherDelegate* FetcherDelegate::instance_ = NULL;
+
+class EvilFetcherDelegate : public FetcherDelegate {
+ public:
+ virtual ~EvilFetcherDelegate() {}
+
+ void SetFetcher(ResourceFetcher* fetcher) {
+ fetcher_.reset(fetcher);
+ }
+
+ virtual void OnURLFetchComplete(const WebURLResponse& response,
+ const std::string& data) OVERRIDE {
+ // Destroy the ResourceFetcher here. We are testing that upon returning
+ // to the ResourceFetcher that it does not crash.
+ fetcher_.reset();
+ FetcherDelegate::OnURLFetchComplete(response, data);
+ }
+
+ private:
+ scoped_ptr<ResourceFetcher> fetcher_;
+};
+
+class ResourceFetcherTests : public ContentBrowserTest {
+ public:
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ command_line->AppendSwitch(switches::kSingleProcess);
+#if defined(OS_WIN) && defined(USE_AURA)
+ // Don't want to try to create a GPU process.
+ command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
+#endif
+ }
+
+ RenderView* GetRenderView() {
+ // We could have the test on the UI thread get the WebContent's routing ID,
+ // but we know this will be the first RV so skip that and just hardcode it.
+ return RenderView::FromRoutingID(1);
+ }
+
+ void ResourceFetcherDownloadOnRenderer(const GURL& url) {
+ WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
+
+ scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
+ scoped_ptr<ResourceFetcher> fetcher(new ResourceFetcher(
+ url, frame, WebURLRequest::TargetIsMainFrame, delegate->NewCallback()));
+
+ delegate->WaitForResponse();
+
+ ASSERT_TRUE(delegate->completed());
+ EXPECT_EQ(delegate->response().httpStatusCode(), 200);
+ std::string text = delegate->data();
+ EXPECT_TRUE(text.find("Basic html test.") != std::string::npos);
+ }
+
+ void ResourceFetcher404OnRenderer(const GURL& url) {
+ WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
+
+ scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
+ scoped_ptr<ResourceFetcher> fetcher(new ResourceFetcher(
+ url, frame, WebURLRequest::TargetIsMainFrame, delegate->NewCallback()));
+
+ delegate->WaitForResponse();
+
+ ASSERT_TRUE(delegate->completed());
+ EXPECT_EQ(delegate->response().httpStatusCode(), 404);
+ EXPECT_TRUE(delegate->data().find("Not Found.") != std::string::npos);
+ }
+
+ void ResourceFetcherDidFailOnRenderer() {
+ WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
+
+ // Try to fetch a page on a site that doesn't exist.
+ GURL url("http://localhost:1339/doesnotexist");
+ scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
+ scoped_ptr<ResourceFetcher> fetcher(new ResourceFetcher(
+ url, frame, WebURLRequest::TargetIsMainFrame, delegate->NewCallback()));
+
+ delegate->WaitForResponse();
+
+ // When we fail, we still call the Delegate callback but we pass in empty
+ // values.
+ EXPECT_TRUE(delegate->completed());
+ EXPECT_TRUE(delegate->response().isNull());
+ EXPECT_EQ(delegate->data(), std::string());
+ EXPECT_FALSE(delegate->timed_out());
+ }
+
+ void ResourceFetcherTimeoutOnRenderer(const GURL& url) {
+ WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
+
+ scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
+ scoped_ptr<ResourceFetcher> fetcher(new ResourceFetcherWithTimeout(
+ url, frame, WebURLRequest::TargetIsMainFrame,
+ 0, delegate->NewCallback()));
+
+ delegate->WaitForResponse();
+
+ // When we timeout, we still call the Delegate callback but we pass in empty
+ // values.
+ EXPECT_TRUE(delegate->completed());
+ EXPECT_TRUE(delegate->response().isNull());
+ EXPECT_EQ(delegate->data(), std::string());
+ EXPECT_FALSE(delegate->timed_out());
+ }
+
+ void ResourceFetcherDeletedInCallbackOnRenderer(const GURL& url) {
+ WebFrame* frame = GetRenderView()->GetWebView()->mainFrame();
+
+ scoped_ptr<EvilFetcherDelegate> delegate(new EvilFetcherDelegate);
+ scoped_ptr<ResourceFetcher> fetcher(new ResourceFetcherWithTimeout(
+ url, frame, WebURLRequest::TargetIsMainFrame,
+ 0, delegate->NewCallback()));
+ delegate->SetFetcher(fetcher.release());
+
+ delegate->WaitForResponse();
+ EXPECT_FALSE(delegate->timed_out());
+ }
+};
+
+// Test a fetch from the test server.
+// If this flakes, use http://crbug.com/51622.
+IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherDownload) {
+ // Need to spin up the renderer.
+ NavigateToURL(shell(), GURL("about:blank"));
+
+ ASSERT_TRUE(test_server()->Start());
+ GURL url(test_server()->GetURL("files/simple_page.html"));
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(&ResourceFetcherTests::ResourceFetcherDownloadOnRenderer,
+ base::Unretained(this), url));
+}
+
+IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcher404) {
+ // Need to spin up the renderer.
+ NavigateToURL(shell(), GURL("about:blank"));
+
+ // Test 404 response.
+ ASSERT_TRUE(test_server()->Start());
+ GURL url = test_server()->GetURL("files/thisfiledoesntexist.html");
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(&ResourceFetcherTests::ResourceFetcher404OnRenderer,
+ base::Unretained(this), url));
+}
+
+// If this flakes, use http://crbug.com/51622.
+IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherDidFail) {
+ // Need to spin up the renderer.
+ NavigateToURL(shell(), GURL("about:blank"));
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(&ResourceFetcherTests::ResourceFetcherDidFailOnRenderer,
+ base::Unretained(this)));
+}
+
+IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherTimeout) {
+ // Need to spin up the renderer.
+ NavigateToURL(shell(), GURL("about:blank"));
+
+ // Grab a page that takes at least 1 sec to respond, but set the fetcher to
+ // timeout in 0 sec.
+ ASSERT_TRUE(test_server()->Start());
+ GURL url(test_server()->GetURL("slow?1"));
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(&ResourceFetcherTests::ResourceFetcherTimeoutOnRenderer,
+ base::Unretained(this), url));
+}
+
+IN_PROC_BROWSER_TEST_F(ResourceFetcherTests, ResourceFetcherDeletedInCallback) {
+ // Need to spin up the renderer.
+ NavigateToURL(shell(), GURL("about:blank"));
+
+ // Grab a page that takes at least 1 sec to respond, but set the fetcher to
+ // timeout in 0 sec.
+ ASSERT_TRUE(test_server()->Start());
+ GURL url(test_server()->GetURL("slow?1"));
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(
+ &ResourceFetcherTests::ResourceFetcherDeletedInCallbackOnRenderer,
+ base::Unretained(this), url));
+}
+
+} // namespace content
diff --git a/content/renderer/v8_value_converter_impl.cc b/content/renderer/v8_value_converter_impl.cc
index b1a063c..e8b2563 100644
--- a/content/renderer/v8_value_converter_impl.cc
+++ b/content/renderer/v8_value_converter_impl.cc
@@ -263,12 +263,12 @@
scoped_ptr<WebKit::WebArrayBuffer> array_buffer(
WebKit::WebArrayBuffer::createFromV8Value(val));
scoped_ptr<WebKit::WebArrayBufferView> view;
- if (array_buffer.get()) {
+ if (array_buffer) {
data = reinterpret_cast<char*>(array_buffer->data());
length = array_buffer->byteLength();
} else {
view.reset(WebKit::WebArrayBufferView::createFromV8Value(val));
- if (view.get()) {
+ if (view) {
data = reinterpret_cast<char*>(view->baseAddress()) + view->byteOffset();
length = view->byteLength();
}
@@ -322,7 +322,7 @@
}
scoped_ptr<base::Value> child(FromV8ValueImpl(child_v8, unique_map));
- if (!child.get())
+ if (!child)
// JSON.stringify skips properties whose values don't serialize, for
// example undefined and functions. Emulate that behavior.
continue;
diff --git a/content/renderer/v8_value_converter_impl_unittest.cc b/content/renderer/v8_value_converter_impl_unittest.cc
index df68e80..8a6a757 100644
--- a/content/renderer/v8_value_converter_impl_unittest.cc
+++ b/content/renderer/v8_value_converter_impl_unittest.cc
@@ -70,7 +70,7 @@
std::string temp;
if (!value->GetString(key, &temp)) {
ADD_FAILURE();
- return "";
+ return std::string();
}
return temp;
}
@@ -80,7 +80,7 @@
value->Get(v8::String::New(key.c_str())).As<v8::String>();
if (temp.IsEmpty()) {
ADD_FAILURE();
- return "";
+ return std::string();
}
v8::String::Utf8Value utf8(temp);
return std::string(*utf8, utf8.length());
@@ -90,7 +90,7 @@
std::string temp;
if (!value->GetString(static_cast<size_t>(index), &temp)) {
ADD_FAILURE();
- return "";
+ return std::string();
}
return temp;
}
@@ -99,7 +99,7 @@
v8::Handle<v8::String> temp = value->Get(index).As<v8::String>();
if (temp.IsEmpty()) {
ADD_FAILURE();
- return "";
+ return std::string();
}
v8::String::Utf8Value utf8(temp);
return std::string(*utf8, utf8.length());
@@ -147,7 +147,7 @@
scoped_ptr<base::Value> expected_value) {
scoped_ptr<base::Value> raw(converter.FromV8Value(val, context_));
- if (expected_value.get()) {
+ if (expected_value) {
ASSERT_TRUE(raw.get());
EXPECT_TRUE(expected_value->Equals(raw.get()));
EXPECT_EQ(expected_type, raw->GetType());
@@ -162,7 +162,7 @@
converter.FromV8Value(object, context_)));
ASSERT_TRUE(dictionary.get());
- if (expected_value.get()) {
+ if (expected_value) {
base::Value* temp = NULL;
ASSERT_TRUE(dictionary->Get("test", &temp));
EXPECT_EQ(expected_type, temp->GetType());
@@ -176,7 +176,7 @@
scoped_ptr<base::ListValue> list(
static_cast<base::ListValue*>(converter.FromV8Value(array, context_)));
ASSERT_TRUE(list.get());
- if (expected_value.get()) {
+ if (expected_value) {
base::Value* temp = NULL;
ASSERT_TRUE(list->Get(0, &temp));
EXPECT_EQ(expected_type, temp->GetType());
diff --git a/content/renderer/webplugin_delegate_proxy.cc b/content/renderer/webplugin_delegate_proxy.cc
index 1421d63..c3459ed 100644
--- a/content/renderer/webplugin_delegate_proxy.cc
+++ b/content/renderer/webplugin_delegate_proxy.cc
@@ -168,14 +168,14 @@
DCHECK(channel_ != NULL);
channel_->Send(new PluginMsg_DidFinishLoading(instance_id_, resource_id_));
channel_ = NULL;
- MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
virtual void DidFail() OVERRIDE {
DCHECK(channel_ != NULL);
channel_->Send(new PluginMsg_DidFail(instance_id_, resource_id_));
channel_ = NULL;
- MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
virtual bool IsMultiByteResponseExpected() OVERRIDE {
@@ -279,7 +279,7 @@
plugin_ = NULL;
- MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
bool WebPluginDelegateProxy::Initialize(
@@ -333,7 +333,7 @@
channel_host =
PluginChannelHost::GetPluginChannelHost(
channel_handle, ChildProcess::current()->io_message_loop_proxy());
- if (!channel_host.get()) {
+ if (!channel_host) {
LOG(ERROR) << "Couldn't get PluginChannelHost";
continue;
}
@@ -537,12 +537,12 @@
if (bitmaps_changed)
#endif
{
- if (transport_stores_[0].dib.get())
+ if (transport_stores_[0].dib)
CopyTransportDIBHandleForMessage(transport_stores_[0].dib->handle(),
¶m.windowless_buffer0,
channel_host_->peer_pid());
- if (transport_stores_[1].dib.get())
+ if (transport_stores_[1].dib)
CopyTransportDIBHandleForMessage(transport_stores_[1].dib->handle(),
¶m.windowless_buffer1,
channel_host_->peer_pid());
diff --git a/content/result_codes_java.target.darwin-arm.mk b/content/result_codes_java.target.darwin-arm.mk
new file mode 100644
index 0000000..8c20ed9
--- /dev/null
+++ b/content/result_codes_java.target.darwin-arm.mk
@@ -0,0 +1,142 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_result_codes_java_gyp
+LOCAL_MODULE_STEM := result_codes_java
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+
+### Generated for rule "content_content_gyp_result_codes_java_target_generate_java_constants":
+# "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/ResultCodes.template $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/gcc_preprocess.py $(LOCAL_PATH)/content/public/common/result_codes_list.h $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common; cd $(gyp_local_path)/content; python ../build/android/gyp/gcc_preprocess.py "--include-path=.." "--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java" "--template=public/android/java/src/org/chromium/content/common/ResultCodes.template"
+
+.PHONY: content_result_codes_java_gyp_rule_trigger
+content_result_codes_java_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES := \
+ content_result_codes_java_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -fno-tree-sra \
+ -fuse-ld=gold \
+ -Wno-psabi \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_result_codes_java_gyp
+
+# Alias gyp target name.
+.PHONY: result_codes_java
+result_codes_java: content_result_codes_java_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/result_codes_java.target.darwin-x86.mk b/content/result_codes_java.target.darwin-x86.mk
new file mode 100644
index 0000000..305c6c3
--- /dev/null
+++ b/content/result_codes_java.target.darwin-x86.mk
@@ -0,0 +1,143 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := content_result_codes_java_gyp
+LOCAL_MODULE_STEM := result_codes_java
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TAGS := optional
+gyp_intermediate_dir := $(call local-intermediates-dir)
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+
+### Generated for rule "content_content_gyp_result_codes_java_target_generate_java_constants":
+# "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/ResultCodes.template $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/gcc_preprocess.py $(LOCAL_PATH)/content/public/common/result_codes_list.h $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common; cd $(gyp_local_path)/content; python ../build/android/gyp/gcc_preprocess.py "--include-path=.." "--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java" "--template=public/android/java/src/org/chromium/content/common/ResultCodes.template"
+
+.PHONY: content_result_codes_java_gyp_rule_trigger
+content_result_codes_java_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java
+
+### Finished generating for all rules
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES := \
+ content_result_codes_java_gyp_rule_trigger
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-exceptions \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -m32 \
+ -mmmx \
+ -march=pentium4 \
+ -msse2 \
+ -mfpmath=sse \
+ -fuse-ld=gold \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -fomit-frame-pointer \
+ -fdata-sections \
+ -ffunction-sections
+
+MY_CFLAGS_C :=
+
+MY_DEFS := \
+ '-DCONTENT_IMPLEMENTATION' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DUSE_LINUX_BREAKPAD' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_GPU=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DENABLE_EGLIMAGE=1' \
+ '-DENABLE_LANGUAGE_DETECTION=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES := \
+ $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
+ $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
+ $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
+
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS := \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-error=c++0x-compat \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+### Rules for final target.
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: content_result_codes_java_gyp
+
+# Alias gyp target name.
+.PHONY: result_codes_java
+result_codes_java: content_result_codes_java_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
diff --git a/content/result_codes_java.target.linux-arm.mk b/content/result_codes_java.target.linux-arm.mk
index 04cf2e7..8c20ed9 100644
--- a/content/result_codes_java.target.linux-arm.mk
+++ b/content/result_codes_java.target.linux-arm.mk
@@ -15,13 +15,13 @@
### Generated for rule "content_content_gyp_result_codes_java_target_generate_java_constants":
-# "{'inputs': ['public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['gcc', '-E', '-D', 'ANDROID', '-x', 'c-header', '-P', '-I', '..', '-o', '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
+# "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/ResultCodes.template $(LOCAL_PATH)/content/public/common/result_codes_list.h $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common; cd $(gyp_local_path)/content; gcc -E -D ANDROID -x c-header -P -I .. -o "$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java" public/android/java/src/org/chromium/content/common/ResultCodes.template
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/ResultCodes.template $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/gcc_preprocess.py $(LOCAL_PATH)/content/public/common/result_codes_list.h $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common; cd $(gyp_local_path)/content; python ../build/android/gyp/gcc_preprocess.py "--include-path=.." "--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java" "--template=public/android/java/src/org/chromium/content/common/ResultCodes.template"
.PHONY: content_result_codes_java_gyp_rule_trigger
content_result_codes_java_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java
@@ -79,7 +79,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -87,7 +86,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
diff --git a/content/result_codes_java.target.linux-x86.mk b/content/result_codes_java.target.linux-x86.mk
index 293b1a7..305c6c3 100644
--- a/content/result_codes_java.target.linux-x86.mk
+++ b/content/result_codes_java.target.linux-x86.mk
@@ -15,13 +15,13 @@
### Generated for rule "content_content_gyp_result_codes_java_target_generate_java_constants":
-# "{'inputs': ['public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['gcc', '-E', '-D', 'ANDROID', '-x', 'c-header', '-P', '-I', '..', '-o', '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
+# "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_local_path := $(LOCAL_PATH)
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/ResultCodes.template $(LOCAL_PATH)/content/public/common/result_codes_list.h $(GYP_TARGET_DEPENDENCIES)
- mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common; cd $(gyp_local_path)/content; gcc -E -D ANDROID -x c-header -P -I .. -o "$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java" public/android/java/src/org/chromium/content/common/ResultCodes.template
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: $(LOCAL_PATH)/content/public/android/java/src/org/chromium/content/common/ResultCodes.template $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/gcc_preprocess.py $(LOCAL_PATH)/content/public/common/result_codes_list.h $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common; cd $(gyp_local_path)/content; python ../build/android/gyp/gcc_preprocess.py "--include-path=.." "--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java" "--template=public/android/java/src/org/chromium/content/common/ResultCodes.template"
.PHONY: content_result_codes_java_gyp_rule_trigger
content_result_codes_java_gyp_rule_trigger: $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java
@@ -59,6 +59,7 @@
-march=pentium4 \
-msse2 \
-mfpmath=sse \
+ -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -80,7 +81,6 @@
MY_DEFS := \
'-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
'-D_FILE_OFFSET_BITS=64' \
'-DUSE_LINUX_BREAKPAD' \
'-DNO_TCMALLOC' \
@@ -88,7 +88,6 @@
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
'-DENABLE_GPU=1' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
diff --git a/content/shell/android/browsertests_apk/content_browser_tests_android.cc b/content/shell/android/browsertests_apk/content_browser_tests_android.cc
index cb4c120..3425480 100644
--- a/content/shell/android/browsertests_apk/content_browser_tests_android.cc
+++ b/content/shell/android/browsertests_apk/content_browser_tests_android.cc
@@ -77,6 +77,10 @@
// Append required switches.
command_line->AppendSwitch(content::kSingleProcessTestsFlag);
command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
+ // Specify a socket name to not conflict with the default one used
+ // in content_shell.
+ command_line->AppendSwitchASCII(switches::kRemoteDebuggingSocketName,
+ "content_browsertests_devtools_remote");
// Create fifo and redirect stdout and stderr to it.
base::FilePath files_dir(
diff --git a/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/ContentBrowserTestsActivity.java b/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/ContentBrowserTestsActivity.java
index 249baf6..3f25e68 100644
--- a/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/ContentBrowserTestsActivity.java
+++ b/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/ContentBrowserTestsActivity.java
@@ -15,15 +15,15 @@
import org.chromium.content.app.LibraryLoader;
import org.chromium.content.browser.AndroidBrowserProcess;
import org.chromium.content.common.ProcessInitException;
-import org.chromium.ui.gfx.ActivityNativeWindow;
import org.chromium.content_shell.ShellManager;
+import org.chromium.ui.WindowAndroid;
@JNINamespace("content")
public class ContentBrowserTestsActivity extends Activity {
private static final String TAG = "ChromeBrowserTestsActivity";
private ShellManager mShellManager;
- private ActivityNativeWindow mActivityNativeWindow;
+ private WindowAndroid mWindowAndroid;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -40,8 +40,8 @@
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.test_activity, null);
mShellManager = (ShellManager) view.findViewById(R.id.shell_container);
- mActivityNativeWindow = new ActivityNativeWindow(this);
- mShellManager.setWindow(mActivityNativeWindow);
+ mWindowAndroid = new WindowAndroid(this);
+ mShellManager.setWindow(mWindowAndroid);
Log.i(TAG, "Running tests");
runTests();
diff --git a/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/ContentBrowserTestsApplication.java b/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/ContentBrowserTestsApplication.java
index 315a17e..c850636 100644
--- a/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/ContentBrowserTestsApplication.java
+++ b/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/ContentBrowserTestsApplication.java
@@ -12,7 +12,6 @@
public class ContentBrowserTestsApplication extends Application {
- private static final String NATIVE_LIBRARY = "content_browsertests";
private static final String[] MANDATORY_PAK_FILES = new String[] {"content_shell.pak"};
private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "content_shell";
@@ -24,7 +23,6 @@
public static void initializeApplicationParameters() {
ResourceExtractor.setMandatoryPaksToExtract(MANDATORY_PAK_FILES);
- LibraryLoader.setLibraryToLoad(NATIVE_LIBRARY);
PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX);
}
diff --git a/content/shell/android/java/src/org/chromium/content_shell/Shell.java b/content/shell/android/java/src/org/chromium/content_shell/Shell.java
index 7a11022..064e312 100644
--- a/content/shell/android/java/src/org/chromium/content_shell/Shell.java
+++ b/content/shell/android/java/src/org/chromium/content_shell/Shell.java
@@ -24,7 +24,7 @@
import org.chromium.content.browser.ContentView;
import org.chromium.content.browser.ContentViewRenderView;
import org.chromium.content.browser.LoadUrlParams;
-import org.chromium.ui.gfx.NativeWindow;
+import org.chromium.ui.WindowAndroid;
/**
* Container for the various UI components that make up a shell window.
@@ -50,7 +50,7 @@
private ClipDrawable mProgressDrawable;
private ContentViewRenderView mContentViewRenderView;
- private NativeWindow mWindow;
+ private WindowAndroid mWindow;
private boolean mLoading = false;
@@ -82,7 +82,7 @@
/**
* @param window The owning window for this shell.
*/
- public void setWindow(NativeWindow window) {
+ public void setWindow(WindowAndroid window) {
mWindow = window;
}
diff --git a/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java b/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java
index 7cf962d..b3fd950 100644
--- a/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java
+++ b/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java
@@ -13,7 +13,7 @@
import org.chromium.base.JNINamespace;
import org.chromium.content.browser.ContentView;
import org.chromium.content.browser.ContentViewRenderView;
-import org.chromium.ui.gfx.NativeWindow;
+import org.chromium.ui.WindowAndroid;
/**
* Container and generator of ShellViews.
@@ -23,7 +23,7 @@
public static final String DEFAULT_SHELL_URL = "http://www.google.com";
private static boolean sStartup = true;
- private NativeWindow mWindow;
+ private WindowAndroid mWindow;
private Shell mActiveShell;
private String mStartupUrl = DEFAULT_SHELL_URL;
@@ -51,14 +51,14 @@
/**
* @param window The window used to generate all shells.
*/
- public void setWindow(NativeWindow window) {
+ public void setWindow(WindowAndroid window) {
mWindow = window;
}
/**
* @return The window used to generate all shells.
*/
- public NativeWindow getWindow() {
+ public WindowAndroid getWindow() {
return mWindow;
}
diff --git a/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellActivity.java b/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellActivity.java
index f72d1fb..9dc2bce 100644
--- a/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellActivity.java
+++ b/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellActivity.java
@@ -4,7 +4,6 @@
package org.chromium.content_shell_apk;
-import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -26,7 +25,7 @@
import org.chromium.content.common.ProcessInitException;
import org.chromium.content_shell.Shell;
import org.chromium.content_shell.ShellManager;
-import org.chromium.ui.gfx.ActivityNativeWindow;
+import org.chromium.ui.WindowAndroid;
/**
* Activity for managing the Content Shell.
@@ -44,7 +43,7 @@
public static final String COMMAND_LINE_ARGS_KEY = "commandLineArgs";
private ShellManager mShellManager;
- private ActivityNativeWindow mActivityNativeWindow;
+ private WindowAndroid mWindowAndroid;
private BroadcastReceiver mReceiver;
@Override
@@ -67,9 +66,9 @@
setContentView(R.layout.content_shell_activity);
mShellManager = (ShellManager) findViewById(R.id.shell_container);
- mActivityNativeWindow = new ActivityNativeWindow(this);
- mActivityNativeWindow.restoreInstanceState(savedInstanceState);
- mShellManager.setWindow(mActivityNativeWindow);
+ mWindowAndroid = new WindowAndroid(this);
+ mWindowAndroid.restoreInstanceState(savedInstanceState);
+ mShellManager.setWindow(mWindowAndroid);
ContentVideoView.registerContentVideoViewContextDelegate(
new ActivityContentVideoViewDelegate(this));
@@ -99,7 +98,7 @@
outState.putString(ACTIVE_SHELL_URL_KEY, activeShell.getContentView().getUrl());
}
- mActivityNativeWindow.saveInstanceState(outState);
+ mWindowAndroid.saveInstanceState(outState);
}
private void waitForDebuggerIfNeeded() {
@@ -179,7 +178,7 @@
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
- mActivityNativeWindow.onActivityResult(requestCode, resultCode, data);
+ mWindowAndroid.onActivityResult(requestCode, resultCode, data);
}
private static String getUrlFromIntent(Intent intent) {
diff --git a/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellApplication.java b/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellApplication.java
index 6d79070..ddbe76f 100644
--- a/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellApplication.java
+++ b/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellApplication.java
@@ -16,7 +16,6 @@
*/
public class ContentShellApplication extends Application {
- private static final String NATIVE_LIBRARY = "content_shell_content_view";
private static final String[] MANDATORY_PAK_FILES = new String[] {"content_shell.pak"};
private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "content_shell";
@@ -28,7 +27,6 @@
public static void initializeApplicationParameters() {
ResourceExtractor.setMandatoryPaksToExtract(MANDATORY_PAK_FILES);
- LibraryLoader.setLibraryToLoad(NATIVE_LIBRARY);
PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX);
}
diff --git a/content/shell/android/shell_manager.cc b/content/shell/android/shell_manager.cc
index 39fd872..0b12e1d 100644
--- a/content/shell/android/shell_manager.cc
+++ b/content/shell/android/shell_manager.cc
@@ -50,8 +50,7 @@
void LaunchShell(JNIEnv* env, jclass clazz, jstring jurl) {
ShellBrowserContext* browserContext =
- static_cast<ShellContentBrowserClient*>(
- GetContentClient()->browser())->browser_context();
+ ShellContentBrowserClient::Get()->browser_context();
GURL url(base::android::ConvertJavaStringToUTF8(env, jurl));
Shell::CreateNewWindow(browserContext,
url,
diff --git a/content/shell/geolocation/shell_access_token_store.cc b/content/shell/geolocation/shell_access_token_store.cc
index 587057c..2c011cd 100644
--- a/content/shell/geolocation/shell_access_token_store.cc
+++ b/content/shell/geolocation/shell_access_token_store.cc
@@ -7,10 +7,15 @@
#include "base/bind.h"
#include "base/message_loop.h"
#include "base/utf_string_conversions.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/shell/shell_browser_context.h"
+
+namespace content {
ShellAccessTokenStore::ShellAccessTokenStore(
- net::URLRequestContextGetter* request_context)
- : request_context_(request_context) {
+ content::ShellBrowserContext* shell_browser_context)
+ : shell_browser_context_(shell_browser_context),
+ system_request_context_(NULL) {
}
ShellAccessTokenStore::~ShellAccessTokenStore() {
@@ -18,22 +23,33 @@
void ShellAccessTokenStore::LoadAccessTokens(
const LoadAccessTokensCallbackType& callback) {
- MessageLoop::current()->PostTask(
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::UI,
FROM_HERE,
- base::Bind(&ShellAccessTokenStore::DidLoadAccessTokens,
- request_context_, callback));
+ base::Bind(&ShellAccessTokenStore::GetRequestContextOnUIThread,
+ this,
+ shell_browser_context_),
+ base::Bind(&ShellAccessTokenStore::RespondOnOriginatingThread,
+ this,
+ callback));
}
-void ShellAccessTokenStore::DidLoadAccessTokens(
- net::URLRequestContextGetter* request_context,
+void ShellAccessTokenStore::GetRequestContextOnUIThread(
+ content::ShellBrowserContext* shell_browser_context) {
+ system_request_context_ = shell_browser_context->GetRequestContext();
+}
+
+void ShellAccessTokenStore::RespondOnOriginatingThread(
const LoadAccessTokensCallbackType& callback) {
// Since content_shell is a test executable, rather than an end user program,
// we provide a dummy access_token set to avoid hitting the server.
AccessTokenSet access_token_set;
access_token_set[GURL()] = ASCIIToUTF16("chromium_content_shell");
- callback.Run(access_token_set, request_context);
+ callback.Run(access_token_set, system_request_context_);
}
void ShellAccessTokenStore::SaveAccessToken(
const GURL& server_url, const string16& access_token) {
}
+
+} // namespace content
diff --git a/content/shell/geolocation/shell_access_token_store.h b/content/shell/geolocation/shell_access_token_store.h
index 1384ac5..82ee0f8 100644
--- a/content/shell/geolocation/shell_access_token_store.h
+++ b/content/shell/geolocation/shell_access_token_store.h
@@ -7,14 +7,22 @@
#include "content/public/browser/access_token_store.h"
+namespace content {
+class ShellBrowserContext;
+
// Dummy access token store used to initialise the network location provider.
class ShellAccessTokenStore : public content::AccessTokenStore {
public:
- explicit ShellAccessTokenStore(net::URLRequestContextGetter* request_context);
+ explicit ShellAccessTokenStore(
+ content::ShellBrowserContext* shell_browser_context);
private:
virtual ~ShellAccessTokenStore();
+ void GetRequestContextOnUIThread(
+ content::ShellBrowserContext* shell_browser_context);
+ void RespondOnOriginatingThread(const LoadAccessTokensCallbackType& callback);
+
// AccessTokenStore
virtual void LoadAccessTokens(
const LoadAccessTokensCallbackType& callback) OVERRIDE;
@@ -22,13 +30,12 @@
virtual void SaveAccessToken(
const GURL& server_url, const string16& access_token) OVERRIDE;
- static void DidLoadAccessTokens(
- net::URLRequestContextGetter* request_context,
- const LoadAccessTokensCallbackType& callback);
-
- net::URLRequestContextGetter* request_context_;
+ content::ShellBrowserContext* shell_browser_context_;
+ net::URLRequestContextGetter* system_request_context_;
DISALLOW_COPY_AND_ASSIGN(ShellAccessTokenStore);
};
+} // namespace content
+
#endif // CONTENT_SHELL_GEOLOCATION_SHELL_ACCESS_TOKEN_STORE_H_
diff --git a/content/shell/notify_done_forwarder.cc b/content/shell/notify_done_forwarder.cc
new file mode 100644
index 0000000..7de67ed
--- /dev/null
+++ b/content/shell/notify_done_forwarder.cc
@@ -0,0 +1,33 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/shell/notify_done_forwarder.h"
+
+#include "content/shell/shell_messages.h"
+#include "content/shell/webkit_test_controller.h"
+
+namespace content {
+
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(NotifyDoneForwarder);
+
+NotifyDoneForwarder::NotifyDoneForwarder(WebContents* web_contents)
+ : WebContentsObserver(web_contents) {}
+
+NotifyDoneForwarder::~NotifyDoneForwarder() {}
+
+bool NotifyDoneForwarder::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(NotifyDoneForwarder, message)
+ IPC_MESSAGE_HANDLER(ShellViewHostMsg_TestFinishedInSecondaryWindow,
+ OnTestFinishedInSecondaryWindow)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void NotifyDoneForwarder::OnTestFinishedInSecondaryWindow() {
+ WebKitTestController::Get()->TestFinishedInSecondaryWindow();
+}
+
+} // namespace content
diff --git a/content/shell/notify_done_forwarder.h b/content/shell/notify_done_forwarder.h
new file mode 100644
index 0000000..008371a
--- /dev/null
+++ b/content/shell/notify_done_forwarder.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_SHELL_NOTIFY_DONE_FORWARDER_H_
+#define CONTENT_SHELL_NOTIFY_DONE_FORWARDER_H_
+
+#include "base/basictypes.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+
+namespace content {
+
+class NotifyDoneForwarder : public WebContentsObserver,
+ public WebContentsUserData<NotifyDoneForwarder> {
+ public:
+ virtual ~NotifyDoneForwarder();
+
+ // WebContentsObserver implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+
+ private:
+ friend class WebContentsUserData<NotifyDoneForwarder>;
+
+ explicit NotifyDoneForwarder(WebContents* web_contents);
+
+ void OnTestFinishedInSecondaryWindow();
+
+ DISALLOW_COPY_AND_ASSIGN(NotifyDoneForwarder);
+};
+
+} // namespace content
+
+#endif // CONTENT_SHELL_NOTIFY_DONE_FORWARDER_H_
diff --git a/content/shell/shell_content_renderer_client.cc b/content/shell/renderer/shell_content_renderer_client.cc
similarity index 93%
rename from content/shell/shell_content_renderer_client.cc
rename to content/shell/renderer/shell_content_renderer_client.cc
index e794f0d..293bc0b 100644
--- a/content/shell/shell_content_renderer_client.cc
+++ b/content/shell/renderer/shell_content_renderer_client.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/shell/shell_content_renderer_client.h"
+#include "content/shell/renderer/shell_content_renderer_client.h"
#include "base/callback.h"
#include "base/command_line.h"
@@ -11,9 +11,9 @@
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_view.h"
#include "content/public/test/layouttest_support.h"
-#include "content/shell/shell_render_process_observer.h"
+#include "content/shell/renderer/shell_render_process_observer.h"
+#include "content/shell/renderer/webkit_test_runner.h"
#include "content/shell/shell_switches.h"
-#include "content/shell/webkit_test_runner.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamCenter.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
@@ -42,7 +42,17 @@
namespace content {
+namespace {
+ShellContentRendererClient* g_renderer_client;
+}
+
+ShellContentRendererClient* ShellContentRendererClient::Get() {
+ return g_renderer_client;
+}
+
ShellContentRendererClient::ShellContentRendererClient() {
+ DCHECK(!g_renderer_client);
+ g_renderer_client = this;
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) {
EnableWebTestProxyCreation(
base::Bind(&ShellContentRendererClient::WebTestProxyCreated,
@@ -51,6 +61,7 @@
}
ShellContentRendererClient::~ShellContentRendererClient() {
+ g_renderer_client = NULL;
}
void ShellContentRendererClient::LoadHyphenDictionary(
diff --git a/content/shell/shell_content_renderer_client.h b/content/shell/renderer/shell_content_renderer_client.h
similarity index 97%
rename from content/shell/shell_content_renderer_client.h
rename to content/shell/renderer/shell_content_renderer_client.h
index 14bc54d..857b5c9 100644
--- a/content/shell/shell_content_renderer_client.h
+++ b/content/shell/renderer/shell_content_renderer_client.h
@@ -33,6 +33,8 @@
class ShellContentRendererClient : public ContentRendererClient {
public:
+ static ShellContentRendererClient* Get();
+
ShellContentRendererClient();
virtual ~ShellContentRendererClient();
diff --git a/content/shell/shell_render_process_observer.cc b/content/shell/renderer/shell_render_process_observer.cc
similarity index 89%
rename from content/shell/shell_render_process_observer.cc
rename to content/shell/renderer/shell_render_process_observer.cc
index da8a5d0..c0fa05c 100644
--- a/content/shell/shell_render_process_observer.cc
+++ b/content/shell/renderer/shell_render_process_observer.cc
@@ -2,17 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/shell/shell_render_process_observer.h"
+#include "content/shell/renderer/shell_render_process_observer.h"
#include "base/command_line.h"
#include "content/public/common/content_client.h"
-#include "content/public/renderer/render_view.h"
#include "content/public/renderer/render_thread.h"
+#include "content/public/renderer/render_view.h"
#include "content/public/test/layouttest_support.h"
-#include "content/shell/shell_content_renderer_client.h"
+#include "content/shell/renderer/shell_content_renderer_client.h"
+#include "content/shell/renderer/webkit_test_runner.h"
#include "content/shell/shell_messages.h"
#include "content/shell/shell_switches.h"
-#include "content/shell/webkit_test_runner.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "third_party/WebKit/Tools/DumpRenderTree/chromium/TestRunner/public/WebTestInterfaces.h"
#include "webkit/glue/webkit_glue.h"
@@ -96,10 +96,7 @@
void ShellRenderProcessObserver::OnLoadHyphenDictionary(
const IPC::PlatformFileForTransit& dict_file) {
- ShellContentRendererClient* renderer_client =
- static_cast<content::ShellContentRendererClient*>(
- content::GetContentClient()->renderer());
- renderer_client->LoadHyphenDictionary(
+ ShellContentRendererClient::Get()->LoadHyphenDictionary(
IPC::PlatformFileForTransitToPlatformFile(dict_file));
}
diff --git a/content/shell/shell_render_process_observer.h b/content/shell/renderer/shell_render_process_observer.h
similarity index 100%
rename from content/shell/shell_render_process_observer.h
rename to content/shell/renderer/shell_render_process_observer.h
diff --git a/content/shell/webkit_test_runner.cc b/content/shell/renderer/webkit_test_runner.cc
similarity index 90%
rename from content/shell/webkit_test_runner.cc
rename to content/shell/renderer/webkit_test_runner.cc
index eb2c10d..a4c2d6b 100644
--- a/content/shell/webkit_test_runner.cc
+++ b/content/shell/renderer/webkit_test_runner.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/shell/webkit_test_runner.h"
+#include "content/shell/renderer/webkit_test_runner.h"
#include <algorithm>
#include <clocale>
@@ -15,14 +15,14 @@
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "content/public/renderer/render_view.h"
#include "content/public/renderer/render_view_visitor.h"
#include "content/public/test/layouttest_support.h"
+#include "content/shell/renderer/shell_render_process_observer.h"
#include "content/shell/shell_messages.h"
-#include "content/shell/shell_render_process_observer.h"
#include "content/shell/webkit_test_helpers.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
@@ -47,6 +47,7 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebHistoryItem.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebTestingSupport.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "third_party/WebKit/Tools/DumpRenderTree/chromium/TestRunner/public/WebTask.h"
@@ -58,6 +59,7 @@
#include "webkit/glue/glue_serialize.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webpreferences.h"
+#include "webkit/mocks/test_media_stream_client.h"
using WebKit::Platform;
using WebKit::WebArrayBufferView;
@@ -68,8 +70,11 @@
using WebKit::WebFrame;
using WebKit::WebGamepads;
using WebKit::WebHistoryItem;
+using WebKit::WebMediaPlayer;
+using WebKit::WebMediaPlayerClient;
using WebKit::WebPoint;
using WebKit::WebRect;
+using WebKit::WebScriptSource;
using WebKit::WebSize;
using WebKit::WebString;
using WebKit::WebURL;
@@ -78,7 +83,6 @@
using WebKit::WebTestingSupport;
using WebKit::WebVector;
using WebKit::WebView;
-using WebTestRunner::WebPreferences;
using WebTestRunner::WebTask;
using WebTestRunner::WebTestInterfaces;
using WebTestRunner::WebTestProxyBase;
@@ -159,6 +163,26 @@
DISALLOW_COPY_AND_ASSIGN(ProxyToRenderViewVisitor);
};
+class NavigateAwayVisitor : public RenderViewVisitor {
+ public:
+ NavigateAwayVisitor(RenderView* main_render_view)
+ : main_render_view_(main_render_view) {}
+ virtual ~NavigateAwayVisitor() {}
+
+ virtual bool Visit(RenderView* render_view) OVERRIDE {
+ if (render_view == main_render_view_)
+ return true;
+ render_view->GetWebView()->mainFrame()
+ ->loadRequest(WebURLRequest(GURL("about:blank")));
+ return true;
+ }
+
+ private:
+ RenderView* main_render_view_;
+
+ DISALLOW_COPY_AND_ASSIGN(NavigateAwayVisitor);
+};
+
} // namespace
WebKitTestRunner::WebKitTestRunner(RenderView* render_view)
@@ -197,7 +221,7 @@
}
void WebKitTestRunner::postDelayedTask(WebTask* task, long long ms) {
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&WebTask::run, base::Owned(task)),
base::TimeDelta::FromMilliseconds(ms));
@@ -274,12 +298,12 @@
return WebURL(GURL(new_url));
}
-WebPreferences* WebKitTestRunner::preferences() {
+WebTestRunner::WebPreferences* WebKitTestRunner::preferences() {
return &prefs_;
}
void WebKitTestRunner::applyPreferences() {
- webkit_glue::WebPreferences prefs = render_view()->GetWebkitPreferences();
+ WebPreferences prefs = render_view()->GetWebkitPreferences();
ExportLayoutTestSpecificPreferences(prefs_, &prefs);
render_view()->SetWebkitPreferences(prefs);
Send(new ShellViewHostMsg_OverridePreferences(routing_id(), prefs));
@@ -402,8 +426,10 @@
}
void WebKitTestRunner::testFinished() {
- if (!is_main_window_)
+ if (!is_main_window_) {
+ Send(new ShellViewHostMsg_TestFinishedInSecondaryWindow(routing_id()));
return;
+ }
WebTestInterfaces* interfaces =
ShellRenderProcessObserver::GetInstance()->test_interfaces();
interfaces->setTestIsRunning(false);
@@ -434,6 +460,8 @@
}
void WebKitTestRunner::closeRemainingWindows() {
+ NavigateAwayVisitor visitor(render_view());
+ RenderView::ForEach(&visitor);
Send(new ShellViewHostMsg_CloseRemainingWindows(routing_id()));
}
@@ -489,6 +517,17 @@
history->swap(result);
}
+WebMediaPlayer* WebKitTestRunner::createWebMediaPlayer(
+ WebFrame* frame, const WebURL& url, WebMediaPlayerClient* client)
+{
+ if (!test_media_stream_client_) {
+ test_media_stream_client_.reset(
+ new webkit_glue::TestMediaStreamClient());
+ }
+ return webkit_glue::CreateMediaPlayer(
+ frame, url, client, test_media_stream_client_.get());
+}
+
// RenderViewObserver --------------------------------------------------------
void WebKitTestRunner::DidClearWindowObject(WebFrame* frame) {
@@ -503,6 +542,7 @@
OnSetTestConfiguration)
IPC_MESSAGE_HANDLER(ShellViewMsg_SessionHistory, OnSessionHistory)
IPC_MESSAGE_HANDLER(ShellViewMsg_Reset, OnReset)
+ IPC_MESSAGE_HANDLER(ShellViewMsg_NotifyDone, OnNotifyDone)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -511,6 +551,13 @@
void WebKitTestRunner::Navigate(const GURL& url) {
focus_on_next_commit_ = true;
+ if (!is_main_window_ &&
+ ShellRenderProcessObserver::GetInstance()->main_test_runner() == this) {
+ WebTestInterfaces* interfaces =
+ ShellRenderProcessObserver::GetInstance()->test_interfaces();
+ interfaces->setTestIsRunning(true);
+ interfaces->configureForTestWithURL(GURL(), false);
+ }
}
void WebKitTestRunner::DidCommitProvisionalLoad(WebFrame* frame,
@@ -582,7 +629,7 @@
const uint8_t* raw_pixels =
reinterpret_cast<const uint8_t*>(snapshot.getPixels());
size_t snapshot_size = snapshot.getSize();
- scoped_array<uint8_t> reordered_pixels(new uint8_t[snapshot_size]);
+ scoped_ptr<uint8_t[]> reordered_pixels(new uint8_t[snapshot_size]);
for (size_t i = 0; i < snapshot_size; i += 4) {
reordered_pixels[i] = raw_pixels[i + 2];
reordered_pixels[i + 1] = raw_pixels[i + 1];
@@ -606,7 +653,7 @@
}
}
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(base::IgnoreResult(&WebKitTestRunner::Send),
base::Unretained(this),
@@ -647,4 +694,9 @@
Send(new ShellViewHostMsg_ResetDone(routing_id()));
}
+void WebKitTestRunner::OnNotifyDone() {
+ render_view()->GetWebView()->mainFrame()->executeScript(
+ WebScriptSource(WebString::fromUTF8("testRunner.notifyDone();")));
+}
+
} // namespace content
diff --git a/content/shell/webkit_test_runner.h b/content/shell/renderer/webkit_test_runner.h
similarity index 92%
rename from content/shell/webkit_test_runner.h
rename to content/shell/renderer/webkit_test_runner.h
index 860378d..0023ec4 100644
--- a/content/shell/webkit_test_runner.h
+++ b/content/shell/renderer/webkit_test_runner.h
@@ -19,6 +19,8 @@
class SkCanvas;
namespace WebKit {
+class WebMediaPlayer;
+class WebMediaPlayerClient;
struct WebRect;
}
@@ -26,6 +28,10 @@
class WebTestProxyBase;
}
+namespace webkit_glue {
+class TestMediaStreamClient;
+}
+
namespace content {
// This is the renderer side of the webkit test runner.
@@ -90,6 +96,10 @@
WebTestRunner::WebTestProxyBase* proxy,
WebKit::WebVector<WebKit::WebHistoryItem>* history,
size_t* currentEntryIndex);
+ virtual WebKit::WebMediaPlayer* createWebMediaPlayer(
+ WebKit::WebFrame* frame,
+ const WebKit::WebURL& url,
+ WebKit::WebMediaPlayerClient* client);
void Reset();
@@ -104,6 +114,7 @@
const std::vector<std::vector<std::string> >& session_histories,
const std::vector<unsigned>& current_entry_indexes);
void OnReset();
+ void OnNotifyDone();
// After finishing the test, retrieves the audio, text, and pixel dumps from
// the TestRunner library and sends them to the browser process.
@@ -125,6 +136,8 @@
bool focus_on_next_commit_;
+ scoped_ptr<webkit_glue::TestMediaStreamClient> test_media_stream_client_;
+
DISALLOW_COPY_AND_ASSIGN(WebKitTestRunner);
};
diff --git a/content/shell/shell.cc b/content/shell/shell.cc
index 0d32f0f..5eac7af 100644
--- a/content/shell/shell.cc
+++ b/content/shell/shell.cc
@@ -22,6 +22,7 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/common/renderer_preferences.h"
+#include "content/shell/notify_done_forwarder.h"
#include "content/shell/shell_browser_main_parts.h"
#include "content/shell/shell_content_browser_client.h"
#include "content/shell/shell_devtools_frontend.h"
@@ -76,7 +77,8 @@
}
if (windows_.empty() && quit_message_loop_)
- MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ base::MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::QuitClosure());
}
Shell* Shell::CreateShell(WebContents* web_contents) {
@@ -104,7 +106,7 @@
std::vector<Shell*> open_windows(windows_);
for (size_t i = 0; i < open_windows.size(); ++i)
open_windows[i]->Close();
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
}
void Shell::SetShellCreatedCallback(
@@ -189,17 +191,25 @@
return;
}
devtools_frontend_ = ShellDevToolsFrontend::Show(web_contents());
+ registrar_.Add(this,
+ NOTIFICATION_WEB_CONTENTS_DESTROYED,
+ Source<WebContents>(
+ devtools_frontend_->frontend_shell()->web_contents()));
}
void Shell::CloseDevTools() {
if (!devtools_frontend_)
return;
+ registrar_.Remove(this,
+ NOTIFICATION_WEB_CONTENTS_DESTROYED,
+ Source<WebContents>(
+ devtools_frontend_->frontend_shell()->web_contents()));
devtools_frontend_->Close();
devtools_frontend_ = NULL;
}
gfx::NativeView Shell::GetContentView() {
- if (!web_contents_.get())
+ if (!web_contents_)
return NULL;
return web_contents_->GetView()->GetNativeView();
}
@@ -263,6 +273,8 @@
const GURL& target_url,
WebContents* new_contents) {
CreateShell(new_contents);
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
+ NotifyDoneForwarder::CreateForWebContents(new_contents);
}
void Shell::DidNavigateMainFramePostCommit(WebContents* web_contents) {
@@ -270,7 +282,7 @@
}
JavaScriptDialogManager* Shell::GetJavaScriptDialogManager() {
- if (!dialog_manager_.get())
+ if (!dialog_manager_)
dialog_manager_.reset(new ShellJavaScriptDialogManager());
return dialog_manager_.get();
}
@@ -308,6 +320,11 @@
string16 text = title->first->GetTitle();
PlatformSetTitle(text);
}
+ } else if (type == NOTIFICATION_WEB_CONTENTS_DESTROYED) {
+ devtools_frontend_ = NULL;
+ registrar_.Remove(this, NOTIFICATION_WEB_CONTENTS_DESTROYED, source);
+ } else {
+ NOTREACHED();
}
}
diff --git a/content/shell/shell.h b/content/shell/shell.h
index fb1c5c6..736bd3f 100644
--- a/content/shell/shell.h
+++ b/content/shell/shell.h
@@ -10,9 +10,9 @@
#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/memory/scoped_ptr.h"
-#include "base/string_piece.h"
-#include "content/public/browser/notification_registrar.h"
+#include "base/strings/string_piece.h"
#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_delegate.h"
#include "ipc/ipc_channel.h"
#include "ui/gfx/native_widget_types.h"
diff --git a/content/shell/shell_android.cc b/content/shell/shell_android.cc
index 32d7fc0..d8a6fcb 100644
--- a/content/shell/shell_android.cc
+++ b/content/shell/shell_android.cc
@@ -6,11 +6,11 @@
#include <jni.h>
-#include "base/android/scoped_java_ref.h"
#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
#include "base/command_line.h"
#include "base/logging.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "content/public/common/content_switches.h"
#include "content/shell/android/shell_manager.h"
#include "jni/Shell_jni.h"
diff --git a/content/shell/shell_application_mac.mm b/content/shell/shell_application_mac.mm
index 7918c1d..a810804 100644
--- a/content/shell/shell_application_mac.mm
+++ b/content/shell/shell_application_mac.mm
@@ -27,8 +27,7 @@
- (IBAction)newDocument:(id)sender {
content::ShellBrowserContext* browserContext =
- static_cast<content::ShellContentBrowserClient*>(
- content::GetContentClient()->browser())->browser_context();
+ content::ShellContentBrowserClient::Get()->browser_context();
content::Shell::CreateNewWindow(browserContext,
GURL("about:blank"),
NULL,
diff --git a/content/shell/shell_browser_context.cc b/content/shell/shell_browser_context.cc
index 81af960..5eb0f6d 100644
--- a/content/shell/shell_browser_context.cc
+++ b/content/shell/shell_browser_context.cc
@@ -62,7 +62,7 @@
}
ShellBrowserContext::~ShellBrowserContext() {
- if (resource_context_.get()) {
+ if (resource_context_) {
BrowserThread::DeleteSoon(
BrowserThread::IO, FROM_HERE, resource_context_.release());
}
@@ -113,7 +113,7 @@
DownloadManagerDelegate* ShellBrowserContext::GetDownloadManagerDelegate() {
DownloadManager* manager = BrowserContext::GetDownloadManager(this);
- if (!download_manager_delegate_.get()) {
+ if (!download_manager_delegate_) {
download_manager_delegate_ = new ShellDownloadManagerDelegate();
download_manager_delegate_->SetDownloadManager(manager);
CommandLine* cmd_line = CommandLine::ForCurrentProcess();
diff --git a/content/shell/shell_browser_main.cc b/content/shell/shell_browser_main.cc
index 28a9431..e6e45c3 100644
--- a/content/shell/shell_browser_main.cc
+++ b/content/shell/shell_browser_main.cc
@@ -13,13 +13,14 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "base/utf_string_conversions.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/shell/shell.h"
#include "content/shell/shell_switches.h"
#include "content/shell/webkit_test_controller.h"
+#include "content/shell/webkit_test_helpers.h"
#include "net/base/net_util.h"
#include "webkit/support/webkit_support.h"
@@ -60,8 +61,11 @@
#else
base::FilePath local_file(path_or_url);
#endif
- file_util::AbsolutePath(&local_file);
- test_url = net::FilePathToFileURL(local_file);
+ if (!file_util::PathExists(local_file)) {
+ local_file = content::GetWebKitRootDirFilePath()
+ .Append(FILE_PATH_LITERAL("LayoutTests")).Append(local_file);
+ }
+ test_url = net::FilePathToFileURL(base::MakeAbsoluteFilePath(local_file));
}
base::FilePath local_path;
if (current_working_directory) {
@@ -116,7 +120,8 @@
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kCheckLayoutTestSysDeps)) {
- MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ base::MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::QuitClosure());
main_runner_->Run();
content::Shell::CloseAllWindows();
main_runner_->Shutdown();
@@ -166,7 +171,8 @@
break;
}
if (!ran_at_least_once) {
- MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ base::MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::QuitClosure());
main_runner_->Run();
}
exit_code = 0;
diff --git a/content/shell/shell_browser_main_parts.cc b/content/shell/shell_browser_main_parts.cc
index c0d9cb4..99ff7ce 100644
--- a/content/shell/shell_browser_main_parts.cc
+++ b/content/shell/shell_browser_main_parts.cc
@@ -8,7 +8,6 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/message_loop.h"
-#include "base/string_number_conversions.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "cc/base/switches.h"
@@ -31,7 +30,7 @@
#endif
#if defined(USE_AURA) && defined(USE_X11)
-#include "ui/base/touch/touch_factory.h"
+#include "ui/base/touch/touch_factory_x11.h"
#endif
namespace content {
@@ -92,7 +91,7 @@
void ShellBrowserMainParts::PostMainMessageLoopStart() {
#if defined(OS_ANDROID)
- MessageLoopForUI::current()->Start();
+ base::MessageLoopForUI::current()->Start();
#endif
}
@@ -113,25 +112,7 @@
Shell::Initialize();
net::NetModule::SetResourceProvider(PlatformResourceProvider);
- int port = 0;
-// On android the port number isn't used.
-#if !defined(OS_ANDROID)
- // See if the user specified a port on the command line (useful for
- // automation). If not, use an ephemeral port by specifying 0.
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) {
- int temp_port;
- std::string port_str =
- command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
- if (base::StringToInt(port_str, &temp_port) &&
- temp_port > 0 && temp_port < 65535) {
- port = temp_port;
- } else {
- DLOG(WARNING) << "Invalid http debugger port number " << temp_port;
- }
- }
-#endif
- devtools_delegate_ = new ShellDevToolsDelegate(browser_context_.get(), port);
+ devtools_delegate_ = new ShellDevToolsDelegate(browser_context_.get());
if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) {
Shell::CreateNewWindow(browser_context_.get(),
diff --git a/content/shell/shell_content_browser_client.cc b/content/shell/shell_content_browser_client.cc
index 163027f..fc2a1e0 100644
--- a/content/shell/shell_content_browser_client.cc
+++ b/content/shell/shell_content_browser_client.cc
@@ -7,6 +7,8 @@
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/storage_partition.h"
@@ -23,6 +25,7 @@
#include "content/shell/shell_switches.h"
#include "content/shell/shell_web_contents_view_delegate_creator.h"
#include "content/shell/webkit_test_controller.h"
+#include "content/shell/webkit_test_helpers.h"
#include "googleurl/src/gurl.h"
#include "webkit/glue/webpreferences.h"
@@ -37,50 +40,25 @@
namespace {
-base::FilePath GetWebKitRootDirFilePath() {
- base::FilePath base_path;
- PathService::Get(base::DIR_SOURCE_ROOT, &base_path);
- if (file_util::PathExists(
- base_path.Append(FILE_PATH_LITERAL("third_party/WebKit")))) {
- // We're in a WebKit-in-chrome checkout.
- return base_path.Append(FILE_PATH_LITERAL("third_party/WebKit"));
- } else if (file_util::PathExists(
- base_path.Append(FILE_PATH_LITERAL("chromium")))) {
- // We're in a WebKit-only checkout on Windows.
- return base_path.Append(FILE_PATH_LITERAL("../.."));
- } else if (file_util::PathExists(
- base_path.Append(FILE_PATH_LITERAL("webkit/support")))) {
- // We're in a WebKit-only/xcodebuild checkout on Mac
- return base_path.Append(FILE_PATH_LITERAL("../../.."));
- }
- // We're in a WebKit-only, make-build, so the DIR_SOURCE_ROOT is already the
- // WebKit root. That, or we have no idea where we are.
- return base_path;
-}
-
-base::FilePath GetChromiumRootDirFilePath() {
- base::FilePath webkit_path = GetWebKitRootDirFilePath();
- if (file_util::PathExists(webkit_path.Append(
- FILE_PATH_LITERAL("Source/WebKit/chromium/webkit/support")))) {
- // We're in a WebKit-only checkout.
- return webkit_path.Append(FILE_PATH_LITERAL("Source/WebKit/chromium"));
- } else {
- // We're in a Chromium checkout, and WebKit is in third_party/WebKit.
- return webkit_path.Append(FILE_PATH_LITERAL("../.."));
- }
-}
+ShellContentBrowserClient* g_browser_client;
} // namespace
+ShellContentBrowserClient* ShellContentBrowserClient::Get() {
+ return g_browser_client;
+}
+
ShellContentBrowserClient::ShellContentBrowserClient()
: hyphen_dictionary_file_(base::kInvalidPlatformFileValue),
shell_browser_main_parts_(NULL) {
+ DCHECK(!g_browser_client);
+ g_browser_client = this;
if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
return;
webkit_source_dir_ = GetWebKitRootDirFilePath();
- base::FilePath dictionary_file_path = GetChromiumRootDirFilePath().Append(
- FILE_PATH_LITERAL("third_party/hyphen/hyph_en_US.dic"));
- file_util::AbsolutePath(&dictionary_file_path);
+ base::FilePath dictionary_file_path = base::MakeAbsoluteFilePath(
+ GetChromiumRootDirFilePath().Append(
+ FILE_PATH_LITERAL("third_party/hyphen/hyph_en_US.dic")));
hyphen_dictionary_file_ = base::CreatePlatformFile(dictionary_file_path,
base::PLATFORM_FILE_READ |
base::PLATFORM_FILE_OPEN,
@@ -89,6 +67,7 @@
}
ShellContentBrowserClient::~ShellContentBrowserClient() {
+ g_browser_client = NULL;
}
BrowserMainParts* ShellContentBrowserClient::CreateBrowserMainParts(
@@ -108,12 +87,9 @@
BrowserContext::GetDefaultStoragePartition(browser_context())
->GetQuotaManager()));
host->Send(new ShellViewMsg_SetWebKitSourceDir(webkit_source_dir_));
-
- if (hyphen_dictionary_file_ != base::kInvalidPlatformFileValue) {
- IPC::PlatformFileForTransit file = IPC::GetFileHandleForProcess(
- hyphen_dictionary_file_, host->GetHandle(), false);
- host->Send(new ShellViewMsg_LoadHyphenDictionary(file));
- }
+ registrar_.Add(this,
+ NOTIFICATION_RENDERER_PROCESS_CREATED,
+ Source<RenderProcessHost>(host));
}
net::URLRequestContextGetter* ShellContentBrowserClient::CreateRequestContext(
@@ -145,7 +121,7 @@
void ShellContentBrowserClient::OverrideWebkitPrefs(
RenderViewHost* render_view_host,
const GURL& url,
- webkit_glue::WebPreferences* prefs) {
+ WebPreferences* prefs) {
if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
return;
WebKitTestController::Get()->OverrideWebkitPrefs(prefs);
@@ -206,6 +182,28 @@
}
#endif
+void ShellContentBrowserClient::Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ switch (type) {
+ case NOTIFICATION_RENDERER_PROCESS_CREATED: {
+ registrar_.Remove(this,
+ NOTIFICATION_RENDERER_PROCESS_CREATED,
+ source);
+ if (hyphen_dictionary_file_ != base::kInvalidPlatformFileValue) {
+ RenderProcessHost* host = Source<RenderProcessHost>(source).ptr();
+ IPC::PlatformFileForTransit file = IPC::GetFileHandleForProcess(
+ hyphen_dictionary_file_, host->GetHandle(), false);
+ host->Send(new ShellViewMsg_LoadHyphenDictionary(file));
+ }
+ break;
+ }
+
+ default:
+ NOTREACHED();
+ }
+}
+
ShellBrowserContext* ShellContentBrowserClient::browser_context() {
return shell_browser_main_parts_->browser_context();
}
@@ -216,7 +214,7 @@
}
AccessTokenStore* ShellContentBrowserClient::CreateAccessTokenStore() {
- return new ShellAccessTokenStore(browser_context()->GetRequestContext());
+ return new ShellAccessTokenStore(browser_context());
}
ShellBrowserContext*
diff --git a/content/shell/shell_content_browser_client.h b/content/shell/shell_content_browser_client.h
index 6fce1f8..0adba6f 100644
--- a/content/shell/shell_content_browser_client.h
+++ b/content/shell/shell_content_browser_client.h
@@ -12,6 +12,8 @@
#include "base/memory/scoped_ptr.h"
#include "base/platform_file.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
namespace content {
@@ -19,8 +21,12 @@
class ShellBrowserMainParts;
class ShellResourceDispatcherHostDelegate;
-class ShellContentBrowserClient : public ContentBrowserClient {
+class ShellContentBrowserClient : public ContentBrowserClient,
+ public NotificationObserver {
public:
+ // Gets the current instance.
+ static ShellContentBrowserClient* Get();
+
ShellContentBrowserClient();
virtual ~ShellContentBrowserClient();
@@ -40,7 +46,7 @@
int child_process_id) OVERRIDE;
virtual void OverrideWebkitPrefs(RenderViewHost* render_view_host,
const GURL& url,
- webkit_glue::WebPreferences* prefs) OVERRIDE;
+ WebPreferences* prefs) OVERRIDE;
virtual void ResourceDispatcherHostCreated() OVERRIDE;
virtual AccessTokenStore* CreateAccessTokenStore() OVERRIDE;
virtual std::string GetDefaultDownloadName() OVERRIDE;
@@ -57,6 +63,11 @@
std::vector<content::FileDescriptorInfo>* mappings) OVERRIDE;
#endif
+ // NotificationObserver implementation.
+ virtual void Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) OVERRIDE;
+
ShellBrowserContext* browser_context();
ShellBrowserContext* off_the_record_browser_context();
ShellResourceDispatcherHostDelegate* resource_dispatcher_host_delegate() {
@@ -78,6 +89,8 @@
base::PlatformFile hyphen_dictionary_file_;
ShellBrowserMainParts* shell_browser_main_parts_;
+
+ NotificationRegistrar registrar_;
};
} // namespace content
diff --git a/content/shell/shell_content_client.cc b/content/shell/shell_content_client.cc
index f96b6a3..a8f697a 100644
--- a/content/shell/shell_content_client.cc
+++ b/content/shell/shell_content_client.cc
@@ -5,7 +5,7 @@
#include "content/shell/shell_content_client.h"
#include "base/command_line.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/utf_string_conversions.h"
#include "content/public/common/content_switches.h"
#include "content/shell/shell_switches.h"
diff --git a/content/shell/shell_devtools_delegate.cc b/content/shell/shell_devtools_delegate.cc
index 8eb4722..ae46298 100644
--- a/content/shell/shell_devtools_delegate.cc
+++ b/content/shell/shell_devtools_delegate.cc
@@ -4,39 +4,63 @@
#include "content/shell/shell_devtools_delegate.h"
+#include <vector>
+
#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/strings/string_number_conversions.h"
#include "content/public/browser/devtools_http_handler.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/shell/shell.h"
#include "grit/shell_resources.h"
-#include "net/base/tcp_listen_socket.h"
+#include "net/socket/tcp_listen_socket.h"
#include "ui/base/resource/resource_bundle.h"
#if defined(OS_ANDROID)
#include "content/public/browser/android/devtools_auth.h"
-#include "net/base/unix_domain_socket_posix.h"
+#include "net/socket/unix_domain_socket_posix.h"
+#endif
namespace {
-const char kSocketName[] = "content_shell_devtools_remote";
-}
+
+net::StreamListenSocketFactory* CreateSocketFactory() {
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+#if defined(OS_ANDROID)
+ std::string socket_name = "content_shell_devtools_remote";
+ if (command_line.HasSwitch(switches::kRemoteDebuggingSocketName)) {
+ socket_name = command_line.GetSwitchValueASCII(
+ switches::kRemoteDebuggingSocketName);
+ }
+ return new net::UnixDomainSocketWithAbstractNamespaceFactory(
+ socket_name, base::Bind(&content::CanUserConnectToDevTools));
+#else
+ // See if the user specified a port on the command line (useful for
+ // automation). If not, use an ephemeral port by specifying 0.
+ int port = 0;
+ if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) {
+ int temp_port;
+ std::string port_str =
+ command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
+ if (base::StringToInt(port_str, &temp_port) &&
+ temp_port > 0 && temp_port < 65535) {
+ port = temp_port;
+ } else {
+ DLOG(WARNING) << "Invalid http debugger port number " << temp_port;
+ }
+ }
+ return new net::TCPListenSocketFactory("127.0.0.1", port);
#endif
+}
+} // namespace
namespace content {
-ShellDevToolsDelegate::ShellDevToolsDelegate(BrowserContext* browser_context,
- int port)
+ShellDevToolsDelegate::ShellDevToolsDelegate(BrowserContext* browser_context)
: browser_context_(browser_context) {
- devtools_http_handler_ = DevToolsHttpHandler::Start(
-#if defined(OS_ANDROID)
- new net::UnixDomainSocketWithAbstractNamespaceFactory(
- kSocketName,
- base::Bind(&CanUserConnectToDevTools)),
-#else
- new net::TCPListenSocketFactory("127.0.0.1", port),
-#endif
- "",
- this);
+ devtools_http_handler_ =
+ DevToolsHttpHandler::Start(CreateSocketFactory(), std::string(), this);
}
ShellDevToolsDelegate::~ShellDevToolsDelegate() {
@@ -61,7 +85,7 @@
}
std::string ShellDevToolsDelegate::GetPageThumbnailData(const GURL& url) {
- return "";
+ return std::string();
}
RenderViewHost* ShellDevToolsDelegate::CreateNewTarget() {
@@ -80,7 +104,14 @@
std::string ShellDevToolsDelegate::GetViewDescription(
content::RenderViewHost*) {
- return "";
+ return std::string();
+}
+
+scoped_refptr<net::StreamListenSocket>
+ShellDevToolsDelegate::CreateSocketForTethering(
+ net::StreamListenSocket::Delegate* delegate,
+ std::string* name) {
+ return NULL;
}
} // namespace content
diff --git a/content/shell/shell_devtools_delegate.h b/content/shell/shell_devtools_delegate.h
index 8fda52a..dd4e762 100644
--- a/content/shell/shell_devtools_delegate.h
+++ b/content/shell/shell_devtools_delegate.h
@@ -5,8 +5,6 @@
#ifndef CONTENT_SHELL_SHELL_DEVTOOLS_DELEGATE_H_
#define CONTENT_SHELL_SHELL_DEVTOOLS_DELEGATE_H_
-#include <vector>
-
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "content/public/browser/devtools_http_handler_delegate.h"
@@ -18,7 +16,7 @@
class ShellDevToolsDelegate : public DevToolsHttpHandlerDelegate {
public:
- ShellDevToolsDelegate(BrowserContext* browser_context, int port);
+ explicit ShellDevToolsDelegate(BrowserContext* browser_context);
virtual ~ShellDevToolsDelegate();
// Stops http server.
@@ -32,6 +30,9 @@
virtual RenderViewHost* CreateNewTarget() OVERRIDE;
virtual TargetType GetTargetType(RenderViewHost*) OVERRIDE;
virtual std::string GetViewDescription(content::RenderViewHost*) OVERRIDE;
+ virtual scoped_refptr<net::StreamListenSocket> CreateSocketForTethering(
+ net::StreamListenSocket::Delegate* delegate,
+ std::string* name) OVERRIDE;
DevToolsHttpHandler* devtools_http_handler() {
return devtools_http_handler_;
diff --git a/content/shell/shell_devtools_frontend.cc b/content/shell/shell_devtools_frontend.cc
index ee78b81..fcb810c 100644
--- a/content/shell/shell_devtools_frontend.cc
+++ b/content/shell/shell_devtools_frontend.cc
@@ -56,11 +56,8 @@
DevToolsAgentHost::GetOrCreateFor(
inspected_contents->GetRenderViewHost()));
- ShellContentBrowserClient* browser_client =
- static_cast<ShellContentBrowserClient*>(
- GetContentClient()->browser());
- ShellDevToolsDelegate* delegate =
- browser_client->shell_browser_main_parts()->devtools_delegate();
+ ShellDevToolsDelegate* delegate = ShellContentBrowserClient::Get()->
+ shell_browser_main_parts()->devtools_delegate();
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
shell->LoadURL(GetDevToolsPathAsURL());
else
diff --git a/content/shell/shell_devtools_frontend.h b/content/shell/shell_devtools_frontend.h
index 2308aa3..bee0bd0 100644
--- a/content/shell/shell_devtools_frontend.h
+++ b/content/shell/shell_devtools_frontend.h
@@ -27,6 +27,8 @@
void Focus();
void Close();
+ Shell* frontend_shell() const { return frontend_shell_; }
+
private:
ShellDevToolsFrontend(Shell* frontend_shell, DevToolsAgentHost* agent_host);
virtual ~ShellDevToolsFrontend();
diff --git a/content/shell/shell_gtk.cc b/content/shell/shell_gtk.cc
index 8d024ce..22d6b33 100644
--- a/content/shell/shell_gtk.cc
+++ b/content/shell/shell_gtk.cc
@@ -8,7 +8,7 @@
#include <gtk/gtk.h>
#include "base/logging.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
#include "base/utf_string_conversions.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/native_web_keyboard_event.h"
@@ -209,7 +209,7 @@
void Shell::SizeTo(int width, int height) {
content_width_ = width;
content_height_ = height;
- if (web_contents_.get()) {
+ if (web_contents_) {
gtk_widget_set_size_request(web_contents_->GetView()->GetNativeView(),
width, height);
}
@@ -271,8 +271,7 @@
guint keyval,
GdkModifierType modifier) {
ShellBrowserContext* browser_context =
- static_cast<ShellContentBrowserClient*>(
- GetContentClient()->browser())->browser_context();
+ ShellContentBrowserClient::Get()->browser_context();
Shell::CreateNewWindow(browser_context,
GURL(),
NULL,
diff --git a/content/shell/shell_javascript_dialog_mac.mm b/content/shell/shell_javascript_dialog_mac.mm
index 920bb66..6bdd9ab 100644
--- a/content/shell/shell_javascript_dialog_mac.mm
+++ b/content/shell/shell_javascript_dialog_mac.mm
@@ -7,7 +7,7 @@
#import <Cocoa/Cocoa.h>
#import "base/memory/scoped_nsobject.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "content/shell/shell_javascript_dialog_manager.h"
// Helper object that receives the notification that the dialog/sheet is
diff --git a/content/shell/shell_javascript_dialog_manager.cc b/content/shell/shell_javascript_dialog_manager.cc
index 17f5b6b..4ef5e2b 100644
--- a/content/shell/shell_javascript_dialog_manager.cc
+++ b/content/shell/shell_javascript_dialog_manager.cc
@@ -46,7 +46,7 @@
#if defined(OS_MACOSX) || defined(OS_WIN) || defined(TOOLKIT_GTK)
*did_suppress_message = false;
- if (dialog_.get()) {
+ if (dialog_) {
// One dialog at a time, please.
*did_suppress_message = true;
return;
@@ -89,7 +89,7 @@
}
#if defined(OS_MACOSX) || defined(OS_WIN) || defined(TOOLKIT_GTK)
- if (dialog_.get()) {
+ if (dialog_) {
// Seriously!?
callback.Run(true, string16());
return;
@@ -118,7 +118,7 @@
void ShellJavaScriptDialogManager::ResetJavaScriptState(
WebContents* web_contents) {
#if defined(OS_MACOSX) || defined(OS_WIN) || defined(TOOLKIT_GTK)
- if (dialog_.get()) {
+ if (dialog_) {
dialog_->Cancel();
dialog_.reset();
}
diff --git a/content/shell/shell_login_dialog_mac.mm b/content/shell/shell_login_dialog_mac.mm
index c315644..5a5d4df 100644
--- a/content/shell/shell_login_dialog_mac.mm
+++ b/content/shell/shell_login_dialog_mac.mm
@@ -9,7 +9,7 @@
#include "base/logging.h"
#include "base/mac/bundle_locations.h"
#import "base/memory/scoped_nsobject.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/sys_string_conversions.h"
#include "content/public/browser/browser_thread.h"
#import "ui/base/cocoa/nib_loading.h"
diff --git a/content/shell/shell_mac.mm b/content/shell/shell_mac.mm
index e0e7ee7..0e1c582 100644
--- a/content/shell/shell_mac.mm
+++ b/content/shell/shell_mac.mm
@@ -8,8 +8,8 @@
#include "base/logging.h"
#import "base/memory/scoped_nsobject.h"
-#include "base/string_piece.h"
-#include "base/sys_string_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/sys_string_conversions.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
diff --git a/content/shell/shell_main_delegate.cc b/content/shell/shell_main_delegate.cc
index e0c5e7f..6981321 100644
--- a/content/shell/shell_main_delegate.cc
+++ b/content/shell/shell_main_delegate.cc
@@ -11,9 +11,9 @@
#include "content/public/browser/browser_main_runner.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
+#include "content/shell/renderer/shell_content_renderer_client.h"
#include "content/shell/shell_browser_main.h"
#include "content/shell/shell_content_browser_client.h"
-#include "content/shell/shell_content_renderer_client.h"
#include "content/shell/shell_switches.h"
#include "content/shell/webkit_test_platform_support.h"
#include "content/public/test/layouttest_support.h"
@@ -104,10 +104,12 @@
InitLogging();
CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(switches::kDumpRenderTree)) {
+ command_line.AppendSwitch(switches::kProcessPerTab);
command_line.AppendSwitch(switches::kAllowFileAccessFromFiles);
command_line.AppendSwitchASCII(
switches::kUseGL, gfx::kGLImplementationOSMesaName);
SetAllowOSMesaImageTransportForTesting();
+ DisableSystemDragDrop();
command_line.AppendSwitch(switches::kSkipGpuDataLoading);
command_line.AppendSwitch(switches::kEnableExperimentalWebKitFeatures);
command_line.AppendSwitch(switches::kEnableCssShaders);
diff --git a/content/shell/shell_message_filter.cc b/content/shell/shell_message_filter.cc
index 0aff194..cb16871 100644
--- a/content/shell/shell_message_filter.cc
+++ b/content/shell/shell_message_filter.cc
@@ -5,6 +5,7 @@
#include "content/shell/shell_message_filter.h"
#include "base/file_util.h"
+#include "base/threading/thread_restrictions.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/shell/shell_messages.h"
#include "content/shell/shell_network_delegate.h"
@@ -51,6 +52,7 @@
void ShellMessageFilter::OnReadFileToString(const base::FilePath& local_file,
std::string* contents) {
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
file_util::ReadFileToString(local_file, contents);
}
diff --git a/content/shell/shell_messages.h b/content/shell/shell_messages.h
index 5389d96..dde2dda 100644
--- a/content/shell/shell_messages.h
+++ b/content/shell/shell_messages.h
@@ -39,6 +39,10 @@
IPC_MESSAGE_ROUTED1(ShellViewMsg_SetTestConfiguration,
content::ShellTestConfiguration)
+// Tells the main window that a secondary window in a different process invoked
+// notifyDone().
+IPC_MESSAGE_ROUTED0(ShellViewMsg_NotifyDone)
+
// Pushes a snapshot of the current session history from the browser process.
// This includes only information about those RenderViews that are in the
// same process as the main window of the layout test and that are the current
@@ -67,9 +71,11 @@
IPC_MESSAGE_ROUTED0(ShellViewHostMsg_ResetDone)
+IPC_MESSAGE_ROUTED0(ShellViewHostMsg_TestFinishedInSecondaryWindow)
+
// WebTestDelegate related.
IPC_MESSAGE_ROUTED1(ShellViewHostMsg_OverridePreferences,
- webkit_glue::WebPreferences /* preferences */)
+ WebPreferences /* preferences */)
IPC_SYNC_MESSAGE_ROUTED1_1(ShellViewHostMsg_RegisterIsolatedFileSystem,
std::vector<base::FilePath> /* absolute_filenames */,
std::string /* filesystem_id */)
diff --git a/content/shell/shell_url_request_context_getter.cc b/content/shell/shell_url_request_context_getter.cc
index e861369..2fa6c39 100644
--- a/content/shell/shell_url_request_context_getter.cc
+++ b/content/shell/shell_url_request_context_getter.cc
@@ -15,7 +15,7 @@
#include "content/public/common/url_constants.h"
#include "content/shell/shell_network_delegate.h"
#include "content/shell/shell_switches.h"
-#include "net/base/cert_verifier.h"
+#include "net/cert/cert_verifier.h"
#include "net/cookies/cookie_monster.h"
#include "net/dns/host_resolver.h"
#include "net/dns/mapped_host_resolver.h"
@@ -56,8 +56,8 @@
ShellURLRequestContextGetter::ShellURLRequestContextGetter(
bool ignore_certificate_errors,
const base::FilePath& base_path,
- MessageLoop* io_loop,
- MessageLoop* file_loop,
+ base::MessageLoop* io_loop,
+ base::MessageLoop* file_loop,
ProtocolHandlerMap* protocol_handlers)
: ignore_certificate_errors_(ignore_certificate_errors),
base_path_(base_path),
@@ -84,7 +84,7 @@
net::URLRequestContext* ShellURLRequestContextGetter::GetURLRequestContext() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (!url_request_context_.get()) {
+ if (!url_request_context_) {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
url_request_context_.reset(new net::URLRequestContext());
diff --git a/content/shell/shell_url_request_context_getter.h b/content/shell/shell_url_request_context_getter.h
index 846c5d3..d7a96b2 100644
--- a/content/shell/shell_url_request_context_getter.h
+++ b/content/shell/shell_url_request_context_getter.h
@@ -13,7 +13,9 @@
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_job_factory.h"
+namespace base {
class MessageLoop;
+}
namespace net {
class HostResolver;
@@ -30,8 +32,8 @@
ShellURLRequestContextGetter(
bool ignore_certificate_errors,
const base::FilePath& base_path,
- MessageLoop* io_loop,
- MessageLoop* file_loop,
+ base::MessageLoop* io_loop,
+ base::MessageLoop* file_loop,
ProtocolHandlerMap* protocol_handlers);
// net::URLRequestContextGetter implementation.
@@ -47,8 +49,8 @@
private:
bool ignore_certificate_errors_;
base::FilePath base_path_;
- MessageLoop* io_loop_;
- MessageLoop* file_loop_;
+ base::MessageLoop* io_loop_;
+ base::MessageLoop* file_loop_;
scoped_ptr<net::ProxyConfigService> proxy_config_service_;
scoped_ptr<net::NetworkDelegate> network_delegate_;
diff --git a/content/shell/shell_web_contents_view_delegate_android.cc b/content/shell/shell_web_contents_view_delegate_android.cc
index d222b88..6277a1c 100644
--- a/content/shell/shell_web_contents_view_delegate_android.cc
+++ b/content/shell/shell_web_contents_view_delegate_android.cc
@@ -32,7 +32,7 @@
ContextMenuSourceType type) {
if (params.is_editable && params.selection_text.empty()) {
content::ContentViewCore* content_view_core =
- web_contents_->GetView()->GetContentNativeView();
+ ContentViewCore::FromWebContents(web_contents_);
if (content_view_core) {
content_view_core->ShowPastePopup(params.selection_start.x(),
params.selection_start.y());
diff --git a/content/shell/shell_web_contents_view_delegate_gtk.cc b/content/shell/shell_web_contents_view_delegate_gtk.cc
index cd72e03..ca0a2af 100644
--- a/content/shell/shell_web_contents_view_delegate_gtk.cc
+++ b/content/shell/shell_web_contents_view_delegate_gtk.cc
@@ -211,8 +211,7 @@
void ShellWebContentsViewDelegate::OnOpenURLMenuActivated(GtkWidget* widget) {
ShellBrowserContext* browser_context =
- static_cast<ShellContentBrowserClient*>(
- GetContentClient()->browser())->browser_context();
+ ShellContentBrowserClient::Get()->browser_context();
Shell::CreateNewWindow(browser_context,
params_.link_url,
NULL,
diff --git a/content/shell/shell_web_contents_view_delegate_mac.mm b/content/shell/shell_web_contents_view_delegate_mac.mm
index 2460595..32a9aad 100644
--- a/content/shell/shell_web_contents_view_delegate_mac.mm
+++ b/content/shell/shell_web_contents_view_delegate_mac.mm
@@ -237,8 +237,7 @@
break;
case ShellContextMenuItemOpenLinkTag: {
ShellBrowserContext* browser_context =
- static_cast<ShellContentBrowserClient*>(
- GetContentClient()->browser())->browser_context();
+ ShellContentBrowserClient::Get()->browser_context();
Shell::CreateNewWindow(browser_context,
params_.link_url,
NULL,
diff --git a/content/shell/shell_web_contents_view_delegate_win.cc b/content/shell/shell_web_contents_view_delegate_win.cc
index df400f7..52bc21f 100644
--- a/content/shell/shell_web_contents_view_delegate_win.cc
+++ b/content/shell/shell_web_contents_view_delegate_win.cc
@@ -205,8 +205,7 @@
break;
case ShellContextMenuItemOpenLinkId: {
ShellBrowserContext* browser_context =
- static_cast<ShellContentBrowserClient*>(
- GetContentClient()->browser())->browser_context();
+ ShellContentBrowserClient::Get()->browser_context();
Shell::CreateNewWindow(browser_context,
params_.link_url,
NULL,
diff --git a/content/shell/webkit_test_controller.cc b/content/shell/webkit_test_controller.cc
index 1f712a8..ab12295 100644
--- a/content/shell/webkit_test_controller.cc
+++ b/content/shell/webkit_test_controller.cc
@@ -22,6 +22,7 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_view.h"
#include "content/shell/shell.h"
#include "content/shell/shell_browser_context.h"
#include "content/shell/shell_content_browser_client.h"
@@ -205,9 +206,8 @@
expected_pixel_hash_ = expected_pixel_hash;
test_url_ = test_url;
printer_->reset();
- content::ShellBrowserContext* browser_context =
- static_cast<content::ShellContentBrowserClient*>(
- content::GetContentClient()->browser())->browser_context();
+ ShellBrowserContext* browser_context =
+ ShellContentBrowserClient::Get()->browser_context();
if (test_url.spec().find("compositing/") != std::string::npos)
is_compositing_test_ = true;
gfx::Size initial_size(kTestWindowWidthDip, kTestWindowHeightDip);
@@ -224,6 +224,7 @@
WebContentsObserver::Observe(main_window_->web_contents());
send_configuration_to_next_host_ = true;
current_pid_ = base::kNullProcessId;
+ main_window_->LoadURL(test_url);
} else {
#if (defined(OS_WIN) && !defined(USE_AURA)) || defined(TOOLKIT_GTK)
// Shell::SizeTo is not implemented on all platforms.
@@ -234,23 +235,24 @@
main_window_->web_contents()->GetRenderViewHost()->WasResized();
RenderViewHost* render_view_host =
main_window_->web_contents()->GetRenderViewHost();
- webkit_glue::WebPreferences prefs =
- render_view_host->GetWebkitPreferences();
+ WebPreferences prefs = render_view_host->GetWebkitPreferences();
OverrideWebkitPrefs(&prefs);
render_view_host->UpdateWebkitPreferences(prefs);
SendTestConfiguration();
- registrar_.Add(this,
- NOTIFICATION_NAV_ENTRY_PENDING,
- Source<NavigationController>(
- &main_window_->web_contents()->GetController()));
+
+ NavigationController::LoadURLParams params(test_url);
+ params.transition_type = PageTransitionFromInt(
+ PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR);
+ params.should_clear_history_list = true;
+ main_window_->web_contents()->GetController().LoadURLWithParams(params);
+ main_window_->web_contents()->GetView()->Focus();
}
- main_window_->LoadURL(test_url);
main_window_->web_contents()->GetRenderViewHost()->SetActive(true);
main_window_->web_contents()->GetRenderViewHost()->Focus();
if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoTimeout)) {
watchdog_.Reset(base::Bind(&WebKitTestController::TimeoutHandler,
base::Unretained(this)));
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
watchdog_.callback(),
base::TimeDelta::FromMilliseconds(kTestTimeoutMilliseconds + 1000));
@@ -268,7 +270,7 @@
enable_pixel_dumping_ = false;
expected_pixel_hash_.clear();
test_url_ = GURL();
- prefs_ = webkit_glue::WebPreferences();
+ prefs_ = WebPreferences();
should_override_prefs_ = false;
watchdog_.Cancel();
return true;
@@ -280,21 +282,17 @@
void WebKitTestController::RendererUnresponsive() {
DCHECK(CalledOnValidThread());
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoTimeout))
- return;
- printer_->AddErrorMessage("#PROCESS UNRESPONSIVE - renderer");
- DiscardMainWindow();
+ LOG(WARNING) << "renderer unresponsive";
}
-void WebKitTestController::OverrideWebkitPrefs(
- webkit_glue::WebPreferences* prefs) {
+void WebKitTestController::OverrideWebkitPrefs(WebPreferences* prefs) {
if (should_override_prefs_) {
*prefs = prefs_;
} else {
ApplyLayoutTestDefaultPreferences(prefs);
if (is_compositing_test_) {
CommandLine& command_line = *CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kEnableSoftwareCompositing))
+ if (!command_line.HasSwitch(switches::kEnableSoftwareCompositing))
prefs->accelerated_2d_canvas_enabled = true;
prefs->accelerated_compositing_for_video_enabled = true;
prefs->mock_scrollbars_enabled = true;
@@ -310,6 +308,13 @@
gfx::Size());
}
+void WebKitTestController::TestFinishedInSecondaryWindow() {
+ RenderViewHost* render_view_host =
+ main_window_->web_contents()->GetRenderViewHost();
+ render_view_host->Send(
+ new ShellViewMsg_NotifyDone(render_view_host->GetRoutingID()));
+}
+
bool WebKitTestController::OnMessageReceived(const IPC::Message& message) {
DCHECK(CalledOnValidThread());
bool handled = true;
@@ -393,11 +398,6 @@
current_pid_ = base::GetProcId(render_process_host->GetHandle());
break;
}
- case NOTIFICATION_NAV_ENTRY_PENDING: {
- registrar_.Remove(this, NOTIFICATION_NAV_ENTRY_PENDING, source);
- main_window_->web_contents()->GetController().PruneAllButActive();
- break;
- }
default:
NOTREACHED();
}
@@ -424,7 +424,8 @@
WebContentsObserver::Observe(NULL);
if (is_running_test_) {
Shell::CloseAllWindows();
- MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ base::MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::QuitClosure());
} else if (main_window_) {
main_window_->Close();
}
@@ -463,7 +464,7 @@
printer_->PrintImageFooter();
RenderViewHost* render_view_host =
main_window_->web_contents()->GetRenderViewHost();
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(base::IgnoreResult(&WebKitTestController::Send),
base::Unretained(this),
@@ -531,8 +532,7 @@
printer_->AddMessageRaw(message);
}
-void WebKitTestController::OnOverridePreferences(
- const webkit_glue::WebPreferences& prefs) {
+void WebKitTestController::OnOverridePreferences(const WebPreferences& prefs) {
should_override_prefs_ = true;
prefs_ = prefs;
}
@@ -609,11 +609,12 @@
if (open_windows[i] != main_window_)
open_windows[i]->Close();
}
- MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
}
void WebKitTestController::OnResetDone() {
- MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ base::MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::QuitClosure());
}
} // namespace content
diff --git a/content/shell/webkit_test_controller.h b/content/shell/webkit_test_controller.h
index 8964f7f..f2e626e 100644
--- a/content/shell/webkit_test_controller.h
+++ b/content/shell/webkit_test_controller.h
@@ -92,8 +92,9 @@
void SetTempPath(const base::FilePath& temp_path);
void RendererUnresponsive();
- void OverrideWebkitPrefs(webkit_glue::WebPreferences* prefs);
+ void OverrideWebkitPrefs(WebPreferences* prefs);
void OpenURL(const GURL& url);
+ void TestFinishedInSecondaryWindow();
WebKitTestResultPrinter* printer() { return printer_.get(); }
void set_printer(WebKitTestResultPrinter* printer) {
@@ -128,7 +129,7 @@
void OnImageDump(const std::string& actual_pixel_hash, const SkBitmap& image);
void OnTextDump(const std::string& dump);
void OnPrintMessage(const std::string& message);
- void OnOverridePreferences(const webkit_glue::WebPreferences& prefs);
+ void OnOverridePreferences(const WebPreferences& prefs);
void OnTestFinished(bool did_timeout);
void OnShowDevTools();
void OnCloseDevTools();
@@ -168,7 +169,7 @@
// True if the WebPreferences of newly created RenderViewHost should be
// overridden with prefs_.
bool should_override_prefs_;
- webkit_glue::WebPreferences prefs_;
+ WebPreferences prefs_;
base::CancelableClosure watchdog_;
diff --git a/content/shell/webkit_test_helpers.cc b/content/shell/webkit_test_helpers.cc
index 0a40a22..1bddfcd 100644
--- a/content/shell/webkit_test_helpers.cc
+++ b/content/shell/webkit_test_helpers.cc
@@ -5,25 +5,25 @@
#include "content/shell/webkit_test_helpers.h"
#include "base/command_line.h"
+#include "base/file_util.h"
+#include "base/path_service.h"
#include "base/utf_string_conversions.h"
#include "content/shell/shell_switches.h"
#include "third_party/WebKit/Tools/DumpRenderTree/chromium/TestRunner/public/WebPreferences.h"
#include "webkit/glue/webpreferences.h"
-using WebTestRunner::WebPreferences;
-
namespace content {
-void ExportLayoutTestSpecificPreferences(const WebPreferences& from,
- webkit_glue::WebPreferences* to) {
+void ExportLayoutTestSpecificPreferences(
+ const WebTestRunner::WebPreferences& from,
+ WebPreferences* to) {
to->allow_universal_access_from_file_urls =
from.allowUniversalAccessFromFileURLs;
to->dom_paste_enabled = from.DOMPasteAllowed;
to->javascript_can_access_clipboard = from.javaScriptCanAccessClipboard;
to->xss_auditor_enabled = from.XSSAuditorEnabled;
- to->editing_behavior =
- static_cast<webkit_glue::WebPreferences::EditingBehavior>(
- from.editingBehavior);
+ to->editing_behavior = static_cast<webkit_glue::EditingBehavior>(
+ from.editingBehavior);
to->default_font_size = from.defaultFontSize;
to->minimum_font_size = from.minimumFontSize;
to->default_encoding = from.defaultTextEncodingName.utf8().data();
@@ -32,8 +32,6 @@
to->loads_images_automatically = from.loadsImagesAutomatically;
to->plugins_enabled = from.pluginsEnabled;
to->java_enabled = from.javaEnabled;
- to->uses_page_cache = from.usesPageCache;
- to->page_cache_supports_plugins = from.pageCacheSupportsPlugins;
to->application_cache_enabled = from.offlineWebApplicationCacheEnabled;
to->tabs_to_links = from.tabsToLinks;
to->experimental_webgl_enabled = from.experimentalWebGLEnabled;
@@ -58,16 +56,16 @@
// Applies settings that differ between layout tests and regular mode. Some
// of the defaults are controlled via command line flags which are
// automatically set for layout tests.
-void ApplyLayoutTestDefaultPreferences(webkit_glue::WebPreferences* prefs) {
+void ApplyLayoutTestDefaultPreferences(WebPreferences* prefs) {
CommandLine& command_line = *CommandLine::ForCurrentProcess();
prefs->allow_universal_access_from_file_urls = true;
prefs->dom_paste_enabled = true;
prefs->javascript_can_access_clipboard = true;
prefs->xss_auditor_enabled = false;
#if defined(OS_MACOSX)
- prefs->editing_behavior = webkit_glue::WebPreferences::EDITING_BEHAVIOR_MAC;
+ prefs->editing_behavior = webkit_glue::EDITING_BEHAVIOR_MAC;
#else
- prefs->editing_behavior = webkit_glue::WebPreferences::EDITING_BEHAVIOR_WIN;
+ prefs->editing_behavior = webkit_glue::EDITING_BEHAVIOR_WIN;
#endif
prefs->java_enabled = false;
prefs->application_cache_enabled = true;
@@ -78,26 +76,26 @@
prefs->webgl_errors_to_console_enabled = false;
string16 serif;
#if defined(OS_MACOSX)
- prefs->cursive_font_family_map[webkit_glue::WebPreferences::kCommonScript] =
+ prefs->cursive_font_family_map[webkit_glue::kCommonScript] =
ASCIIToUTF16("Apple Chancery");
- prefs->fantasy_font_family_map[webkit_glue::WebPreferences::kCommonScript] =
+ prefs->fantasy_font_family_map[webkit_glue::kCommonScript] =
ASCIIToUTF16("Papyrus");
serif = ASCIIToUTF16("Times");
#else
- prefs->cursive_font_family_map[webkit_glue::WebPreferences::kCommonScript] =
+ prefs->cursive_font_family_map[webkit_glue::kCommonScript] =
ASCIIToUTF16("Comic Sans MS");
- prefs->fantasy_font_family_map[webkit_glue::WebPreferences::kCommonScript] =
+ prefs->fantasy_font_family_map[webkit_glue::kCommonScript] =
ASCIIToUTF16("Impact");
serif = ASCIIToUTF16("times new roman");
#endif
- prefs->serif_font_family_map[webkit_glue::WebPreferences::kCommonScript] =
+ prefs->serif_font_family_map[webkit_glue::kCommonScript] =
serif;
- prefs->standard_font_family_map[webkit_glue::WebPreferences::kCommonScript] =
+ prefs->standard_font_family_map[webkit_glue::kCommonScript] =
serif;
- prefs->fixed_font_family_map[webkit_glue::WebPreferences::kCommonScript] =
+ prefs->fixed_font_family_map[webkit_glue::kCommonScript] =
ASCIIToUTF16("Courier");
prefs->sans_serif_font_family_map[
- webkit_glue::WebPreferences::kCommonScript] = ASCIIToUTF16("Helvetica");
+ webkit_glue::kCommonScript] = ASCIIToUTF16("Helvetica");
prefs->minimum_logical_font_size = 9;
prefs->asynchronous_spell_checking_enabled = false;
prefs->user_style_sheet_enabled = true;
@@ -112,4 +110,37 @@
prefs->minimum_accelerated_2d_canvas_size = 0;
}
+base::FilePath GetWebKitRootDirFilePath() {
+ base::FilePath base_path;
+ PathService::Get(base::DIR_SOURCE_ROOT, &base_path);
+ if (file_util::PathExists(
+ base_path.Append(FILE_PATH_LITERAL("third_party/WebKit")))) {
+ // We're in a WebKit-in-chrome checkout.
+ return base_path.Append(FILE_PATH_LITERAL("third_party/WebKit"));
+ } else if (file_util::PathExists(
+ base_path.Append(FILE_PATH_LITERAL("chromium")))) {
+ // We're in a WebKit-only checkout on Windows.
+ return base_path.Append(FILE_PATH_LITERAL("../.."));
+ } else if (file_util::PathExists(
+ base_path.Append(FILE_PATH_LITERAL("webkit/support")))) {
+ // We're in a WebKit-only/xcodebuild checkout on Mac
+ return base_path.Append(FILE_PATH_LITERAL("../../.."));
+ }
+ // We're in a WebKit-only, make-build, so the DIR_SOURCE_ROOT is already the
+ // WebKit root. That, or we have no idea where we are.
+ return base_path;
+}
+
+base::FilePath GetChromiumRootDirFilePath() {
+ base::FilePath webkit_path = GetWebKitRootDirFilePath();
+ if (file_util::PathExists(webkit_path.Append(
+ FILE_PATH_LITERAL("Source/WebKit/chromium/webkit/support")))) {
+ // We're in a WebKit-only checkout.
+ return webkit_path.Append(FILE_PATH_LITERAL("Source/WebKit/chromium"));
+ } else {
+ // We're in a Chromium checkout, and WebKit is in third_party/WebKit.
+ return webkit_path.Append(FILE_PATH_LITERAL("../.."));
+ }
+}
+
} // namespace content
diff --git a/content/shell/webkit_test_helpers.h b/content/shell/webkit_test_helpers.h
index 4cb9626..08ccec8 100644
--- a/content/shell/webkit_test_helpers.h
+++ b/content/shell/webkit_test_helpers.h
@@ -5,25 +5,35 @@
#ifndef CONTENT_SHELL_WEBKIT_TEST_HELPERS_H_
#define CONTENT_SHELL_WEBKIT_TEST_HELPERS_H_
+struct WebPreferences;
+
namespace WebTestRunner {
struct WebPreferences;
}
-namespace webkit_glue {
-struct WebPreferences;
+namespace base {
+class FilePath;
}
+struct WebPreferences;
+
namespace content {
// The TestRunner library keeps its settings in a WebTestRunner::WebPreferenes
-// object. The content_shell, however, uses webkit_glue::WebPreferences. This
+// object. The content_shell, however, uses WebPreferences. This
// method exports the settings from the WebTestRunner library which are relevant
// for layout tests.
void ExportLayoutTestSpecificPreferences(
- const WebTestRunner::WebPreferences& from, webkit_glue::WebPreferences* to);
+ const WebTestRunner::WebPreferences& from, WebPreferences* to);
// Applies settings that differ between layout tests and regular mode.
-void ApplyLayoutTestDefaultPreferences(webkit_glue::WebPreferences* prefs);
+void ApplyLayoutTestDefaultPreferences(WebPreferences* prefs);
+
+// Returns the root of the Blink checkout.
+base::FilePath GetWebKitRootDirFilePath();
+
+// Returns the root of the chromium checkout.
+base::FilePath GetChromiumRootDirFilePath();
} // namespace content
diff --git a/content/surface_texture_jni_headers.target.linux-arm.mk b/content/surface_texture_jni_headers.target.linux-arm.mk
deleted file mode 100644
index d650167..0000000
--- a/content/surface_texture_jni_headers.target.linux-arm.mk
+++ /dev/null
@@ -1,140 +0,0 @@
-# This file is generated by gyp; do not edit.
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_CLASS := GYP
-LOCAL_MODULE := content_surface_texture_jni_headers_gyp
-LOCAL_MODULE_STEM := surface_texture_jni_headers
-LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
-gyp_intermediate_dir := $(call local-intermediates-dir)
-gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
-
-# Make sure our deps are built first.
-GYP_TARGET_DEPENDENCIES :=
-
-### Rules for action "generate_jni_headers_from_jar_file":
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTexture_jni.h: gyp_local_path := $(LOCAL_PATH)
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTexture_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTexture_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTexture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTexture_jni.h: $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar $(GYP_TARGET_DEPENDENCIES)
- @echo "Gyp action: Generating JNI bindings from $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar/android/graphics/SurfaceTexture.class ($@)"
- $(hide)cd $(gyp_local_path)/content; mkdir -p $(gyp_shared_intermediate_dir)/content/jni; ../base/android/jni_generator/jni_generator.py -j "$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar" --input_file android/graphics/SurfaceTexture.class --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
-
-
-
-GYP_GENERATED_OUTPUTS := \
- $(gyp_shared_intermediate_dir)/content/jni/SurfaceTexture_jni.h
-
-# Make sure our deps and generated files are built first.
-LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
-
-LOCAL_GENERATED_SOURCES := \
- $(gyp_shared_intermediate_dir)/content/jni/SurfaceTexture_jni.h
-
-GYP_COPIED_SOURCE_ORIGIN_DIRS :=
-
-LOCAL_SRC_FILES :=
-
-
-# Flags passed to both C and C++ files.
-MY_CFLAGS := \
- -fstack-protector \
- --param=ssp-buffer-size=4 \
- -Werror \
- -fno-exceptions \
- -fno-strict-aliasing \
- -Wall \
- -Wno-unused-parameter \
- -Wno-missing-field-initializers \
- -fvisibility=hidden \
- -pipe \
- -fPIC \
- -fno-tree-sra \
- -fuse-ld=gold \
- -Wno-psabi \
- -ffunction-sections \
- -funwind-tables \
- -g \
- -fstack-protector \
- -fno-short-enums \
- -finline-limit=64 \
- -Wa,--noexecstack \
- -U_FORTIFY_SOURCE \
- -Wno-extra \
- -Wno-ignored-qualifiers \
- -Wno-type-limits \
- -Os \
- -g \
- -fomit-frame-pointer \
- -fdata-sections \
- -ffunction-sections
-
-MY_CFLAGS_C :=
-
-MY_DEFS := \
- '-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
- '-D_FILE_OFFSET_BITS=64' \
- '-DUSE_LINUX_BREAKPAD' \
- '-DNO_TCMALLOC' \
- '-DDISABLE_NACL' \
- '-DCHROMIUM_BUILD' \
- '-DUSE_LIBJPEG_TURBO=1' \
- '-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
- '-DENABLE_GPU=1' \
- '-DUSE_OPENSSL=1' \
- '-DENABLE_EGLIMAGE=1' \
- '-DENABLE_LANGUAGE_DETECTION=1' \
- '-D__STDC_CONSTANT_MACROS' \
- '-D__STDC_FORMAT_MACROS' \
- '-DANDROID' \
- '-D__GNU_SOURCE=1' \
- '-DUSE_STLPORT=1' \
- '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
- '-DCHROME_BUILD_ID=""' \
- '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
- '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
- '-D_DEBUG'
-
-LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
-
-# Include paths placed before CFLAGS/CPPFLAGS
-LOCAL_C_INCLUDES := \
- $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
- $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
- $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
-
-LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
-
-# Flags passed to only C++ (and not C) files.
-LOCAL_CPPFLAGS := \
- -fno-rtti \
- -fno-threadsafe-statics \
- -fvisibility-inlines-hidden \
- -Wsign-compare \
- -Wno-abi \
- -Wno-error=c++0x-compat \
- -Wno-non-virtual-dtor \
- -Wno-sign-promo
-
-### Rules for final target.
-# Add target alias to "gyp_all_modules" target.
-.PHONY: gyp_all_modules
-gyp_all_modules: content_surface_texture_jni_headers_gyp
-
-# Alias gyp target name.
-.PHONY: surface_texture_jni_headers
-surface_texture_jni_headers: content_surface_texture_jni_headers_gyp
-
-LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
-LOCAL_UNINSTALLABLE_MODULE := true
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
- $(hide) echo "Gyp timestamp: $@"
- $(hide) mkdir -p $(dir $@)
- $(hide) touch $@
diff --git a/content/surface_texture_jni_headers.target.linux-x86.mk b/content/surface_texture_jni_headers.target.linux-x86.mk
deleted file mode 100644
index d4b7c87..0000000
--- a/content/surface_texture_jni_headers.target.linux-x86.mk
+++ /dev/null
@@ -1,140 +0,0 @@
-# This file is generated by gyp; do not edit.
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_CLASS := GYP
-LOCAL_MODULE := content_surface_texture_jni_headers_gyp
-LOCAL_MODULE_STEM := surface_texture_jni_headers
-LOCAL_MODULE_SUFFIX := .stamp
-LOCAL_MODULE_TAGS := optional
-gyp_intermediate_dir := $(call local-intermediates-dir)
-gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
-
-# Make sure our deps are built first.
-GYP_TARGET_DEPENDENCIES :=
-
-### Rules for action "generate_jni_headers_from_jar_file":
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTexture_jni.h: gyp_local_path := $(LOCAL_PATH)
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTexture_jni.h: gyp_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTexture_jni.h: gyp_shared_intermediate_dir := $(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTexture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/content/jni/SurfaceTexture_jni.h: $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar $(GYP_TARGET_DEPENDENCIES)
- @echo "Gyp action: Generating JNI bindings from $(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar/android/graphics/SurfaceTexture.class ($@)"
- $(hide)cd $(gyp_local_path)/content; mkdir -p $(gyp_shared_intermediate_dir)/content/jni; ../base/android/jni_generator/jni_generator.py -j "$(GYP_ABS_ANDROID_TOP_DIR)/prebuilts/sdk/17/android.jar" --input_file android/graphics/SurfaceTexture.class --output_dir "$(gyp_shared_intermediate_dir)/content/jni" --optimize_generation 0
-
-
-
-GYP_GENERATED_OUTPUTS := \
- $(gyp_shared_intermediate_dir)/content/jni/SurfaceTexture_jni.h
-
-# Make sure our deps and generated files are built first.
-LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
-
-LOCAL_GENERATED_SOURCES := \
- $(gyp_shared_intermediate_dir)/content/jni/SurfaceTexture_jni.h
-
-GYP_COPIED_SOURCE_ORIGIN_DIRS :=
-
-LOCAL_SRC_FILES :=
-
-
-# Flags passed to both C and C++ files.
-MY_CFLAGS := \
- --param=ssp-buffer-size=4 \
- -Werror \
- -fno-exceptions \
- -fno-strict-aliasing \
- -Wall \
- -Wno-unused-parameter \
- -Wno-missing-field-initializers \
- -fvisibility=hidden \
- -pipe \
- -fPIC \
- -m32 \
- -mmmx \
- -march=pentium4 \
- -msse2 \
- -mfpmath=sse \
- -ffunction-sections \
- -funwind-tables \
- -g \
- -fno-short-enums \
- -finline-limit=64 \
- -Wa,--noexecstack \
- -U_FORTIFY_SOURCE \
- -Wno-extra \
- -Wno-ignored-qualifiers \
- -Wno-type-limits \
- -fno-stack-protector \
- -Os \
- -g \
- -fomit-frame-pointer \
- -fdata-sections \
- -ffunction-sections
-
-MY_CFLAGS_C :=
-
-MY_DEFS := \
- '-DCONTENT_IMPLEMENTATION' \
- '-DUSE_SKIA' \
- '-D_FILE_OFFSET_BITS=64' \
- '-DUSE_LINUX_BREAKPAD' \
- '-DNO_TCMALLOC' \
- '-DDISABLE_NACL' \
- '-DCHROMIUM_BUILD' \
- '-DUSE_LIBJPEG_TURBO=1' \
- '-DUSE_PROPRIETARY_CODECS' \
- '-DENABLE_PEPPER_THREADING' \
- '-DENABLE_GPU=1' \
- '-DUSE_OPENSSL=1' \
- '-DENABLE_EGLIMAGE=1' \
- '-DENABLE_LANGUAGE_DETECTION=1' \
- '-D__STDC_CONSTANT_MACROS' \
- '-D__STDC_FORMAT_MACROS' \
- '-DANDROID' \
- '-D__GNU_SOURCE=1' \
- '-DUSE_STLPORT=1' \
- '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
- '-DCHROME_BUILD_ID=""' \
- '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
- '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
- '-D_DEBUG'
-
-LOCAL_CFLAGS := $(MY_CFLAGS_C) $(MY_CFLAGS) $(MY_DEFS)
-
-# Include paths placed before CFLAGS/CPPFLAGS
-LOCAL_C_INCLUDES := \
- $(GYP_ABS_ANDROID_TOP_DIR)/frameworks/wilhelm/include \
- $(GYP_ABS_ANDROID_TOP_DIR)/bionic \
- $(GYP_ABS_ANDROID_TOP_DIR)/external/stlport/stlport
-
-LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES)
-
-# Flags passed to only C++ (and not C) files.
-LOCAL_CPPFLAGS := \
- -fno-rtti \
- -fno-threadsafe-statics \
- -fvisibility-inlines-hidden \
- -Wsign-compare \
- -Wno-error=c++0x-compat \
- -Wno-non-virtual-dtor \
- -Wno-sign-promo
-
-### Rules for final target.
-# Add target alias to "gyp_all_modules" target.
-.PHONY: gyp_all_modules
-gyp_all_modules: content_surface_texture_jni_headers_gyp
-
-# Alias gyp target name.
-.PHONY: surface_texture_jni_headers
-surface_texture_jni_headers: content_surface_texture_jni_headers_gyp
-
-LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
-LOCAL_UNINSTALLABLE_MODULE := true
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
- $(hide) echo "Gyp timestamp: $@"
- $(hide) mkdir -p $(dir $@)
- $(hide) touch $@
diff --git a/content/test/browser_test_message_pump_android.cc b/content/test/browser_test_message_pump_android.cc
index b20b491..f992110 100644
--- a/content/test/browser_test_message_pump_android.cc
+++ b/content/test/browser_test_message_pump_android.cc
@@ -56,7 +56,6 @@
RunState state(delegate, state_ ? state_->run_depth + 1 : 1);
RunState* previous_state = state_;
state_ = &state;
- DCHECK(state_->run_depth <= 1) << "Only one level nested loops supported";
JNIEnv* env = base::android::AttachCurrentThread();
DCHECK(env);
diff --git a/content/test/content_browser_test.cc b/content/test/content_browser_test.cc
index aa91303..bcaa587 100644
--- a/content/test/content_browser_test.cc
+++ b/content/test/content_browser_test.cc
@@ -12,10 +12,10 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
+#include "content/shell/renderer/shell_content_renderer_client.h"
#include "content/shell/shell.h"
#include "content/shell/shell_browser_context.h"
#include "content/shell/shell_content_browser_client.h"
-#include "content/shell/shell_content_renderer_client.h"
#include "content/shell/shell_main_delegate.h"
#include "content/shell/shell_switches.h"
#include "content/test/test_content_client.h"
@@ -60,8 +60,7 @@
// and set up renderer.
if (command_line->HasSwitch(switches::kSingleProcess)) {
single_process_renderer_client_.reset(new ShellContentRendererClient);
- GetContentClient()->set_renderer_for_testing(
- single_process_renderer_client_.get());
+ SetRendererClientForTesting(single_process_renderer_client_.get());
}
#if defined(OS_MACOSX)
@@ -109,7 +108,7 @@
#endif
// Pump startup related events.
- MessageLoopForUI::current()->RunUntilIdle();
+ base::MessageLoopForUI::current()->RunUntilIdle();
#if defined(OS_MACOSX)
pool.Recycle();
@@ -131,10 +130,8 @@
}
Shell* ContentBrowserTest::CreateBrowser() {
- ShellContentBrowserClient* browser_client =
- static_cast<ShellContentBrowserClient*>(GetContentClient()->browser());
return Shell::CreateNewWindow(
- browser_client->browser_context(),
+ ShellContentBrowserClient::Get()->browser_context(),
GURL(chrome::kAboutBlankURL),
NULL,
MSG_ROUTING_NONE,
@@ -142,10 +139,8 @@
}
Shell* ContentBrowserTest::CreateOffTheRecordBrowser() {
- ShellContentBrowserClient* browser_client =
- static_cast<ShellContentBrowserClient*>(GetContentClient()->browser());
return Shell::CreateNewWindow(
- browser_client->off_the_record_browser_context(),
+ ShellContentBrowserClient::Get()->off_the_record_browser_context(),
GURL(chrome::kAboutBlankURL),
NULL,
MSG_ROUTING_NONE,
diff --git a/content/test/content_test_launcher.cc b/content/test/content_test_launcher.cc
index aa1f362..ae26552 100644
--- a/content/test/content_test_launcher.cc
+++ b/content/test/content_test_launcher.cc
@@ -36,15 +36,13 @@
}
virtual void OnTestStart(const testing::TestInfo& test_info) OVERRIDE {
- DCHECK(!GetContentClient());
content_client_.reset(new ShellContentClient);
browser_content_client_.reset(new ShellContentBrowserClient());
- content_client_->set_browser_for_testing(browser_content_client_.get());
SetContentClient(content_client_.get());
+ SetBrowserClientForTesting(browser_content_client_.get());
}
virtual void OnTestEnd(const testing::TestInfo& test_info) OVERRIDE {
- DCHECK_EQ(content_client_.get(), GetContentClient());
browser_content_client_.reset();
content_client_.reset();
SetContentClient(NULL);
@@ -77,7 +75,8 @@
#if defined(OS_ANDROID)
// This needs to be done before base::TestSuite::Initialize() is called,
// as it also tries to set MessagePumpForUIFactory.
- if (!MessageLoop::InitMessagePumpForUIFactory(&CreateMessagePumpForUI))
+ if (!base::MessageLoop::InitMessagePumpForUIFactory(
+ &CreateMessagePumpForUI))
LOG(INFO) << "MessagePumpForUIFactory already set, unable to override.";
#endif
diff --git a/content/test/data/accessibility/a-expected-mac.txt b/content/test/data/accessibility/a-expected-mac.txt
index 27da7da..2a7792a 100644
--- a/content/test/data/accessibility/a-expected-mac.txt
+++ b/content/test/data/accessibility/a-expected-mac.txt
@@ -1,4 +1,4 @@
AXWebArea
AXGroup
- AXLink title='normal link'
- AXStaticText value='normal link'
+ AXLink AXTitle='normal link'
+ AXStaticText AXValue='normal link'
diff --git a/content/test/data/accessibility/a-with-img-expected-mac.txt b/content/test/data/accessibility/a-with-img-expected-mac.txt
index b4261da..37db67f 100644
--- a/content/test/data/accessibility/a-with-img-expected-mac.txt
+++ b/content/test/data/accessibility/a-with-img-expected-mac.txt
@@ -1,16 +1,16 @@
AXWebArea
AXGroup
- AXLink title='Link with image at start.'
- AXImage description='Link'
- AXStaticText value=' with image at start.'
- AXLink title='Link with image in the middle.'
- AXStaticText value='Link with '
- AXImage description='image'
- AXStaticText value=' in the middle.'
- AXLink title='Link with broken in the middle.'
- AXStaticText value='Link with '
- AXImage description='broken'
- AXStaticText value=' in the middle.'
- AXLink title='Link with image at the end'
- AXStaticText value='Link with image at the '
- AXImage description='end'
+ AXLink AXTitle='Link with image at start.'
+ AXImage AXDescription='Link'
+ AXStaticText AXValue=' with image at start.'
+ AXLink AXTitle='Link with image in the middle.'
+ AXStaticText AXValue='Link with '
+ AXImage AXDescription='image'
+ AXStaticText AXValue=' in the middle.'
+ AXLink AXTitle='Link with broken in the middle.'
+ AXStaticText AXValue='Link with '
+ AXImage AXDescription='broken'
+ AXStaticText AXValue=' in the middle.'
+ AXLink AXTitle='Link with image at the end'
+ AXStaticText AXValue='Link with image at the '
+ AXImage AXDescription='end'
diff --git a/content/test/data/accessibility/a-with-img.html b/content/test/data/accessibility/a-with-img.html
index f090da8..daeede6 100644
--- a/content/test/data/accessibility/a-with-img.html
+++ b/content/test/data/accessibility/a-with-img.html
@@ -1,5 +1,5 @@
<!--
-@MAC-ALLOW:description*
+@MAC-ALLOW:AXDescription*
-->
<html>
<body>
diff --git a/content/test/data/accessibility/address-expected-mac.txt b/content/test/data/accessibility/address-expected-mac.txt
index 23b45b2..3a129b2 100644
--- a/content/test/data/accessibility/address-expected-mac.txt
+++ b/content/test/data/accessibility/address-expected-mac.txt
@@ -1,4 +1,4 @@
#<skip -- wrong roleDescription (bug)>
-AXWebArea subrole=(null) roleDescription='HTML content'
- AXGroup subrole=AXLandmarkContentInfo roleDescription='address'
- AXStaticText subrole=(null) roleDescription='text' value='Please contact John Citizen for more information.'
+AXWebArea AXRoleDescription='HTML content'
+ AXGroup AXSubrole=AXLandmarkContentInfo AXRoleDescription='group'
+ AXStaticText AXRoleDescription='text' AXValue='Please contact John Citizen for more information.'
diff --git a/content/test/data/accessibility/address.html b/content/test/data/accessibility/address.html
index 2082cd9..a78bf41 100644
--- a/content/test/data/accessibility/address.html
+++ b/content/test/data/accessibility/address.html
@@ -1,6 +1,6 @@
<!--
-@MAC-ALLOW:subrole=*
-@MAC-ALLOW:roleDescription=*
+@MAC-ALLOW:AXSubrole=*
+@MAC-ALLOW:AXRoleDescription=*
@WIN-ALLOW:role:*
@WIN-ALLOW:xml-role*
-->
diff --git a/content/test/data/accessibility/aria-application-expected-mac.txt b/content/test/data/accessibility/aria-application-expected-mac.txt
index f8e11fb..febaff7 100644
--- a/content/test/data/accessibility/aria-application-expected-mac.txt
+++ b/content/test/data/accessibility/aria-application-expected-mac.txt
@@ -1,2 +1,2 @@
AXWebArea
- AXGroup subrole=AXLandmarkApplication roleDescription='application'
+ AXGroup AXSubrole=AXLandmarkApplication AXRoleDescription='application'
diff --git a/content/test/data/accessibility/aria-application.html b/content/test/data/accessibility/aria-application.html
index 6c59998..445ab95 100644
--- a/content/test/data/accessibility/aria-application.html
+++ b/content/test/data/accessibility/aria-application.html
@@ -1,6 +1,6 @@
<!--
-@MAC-ALLOW:roleDescription='application'
-@MAC-ALLOW:subrole*
+@MAC-ALLOW:AXRoleDescription='application'
+@MAC-ALLOW:AXSubrole*
-->
<html>
<body role="application" id="testAriaApplication">
diff --git a/content/test/data/accessibility/aria-combobox-expected-mac.txt b/content/test/data/accessibility/aria-combobox-expected-mac.txt
index 6f2ef42..6fc5996 100644
--- a/content/test/data/accessibility/aria-combobox-expected-mac.txt
+++ b/content/test/data/accessibility/aria-combobox-expected-mac.txt
@@ -1,7 +1,7 @@
AXWebArea
AXGroup
- AXStaticText value='State'
+ AXStaticText AXValue='State'
AXComboBox
AXList
- AXStaticText title='Alabama'
- AXStaticText title='Alaska'
+ AXStaticText AXTitle='Alabama'
+ AXStaticText AXTitle='Alaska'
diff --git a/content/test/data/accessibility/aria-invalid-expected-mac.txt b/content/test/data/accessibility/aria-invalid-expected-mac.txt
index 5b3db34..daa90ed 100644
--- a/content/test/data/accessibility/aria-invalid-expected-mac.txt
+++ b/content/test/data/accessibility/aria-invalid-expected-mac.txt
@@ -1,13 +1,13 @@
AXWebArea
- AXGroup invalid='true'
- AXStaticText value='invalid=true'
- AXGroup invalid='spelling'
- AXStaticText value='invalid=spelling'
- AXGroup invalid='grammar'
- AXStaticText value='invalid=grammar'
- AXGroup invalid='false'
- AXStaticText value='invalid=false'
- AXGroup invalid='false'
- AXStaticText value='invalid=<empty>'
- AXGroup invalid='somethingelse'
- AXStaticText value='invalid=somethingelse'
+ AXGroup AXInvalid='true'
+ AXStaticText AXValue='invalid=true'
+ AXGroup AXInvalid='spelling'
+ AXStaticText AXValue='invalid=spelling'
+ AXGroup AXInvalid='grammar'
+ AXStaticText AXValue='invalid=grammar'
+ AXGroup AXInvalid='false'
+ AXStaticText AXValue='invalid=false'
+ AXGroup AXInvalid='false'
+ AXStaticText AXValue='invalid=<empty>'
+ AXGroup AXInvalid='somethingelse'
+ AXStaticText AXValue='invalid=somethingelse'
diff --git a/content/test/data/accessibility/aria-invalid.html b/content/test/data/accessibility/aria-invalid.html
index 80d86cc..fcacee2 100644
--- a/content/test/data/accessibility/aria-invalid.html
+++ b/content/test/data/accessibility/aria-invalid.html
@@ -1,5 +1,5 @@
<!--
-@MAC-ALLOW:invalid=*
+@MAC-ALLOW:AXInvalid=*
@WIN-ALLOW:checkable:*
@WIN-DENY:name=''
-->
diff --git a/content/test/data/accessibility/aria-level-expected-mac.txt b/content/test/data/accessibility/aria-level-expected-mac.txt
index 2879b99..43fccc3 100644
--- a/content/test/data/accessibility/aria-level-expected-mac.txt
+++ b/content/test/data/accessibility/aria-level-expected-mac.txt
@@ -1,21 +1,21 @@
AXWebArea
- AXHeading title='H3' value='3'
- AXStaticText value='H3'
- AXHeading title='ARIA heading level 3' value='3'
- AXStaticText value='ARIA heading level 3'
+ AXHeading AXTitle='H3' AXValue='3'
+ AXStaticText AXValue='H3'
+ AXHeading AXTitle='ARIA heading level 3' AXValue='3'
+ AXStaticText AXValue='ARIA heading level 3'
AXOutline
- AXRow subrole=AXOutlineRow disclosing='1' disclosureLevel='0'
- AXStaticText value='Tree item at level 1'
- AXRow subrole=AXOutlineRow disclosing='0' disclosureLevel='1'
- AXStaticText value='Tree item at level 2'
- AXRow subrole=AXOutlineRow disclosing='0' disclosureLevel='2'
- AXStaticText value='Tree item at level 3'
+ AXRow AXSubrole=AXOutlineRow AXDisclosing='1' AXDisclosureLevel='0'
+ AXStaticText AXValue='Tree item at level 1'
+ AXRow AXSubrole=AXOutlineRow AXDisclosing='0' AXDisclosureLevel='1'
+ AXStaticText AXValue='Tree item at level 2'
+ AXRow AXSubrole=AXOutlineRow AXDisclosing='0' AXDisclosureLevel='2'
+ AXStaticText AXValue='Tree item at level 3'
AXTable
- AXRow disclosureLevel='0'
+ AXRow AXDisclosureLevel='0'
AXCell
- AXStaticText value='Cell at level 1'
- AXRow disclosureLevel='1'
+ AXStaticText AXValue='Cell at level 1'
+ AXRow AXDisclosureLevel='1'
AXCell
- AXStaticText value='Cell at level 2'
+ AXStaticText AXValue='Cell at level 2'
AXColumn
AXGroup
diff --git a/content/test/data/accessibility/aria-level.html b/content/test/data/accessibility/aria-level.html
index 56240ff..94df22d 100644
--- a/content/test/data/accessibility/aria-level.html
+++ b/content/test/data/accessibility/aria-level.html
@@ -1,8 +1,8 @@
<!doctype html>
<!--
-@MAC-ALLOW:subrole=AXOutlineRow
-@MAC-ALLOW:disclosing*
-@MAC-ALLOW:disclosureLevel*
+@MAC-ALLOW:AXSubrole=AXOutlineRow
+@MAC-ALLOW:AXDisclosing*
+@MAC-ALLOW:AXDisclosureLevel*
@WIN-ALLOW:level:1
@WIN-ALLOW:level:2
@WIN-ALLOW:level:3
diff --git a/content/test/data/accessibility/aria-menu-expected-mac.txt b/content/test/data/accessibility/aria-menu-expected-mac.txt
index 021e959..570809e 100644
--- a/content/test/data/accessibility/aria-menu-expected-mac.txt
+++ b/content/test/data/accessibility/aria-menu-expected-mac.txt
@@ -1,10 +1,10 @@
AXWebArea
AXMenuBar
- AXMenuItem title='File'
- AXMenuItem title='Edit'
- AXMenuItem title='View'
- AXMenu description='File'
- AXMenuItem title='New'
- AXMenuItem title='Open'
- AXMenuItem title='Save'
- AXMenuItem title='Quit'
+ AXMenuItem AXTitle='File'
+ AXMenuItem AXTitle='Edit'
+ AXMenuItem AXTitle='View'
+ AXMenu AXDescription='File'
+ AXMenuItem AXTitle='New'
+ AXMenuItem AXTitle='Open'
+ AXMenuItem AXTitle='Save'
+ AXMenuItem AXTitle='Quit'
diff --git a/content/test/data/accessibility/aria-menu.html b/content/test/data/accessibility/aria-menu.html
index c729d82..1fd7ebb 100644
--- a/content/test/data/accessibility/aria-menu.html
+++ b/content/test/data/accessibility/aria-menu.html
@@ -1,6 +1,6 @@
<!--
-@MAC-ALLOW:description='File'
-@MAC-DENY:value*
+@MAC-ALLOW:AXDescription='File'
+@MAC-DENY:AXValue*
@WIN-DENY:description=''
-->
<html>
diff --git a/content/test/data/accessibility/aria-menuitemradio-expected-mac.txt b/content/test/data/accessibility/aria-menuitemradio-expected-mac.txt
index b475e71..1f4295c 100644
--- a/content/test/data/accessibility/aria-menuitemradio-expected-mac.txt
+++ b/content/test/data/accessibility/aria-menuitemradio-expected-mac.txt
@@ -1,9 +1,9 @@
#<skip - role should be AXMenuItem. http://crbug.com/169578
- role description should be 'menu item'. http://crbug.com/169580
- AXMenuItemMarkChar should be \236. http://crbug.com/169582>
-AXWebArea roleDescription='HTML content'
- AXMenu roleDescription='menu'
- AXMenuItem roleDescription='menu item' AXMenuItemMarkChar='\236'
- AXStaticText roleDescription='text' value='Menu item 1'
- AXMenuItem roleDescription='menu item' AXMenuItemMarkChar='(null)'
- AXStaticText roleDescription='text' value='Menu item 2'
+AXWebArea AXRoleDescription='HTML content'
+ AXMenu AXRoleDescription='menu'
+ AXGroup AXRoleDescription='aria-menuitemradio'
+ AXStaticText AXRoleDescription='text' AXValue='Menu item 1'
+ AXGroup AXRoleDescription='aria-menuitemradio'
+ AXStaticText AXRoleDescription='text' AXValue='Menu item 2'
diff --git a/content/test/data/accessibility/aria-menuitemradio.html b/content/test/data/accessibility/aria-menuitemradio.html
index d5292ff..4e096c1 100644
--- a/content/test/data/accessibility/aria-menuitemradio.html
+++ b/content/test/data/accessibility/aria-menuitemradio.html
@@ -1,5 +1,5 @@
<!--
-@MAC-ALLOW:roleDescription=*
+@MAC-ALLOW:AXRoleDescription=*
@WIN-ALLOW:checkable:*
@WIN-DENY:name=''
-->
diff --git a/content/test/data/accessibility/aria-pressed-expected-mac.txt b/content/test/data/accessibility/aria-pressed-expected-mac.txt
index 6ca8346..c5ab71d 100644
--- a/content/test/data/accessibility/aria-pressed-expected-mac.txt
+++ b/content/test/data/accessibility/aria-pressed-expected-mac.txt
@@ -1,5 +1,5 @@
AXWebArea
- AXButton title='Regular button'
- AXButton title='Toggle button unpressed'
- AXButton title='Toggle button pressed'
- AXButton title='Toggle button mixed'
+ AXButton AXTitle='Regular button'
+ AXButton AXTitle='Toggle button unpressed'
+ AXButton AXTitle='Toggle button pressed'
+ AXButton AXTitle='Toggle button mixed'
diff --git a/content/test/data/accessibility/aria-progressbar-expected-mac.txt b/content/test/data/accessibility/aria-progressbar-expected-mac.txt
index 7e7da6e..a3329cb 100644
--- a/content/test/data/accessibility/aria-progressbar-expected-mac.txt
+++ b/content/test/data/accessibility/aria-progressbar-expected-mac.txt
@@ -1,3 +1,3 @@
-AXWebArea roleDescription='HTML content'
- AXProgressIndicator roleDescription='progress indicator' value='3' minValue='1' maxValue='37'
- AXProgressIndicator roleDescription='progress indicator' value='0' minValue='1' maxValue='96' valueDescription='three'
+AXWebArea AXRoleDescription='HTML content'
+ AXProgressIndicator AXRoleDescription='progress indicator' AXValue='3' AXMinValue='1' AXMaxValue='37'
+ AXProgressIndicator AXRoleDescription='progress indicator' AXValue='0' AXMinValue='1' AXMaxValue='96' AXValueDescription='three'
diff --git a/content/test/data/accessibility/aria-progressbar.html b/content/test/data/accessibility/aria-progressbar.html
index 3f888ee..3c3f350 100644
--- a/content/test/data/accessibility/aria-progressbar.html
+++ b/content/test/data/accessibility/aria-progressbar.html
@@ -1,8 +1,8 @@
<!--
-@MAC-ALLOW:roleDescription=*
-@MAC-ALLOW:valueDescription=*
-@MAC-ALLOW:minValue=*
-@MAC-ALLOW:maxValue=*
+@MAC-ALLOW:AXRoleDescription=*
+@MAC-ALLOW:AXValueDescription=*
+@MAC-ALLOW:AXMinValue=*
+@MAC-ALLOW:AXMaxValue=*
@WIN-ALLOW:READONLY
@WIN-ALLOW:STATE_SYSTEM_READONLY
@WIN-ALLOW:valuetext:*
diff --git a/content/test/data/accessibility/aria-valuemax-expected-mac.txt b/content/test/data/accessibility/aria-valuemax-expected-mac.txt
index ce04ee5..2914a44 100644
--- a/content/test/data/accessibility/aria-valuemax-expected-mac.txt
+++ b/content/test/data/accessibility/aria-valuemax-expected-mac.txt
@@ -1,5 +1,5 @@
AXWebArea
- AXProgressIndicator value='51' maxValue='101'
- AXScrollBar value='52' maxValue='102'
- AXSlider value='53' maxValue='103'
- AXSlider value='54' maxValue='104'
+ AXProgressIndicator AXValue='51' AXMaxValue='101'
+ AXScrollBar AXValue='52' AXMaxValue='102'
+ AXSlider AXValue='53' AXMaxValue='103'
+ AXSlider AXValue='54' AXMaxValue='104'
diff --git a/content/test/data/accessibility/aria-valuemax.html b/content/test/data/accessibility/aria-valuemax.html
index d894018..d4c23d9 100644
--- a/content/test/data/accessibility/aria-valuemax.html
+++ b/content/test/data/accessibility/aria-valuemax.html
@@ -1,7 +1,7 @@
<!doctype html>
<!--
-@MAC-ALLOW:maxValue=*
-@MAC-DENY:title*
+@MAC-ALLOW:AXMaxValue=*
+@MAC-DENY:AXTitle*
@WIN-ALLOW:maximumValue=*
@WIN-DENY:description=''
-->
diff --git a/content/test/data/accessibility/aria-valuemin-expected-mac.txt b/content/test/data/accessibility/aria-valuemin-expected-mac.txt
index 74824b1..a348f78 100644
--- a/content/test/data/accessibility/aria-valuemin-expected-mac.txt
+++ b/content/test/data/accessibility/aria-valuemin-expected-mac.txt
@@ -1,5 +1,5 @@
AXWebArea
- AXProgressIndicator minValue='1'
- AXScrollBar minValue='2'
- AXSlider minValue='3'
- AXSlider minValue='4'
+ AXProgressIndicator AXMinValue='1'
+ AXScrollBar AXMinValue='2'
+ AXSlider AXMinValue='3'
+ AXSlider AXMinValue='4'
diff --git a/content/test/data/accessibility/aria-valuemin.html b/content/test/data/accessibility/aria-valuemin.html
index d4df6e1..0352c01 100644
--- a/content/test/data/accessibility/aria-valuemin.html
+++ b/content/test/data/accessibility/aria-valuemin.html
@@ -1,8 +1,8 @@
<!doctype html>
<!--
-@MAC-ALLOW:minValue=*
-@MAC-DENY:title*
-@MAC-DENY:value*
+@MAC-ALLOW:AXMinValue=*
+@MAC-DENY:AXTitle*
+@MAC-DENY:AXValue*
@WIN-ALLOW:minimumValue=*
@WIN-DENY:description=''
-->
diff --git a/content/test/data/accessibility/article-expected-mac.txt b/content/test/data/accessibility/article-expected-mac.txt
index 2d07907..8f0006d 100644
--- a/content/test/data/accessibility/article-expected-mac.txt
+++ b/content/test/data/accessibility/article-expected-mac.txt
@@ -1,3 +1,3 @@
AXWebArea
- AXGroup subrole=AXDocumentArticle
- AXStaticText value='This is an article.'
+ AXGroup AXSubrole=AXDocumentArticle
+ AXStaticText AXValue='This is an article.'
diff --git a/content/test/data/accessibility/article.html b/content/test/data/accessibility/article.html
index 49f7b08..6abc7b6 100644
--- a/content/test/data/accessibility/article.html
+++ b/content/test/data/accessibility/article.html
@@ -1,6 +1,6 @@
<!--
-@MAC-ALLOW:subrole=AXDocumentArticle
-@MAC-DENY:title*
+@MAC-ALLOW:AXSubrole=AXDocumentArticle
+@MAC-DENY:AXTitle*
@WIN-ALLOW:xml-roles:article
-->
<!doctype html>
diff --git a/content/test/data/accessibility/bdo-expected-mac.txt b/content/test/data/accessibility/bdo-expected-mac.txt
index d5c29c8..2473176 100644
--- a/content/test/data/accessibility/bdo-expected-mac.txt
+++ b/content/test/data/accessibility/bdo-expected-mac.txt
@@ -2,6 +2,6 @@
# wrong, so we assume this is correct.
AXWebArea
AXGroup
- AXStaticText value='Some LTR text'
- AXStaticText value='Some RTL text '
- AXStaticText value='with some LTR text embedded'
+ AXStaticText AXValue='Some LTR text'
+ AXStaticText AXValue='Some RTL text '
+ AXStaticText AXValue='with some LTR text embedded'
diff --git a/content/test/data/accessibility/bdo.html b/content/test/data/accessibility/bdo.html
index dc64edf..4b679f2 100644
--- a/content/test/data/accessibility/bdo.html
+++ b/content/test/data/accessibility/bdo.html
@@ -1,5 +1,5 @@
<!--
-@MAC_ALLOW:subrole=*
+@MAC_ALLOW:AXSubrole=*
@WIN_ALLOW:*
-->
<html>
diff --git a/content/test/data/accessibility/br-expected-mac.txt b/content/test/data/accessibility/br-expected-mac.txt
index 06846de..9fa5426 100644
--- a/content/test/data/accessibility/br-expected-mac.txt
+++ b/content/test/data/accessibility/br-expected-mac.txt
@@ -1,4 +1,4 @@
AXWebArea
AXGroup
- AXStaticText value='Text line 1 '
- AXStaticText value='Text line 2'
+ AXStaticText AXValue='Text line 1 '
+ AXStaticText AXValue='Text line 2'
diff --git a/content/test/data/accessibility/button-name-calc-expected-mac.txt b/content/test/data/accessibility/button-name-calc-expected-mac.txt
index 952c013..75c006e 100644
--- a/content/test/data/accessibility/button-name-calc-expected-mac.txt
+++ b/content/test/data/accessibility/button-name-calc-expected-mac.txt
@@ -1,8 +1,8 @@
AXWebArea
AXGroup
- AXButton title='InnerText0'
- AXButton title='InnerText1' help='Title1'
- AXButton title='InnerText2' description='AriaLabel2' help='Title2'
- AXButton title='InnerText3' description='LabelledBy3' help='Title3'
- AXButton title='InnerText4' description='LabelledBy4' help='DescribedBy4'
- AXButton title='InnerText5' help='DescribedBy5'
+ AXButton AXTitle='InnerText0'
+ AXButton AXTitle='InnerText1' AXHelp='Title1'
+ AXButton AXTitle='InnerText2' AXDescription='AriaLabel2' AXHelp='Title2'
+ AXButton AXTitle='InnerText3' AXDescription='LabelledBy3' AXHelp='Title3'
+ AXButton AXTitle='InnerText4' AXDescription='LabelledBy4' AXHelp='DescribedBy4'
+ AXButton AXTitle='InnerText5' AXHelp='DescribedBy5'
diff --git a/content/test/data/accessibility/button-name-calc.html b/content/test/data/accessibility/button-name-calc.html
index c9d3778..4eace79 100644
--- a/content/test/data/accessibility/button-name-calc.html
+++ b/content/test/data/accessibility/button-name-calc.html
@@ -1,8 +1,8 @@
<!--
@WIN-ALLOW:description*
-@MAC-ALLOW:description*
-@MAC-ALLOW:help*
-@MAC-DENY:value*
+@MAC-ALLOW:AXDescription*
+@MAC-ALLOW:AXHelp*
+@MAC-DENY:AXValue*
-->
<html>
<body>
diff --git a/content/test/data/accessibility/canvas-expected-mac.txt b/content/test/data/accessibility/canvas-expected-mac.txt
index 411c22f..d184251 100644
--- a/content/test/data/accessibility/canvas-expected-mac.txt
+++ b/content/test/data/accessibility/canvas-expected-mac.txt
@@ -1,7 +1,7 @@
AXWebArea
AXGroup
AXImage
- AXStaticText value='Static fallback'
+ AXStaticText AXValue='Static fallback'
AXGroup
- AXLink title='Interactive fallback'
- AXStaticText value='Interactive fallback'
+ AXLink AXTitle='Interactive fallback'
+ AXStaticText AXValue='Interactive fallback'
diff --git a/content/test/data/accessibility/checkbox-name-calc-expected-mac.txt b/content/test/data/accessibility/checkbox-name-calc-expected-mac.txt
index 192dbc0..f8d9d09 100644
--- a/content/test/data/accessibility/checkbox-name-calc-expected-mac.txt
+++ b/content/test/data/accessibility/checkbox-name-calc-expected-mac.txt
@@ -1,8 +1,8 @@
AXWebArea
AXGroup
- AXCheckBox description='Title0'
- AXCheckBox title='Label1' help='Title1'
- AXCheckBox description='AriaLabel2' help='Title2'
- AXCheckBox description='LabelledBy3' help='Title3'
- AXCheckBox description='LabelledBy4' help='DescribedBy4'
- AXCheckBox help='DescribedBy5'
+ AXCheckBox AXDescription='Title0'
+ AXCheckBox AXTitle='Label1' AXHelp='Title1'
+ AXCheckBox AXDescription='AriaLabel2' AXHelp='Title2'
+ AXCheckBox AXDescription='LabelledBy3' AXHelp='Title3'
+ AXCheckBox AXDescription='LabelledBy4' AXHelp='DescribedBy4'
+ AXCheckBox AXHelp='DescribedBy5'
diff --git a/content/test/data/accessibility/checkbox-name-calc.html b/content/test/data/accessibility/checkbox-name-calc.html
index c6bf76a..c9aa59f 100644
--- a/content/test/data/accessibility/checkbox-name-calc.html
+++ b/content/test/data/accessibility/checkbox-name-calc.html
@@ -1,8 +1,8 @@
<!--
@WIN-ALLOW:description*
-@MAC-ALLOW:description*
-@MAC-ALLOW:help*
-@MAC-DENY:value*
+@MAC-ALLOW:AXDescription*
+@MAC-ALLOW:AXHelp*
+@MAC-DENY:AXValue*
-->
<html>
<body>
diff --git a/content/test/data/accessibility/div-expected-mac.txt b/content/test/data/accessibility/div-expected-mac.txt
index d3ddd33..db92d6d 100644
--- a/content/test/data/accessibility/div-expected-mac.txt
+++ b/content/test/data/accessibility/div-expected-mac.txt
@@ -1,3 +1,3 @@
AXWebArea
- AXGroup title='Focusable div'
- AXStaticText value='Focusable div'
+ AXGroup AXTitle='Focusable div'
+ AXStaticText AXValue='Focusable div'
diff --git a/content/test/data/accessibility/dl-expected-mac.txt b/content/test/data/accessibility/dl-expected-mac.txt
index 607ac4e..0fdb7ba 100644
--- a/content/test/data/accessibility/dl-expected-mac.txt
+++ b/content/test/data/accessibility/dl-expected-mac.txt
@@ -1,8 +1,8 @@
AXWebArea
- AXList subrole=AXDescriptionList
- AXGroup subrole=AXTerm
- AXStaticText value='Term'
- AXGroup subrole=AXDescription
- AXStaticText value='Description'
- AXGroup subrole=AXDefinition
- AXStaticText value='Definition'
+ AXList AXSubrole=AXDescriptionList
+ AXGroup AXSubrole=AXTerm
+ AXStaticText AXValue='Term'
+ AXGroup AXSubrole=AXDescription
+ AXStaticText AXValue='Description'
+ AXGroup AXSubrole=AXDefinition
+ AXStaticText AXValue='Definition'
diff --git a/content/test/data/accessibility/dl.html b/content/test/data/accessibility/dl.html
index 1e029f4..85e2601 100644
--- a/content/test/data/accessibility/dl.html
+++ b/content/test/data/accessibility/dl.html
@@ -1,6 +1,6 @@
<!doctype html>
<!--
-@MAC-ALLOW:subrole*
+@MAC-ALLOW:AXSubrole*
-->
<html>
<body>
diff --git a/content/test/data/accessibility/em-expected-mac.txt b/content/test/data/accessibility/em-expected-mac.txt
index dd3c675..b6f59f5 100644
--- a/content/test/data/accessibility/em-expected-mac.txt
+++ b/content/test/data/accessibility/em-expected-mac.txt
@@ -1,5 +1,5 @@
AXWebArea
AXGroup
- AXStaticText value='One word is '
- AXStaticText value='emphasized'
- AXStaticText value='.'
+ AXStaticText AXValue='One word is '
+ AXStaticText AXValue='emphasized'
+ AXStaticText AXValue='.'
diff --git a/content/test/data/accessibility/footer-expected-mac.txt b/content/test/data/accessibility/footer-expected-mac.txt
index 2147226..c104310 100644
--- a/content/test/data/accessibility/footer-expected-mac.txt
+++ b/content/test/data/accessibility/footer-expected-mac.txt
@@ -1,3 +1,3 @@
AXWebArea
- AXGroup subrole=AXLandmarkContentInfo roleDescription='footer'
- AXStaticText value='Footer element'
+ AXGroup AXSubrole=AXLandmarkContentInfo AXRoleDescription='footer'
+ AXStaticText AXValue='Footer element'
diff --git a/content/test/data/accessibility/footer.html b/content/test/data/accessibility/footer.html
index 5996b5c..16d7044 100644
--- a/content/test/data/accessibility/footer.html
+++ b/content/test/data/accessibility/footer.html
@@ -1,6 +1,6 @@
<!--
-@MAC-ALLOW:roleDescription='footer'
-@MAC-ALLOW:subrole*
+@MAC-ALLOW:AXRoleDescription='footer'
+@MAC-ALLOW:AXSubrole*
-->
<html>
<body>
diff --git a/content/test/data/accessibility/form-expected-mac.txt b/content/test/data/accessibility/form-expected-mac.txt
index 9e7b4f7..5f7bb3a 100644
--- a/content/test/data/accessibility/form-expected-mac.txt
+++ b/content/test/data/accessibility/form-expected-mac.txt
@@ -1,3 +1,3 @@
AXWebArea
AXGroup
- AXButton title='Submit'
+ AXButton AXTitle='Submit'
diff --git a/content/test/data/accessibility/heading-expected-mac.txt b/content/test/data/accessibility/heading-expected-mac.txt
index 41ea300..caeaa19 100644
--- a/content/test/data/accessibility/heading-expected-mac.txt
+++ b/content/test/data/accessibility/heading-expected-mac.txt
@@ -1,25 +1,25 @@
AXWebArea
- AXHeading title='Heading 1' value='1'
- AXStaticText value='Heading 1'
- AXHeading title='Heading 2' value='2'
- AXStaticText value='Heading 2'
- AXHeading title='Heading 3' value='3'
- AXStaticText value='Heading 3'
- AXHeading title='Heading 4' value='4'
- AXStaticText value='Heading 4'
- AXHeading title='Heading 5' value='5'
- AXStaticText value='Heading 5'
- AXHeading title='Heading 6' value='6'
- AXStaticText value='Heading 6'
- AXHeading title='ARIA Heading 1' value='1'
- AXStaticText value='ARIA Heading 1'
- AXHeading title='ARIA Heading 2' value='2'
- AXStaticText value='ARIA Heading 2'
- AXHeading title='ARIA Heading 3' value='3'
- AXStaticText value='ARIA Heading 3'
- AXHeading title='ARIA Heading 4' value='4'
- AXStaticText value='ARIA Heading 4'
- AXHeading title='ARIA Heading 5' value='5'
- AXStaticText value='ARIA Heading 5'
- AXHeading title='ARIA Heading 6' value='6'
- AXStaticText value='ARIA Heading 6'
+ AXHeading AXTitle='Heading 1' AXValue='1'
+ AXStaticText AXValue='Heading 1'
+ AXHeading AXTitle='Heading 2' AXValue='2'
+ AXStaticText AXValue='Heading 2'
+ AXHeading AXTitle='Heading 3' AXValue='3'
+ AXStaticText AXValue='Heading 3'
+ AXHeading AXTitle='Heading 4' AXValue='4'
+ AXStaticText AXValue='Heading 4'
+ AXHeading AXTitle='Heading 5' AXValue='5'
+ AXStaticText AXValue='Heading 5'
+ AXHeading AXTitle='Heading 6' AXValue='6'
+ AXStaticText AXValue='Heading 6'
+ AXHeading AXTitle='ARIA Heading 1' AXValue='1'
+ AXStaticText AXValue='ARIA Heading 1'
+ AXHeading AXTitle='ARIA Heading 2' AXValue='2'
+ AXStaticText AXValue='ARIA Heading 2'
+ AXHeading AXTitle='ARIA Heading 3' AXValue='3'
+ AXStaticText AXValue='ARIA Heading 3'
+ AXHeading AXTitle='ARIA Heading 4' AXValue='4'
+ AXStaticText AXValue='ARIA Heading 4'
+ AXHeading AXTitle='ARIA Heading 5' AXValue='5'
+ AXStaticText AXValue='ARIA Heading 5'
+ AXHeading AXTitle='ARIA Heading 6' AXValue='6'
+ AXStaticText AXValue='ARIA Heading 6'
diff --git a/content/test/data/accessibility/iframe-coordinates-expected-mac.txt b/content/test/data/accessibility/iframe-coordinates-expected-mac.txt
deleted file mode 100644
index 9f2a91a..0000000
--- a/content/test/data/accessibility/iframe-coordinates-expected-mac.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-AXWebArea position=(0, 0) size=(800, 600)
- AXGroup position=(0, 0) size=(300, 150)
- AXButton position=(25, 25) size=(250, 50)
- AXGroup position=(0, 150) size=(300, 150)
- AXButton position=(25, 175) size=(250, 50)
- AXGroup position=(0, 300) size=(300, 150)
- AXUnknown position=(0, 300) size=(300, 100)
- AXUnknown position=(0, 0) size=(0, 0)
- AXWebArea position=(0, 300) size=(300, 100)
- AXGroup position=(0, 300) size=(300, 100)
- AXButton position=(25, 325) size=(250, 50)
- AXGroup position=(0, 450) size=(300, 150)
- AXUnknown position=(0, 450) size=(150, 50)
- AXUnknown position=(0, 0) size=(0, 0)
- AXWebArea position=(0, 450) size=(300, 100)
- AXGroup position=(-150, 400) size=(300, 100)
- AXButton position=(-125, 425) size=(250, 50)
- AXScrollBar position=(0, 0) size=(0, 0)
- AXScrollBar position=(0, 0) size=(0, 0)
diff --git a/content/test/data/accessibility/iframe-coordinates.html b/content/test/data/accessibility/iframe-coordinates.html
index 1c1711b..0a9e958 100644
--- a/content/test/data/accessibility/iframe-coordinates.html
+++ b/content/test/data/accessibility/iframe-coordinates.html
@@ -1,7 +1,7 @@
<!doctype html>
<!--
-@MAC-DENY:title*
-@MAC-DENY:value*
+@MAC-DENY:AXTitle*
+@MAC-DENY:AXValue*
@MAC-ALLOW:position*
@MAC-ALLOW:size*
diff --git a/content/test/data/accessibility/input-button-expected-mac.txt b/content/test/data/accessibility/input-button-expected-mac.txt
index 4d52ae1..4b4ddba 100644
--- a/content/test/data/accessibility/input-button-expected-mac.txt
+++ b/content/test/data/accessibility/input-button-expected-mac.txt
@@ -1,3 +1,3 @@
AXWebArea
AXGroup
- AXButton title='Button'
+ AXButton AXTitle='Button'
diff --git a/content/test/data/accessibility/input-button.html b/content/test/data/accessibility/input-button.html
index 3ac815e..14b6e84 100644
--- a/content/test/data/accessibility/input-button.html
+++ b/content/test/data/accessibility/input-button.html
@@ -1,6 +1,6 @@
<!doctype html>
<!--
-@MAC-DENY:value*
+@MAC-DENY:AXValue*
-->
<html>
<body>
diff --git a/content/test/data/accessibility/input-color-expected-mac.txt b/content/test/data/accessibility/input-color-expected-mac.txt
index ecfb7a0..4c426aa 100644
--- a/content/test/data/accessibility/input-color-expected-mac.txt
+++ b/content/test/data/accessibility/input-color-expected-mac.txt
@@ -1,3 +1,3 @@
AXWebArea
AXGroup
- AXColorWell value='rgb 1.00000 0.60000 0.00000 1'
+ AXColorWell AXValue='rgb 1.00000 0.60000 0.00000 1'
diff --git a/content/test/data/accessibility/input-color.html b/content/test/data/accessibility/input-color.html
index d2832cc..f6e1eca 100644
--- a/content/test/data/accessibility/input-color.html
+++ b/content/test/data/accessibility/input-color.html
@@ -1,6 +1,6 @@
<!doctype html>
<!--
-@MAC-DENY:title*
+@MAC-DENY:AXTitle*
@WIN-ALLOW:value*
@WIN-DENY:value='file://*
-->
diff --git a/content/test/data/accessibility/input-range-expected-mac.txt b/content/test/data/accessibility/input-range-expected-mac.txt
index 2d9c3e8..366f98e 100644
--- a/content/test/data/accessibility/input-range-expected-mac.txt
+++ b/content/test/data/accessibility/input-range-expected-mac.txt
@@ -1,3 +1,3 @@
AXWebArea
AXGroup
- AXSlider value='5'
+ AXSlider AXValue='5'
diff --git a/content/test/data/accessibility/label-expected-mac.txt b/content/test/data/accessibility/label-expected-mac.txt
index 120d0a8..ecbf184 100644
--- a/content/test/data/accessibility/label-expected-mac.txt
+++ b/content/test/data/accessibility/label-expected-mac.txt
@@ -1,4 +1,4 @@
AXWebArea
AXGroup
AXGroup
- AXStaticText value='Label'
+ AXStaticText AXValue='Label'
diff --git a/content/test/data/accessibility/list-markers-expected-mac.txt b/content/test/data/accessibility/list-markers-expected-mac.txt
index fb55b8c..064c829 100644
--- a/content/test/data/accessibility/list-markers-expected-mac.txt
+++ b/content/test/data/accessibility/list-markers-expected-mac.txt
@@ -1,17 +1,17 @@
AXWebArea
- AXList subrole=AXContentList
+ AXList AXSubrole=AXContentList
AXGroup
- AXListMarker value='•'
- AXStaticText value='First item properly groups itself despite '
- AXStaticText value='bolded'
- AXStaticText value=' text.'
+ AXListMarker AXValue='•'
+ AXStaticText AXValue='First item properly groups itself despite '
+ AXStaticText AXValue='bolded'
+ AXStaticText AXValue=' text.'
AXGroup
- AXListMarker value='•'
- AXStaticText value='This should also be '
- AXStaticText value='seen'
- AXStaticText value=' as a group.'
+ AXListMarker AXValue='•'
+ AXStaticText AXValue='This should also be '
+ AXStaticText AXValue='seen'
+ AXStaticText AXValue=' as a group.'
AXGroup
- AXListMarker value='•'
- AXStaticText value='Some '
- AXStaticText value='more'
- AXStaticText value=' text.'
+ AXListMarker AXValue='•'
+ AXStaticText AXValue='Some '
+ AXStaticText AXValue='more'
+ AXStaticText AXValue=' text.'
diff --git a/content/test/data/accessibility/list-markers.html b/content/test/data/accessibility/list-markers.html
index 6a92bfd..edba4c6 100644
--- a/content/test/data/accessibility/list-markers.html
+++ b/content/test/data/accessibility/list-markers.html
@@ -1,5 +1,5 @@
<!--
-@MAC-ALLOW:subrole*
+@MAC-ALLOW:AXSubrole*
-->
<html>
<body>
diff --git a/content/test/data/accessibility/p-expected-mac.txt b/content/test/data/accessibility/p-expected-mac.txt
index 53ebca6..5429233 100644
--- a/content/test/data/accessibility/p-expected-mac.txt
+++ b/content/test/data/accessibility/p-expected-mac.txt
@@ -1,7 +1,7 @@
AXWebArea
AXGroup
- AXStaticText value='Before'
+ AXStaticText AXValue='Before'
AXGroup
- AXStaticText value='Paragraph'
+ AXStaticText AXValue='Paragraph'
AXGroup
- AXStaticText value='After'
+ AXStaticText AXValue='After'
diff --git a/content/test/data/accessibility/select-expected-mac.txt b/content/test/data/accessibility/select-expected-mac.txt
index 117da80..ed7fc5d 100644
--- a/content/test/data/accessibility/select-expected-mac.txt
+++ b/content/test/data/accessibility/select-expected-mac.txt
@@ -1,17 +1,17 @@
-AXWebArea roleDescription='HTML content'
- AXGroup roleDescription='group'
- AXPopUpButton roleDescription='pop up button' value='Placeholder option'
- AXUnknown roleDescription='unknown'
- AXMenuItem roleDescription='menu item' value='Placeholder option'
- AXMenuItem roleDescription='menu item' value='Option 1'
- AXMenuItem roleDescription='menu item' value='Option 2'
- AXPopUpButton roleDescription='pop up button' value='Option 2'
- AXUnknown roleDescription='unknown'
- AXMenuItem roleDescription='menu item' value='Option 1'
- AXMenuItem roleDescription='menu item' value='Option 2'
- AXMenuItem roleDescription='menu item' value='Option 3'
- AXPopUpButton roleDescription='pop up button' value='Option 1'
- AXUnknown roleDescription='unknown'
- AXMenuItem roleDescription='menu item' value='Option 1'
- AXMenuItem roleDescription='menu item' value='Option 2'
- AXMenuItem roleDescription='menu item' value='Option 3'
+AXWebArea AXRoleDescription='HTML content'
+ AXGroup AXRoleDescription='group'
+ AXPopUpButton AXRoleDescription='pop up button' AXValue='Placeholder option'
+ AXUnknown AXRoleDescription='unknown'
+ AXMenuItem AXRoleDescription='menu item' AXValue='Placeholder option'
+ AXMenuItem AXRoleDescription='menu item' AXValue='Option 1'
+ AXMenuItem AXRoleDescription='menu item' AXValue='Option 2'
+ AXPopUpButton AXRoleDescription='pop up button' AXValue='Option 2'
+ AXUnknown AXRoleDescription='unknown'
+ AXMenuItem AXRoleDescription='menu item' AXValue='Option 1'
+ AXMenuItem AXRoleDescription='menu item' AXValue='Option 2'
+ AXMenuItem AXRoleDescription='menu item' AXValue='Option 3'
+ AXPopUpButton AXRoleDescription='pop up button' AXValue='Option 1'
+ AXUnknown AXRoleDescription='unknown'
+ AXMenuItem AXRoleDescription='menu item' AXValue='Option 1'
+ AXMenuItem AXRoleDescription='menu item' AXValue='Option 2'
+ AXMenuItem AXRoleDescription='menu item' AXValue='Option 3'
diff --git a/content/test/data/accessibility/select.html b/content/test/data/accessibility/select.html
index 7699486..c699247 100644
--- a/content/test/data/accessibility/select.html
+++ b/content/test/data/accessibility/select.html
@@ -1,5 +1,5 @@
<!--
-@MAC-ALLOW:roleDescription=*
+@MAC-ALLOW:AXRoleDescription=*
-->
<html>
<body>
diff --git a/content/test/data/accessibility/span-expected-mac.txt b/content/test/data/accessibility/span-expected-mac.txt
index 8bc3a10..8078c2a 100644
--- a/content/test/data/accessibility/span-expected-mac.txt
+++ b/content/test/data/accessibility/span-expected-mac.txt
@@ -1,5 +1,5 @@
AXWebArea
AXGroup
- AXStaticText value='This paragraph has one '
- AXStaticText value='word'
- AXStaticText value=' in a span.'
+ AXStaticText AXValue='This paragraph has one '
+ AXStaticText AXValue='word'
+ AXStaticText AXValue=' in a span.'
diff --git a/content/test/data/accessibility/span.html b/content/test/data/accessibility/span.html
index 3dcf6a0..0609636 100644
--- a/content/test/data/accessibility/span.html
+++ b/content/test/data/accessibility/span.html
@@ -1,5 +1,5 @@
<!--
-@MAC-DENY:title*
+@MAC-DENY:AXTitle*
-->
<!doctype html>
<html>
diff --git a/content/test/data/accessibility/spinbutton-expected-mac.txt b/content/test/data/accessibility/spinbutton-expected-mac.txt
index c017dc4..ef75729 100644
--- a/content/test/data/accessibility/spinbutton-expected-mac.txt
+++ b/content/test/data/accessibility/spinbutton-expected-mac.txt
@@ -1,2 +1,2 @@
-AXWebArea roleDescription='HTML content'
- AXSlider roleDescription='stepper' value='5'
+AXWebArea AXRoleDescription='HTML content'
+ AXSlider AXRoleDescription='stepper' AXValue='5'
diff --git a/content/test/data/accessibility/spinbutton.html b/content/test/data/accessibility/spinbutton.html
index 6978d68..fd2d494 100644
--- a/content/test/data/accessibility/spinbutton.html
+++ b/content/test/data/accessibility/spinbutton.html
@@ -1,5 +1,5 @@
<!--
-@MAC-ALLOW:roleDescription*
+@MAC-ALLOW:AXRoleDescription*
-->
<html>
<body>
diff --git a/content/test/data/accessibility/svg-expected-mac.txt b/content/test/data/accessibility/svg-expected-mac.txt
index eb2adbe..1352fa8 100644
--- a/content/test/data/accessibility/svg-expected-mac.txt
+++ b/content/test/data/accessibility/svg-expected-mac.txt
@@ -1,5 +1,5 @@
AXWebArea
AXGroup
- AXGroup description='svg'
- AXGroup title='Test'
- AXStaticText value='Test'
+ AXGroup AXDescription='svg'
+ AXGroup AXTitle='Test'
+ AXStaticText AXValue='Test'
diff --git a/content/test/data/accessibility/svg.html b/content/test/data/accessibility/svg.html
index 446cd98..1b7a175 100644
--- a/content/test/data/accessibility/svg.html
+++ b/content/test/data/accessibility/svg.html
@@ -1,5 +1,5 @@
<!--
-@MAC-ALLOW:description='svg'
+@MAC-ALLOW:AXDescription='svg'
-->
<!doctype html>
<html>
diff --git a/content/test/data/accessibility/tab-expected-mac.txt b/content/test/data/accessibility/tab-expected-mac.txt
index dc69430..b76698e 100644
--- a/content/test/data/accessibility/tab-expected-mac.txt
+++ b/content/test/data/accessibility/tab-expected-mac.txt
@@ -1,4 +1,4 @@
AXWebArea
AXTabGroup
- AXRadioButton title='Tab 1' value='0'
- AXRadioButton title='Tab 2' value='0'
+ AXRadioButton AXTitle='Tab 1' AXValue='0'
+ AXRadioButton AXTitle='Tab 2' AXValue='0'
diff --git a/content/test/data/accessibility/table-simple-expected-mac.txt b/content/test/data/accessibility/table-simple-expected-mac.txt
new file mode 100644
index 0000000..798e4c7
--- /dev/null
+++ b/content/test/data/accessibility/table-simple-expected-mac.txt
@@ -0,0 +1,20 @@
+AXWebArea AXTitle='Table example'
+ AXTable
+ AXRow AXIndex='0'
+ AXCell AXColumnIndexRange={"len":1,"loc":0} AXRowIndexRange={"len":1,"loc":0}
+ AXStaticText AXValue='A'
+ AXCell AXColumnIndexRange={"len":1,"loc":1} AXRowIndexRange={"len":1,"loc":0}
+ AXStaticText AXValue='B'
+ AXCell AXColumnIndexRange={"len":1,"loc":2} AXRowIndexRange={"len":1,"loc":0}
+ AXStaticText AXValue='C'
+ AXRow AXIndex='1'
+ AXCell AXColumnIndexRange={"len":1,"loc":0} AXRowIndexRange={"len":1,"loc":1}
+ AXStaticText AXValue='D'
+ AXCell AXColumnIndexRange={"len":1,"loc":1} AXRowIndexRange={"len":1,"loc":1}
+ AXStaticText AXValue='E'
+ AXCell AXColumnIndexRange={"len":1,"loc":2} AXRowIndexRange={"len":1,"loc":1}
+ AXStaticText AXValue='F'
+ AXColumn AXIndex='0'
+ AXColumn AXIndex='1'
+ AXColumn AXIndex='2'
+ AXGroup
diff --git a/content/test/data/accessibility/table-simple-expected-win.txt b/content/test/data/accessibility/table-simple-expected-win.txt
new file mode 100644
index 0000000..839b7a2
--- /dev/null
+++ b/content/test/data/accessibility/table-simple-expected-win.txt
@@ -0,0 +1 @@
+#<skip - we don't dump table attrs on win yet>
diff --git a/content/test/data/accessibility/table-simple.html b/content/test/data/accessibility/table-simple.html
new file mode 100644
index 0000000..9bfbbf8
--- /dev/null
+++ b/content/test/data/accessibility/table-simple.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<!--
+@MAC-ALLOW:AXIndex=*
+@MAC-ALLOW:AXColumnIndexRange=*
+@MAC-ALLOW:AXRowIndexRange=*
+-->
+<html>
+<head>
+ <title>Table example</title>
+</head>
+<body>
+
+<table border=1>
+ <tr>
+ <td>A</td>
+ <td>B</td>
+ <td>C</td>
+ </tr>
+ <tr>
+ <td>D</td>
+ <td>E</td>
+ <td>F</td>
+ </tr>
+</table>
+
+</body>
+</html>
diff --git a/content/test/data/accessibility/table-spans-expected-mac.txt b/content/test/data/accessibility/table-spans-expected-mac.txt
new file mode 100644
index 0000000..55160c1
--- /dev/null
+++ b/content/test/data/accessibility/table-spans-expected-mac.txt
@@ -0,0 +1,13 @@
+AXWebArea AXTitle='Table example with rowspan and colspan'
+ AXTable
+ AXRow AXIndex='0'
+ AXCell AXColumnIndexRange={"len":1,"loc":0} AXRowIndexRange={"len":2,"loc":0}
+ AXStaticText AXValue='AD'
+ AXCell AXColumnIndexRange={"len":2,"loc":1} AXRowIndexRange={"len":1,"loc":0}
+ AXStaticText AXValue='BC'
+ AXRow AXIndex='1'
+ AXCell AXColumnIndexRange={"len":2,"loc":1} AXRowIndexRange={"len":1,"loc":1}
+ AXStaticText AXValue='EF'
+ AXColumn AXIndex='0'
+ AXColumn AXIndex='1'
+ AXGroup
diff --git a/content/test/data/accessibility/table-spans-expected-win.txt b/content/test/data/accessibility/table-spans-expected-win.txt
new file mode 100644
index 0000000..839b7a2
--- /dev/null
+++ b/content/test/data/accessibility/table-spans-expected-win.txt
@@ -0,0 +1 @@
+#<skip - we don't dump table attrs on win yet>
diff --git a/content/test/data/accessibility/table-spans.html b/content/test/data/accessibility/table-spans.html
new file mode 100644
index 0000000..608b321
--- /dev/null
+++ b/content/test/data/accessibility/table-spans.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+@MAC-ALLOW:AXIndex=*
+@MAC-ALLOW:AXColumnIndexRange=*
+@MAC-ALLOW:AXRowIndexRange=*
+-->
+<html>
+<head>
+ <title>Table example with rowspan and colspan</title>
+</head>
+<body>
+
+<table border=1>
+ <tr>
+ <td rowspan="2">AD</td>
+ <td colspan="2">BC</td>
+ </tr>
+ <tr>
+ <td colspan="2">EF</td>
+ </tr>
+</table>
+
+</body>
+</html>
diff --git a/content/test/data/accessibility/togglebutton-expected-mac.txt b/content/test/data/accessibility/togglebutton-expected-mac.txt
index 3544dbf..6710157 100644
--- a/content/test/data/accessibility/togglebutton-expected-mac.txt
+++ b/content/test/data/accessibility/togglebutton-expected-mac.txt
@@ -1,3 +1,3 @@
AXWebArea
- AXButton title='Regular button'
- AXButton title='Toggle button'
+ AXButton AXTitle='Regular button'
+ AXButton AXTitle='Toggle button'
diff --git a/content/test/data/accessibility/toolbar-expected-mac.txt b/content/test/data/accessibility/toolbar-expected-mac.txt
index 0b2df0f..91db02e 100644
--- a/content/test/data/accessibility/toolbar-expected-mac.txt
+++ b/content/test/data/accessibility/toolbar-expected-mac.txt
@@ -1,3 +1,3 @@
-AXWebArea roleDescription='HTML content'
- AXToolbar roleDescription='toolbar'
- AXStaticText roleDescription='text' value='A toolbar'
+AXWebArea AXRoleDescription='HTML content'
+ AXToolbar AXRoleDescription='toolbar'
+ AXStaticText AXRoleDescription='text' AXValue='A toolbar'
diff --git a/content/test/data/accessibility/toolbar.html b/content/test/data/accessibility/toolbar.html
index 7f4f541..f0274c5 100644
--- a/content/test/data/accessibility/toolbar.html
+++ b/content/test/data/accessibility/toolbar.html
@@ -1,5 +1,5 @@
<!--
-@MAC-ALLOW:roleDescription=*
+@MAC-ALLOW:AXRoleDescription=*
@WIN-DENY:name=''
-->
<html>
diff --git a/content/test/data/accessibility/ul-expected-mac.txt b/content/test/data/accessibility/ul-expected-mac.txt
index 317db0a..776cf1b 100644
--- a/content/test/data/accessibility/ul-expected-mac.txt
+++ b/content/test/data/accessibility/ul-expected-mac.txt
@@ -1,11 +1,11 @@
AXWebArea
- AXList subrole=AXContentList
+ AXList AXSubrole=AXContentList
AXGroup
- AXListMarker value='•'
- AXStaticText value='Item 1'
+ AXListMarker AXValue='•'
+ AXStaticText AXValue='Item 1'
AXGroup
- AXListMarker value='•'
- AXStaticText value='Item 2'
+ AXListMarker AXValue='•'
+ AXStaticText AXValue='Item 2'
AXGroup
- AXListMarker value='•'
- AXStaticText value='Item 3'
+ AXListMarker AXValue='•'
+ AXStaticText AXValue='Item 3'
diff --git a/content/test/data/accessibility/ul.html b/content/test/data/accessibility/ul.html
index 3520fe5..b500201 100644
--- a/content/test/data/accessibility/ul.html
+++ b/content/test/data/accessibility/ul.html
@@ -1,5 +1,5 @@
<!--
-@MAC-ALLOW:subrole*
+@MAC-ALLOW:AXSubrole*
-->
<html>
<body>
diff --git a/content/test/data/accessibility/wbr-expected-mac.txt b/content/test/data/accessibility/wbr-expected-mac.txt
index b8bf1ea..5611f0d 100644
--- a/content/test/data/accessibility/wbr-expected-mac.txt
+++ b/content/test/data/accessibility/wbr-expected-mac.txt
@@ -2,6 +2,6 @@
# wrong, so we assume this is correct.
AXWebArea
AXGroup
- AXStaticText value='Supercali'
- AXStaticText value='fragilistic'
- AXStaticText value='expialidocious'
+ AXStaticText AXValue='Supercali'
+ AXStaticText AXValue='fragilistic'
+ AXStaticText AXValue='expialidocious'
diff --git a/content/test/data/dom_serializer/html_doc_has_base_tag.htm b/content/test/data/dom_serializer/html_doc_has_base_tag.htm
new file mode 100644
index 0000000..f2b43d8
--- /dev/null
+++ b/content/test/data/dom_serializer/html_doc_has_base_tag.htm
@@ -0,0 +1,13 @@
+<html>
+<head>
+<base href="http://www.youtube.com">
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<script>
+document.write("<base href=\"http://www.youtube.com\">");
+</script>
+</head>
+<body>
+<a href="/signup">Sign Up</a>
+<a href="/forgot_username?next=/">Forgot Username</a>
+</body>
+</html>
diff --git a/content/test/data/dom_serializer/iframe-src-is-exe.htm b/content/test/data/dom_serializer/iframe-src-is-exe.htm
new file mode 100644
index 0000000..ed32b12
--- /dev/null
+++ b/content/test/data/dom_serializer/iframe-src-is-exe.htm
@@ -0,0 +1,8 @@
+<html>
+<body>
+This tests that we can serialize a page that has a downloaded url in an iframe without crashing.
+
+<iframe src="dummy.exe"></iframe>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/content/test/data/dom_serializer/non_html_namespace.htm b/content/test/data/dom_serializer/non_html_namespace.htm
new file mode 100644
index 0000000..ec3a50a
--- /dev/null
+++ b/content/test/data/dom_serializer/non_html_namespace.htm
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script>
+window.onload = function() {
+ var input = document.createElementNS("urn:x-foo", "input");
+ input.setAttribute("type", "image");
+ input.setAttribute("src", "bar.png");
+ document.body.appendChild(input);
+};
+</script>
+</body>
+</html>
diff --git a/content/test/data/dom_serializer/nonstandard_htmlentities.htm b/content/test/data/dom_serializer/nonstandard_htmlentities.htm
new file mode 100644
index 0000000..17cd529
--- /dev/null
+++ b/content/test/data/dom_serializer/nonstandard_htmlentities.htm
@@ -0,0 +1 @@
+<HTML><BODY title="%⊅¹'">%⊅¹'</BODY></HTML>
diff --git a/content/test/data/dom_serializer/note.html b/content/test/data/dom_serializer/note.html
new file mode 100644
index 0000000..69b83a6
--- /dev/null
+++ b/content/test/data/dom_serializer/note.html
@@ -0,0 +1,5 @@
+<html>
+ <body>
+ <iframe src="note.xml"></iframe>
+ </body>
+</html>
diff --git a/content/test/data/dom_serializer/note.xml b/content/test/data/dom_serializer/note.xml
new file mode 100644
index 0000000..cef4920
--- /dev/null
+++ b/content/test/data/dom_serializer/note.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<note>
+<to><Johnny></to>
+<from><Boss></from>
+<heading>Reminder</heading>
+<body>Get "review" and 'check' in code!</body>
+</note>
\ No newline at end of file
diff --git a/content/test/data/dom_serializer/youtube_1.htm b/content/test/data/dom_serializer/youtube_1.htm
new file mode 100644
index 0000000..0e1f92a
--- /dev/null
+++ b/content/test/data/dom_serializer/youtube_1.htm
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+<head>
+ <title>YouTube - Broadcast Yourself.</title>
+ <link rel="stylesheet" href="file:///c:/yt/css/base_all-vfl36460.css" type="text/css">
+ <link rel="search" type="application/opensearchdescription+xml" href="http://www.youtube.com/opensearch?locale=en_US" title="YouTube Video Search">
+ <link rel="icon" href="http://s.ytimg.com/yt/favicon-vfl1123.ico" type="image/x-icon">
+ <link rel="shortcut icon" href="http://s.ytimg.com/yt/favicon-vfl1123.ico" type="image/x-icon">
+ <meta name="description" content="Share your videos with friends and family">
+ <meta name="keywords" content="video,sharing,camera phone,video phone">
+ <link rel="alternate" type="application/rss+xml" title="YouTube - [RSS]" href="/rssls">
+ <link rel="alternate" media="handheld" href="http://m.youtube.com">
+ <script type="text/javascript" src="file:///c:/yt/js/base_all_with_bidi-vfl36451.js"></script>
+</head>
+<body>
+ <div id="baseDiv"><img src="file:///c:/yt/img/pixel-vfl73.gif" width="132" height="63" border="0" alt=""/>contents in youtube_1</div>
+ <iframe width="300" height="300" src="./youtube_2.htm">
+</body>
+</html>
diff --git a/content/test/data/dom_serializer/youtube_2.htm b/content/test/data/dom_serializer/youtube_2.htm
new file mode 100644
index 0000000..790dad6
--- /dev/null
+++ b/content/test/data/dom_serializer/youtube_2.htm
@@ -0,0 +1,17 @@
+<html lang="en">
+<head>
+ <title>YouTube - Broadcast Yourself.</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="search" type="application/opensearchdescription+xml" href="http://www.youtube.com/opensearch?locale=en_US" title="YouTube Video Search">
+ <link rel="icon" href="http://s.ytimg.com/yt/favicon-vfl1123.ico" type="image/x-icon">
+ <link rel="shortcut icon" href="http://s.ytimg.com/yt/favicon-vfl1123.ico" type="image/x-icon">
+ <meta http-equiv="Content-Type" content="text/html; charset=GB2312">
+ <meta name="description" content="Share your videos with friends and family">
+ <meta name="keywords" content="video,sharing,camera phone,video phone">
+ <link rel="alternate" type="application/rss+xml" title="YouTube - [RSS]" href="/rssls">
+ <link rel="alternate" media="handheld" href="http://m.youtube.com">
+</head>
+<body>
+ <div id="baseDiv">contents in youtube_2</div>
+</body>
+</html>
diff --git a/content/test/data/gpu/functional_3d_css.html b/content/test/data/gpu/functional_3d_css.html
new file mode 100644
index 0000000..6bee8d0
--- /dev/null
+++ b/content/test/data/gpu/functional_3d_css.html
@@ -0,0 +1,16 @@
+<html>
+<head>
+<style>
+ div {
+ width:200px;
+ height:100px;
+ background-color:black;
+ color:#ffffff;
+ -webkit-transform:translateZ(0);
+ }
+</style>
+</head>
+<body>
+<div>3D CSS</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/content/test/data/gpu/functional_canvas_demo.html b/content/test/data/gpu/functional_canvas_demo.html
new file mode 100644
index 0000000..cf6ef03
--- /dev/null
+++ b/content/test/data/gpu/functional_canvas_demo.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Canvas Demo</title>
+</head>
+<body>
+<canvas id="canv" class="output" width="600" height="400" style="width:600px;height:400px;border:2px solid #c3c3c3;">
+ <p><b>Browser doesn't support canvas</b></p>
+</canvas>
+<script>
+ var c = document.getElementById('canv');
+ var ctx = c.getContext('2d');
+ ctx.fillStyle = "#000000";
+ ctx.fillRect(10, 10, 250, 250);
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/content/test/data/gpu/functional_color2.ogv b/content/test/data/gpu/functional_color2.ogv
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/content/test/data/gpu/functional_color2.ogv
diff --git a/content/test/data/gpu/functional_files/context.js b/content/test/data/gpu/functional_files/context.js
new file mode 100644
index 0000000..af56f6f
--- /dev/null
+++ b/content/test/data/gpu/functional_files/context.js
@@ -0,0 +1,33 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Global variable.
+var gl_context;
+
+initializeWebGL = function(canvas) {
+ gl_context = null;
+ // Try to grab the standard context.
+ gl_context = canvas.getContext("webgl") ||
+ canvas.getContext("experimental-webgl");
+ // If we don't have a GL context, give up now
+ if (!gl_context) {
+ alert("Unable to initialize WebGL. Your browser may not support it.");
+ }
+}
+
+startWebGLContext = function() {
+ var canvas = document.getElementById("glcanvas");
+ // Initialize the GL context.
+ initializeWebGL(canvas);
+
+ // Only continue if WebGL is available and working.
+ if (gl_context) {
+ gl_context.clearColor(0.0, 0.0, 0.0, 1.0);
+ gl_context.enable(gl_context.DEPTH_TEST);
+ gl_context.depthFunc(gl_context.LEQUAL);
+ gl_context.clearDepth(1);
+ gl_context.clear(gl_context.COLOR_BUFFER_BIT |
+ gl_context.DEPTH_BUFFER_BIT);
+ }
+}
\ No newline at end of file
diff --git a/content/test/data/gpu/functional_webgl.html b/content/test/data/gpu/functional_webgl.html
new file mode 100644
index 0000000..abb0fe0
--- /dev/null
+++ b/content/test/data/gpu/functional_webgl.html
@@ -0,0 +1,8 @@
+<html>
+<script type="text/javascript" src="./functional_files/context.js"></script>
+<body onload="startWebGLContext()">
+ <canvas id="glcanvas" width="640" height="480">
+ Your browser doesn't appear to support the HTML5 <code><canvas></code> element.
+ </canvas>
+</body>
+</html>
\ No newline at end of file
diff --git a/content/test/data/media/encrypted_media_utils.js b/content/test/data/media/encrypted_media_utils.js
index a29c0f5..e5d4230 100644
--- a/content/test/data/media/encrypted_media_utils.js
+++ b/content/test/data/media/encrypted_media_utils.js
@@ -41,12 +41,10 @@
function isHeartbeatMessage(msg) {
if (msg.length < HEART_BEAT_HEADER.length)
return false;
-
for (var i = 0; i < HEART_BEAT_HEADER.length; ++i) {
if (String.fromCharCode(msg[i]) != HEART_BEAT_HEADER[i])
return false;
}
-
return true;
}
@@ -87,6 +85,7 @@
video.receivedKeyAdded = false;
video.receivedHeartbeat = false;
video.isHeartbeatExpected = keySystem === EXTERNAL_CLEAR_KEY_KEY_SYSTEM;
+ video.receivedKeyMessage = false;
if (!(video && mediaFile && keySystem && key))
failTest('Missing parameters in loadEncryptedMedia().');
@@ -126,6 +125,7 @@
}
function onKeyMessage(e) {
+ video.receivedKeyMessage = true;
if (!e.keySystem) {
failTest('keymessage without a keySystem: ' + e.keySystem);
return;
@@ -180,7 +180,9 @@
mediaSource.addEventListener('webkitsourceopen', onSourceOpen);
video.addEventListener('webkitneedkey', onNeedKey);
video.addEventListener('webkitkeymessage', onKeyMessage);
- video.addEventListener('webkitkeyerror', failTest);
+ video.addEventListener('webkitkeyerror', function() {
+ setResultInTitle("WebKitKeyError");
+ });
video.addEventListener('webkitkeyadded', onKeyAdded);
installTitleEventHandler(video, 'error');
diff --git a/content/test/data/media/getusermedia.html b/content/test/data/media/getusermedia.html
new file mode 100644
index 0000000..429dd66
--- /dev/null
+++ b/content/test/data/media/getusermedia.html
@@ -0,0 +1,76 @@
+<html>
+<head>
+ <script type="text/javascript" src="webrtc_test_utilities.js"></script>
+ <script type="text/javascript">
+ $ = function(id) {
+ return document.getElementById(id);
+ };
+
+ var gLocalStream = null;
+
+ setAllEventsOccuredHandler(function() {
+ gLocalStream.stop();
+ document.title = 'OK';
+ });
+
+ // This test that a MediaStream can be created and a local preview
+ // rendered.
+ function getUserMedia(constraints) {
+ navigator.webkitGetUserMedia(constraints, displayAndWaitForVideo,
+ failedCallback);
+ }
+
+ // This test that a MediaStream can be cloned and that the clone can
+ // be rendered.
+ function getUserMediaAndClone() {
+ navigator.webkitGetUserMedia({video: true, audio: true},
+ createAndRenderClone, failedCallback);
+ }
+
+ function failedCallback(error) {
+ document.title = 'GetUserMedia call failed with code ' + error.code;
+ }
+
+ function displayAndWaitForVideo(stream) {
+ gLocalStream = stream;
+ var localStreamUrl = webkitURL.createObjectURL(stream);
+ $('local-view').src = localStreamUrl;
+ waitForVideo('local-view');
+ }
+
+ function createAndRenderClone(stream) {
+ gLocalStream = stream;
+ // TODO(perkj): --use-fake-device-for-media-stream do not currently
+ // work with audio devices and not all bots has a microphone.
+ new_stream = new webkitMediaStream();
+ new_stream.addTrack(stream.getVideoTracks()[0]);
+ expectEquals(new_stream.getVideoTracks().length, 1);
+ if (stream.getAudioTracks().length > 0) {
+ new_stream.addTrack(stream.getAudioTracks()[0]);
+ expectEquals(new_stream.getAudioTracks().length, 1);
+ new_stream.removeTrack(new_stream.getAudioTracks()[0]);
+ expectEquals(new_stream.getAudioTracks().length, 0);
+ }
+
+ var newStreamUrl = webkitURL.createObjectURL(new_stream);
+ $('local-view').src = newStreamUrl;
+ waitForVideo('local-view');
+ }
+
+ </script>
+</head>
+<body>
+ <table border="0">
+ <tr>
+ <td>Local Preview</td>
+ </tr>
+ <tr>
+ <td><video width="320" height="240" id="local-view"
+ autoplay="autoplay"></video></td>
+ <!-- Canvases are named after their corresponding video elements. -->
+ <td><canvas width="320" height="240" id="local-view-canvas"
+ style="display:none"></canvas></td>
+ </tr>
+ </table>
+</body>
+</html>
\ No newline at end of file
diff --git a/content/test/data/media/getusermedia_and_stop.html b/content/test/data/media/getusermedia_and_stop.html
deleted file mode 100644
index f1c43be..0000000
--- a/content/test/data/media/getusermedia_and_stop.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<html>
-<head>
- <script type="text/javascript">
- function getUserMedia(constraints) {
- navigator.webkitGetUserMedia(constraints, okCallback, failedCallback);
- }
-
- function failedCallback(error) {
- document.title = 'GetUserMedia call failed with code ' + error.code;
- }
-
- function okCallback(stream) {
- stream.stop();
- document.title = 'OK';
- }
- </script>
-</head>
-</html>
\ No newline at end of file
diff --git a/content/test/data/media/peerconnection-call.html b/content/test/data/media/peerconnection-call.html
index 4a85e9c..a157213 100644
--- a/content/test/data/media/peerconnection-call.html
+++ b/content/test/data/media/peerconnection-call.html
@@ -1,28 +1,22 @@
<html>
<head>
+ <script type="text/javascript" src="webrtc_test_utilities.js"></script>
<script type="text/javascript">
$ = function(id) {
return document.getElementById(id);
};
- // These must match with how the video and canvas tags are declared in html.
- const VIDEO_TAG_WIDTH = 320;
- const VIDEO_TAG_HEIGHT = 240;
-
var gFirstConnection = null;
var gSecondConnection = null;
var gTestWithoutMsidAndBundle = false;
- // Number of test events to occur before the test pass. When the test pass,
- // the document title change to OK.
- var gNumberOfExpectedEvents = 0;
-
- // Number of events that currently have occured.
- var gNumberOfEvents = 0;
-
var gLocalStream = null;
var gSentTones = '';
+ setAllEventsOccuredHandler(function() {
+ document.title = 'OK';
+ });
+
// Test that we can setup call with an audio and video track.
function call(constraints) {
createConnections(null);
@@ -50,8 +44,7 @@
gTestWithoutMsidAndBundle = true;
navigator.webkitGetUserMedia({audio:true, video:true},
addStreamToBothConnectionsAndNegotiate, printGetUserMediaError);
- // TODO(phoglund): this should work but it doesn't! http://crbug.com/177443.
- // waitForVideo('remote-view-1');
+ waitForVideo('remote-view-1');
waitForVideo('remote-view-2');
}
@@ -75,10 +68,6 @@
// Test call with a data channel and later add audio and video.
function callWithDataAndLaterAddMedia() {
- // TODO(perkj): This is needed for now until
- // https://code.google.com/p/webrtc/issues/detail?id=1203 is fixed.
- gTestWithoutMsidAndBundle = true;
-
createConnections({optional:[{RtpDataChannels: true}]});
setupDataChannel();
gFirstConnection.createOffer(onOfferCreated);
@@ -115,6 +104,79 @@
detectVideoIn('remote-view-2', onCallEstablished);
}
+ // Test call with a new Video MediaStream that has been created based on a
+ // stream generated by getUserMedia.
+ function callWithNewVideoMediaStream() {
+ createConnections(null);
+ navigator.webkitGetUserMedia({audio:true, video:true},
+ createNewVideoStreamAndAddToBothConnections, printGetUserMediaError);
+ waitForVideo('remote-view-1');
+ waitForVideo('remote-view-2');
+ }
+
+ // Test call with a new Video MediaStream that has been created based on a
+ // stream generated by getUserMedia. When Video is flowing, an audio track
+ // is added to the sent stream and the video track is removed. This
+ // is to test that adding and removing of remote tracks on an existing
+ // mediastream works.
+ function callWithNewVideoMediaStreamLaterSwitchToAudio() {
+ createConnections(null);
+ navigator.webkitGetUserMedia({audio:true, video:true},
+ createNewVideoStreamAndAddToBothConnections, printGetUserMediaError);
+
+ waitForVideo('remote-view-1');
+ waitForVideo('remote-view-2');
+
+ // Set an event handler for when video is playing.
+ setAllEventsOccuredHandler(function() {
+ // Add an audio track to the local stream and remove the video track and
+ // then renegotiate. But first - setup the expectations.
+ local_stream = gFirstConnection.getLocalStreams()[0];
+
+ remote_stream_1 = gFirstConnection.getRemoteStreams()[0];
+ // Add an expected event that onaddtrack will be called on the remote
+ // mediastream received on gFirstConnection when the audio track is
+ // received.
+ addExpectedEvent();
+ remote_stream_1.onaddtrack = function(){
+ expectEquals(remote_stream_1.getAudioTracks()[0].id,
+ local_stream.getAudioTracks()[0].id);
+ eventOccured();
+ }
+
+ // Add an expectation that the received video track is removed from
+ // gFirstConnection.
+ addExpectedEvent();
+ remote_stream_1.onremovetrack = function() {
+ eventOccured();
+ }
+
+ // Add an expected event that onaddtrack will be called on the remote
+ // mediastream received on gSecondConnection when the audio track is
+ // received.
+ remote_stream_2 = gSecondConnection.getRemoteStreams()[0];
+ addExpectedEvent();
+ remote_stream_2.onaddtrack = function() {
+ expectEquals(remote_stream_2.getAudioTracks()[0].id,
+ local_stream.getAudioTracks()[0].id);
+ eventOccured();
+ }
+
+ // Add an expectation that the received video track is removed from
+ // gSecondConnection.
+ addExpectedEvent();
+ remote_stream_2.onremovetrack = function() {
+ eventOccured();
+ }
+ // When all the above events have occurred- the test pass.
+ setAllEventsOccuredHandler(function() { document.title = 'OK'; });
+
+ local_stream.addTrack(gLocalStream.getAudioTracks()[0]);
+ local_stream.removeTrack(local_stream.getVideoTracks()[0]);
+ negotiate();
+ }); // End of setAllEventsOccuredHandler.
+ }
+
// This function is used for setting up a test that:
// 1. Creates a data channel on |gFirstConnection| and sends data to
// |gSecondConnection|.
@@ -209,6 +271,18 @@
negotiate();
}
+ // Called if getUserMedia succeeds when we want to send a modified
+ // MediaStream. A new MediaStream is created and the video track from
+ // |localStream| is added.
+ function createNewVideoStreamAndAddToBothConnections(localStream) {
+ displayAndRemember(localStream);
+ var new_stream = new webkitMediaStream();
+ new_stream.addTrack(localStream.getVideoTracks()[0]);
+ gFirstConnection.addStream(new_stream);
+ gSecondConnection.addStream(new_stream);
+ negotiate();
+ }
+
function negotiate() {
gFirstConnection.createOffer(onOfferCreated);
}
@@ -243,10 +317,13 @@
function onAnswerCreated(answer) {
gSecondConnection.setLocalDescription(answer);
expectEquals('stable', gSecondConnection.signalingState);
- handleAnswer(answer.sdp);
+ receiveAnswer(answer.sdp);
}
- function handleAnswer(answerSdp) {
+ function receiveAnswer(answerSdp) {
+ if (gTestWithoutMsidAndBundle) {
+ answerSdp = removeMsidAndBundle(answerSdp);
+ }
var parsedAnswer = new RTCSessionDescription({ type: 'answer',
sdp: answerSdp });
gFirstConnection.setRemoteDescription(parsedAnswer);
@@ -268,9 +345,9 @@
}
function onRemoteStream(e, target) {
- if (gTestWithoutMsidAndBundle && e.stream.label != "default") {
+ if (gTestWithoutMsidAndBundle && e.stream.id != "default") {
document.title = 'a default remote stream was expected but instead ' +
- e.stream.label + ' was received.';
+ e.stream.id + ' was received.';
return;
}
var remoteStreamUrl = webkitURL.createObjectURL(e.stream);
@@ -278,65 +355,6 @@
remoteVideo.src = remoteStreamUrl;
}
- // TODO(phoglund): perhaps use the video detector in chrome/test/data/webrtc/?
- function detectVideoIn(videoElementName, callback) {
- var width = VIDEO_TAG_WIDTH;
- var height = VIDEO_TAG_HEIGHT;
- var videoElement = $(videoElementName);
- var canvas = $(videoElementName + '-canvas');
- var waitVideo = setInterval(function() {
- var context = canvas.getContext('2d');
- context.drawImage(videoElement, 0, 0, width, height);
- var pixels = context.getImageData(0, 0, width, height).data;
-
- if (isVideoPlaying(pixels, width, height)) {
- clearInterval(waitVideo);
- callback();
- }
- }, 100);
- }
-
- function waitForVideo(videoElement) {
- document.title = 'Waiting for video...';
- addExpectedEvent();
- detectVideoIn(videoElement, function () { eventOccured(); });
- }
-
- // This very basic video verification algorithm will be satisfied if any
- // pixels are nonzero in a small sample area in the middle. It relies on the
- // assumption that a video element with null source just presents zeroes.
- function isVideoPlaying(pixels, width, height) {
- // Sample somewhere near the middle of the image.
- var middle = width * height / 2;
- for (var i = 0; i < 20; i++) {
- if (pixels[middle + i] > 0) {
- return true;
- }
- }
- return false;
- }
-
-
- // This function matches |left| and |right| and throws an exception if the
- // values don't match.
- function expectEquals(left, right) {
- if (left != right) {
- var s = "expectEquals failed left: " + left + " right: " + right;
- document.title = s;
- throw s;
- }
- }
-
- function addExpectedEvent() {
- ++gNumberOfExpectedEvents;
- }
-
- function eventOccured() {
- ++gNumberOfEvents;
- if (gNumberOfEvents == gNumberOfExpectedEvents) {
- document.title = 'OK';
- }
- }
</script>
</head>
<body>
diff --git a/content/test/data/media/webrtc_test_utilities.js b/content/test/data/media/webrtc_test_utilities.js
new file mode 100644
index 0000000..dae549f
--- /dev/null
+++ b/content/test/data/media/webrtc_test_utilities.js
@@ -0,0 +1,80 @@
+// 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.
+
+// These must match with how the video and canvas tags are declared in html.
+const VIDEO_TAG_WIDTH = 320;
+const VIDEO_TAG_HEIGHT = 240;
+
+// Number of test events to occur before the test pass. When the test pass,
+// the function gAllEventsOccured is called.
+var gNumberOfExpectedEvents = 0;
+
+// Number of events that currently have occurred.
+var gNumberOfEvents = 0;
+
+var gAllEventsOccured = function () {};
+
+// Use this function to set a function that will be called once all expected
+// events has occurred.
+function setAllEventsOccuredHandler(handler) {
+ gAllEventsOccured = handler;
+}
+
+function detectVideoIn(videoElementName, callback) {
+ var width = VIDEO_TAG_WIDTH;
+ var height = VIDEO_TAG_HEIGHT;
+ var videoElement = $(videoElementName);
+ var canvas = $(videoElementName + '-canvas');
+ var waitVideo = setInterval(function() {
+ var context = canvas.getContext('2d');
+ context.drawImage(videoElement, 0, 0, width, height);
+ var pixels = context.getImageData(0, 0, width, height).data;
+
+ if (isVideoPlaying(pixels, width, height)) {
+ clearInterval(waitVideo);
+ callback();
+ }
+ }, 100);
+}
+
+function waitForVideo(videoElement) {
+ document.title = 'Waiting for video...';
+ addExpectedEvent();
+ detectVideoIn(videoElement, function () { eventOccured(); });
+}
+
+function addExpectedEvent() {
+ ++gNumberOfExpectedEvents;
+}
+
+function eventOccured() {
+ ++gNumberOfEvents;
+ if (gNumberOfEvents == gNumberOfExpectedEvents) {
+ gAllEventsOccured();
+ }
+}
+
+// This very basic video verification algorithm will be satisfied if any
+// pixels are nonzero in a small sample area in the middle. It relies on the
+// assumption that a video element with null source just presents zeroes.
+function isVideoPlaying(pixels, width, height) {
+ // Sample somewhere near the middle of the image.
+ var middle = width * height / 2;
+ for (var i = 0; i < 20; i++) {
+ if (pixels[middle + i] > 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// This function matches |left| and |right| and throws an exception if the
+// values don't match.
+function expectEquals(left, right) {
+ if (left != right) {
+ var s = "expectEquals failed left: " + left + " right: " + right;
+ document.title = s;
+ throw s;
+ }
+}
\ No newline at end of file
diff --git a/content/test/data/rwh_simple.html b/content/test/data/rwh_simple.html
new file mode 100644
index 0000000..940fee6
--- /dev/null
+++ b/content/test/data/rwh_simple.html
@@ -0,0 +1,4 @@
+<html>
+<head><title>The background is red.</title></head>
+<body style="background-color:#FF0000"></body>
+</html>
diff --git a/content/test/data/touch_selection.html b/content/test/data/touch_selection.html
new file mode 100644
index 0000000..0c4721a
--- /dev/null
+++ b/content/test/data/touch_selection.html
@@ -0,0 +1,35 @@
+<html>
+<div id='textDiv'>Some text we can select</div>
+<input id='textfield' type="text" value="Text in a textfield">
+<script>
+
+function select_all_text() {
+ var div = document.getElementById("textDiv");
+ var range = document.createRange();
+ range.selectNodeContents(div);
+ var sel = window.getSelection();
+ sel.removeAllRanges();
+ sel.addRange(range);
+}
+
+function get_selection() {
+ return (window.getSelection() + "");
+}
+
+function focus_textfield() {
+ document.getElementById("textfield").focus();
+}
+
+function get_cursor_position() {
+ var div = document.getElementById("textfield");
+ var start = div.selectionStart;
+ var end = div.selectionEnd;
+ if (start == end)
+ return start;
+ else
+ return -1;
+}
+
+</script>
+
+</html>
diff --git a/content/test/gpu/OWNERS b/content/test/gpu/OWNERS
index 5b3dc2a..eea0460 100644
--- a/content/test/gpu/OWNERS
+++ b/content/test/gpu/OWNERS
@@ -1,3 +1,3 @@
kbr@chromium.org
zmo@chromium.org
-jbates@chromium.org
+apatrick@chromium.org
diff --git a/content/test/gpu/gpu_test_config_unittest.cc b/content/test/gpu/gpu_test_config_unittest.cc
index f58139f..a87d215 100644
--- a/content/test/gpu/gpu_test_config_unittest.cc
+++ b/content/test/gpu/gpu_test_config_unittest.cc
@@ -148,7 +148,7 @@
config.set_gpu_device_id(0x0640);
EXPECT_TRUE(config.IsValid());
- EXPECT_TRUE(config.Matches(""));
+ EXPECT_TRUE(config.Matches(std::string()));
// os matching
EXPECT_TRUE(config.Matches("WIN"));
diff --git a/content/test/gpu/gpu_tests/bootstrap_deps b/content/test/gpu/gpu_tests/bootstrap_deps
index c56d53b..2e683cb 100644
--- a/content/test/gpu/gpu_tests/bootstrap_deps
+++ b/content/test/gpu/gpu_tests/bootstrap_deps
@@ -12,6 +12,8 @@
"https://src.chromium.org/chrome/trunk/src/content/test/gpu/gpu_tests",
"src/content/test/gpu/page_sets":
"https://src.chromium.org/chrome/trunk/src/content/test/gpu/page_sets",
+ "src/third_party/webgl_conformance":
+ "https://src.chromium.org/chrome/trunk/deps/third_party/webgl/sdk/tests",
}
# gpu_tests depends on Telemetry, so pull in the Telemetry deps, too.
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_test.py b/content/test/gpu/gpu_tests/webgl_conformance_test.py
new file mode 100644
index 0000000..cbc5609
--- /dev/null
+++ b/content/test/gpu/gpu_tests/webgl_conformance_test.py
@@ -0,0 +1,126 @@
+# 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.
+import os
+import sys
+import json
+
+from telemetry.page import page_set
+from telemetry.page import page_test
+from telemetry.core import util
+
+src_path = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..')
+conformance_path = os.path.join(src_path, 'third_party', 'webgl_conformance')
+
+conformance_harness_script = r"""
+ var testHarness = {};
+ testHarness._allTestSucceeded = true;
+ testHarness._messages = '';
+ testHarness._failures = 0;
+ testHarness._finished = false;
+
+ testHarness.reportResults = function(success, msg) {
+ testHarness._allTestSucceeded = testHarness._allTestSucceeded && !!success;
+ if(!success) {
+ testHarness._failures++;
+ if(msg) {
+ testHarness._messages += msg + "\n";
+ }
+ }
+ };
+ testHarness.notifyFinished = function() {
+ testHarness._finished = true;
+ };
+ testHarness.navigateToPage = function(src) {
+ var testFrame = document.getElementById("test-frame");
+ testFrame.src = src;
+ };
+
+ window.webglTestHarness = testHarness;
+ window.parent.webglTestHarness = testHarness;
+ console.log("Harness injected.");
+"""
+
+def _DidWebGLTestSucceed(tab):
+ return tab.EvaluateJavaScript('webglTestHarness._allTestSucceeded')
+
+def _WebGLTestMessages(tab):
+ return tab.EvaluateJavaScript('webglTestHarness._messages')
+
+class WebGLConformanceTest(page_test.PageTest):
+ def __init__(self):
+ super(WebGLConformanceTest, self).__init__('ValidatePage')
+
+ def CreatePageSet(self, options):
+ tests = WebGLConformanceTest._ParseTests('00_test_list.txt')
+
+ page_set_dict = {
+ 'description': 'Executes WebGL conformance tests',
+ 'user_agent_type': 'desktop',
+ 'serving_dirs': [
+ '../../../../third_party/webgl_conformance'
+ ],
+ 'pages': []
+ }
+
+ pages = page_set_dict['pages']
+
+ for test in tests:
+ pages.append({
+ 'url': 'file:///../../../../third_party/webgl_conformance/' + test,
+ 'script_to_evaluate_on_commit': conformance_harness_script,
+ 'wait_for_javascript_expression': 'webglTestHarness._finished'
+ })
+
+ return page_set.PageSet.FromDict(page_set_dict, __file__)
+
+ def ValidatePage(self, page, tab, results):
+ if _DidWebGLTestSucceed(tab):
+ results.AddSuccess(page)
+ else:
+ results.AddFailure(page, _WebGLTestMessages(tab), None)
+
+ @staticmethod
+ def _ParseTests(path, version = None):
+ test_paths = []
+ current_dir = os.path.dirname(path)
+ full_path = os.path.normpath(os.path.join(conformance_path, path))
+
+ if not os.path.exists(full_path):
+ raise Exception('The WebGL conformance test path specified ' +
+ 'does not exist: ' + full_path)
+
+ with open(full_path, 'r') as f:
+ for line in f:
+ line = line.strip()
+
+ if not line:
+ continue
+
+ if line.startswith('//') or line.startswith('#'):
+ continue
+
+ line_tokens = line.split(' ')
+
+ i = 0
+ while i < len(line_tokens):
+ token = line_tokens[i]
+ if token == '--min-version':
+ i += 1
+ min_version = line_tokens[i]
+ i += 1
+
+ if version and version < min_version:
+ continue
+
+ test_name = line_tokens[-1]
+
+ if '.txt' in test_name:
+ include_path = os.path.join(current_dir, test_name)
+ test_paths += WebGLConformanceTest._ParseTests(
+ include_path, version)
+ else:
+ test = os.path.join(current_dir, test_name)
+ test_paths.append(test)
+
+ return test_paths
diff --git a/content/test/layout_browsertest.cc b/content/test/layout_browsertest.cc
index 4c34a38..3425ac6 100644
--- a/content/test/layout_browsertest.cc
+++ b/content/test/layout_browsertest.cc
@@ -73,7 +73,7 @@
}
InProcessBrowserLayoutTest::~InProcessBrowserLayoutTest() {
- if (test_http_server_.get())
+ if (test_http_server_)
CHECK(test_http_server_->Stop());
}
@@ -155,8 +155,8 @@
test_controller_->set_printer(printer.release());
LOG(INFO) << "Navigating to URL " << url << " and blocking.";
- ASSERT_TRUE(
- test_controller_->PrepareForLayoutTest(url, layout_test_dir_, false, ""));
+ ASSERT_TRUE(test_controller_->PrepareForLayoutTest(
+ url, layout_test_dir_, false, std::string()));
base::RunLoop run_loop;
run_loop.Run();
LOG(INFO) << "Navigation completed.";
@@ -195,9 +195,10 @@
std::string InProcessBrowserLayoutTest::SaveResults(const std::string& expected,
const std::string& actual) {
base::FilePath cwd;
- EXPECT_TRUE(file_util::CreateNewTempDirectory(FILE_PATH_LITERAL(""), &cwd));
- base::FilePath expected_filename = cwd.Append(
- FILE_PATH_LITERAL("expected.txt"));
+ EXPECT_TRUE(file_util::CreateNewTempDirectory(
+ base::FilePath::StringType(), &cwd));
+ base::FilePath expected_filename =
+ cwd.Append(FILE_PATH_LITERAL("expected.txt"));
base::FilePath actual_filename = cwd.Append(FILE_PATH_LITERAL("actual.txt"));
EXPECT_NE(-1, file_util::WriteFile(expected_filename,
expected.c_str(),
diff --git a/content/test/layout_test_http_server.cc b/content/test/layout_test_http_server.cc
index 23c972a..a9ba553 100644
--- a/content/test/layout_test_http_server.cc
+++ b/content/test/layout_test_http_server.cc
@@ -32,7 +32,7 @@
script_path = script_path.AppendASCII("WebKit");
script_path = script_path.AppendASCII("Tools");
script_path = script_path.AppendASCII("Scripts");
- script_path = script_path.AppendASCII("new-run-webkit-httpd");
+ script_path = script_path.AppendASCII("run-blink-httpd");
cmd_line->AppendArgPath(script_path);
return true;
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc
index efa333a..bd85a4f 100644
--- a/content/test/layouttest_support.cc
+++ b/content/test/layouttest_support.cc
@@ -15,6 +15,10 @@
#include "third_party/WebKit/Source/Platform/chromium/public/WebGamepads.h"
#include "third_party/WebKit/Tools/DumpRenderTree/chromium/TestRunner/public/WebTestProxy.h"
+#if defined(OS_WIN) && !defined(USE_AURA)
+#include "content/browser/web_contents/web_contents_drag_win.h"
+#endif
+
using WebKit::WebGamepads;
using WebTestRunner::WebTestProxy;
using WebTestRunner::WebTestProxyBase;
@@ -100,4 +104,10 @@
->SetDeviceScaleFactorForTesting(factor);
}
+void DisableSystemDragDrop() {
+#if defined(OS_WIN) && !defined(USE_AURA)
+ WebContentsDragWin::DisableDragDropForTesting();
+#endif
+}
+
} // namespace content
diff --git a/content/test/net/url_request_abort_on_end_job.cc b/content/test/net/url_request_abort_on_end_job.cc
index 4d49145..2173887 100644
--- a/content/test/net/url_request_abort_on_end_job.cc
+++ b/content/test/net/url_request_abort_on_end_job.cc
@@ -70,7 +70,7 @@
net::URLRequest* request, net::NetworkDelegate* network_delegate)
: URLRequestJob(request, network_delegate),
sent_data_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ weak_factory_(this) {
}
URLRequestAbortOnEndJob::~URLRequestAbortOnEndJob() {
@@ -91,7 +91,7 @@
}
void URLRequestAbortOnEndJob::Start() {
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&URLRequestAbortOnEndJob::StartAsync,
weak_factory_.GetWeakPtr()));
diff --git a/content/test/net/url_request_failed_job.cc b/content/test/net/url_request_failed_job.cc
index 79df121..dfeac52 100644
--- a/content/test/net/url_request_failed_job.cc
+++ b/content/test/net/url_request_failed_job.cc
@@ -46,15 +46,14 @@
int net_error)
: net::URLRequestJob(request, network_delegate),
net_error_(net_error),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {}
+ weak_factory_(this) {}
URLRequestFailedJob::~URLRequestFailedJob() {}
void URLRequestFailedJob::Start() {
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&URLRequestFailedJob::StartAsync,
- weak_factory_.GetWeakPtr()));
+ base::Bind(&URLRequestFailedJob::StartAsync, weak_factory_.GetWeakPtr()));
}
// static
diff --git a/content/test/net/url_request_prepackaged_interceptor.cc b/content/test/net/url_request_prepackaged_interceptor.cc
index f8603ef..9150a7e 100644
--- a/content/test/net/url_request_prepackaged_interceptor.cc
+++ b/content/test/net/url_request_prepackaged_interceptor.cc
@@ -38,23 +38,26 @@
class URLRequestPrepackagedInterceptor::Delegate
: public net::URLRequestJobFactory::ProtocolHandler {
public:
- Delegate() : hit_count_(0) {}
+ Delegate(const std::string& scheme, const std::string& hostname)
+ : scheme_(scheme), hostname_(hostname), hit_count_(0) {}
virtual ~Delegate() {}
void Register() {
net::URLRequestFilter::GetInstance()->AddHostnameProtocolHandler(
- "http", "localhost",
+ scheme_, hostname_,
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(this));
}
- static void Unregister() {
- net::URLRequestFilter::GetInstance()->RemoveHostnameHandler("http",
- "localhost");
+ static void Unregister(
+ const std::string& scheme,
+ const std::string& hostname) {
+ net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(scheme,
+ hostname);
}
// When requests for |url| arrive, respond with the contents of |path|. The
- // hostname of |url| must be "localhost" to avoid DNS lookups, and the scheme
- // must be "http".
+ // hostname and scheme of |url| must match the corresponding parameters
+ // passed as constructor arguments.
void SetResponse(const GURL& url,
const base::FilePath& path,
bool ignore_query) {
@@ -84,8 +87,8 @@
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const OVERRIDE {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (request->url().scheme() != "http" ||
- request->url().host() != "localhost") {
+ if (request->url().scheme() != scheme_ ||
+ request->url().host() != hostname_) {
return NULL;
}
@@ -112,6 +115,9 @@
it->second);
}
+ const std::string scheme_;
+ const std::string hostname_;
+
ResponseMap responses_;
ResponseMap ignore_query_responses_;
@@ -122,8 +128,12 @@
};
-URLRequestPrepackagedInterceptor::URLRequestPrepackagedInterceptor()
- : delegate_(new Delegate) {
+URLRequestPrepackagedInterceptor::URLRequestPrepackagedInterceptor(
+ const std::string& scheme,
+ const std::string& hostname)
+ : scheme_(scheme),
+ hostname_(hostname),
+ delegate_(new Delegate(scheme, hostname)) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&Delegate::Register,
base::Unretained(delegate_)));
@@ -131,13 +141,16 @@
URLRequestPrepackagedInterceptor::~URLRequestPrepackagedInterceptor() {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::Bind(&Delegate::Unregister));
+ base::Bind(&Delegate::Unregister,
+ scheme_,
+ hostname_));
}
-void URLRequestPrepackagedInterceptor::SetResponse(const GURL& url,
- const base::FilePath& path) {
- CHECK_EQ("http", url.scheme());
- CHECK_EQ("localhost", url.host());
+void URLRequestPrepackagedInterceptor::SetResponse(
+ const GURL& url,
+ const base::FilePath& path) {
+ CHECK_EQ(scheme_, url.scheme());
+ CHECK_EQ(hostname_, url.host());
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&Delegate::SetResponse,
base::Unretained(delegate_), url, path,
@@ -147,8 +160,8 @@
void URLRequestPrepackagedInterceptor::SetResponseIgnoreQuery(
const GURL& url,
const base::FilePath& path) {
- CHECK_EQ("http", url.scheme());
- CHECK_EQ("localhost", url.host());
+ CHECK_EQ(scheme_, url.scheme());
+ CHECK_EQ(hostname_, url.host());
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&Delegate::SetResponse,
base::Unretained(delegate_), url, path,
@@ -159,4 +172,10 @@
return delegate_->GetHitCount();
}
+
+URLLocalHostRequestPrepackagedInterceptor
+ ::URLLocalHostRequestPrepackagedInterceptor()
+ : URLRequestPrepackagedInterceptor("http", "localhost") {
+}
+
} // namespace content
diff --git a/content/test/net/url_request_prepackaged_interceptor.h b/content/test/net/url_request_prepackaged_interceptor.h
index edb65c5..cc5736d 100644
--- a/content/test/net/url_request_prepackaged_interceptor.h
+++ b/content/test/net/url_request_prepackaged_interceptor.h
@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_UPDATER_INTERCEPTOR_H_
#define CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_UPDATER_INTERCEPTOR_H_
+#include <string>
+
#include "base/basictypes.h"
class GURL;
@@ -20,12 +22,15 @@
// occurs while the URLRequestPrepackagedInterceptor is alive.
class URLRequestPrepackagedInterceptor {
public:
- URLRequestPrepackagedInterceptor();
+ // Registers an interceptor for urls using |scheme| and |hostname|. Urls
+ // passed to "SetResponse" are required to use |scheme| and |hostname|.
+ URLRequestPrepackagedInterceptor(const std::string& scheme,
+ const std::string& hostname);
virtual ~URLRequestPrepackagedInterceptor();
// When requests for |url| arrive, respond with the contents of |path|. The
- // hostname of |url| must be "localhost" to avoid DNS lookups, and the scheme
- // must be "http".
+ // hostname and scheme of |url| must match the corresponding parameters
+ // passed as constructor arguments.
void SetResponse(const GURL& url, const base::FilePath& path);
// Identical to SetResponse except that query parameters are ignored on
@@ -38,6 +43,9 @@
private:
class Delegate;
+ const std::string scheme_;
+ const std::string hostname_;
+
// After creation, |delegate_| lives on the IO thread, and a task to delete
// it is posted from ~URLRequestPrepackagedInterceptor().
Delegate* delegate_;
@@ -45,6 +53,17 @@
DISALLOW_COPY_AND_ASSIGN(URLRequestPrepackagedInterceptor);
};
+// Specialization of URLRequestPrepackagedInterceptor where scheme is "http" and
+// hostname is "localhost".
+class URLLocalHostRequestPrepackagedInterceptor
+ : public URLRequestPrepackagedInterceptor {
+ public:
+ URLLocalHostRequestPrepackagedInterceptor();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(URLLocalHostRequestPrepackagedInterceptor);
+};
+
} // namespace content
#endif // CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_UPDATER_INTERCEPTOR_H_
diff --git a/content/test/net/url_request_slow_download_job.cc b/content/test/net/url_request_slow_download_job.cc
index 62e3829..7b46136 100644
--- a/content/test/net/url_request_slow_download_job.cc
+++ b/content/test/net/url_request_slow_download_job.cc
@@ -37,7 +37,7 @@
URLRequestSlowDownloadJob::pending_requests_ = LAZY_INSTANCE_INITIALIZER;
void URLRequestSlowDownloadJob::Start() {
- MessageLoop::current()->PostTask(
+ base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&URLRequestSlowDownloadJob::StartAsync,
weak_factory_.GetWeakPtr()));
@@ -102,7 +102,7 @@
should_error_download_(false),
should_finish_download_(false),
buffer_size_(0),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+ weak_factory_(this) {
}
void URLRequestSlowDownloadJob::StartAsync() {
@@ -186,7 +186,7 @@
buffer_ = buf;
buffer_size_ = buf_size;
SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&URLRequestSlowDownloadJob::CheckDoneStatus,
weak_factory_.GetWeakPtr()),
@@ -215,7 +215,7 @@
NotifyDone(net::URLRequestStatus(
net::URLRequestStatus::FAILED, net::ERR_CONNECTION_RESET));
} else {
- MessageLoop::current()->PostDelayedTask(
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&URLRequestSlowDownloadJob::CheckDoneStatus,
weak_factory_.GetWeakPtr()),
diff --git a/content/test/test_content_client.cc b/content/test/test_content_client.cc
index fa09e9f..abd1aea 100644
--- a/content/test/test_content_client.cc
+++ b/content/test/test_content_client.cc
@@ -8,7 +8,7 @@
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/path_service.h"
-#include "base/string_piece.h"
+#include "base/strings/string_piece.h"
namespace content {
diff --git a/content/test/test_web_contents.cc b/content/test/test_web_contents.cc
index 678aa1f..a51be65 100644
--- a/content/test/test_web_contents.cc
+++ b/content/test/test_web_contents.cc
@@ -88,7 +88,7 @@
DidNavigate(render_view_host, params);
}
-webkit_glue::WebPreferences TestWebContents::TestGetWebkitPrefs() {
+WebPreferences TestWebContents::TestGetWebkitPrefs() {
return GetWebkitPrefs();
}
diff --git a/content/test/test_web_contents.h b/content/test/test_web_contents.h
index 644c45d..569edb9 100644
--- a/content/test/test_web_contents.h
+++ b/content/test/test_web_contents.h
@@ -42,7 +42,7 @@
const GURL& url,
const Referrer& referrer,
PageTransition transition) OVERRIDE;
- virtual webkit_glue::WebPreferences TestGetWebkitPrefs() OVERRIDE;
+ virtual WebPreferences TestGetWebkitPrefs() OVERRIDE;
TestRenderViewHost* pending_test_rvh() const;
diff --git a/content/test/webrtc_audio_device_test.cc b/content/test/webrtc_audio_device_test.cc
index 1ebcce9..7bd5b30 100644
--- a/content/test/webrtc_audio_device_test.cc
+++ b/content/test/webrtc_audio_device_test.cc
@@ -43,11 +43,6 @@
#include "base/win/scoped_com_initializer.h"
#endif
-#if defined(OS_ANDROID)
-#include "base/android/jni_android.h"
-#include "media/audio/audio_manager_base.h"
-#endif
-
using media::AudioParameters;
using media::ChannelLayout;
using testing::_;
@@ -87,12 +82,11 @@
class ReplaceContentClientRenderer {
public:
explicit ReplaceContentClientRenderer(ContentRendererClient* new_renderer) {
- saved_renderer_ = GetContentClient()->renderer();
- GetContentClient()->set_renderer_for_testing(new_renderer);
+ saved_renderer_ = SetRendererClientForTesting(new_renderer);
}
~ReplaceContentClientRenderer() {
// Restore the original renderer.
- GetContentClient()->set_renderer_for_testing(saved_renderer_);
+ SetRendererClientForTesting(saved_renderer_);
}
private:
ContentRendererClient* saved_renderer_;
@@ -123,7 +117,7 @@
};
ACTION_P(QuitMessageLoop, loop_or_proxy) {
- loop_or_proxy->PostTask(FROM_HERE, MessageLoop::QuitClosure());
+ loop_or_proxy->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
}
WebRTCAudioDeviceTest::WebRTCAudioDeviceTest()
@@ -134,11 +128,6 @@
WebRTCAudioDeviceTest::~WebRTCAudioDeviceTest() {}
void WebRTCAudioDeviceTest::SetUp() {
-#if defined(OS_ANDROID)
- media::AudioManagerBase::RegisterAudioManager(
- base::android::AttachCurrentThread());
-#endif
-
// This part sets up a RenderThread environment to ensure that
// RenderThread::current() (<=> TLS pointer) is valid.
// Main parts are inspired by the RenderViewFakeResourcesTest.
@@ -146,8 +135,8 @@
saved_content_renderer_.reset(
new ReplaceContentClientRenderer(&content_renderer_client_));
mock_process_.reset(new WebRTCMockRenderProcess());
- ui_thread_.reset(new TestBrowserThread(BrowserThread::UI,
- MessageLoop::current()));
+ ui_thread_.reset(
+ new TestBrowserThread(BrowserThread::UI, base::MessageLoop::current()));
// Construct the resource context on the UI thread.
resource_context_.reset(new MockRTCResourceContext);
@@ -213,8 +202,8 @@
#endif
// Set the current thread as the IO thread.
- io_thread_.reset(new TestBrowserThread(BrowserThread::IO,
- MessageLoop::current()));
+ io_thread_.reset(
+ new TestBrowserThread(BrowserThread::IO, base::MessageLoop::current()));
// Populate our resource context.
test_request_context_.reset(new net::TestURLRequestContext());
@@ -296,13 +285,13 @@
return true;
}
- if (audio_render_host_.get()) {
+ if (audio_render_host_) {
bool message_was_ok = false;
if (audio_render_host_->OnMessageReceived(message, &message_was_ok))
return true;
}
- if (audio_input_renderer_host_.get()) {
+ if (audio_input_renderer_host_) {
bool message_was_ok = false;
if (audio_input_renderer_host_->OnMessageReceived(message, &message_was_ok))
return true;
@@ -328,7 +317,7 @@
}
void WebRTCAudioDeviceTest::WaitForAudioManagerCompletion() {
- if (audio_manager_.get())
+ if (audio_manager_)
WaitForMessageLoopCompletion(audio_manager_->GetMessageLoop());
}
diff --git a/content/test/webrtc_audio_device_test.h b/content/test/webrtc_audio_device_test.h
index ed9760d..f15e3bb 100644
--- a/content/test/webrtc_audio_device_test.h
+++ b/content/test/webrtc_audio_device_test.h
@@ -151,7 +151,7 @@
std::string GetTestDataPath(const base::FilePath::StringType& file_name);
scoped_ptr<ReplaceContentClientRenderer> saved_content_renderer_;
- MessageLoopForUI message_loop_;
+ base::MessageLoopForUI message_loop_;
ContentRendererClient content_renderer_client_;
RenderThreadImpl* render_thread_; // Owned by mock_process_.
scoped_ptr<WebRTCMockRenderProcess> mock_process_;
diff --git a/content/utility/utility_main.cc b/content/utility/utility_main.cc
index 549af2c..04f7714 100644
--- a/content/utility/utility_main.cc
+++ b/content/utility/utility_main.cc
@@ -5,9 +5,10 @@
#include "base/command_line.h"
#include "base/hi_res_timer_manager.h"
#include "base/message_loop.h"
-#include "base/system_monitor/system_monitor.h"
+#include "base/power_monitor/power_monitor.h"
#include "base/threading/platform_thread.h"
#include "content/common/child_process.h"
+#include "content/common/sandbox_linux.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "content/public/common/sandbox_init.h"
@@ -22,15 +23,15 @@
// Mainline routine for running as the utility process.
int UtilityMain(const MainFunctionParams& parameters) {
// The main message loop of the utility process.
- MessageLoop main_message_loop;
+ base::MessageLoop main_message_loop;
base::PlatformThread::SetName("CrUtilityMain");
- base::SystemMonitor system_monitor;
+ base::PowerMonitor power_monitor;
HighResolutionTimerManager hi_res_timer_manager;
#if defined(OS_LINUX)
// Initialize the sandbox before any thread is created.
- InitializeSandbox();
+ LinuxSandbox::InitializeSandbox();
#endif
ChildProcess utility_process;
@@ -47,7 +48,7 @@
}
#endif
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
return 0;
}
diff --git a/content/utility/utility_thread_impl.cc b/content/utility/utility_thread_impl.cc
index 4febffa..eed1704 100644
--- a/content/utility/utility_thread_impl.cc
+++ b/content/utility/utility_thread_impl.cc
@@ -45,6 +45,9 @@
}
UtilityThreadImpl::~UtilityThreadImpl() {
+}
+
+void UtilityThreadImpl::Shutdown() {
WebKit::shutdown();
}
diff --git a/content/utility/utility_thread_impl.h b/content/utility/utility_thread_impl.h
index da2ffbd..31c51a1 100644
--- a/content/utility/utility_thread_impl.h
+++ b/content/utility/utility_thread_impl.h
@@ -27,6 +27,7 @@
public:
UtilityThreadImpl();
virtual ~UtilityThreadImpl();
+ virtual void Shutdown() OVERRIDE;
virtual bool Send(IPC::Message* msg) OVERRIDE;
virtual void ReleaseProcessIfNeeded() OVERRIDE;
diff --git a/content/worker/websharedworker_stub.cc b/content/worker/websharedworker_stub.cc
index f51487f..39986cc 100644
--- a/content/worker/websharedworker_stub.cc
+++ b/content/worker/websharedworker_stub.cc
@@ -23,7 +23,7 @@
const WorkerAppCacheInitInfo& appcache_init_info)
: route_id_(route_id),
appcache_init_info_(appcache_init_info),
- ALLOW_THIS_IN_INITIALIZER_LIST(client_(route_id, this)),
+ client_(route_id, this),
name_(name),
started_(false),
worker_devtools_agent_(NULL) {
diff --git a/content/worker/websharedworkerclient_proxy.cc b/content/worker/websharedworkerclient_proxy.cc
index 049361e..4db74b8 100644
--- a/content/worker/websharedworkerclient_proxy.cc
+++ b/content/worker/websharedworkerclient_proxy.cc
@@ -44,7 +44,7 @@
: route_id_(route_id),
appcache_host_id_(0),
stub_(stub),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+ weak_factory_(this),
devtools_agent_(NULL) {
}
@@ -207,10 +207,10 @@
// process, and avoids the crashed worker infobar from appearing to the new
// page. It's ok to post several of theese, because the first executed task
// will exit the message loop and subsequent ones won't be executed.
- MessageLoop::current()->PostDelayedTask(FROM_HERE,
- base::Bind(
- &WebSharedWorkerClientProxy::workerContextDestroyed,
- weak_factory_.GetWeakPtr()),
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&WebSharedWorkerClientProxy::workerContextDestroyed,
+ weak_factory_.GetWeakPtr()),
base::TimeDelta::FromSeconds(kMaxTimeForRunawayWorkerSeconds));
}
diff --git a/content/worker/worker_main.cc b/content/worker/worker_main.cc
index 192cc57..459e907 100644
--- a/content/worker/worker_main.cc
+++ b/content/worker/worker_main.cc
@@ -6,10 +6,11 @@
#include "base/command_line.h"
#include "base/hi_res_timer_manager.h"
#include "base/message_loop.h"
+#include "base/power_monitor/power_monitor.h"
#include "base/string_util.h"
-#include "base/system_monitor/system_monitor.h"
#include "base/threading/platform_thread.h"
#include "content/common/child_process.h"
+#include "content/common/sandbox_linux.h"
#include "content/public/common/main_function_params.h"
#include "content/public/common/sandbox_init.h"
#include "content/worker/worker_thread.h"
@@ -27,10 +28,10 @@
// Mainline routine for running as the worker process.
int WorkerMain(const MainFunctionParams& parameters) {
// The main message loop of the worker process.
- MessageLoop main_message_loop;
+ base::MessageLoop main_message_loop;
base::PlatformThread::SetName("CrWorkerMain");
- base::SystemMonitor system_monitor;
+ base::PowerMonitor power_monitor;
HighResolutionTimerManager hi_res_timer_manager;
#if defined(OS_WIN)
@@ -53,7 +54,7 @@
#elif defined(OS_LINUX)
// On Linux, the sandbox must be initialized early, before any thread is
// created.
- InitializeSandbox();
+ LinuxSandbox::InitializeSandbox();
#endif
ChildProcess worker_process;
@@ -66,7 +67,7 @@
// Load the accelerator table from the browser executable and tell the
// message loop to use it when translating messages.
- MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
return 0;
}
diff --git a/content/worker/worker_thread.cc b/content/worker/worker_thread.cc
index e7cc319..a88f615 100644
--- a/content/worker/worker_thread.cc
+++ b/content/worker/worker_thread.cc
@@ -18,7 +18,6 @@
#include "ipc/ipc_sync_channel.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebBlobRegistry.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDatabase.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBFactory.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebRuntimeFeatures.h"
#include "webkit/glue/webkit_glue.h"
@@ -66,9 +65,6 @@
!command_line.HasSwitch(switches::kDisableDesktopNotifications));
#endif
- WebRuntimeFeatures::enableSockets(
- !command_line.HasSwitch(switches::kDisableWebSockets));
-
WebRuntimeFeatures::enableFileSystem(
!command_line.HasSwitch(switches::kDisableFileSystem));
@@ -76,6 +72,9 @@
}
WorkerThread::~WorkerThread() {
+}
+
+void WorkerThread::Shutdown() {
// Shutdown in reverse of the initialization order.
channel()->RemoveFilter(indexed_db_message_filter_.get());
indexed_db_message_filter_ = NULL;
diff --git a/content/worker/worker_thread.h b/content/worker/worker_thread.h
index aaa78a3..bc51f49 100644
--- a/content/worker/worker_thread.h
+++ b/content/worker/worker_thread.h
@@ -23,6 +23,7 @@
public:
WorkerThread();
virtual ~WorkerThread();
+ virtual void Shutdown() OVERRIDE;
// Returns the one worker thread.
static WorkerThread* current();
diff --git a/content/worker/worker_webkitplatformsupport_impl.cc b/content/worker/worker_webkitplatformsupport_impl.cc
index b81990d..f6a9a20 100644
--- a/content/worker/worker_webkitplatformsupport_impl.cc
+++ b/content/worker/worker_webkitplatformsupport_impl.cc
@@ -89,13 +89,13 @@
}
WebFileSystem* WorkerWebKitPlatformSupportImpl::fileSystem() {
- if (!web_file_system_.get())
+ if (!web_file_system_)
web_file_system_.reset(new WebFileSystemImpl());
return web_file_system_.get();
}
WebFileUtilities* WorkerWebKitPlatformSupportImpl::fileUtilities() {
- if (!file_utilities_.get()) {
+ if (!file_utilities_) {
file_utilities_.reset(new FileUtilities(thread_safe_sender_));
file_utilities_->set_sandbox_enabled(sandboxEnabled());
}
@@ -195,7 +195,7 @@
}
WebKit::WebIDBFactory* WorkerWebKitPlatformSupportImpl::idbFactory() {
- if (!web_idb_factory_.get())
+ if (!web_idb_factory_)
web_idb_factory_.reset(new RendererWebIDBFactoryImpl());
return web_idb_factory_.get();
}
@@ -282,7 +282,7 @@
}
WebBlobRegistry* WorkerWebKitPlatformSupportImpl::blobRegistry() {
- if (!blob_registry_.get() && thread_safe_sender_.get())
+ if (!blob_registry_.get() && thread_safe_sender_)
blob_registry_.reset(new WebBlobRegistryImpl(thread_safe_sender_));
return blob_registry_.get();
}
diff --git a/content/worker/worker_webkitplatformsupport_impl.h b/content/worker/worker_webkitplatformsupport_impl.h
index 7f95bd7..6274a74 100644
--- a/content/worker/worker_webkitplatformsupport_impl.h
+++ b/content/worker/worker_webkitplatformsupport_impl.h
@@ -7,8 +7,8 @@
#include "base/memory/scoped_ptr.h"
#include "content/common/webkitplatformsupport_impl.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBFactory.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebMimeRegistry.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBFactory.h"
namespace WebKit {
class WebFileUtilities;
diff --git a/content/zygote/zygote_linux.cc b/content/zygote/zygote_linux.cc
index b546e15..5d26a05 100644
--- a/content/zygote/zygote_linux.cc
+++ b/content/zygote/zygote_linux.cc
@@ -67,6 +67,8 @@
} // namespace
+const int Zygote::kMagicSandboxIPCDescriptor;
+
Zygote::Zygote(int sandbox_flags,
ZygoteForkDelegate* helper)
: sandbox_flags_(sandbox_flags),
@@ -434,9 +436,6 @@
if (!child_pid) {
// This is the child process.
- // At this point, we finally know our process type.
- LinuxSandbox::GetInstance()->PreinitializeSandboxFinish(process_type);
-
close(kBrowserDescriptor); // Our socket from the browser.
if (UsingSUIDSandbox())
close(kZygoteIdFd); // Another socket from the browser.
diff --git a/content/zygote/zygote_main.h b/content/zygote/zygote_main.h
new file mode 100644
index 0000000..6470232
--- /dev/null
+++ b/content/zygote/zygote_main.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_ZYGOTE_ZYGOTE_MAIN_H_
+#define CONTENT_ZYGOTE_ZYGOTE_MAIN_H_
+
+namespace content {
+
+struct MainFunctionParams;
+class ZygoteForkDelegate;
+
+bool ZygoteMain(const MainFunctionParams& params,
+ ZygoteForkDelegate* forkdelegate);
+
+} // namespace content
+
+#endif // CONTENT_ZYGOTE_ZYGOTE_MAIN_H_
diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc
index fd4a709..ca75518 100644
--- a/content/zygote/zygote_main_linux.cc
+++ b/content/zygote/zygote_main_linux.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/zygote/zygote_main.h"
+
#include <dlfcn.h>
#include <fcntl.h>
#include <pthread.h>
@@ -38,6 +40,7 @@
#include "sandbox/linux/services/libc_urandom_override.h"
#include "sandbox/linux/suid/client/setuid_sandbox_client.h"
#include "third_party/icu/public/i18n/unicode/timezone.h"
+#include "third_party/libjingle/overrides/init_webrtc.h"
#include "third_party/skia/include/ports/SkFontConfigInterface.h"
#if defined(OS_LINUX)
@@ -279,6 +282,9 @@
// Ensure access to the Pepper plugins before the sandbox is turned on.
PepperPluginRegistry::PreloadModules();
#endif
+#if defined(ENABLE_WEBRTC)
+ InitializeWebRtcModule();
+#endif
}
#if !defined(CHROMIUM_SELINUX)
@@ -439,7 +445,7 @@
PreSandboxInit();
SkFontConfigInterface::SetGlobal(
- new FontConfigIPC(Zygote::kMagicSandboxIPCDescriptor)))->unref();
+ new FontConfigIPC(Zygote::kMagicSandboxIPCDescriptor))->unref();
return true;
}
@@ -454,10 +460,7 @@
LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance();
// This will pre-initialize the various sandboxes that need it.
- // There need to be a corresponding call to PreinitializeSandboxFinish()
- // for each new process, this will be done in the Zygote child, once we know
- // our process type.
- linux_sandbox->PreinitializeSandboxBegin();
+ linux_sandbox->PreinitializeSandbox();
sandbox::SetuidSandboxClient* setuid_sandbox =
linux_sandbox->setuid_sandbox_client();