Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / renderer / pepper / pepper_webplugin_impl_browsertest.cc
blob6dd2e0adb6002a52166fe2b2cc4101fcb334010b
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/command_line.h"
6 #include "content/public/common/content_client.h"
7 #include "content/public/common/content_constants.h"
8 #include "content/public/common/content_switches.h"
9 #include "content/public/common/pepper_plugin_info.h"
10 #include "content/public/renderer/content_renderer_client.h"
11 #include "content/public/test/render_view_test.h"
12 #include "content/renderer/pepper/pepper_webplugin_impl.h"
13 #include "content/renderer/pepper/plugin_instance_throttler_impl.h"
14 #include "content/renderer/pepper/plugin_module.h"
15 #include "content/renderer/pepper/renderer_ppapi_host_impl.h"
16 #include "content/renderer/render_frame_impl.h"
17 #include "content/test/test_content_client.h"
18 #include "ppapi/c/pp_errors.h"
19 #include "ppapi/c/ppb_core.h"
20 #include "ppapi/c/ppb_graphics_2d.h"
21 #include "ppapi/c/ppb_image_data.h"
22 #include "ppapi/c/ppb_instance.h"
23 #include "ppapi/c/ppp_instance.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "third_party/WebKit/public/web/WebLocalFrame.h"
27 namespace content {
28 namespace {
30 class PepperWebPluginImplBrowserTest
31 : public RenderViewTest,
32 public PluginInstanceThrottler::Observer {
33 public:
34 PepperWebPluginImplBrowserTest()
35 : throttler_(nullptr),
36 throttle_engaged_(false),
37 pp_module_(0),
38 pp_instance_(0),
39 graphics2d_(0) {}
41 void SetUp() override {
42 base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
43 command_line.AppendSwitchASCII(
44 switches::kOverridePluginPowerSaverForTesting, "always");
46 current_test_ = this;
47 RenderViewTest::SetUp();
49 void TearDown() override {
50 RenderViewTest::TearDown();
51 current_test_ = nullptr;
53 ContentClient* CreateContentClient() override {
54 return new MockContentClient;
56 ContentRendererClient* CreateContentRendererClient() override {
57 return new MockContentRendererClient;
60 // PluginInstanceThrottler::Observer implementation
61 void OnThrottleStateChange() override {
62 if (throttler_->IsThrottled())
63 throttle_engaged_ = true;
66 protected:
67 // PPP implementation
68 static const void* GetInterface(const char* name) {
69 static PPP_Instance ppp_instance = {
70 &PepperWebPluginImplBrowserTest::DidCreate,
71 &PepperWebPluginImplBrowserTest::DidDestroy,
72 &PepperWebPluginImplBrowserTest::DidChangeView,
73 &PepperWebPluginImplBrowserTest::DidChangeFocus,
74 &PepperWebPluginImplBrowserTest::HandleDocumentLoad};
75 if (!strcmp(name, PPP_INSTANCE_INTERFACE))
76 return &ppp_instance;
77 return nullptr;
79 static int InitializeModule(PP_Module module,
80 PPB_GetInterface get_interface) {
81 EXPECT_EQ(0, current_test_->pp_module_);
82 current_test_->pp_module_ = module;
83 ppb_core_ = static_cast<const PPB_Core*>(get_interface(PPB_CORE_INTERFACE));
84 ppb_graphics2d_ = static_cast<const PPB_Graphics2D*>(
85 get_interface(PPB_GRAPHICS_2D_INTERFACE));
86 ppb_image_data_ = static_cast<const PPB_ImageData*>(
87 get_interface(PPB_IMAGEDATA_INTERFACE));
88 ppb_instance_ =
89 static_cast<const PPB_Instance*>(get_interface(PPB_INSTANCE_INTERFACE));
90 return PP_OK;
92 static void ShutdownModule() {
93 EXPECT_NE(0, current_test_->pp_module_);
94 current_test_->pp_module_ = 0;
97 static void DummyCallback(void*, int32_t) {}
99 void PaintSomething() {
100 PP_Size size = {2, 1};
101 PP_Resource image = ppb_image_data_->Create(
102 pp_instance_, ppb_image_data_->GetNativeImageDataFormat(), &size,
103 PP_TRUE);
104 int32_t* pixels = static_cast<int32_t*>(ppb_image_data_->Map(image));
105 pixels[0] = 0xff000000;
106 pixels[1] = 0xffffffff;
107 ppb_image_data_->Unmap(image);
108 ppb_graphics2d_->ReplaceContents(graphics2d_, image);
109 PP_CompletionCallback callback = {
110 &PepperWebPluginImplBrowserTest::DummyCallback, nullptr, 0};
111 ppb_graphics2d_->Flush(graphics2d_, callback);
112 ppb_core_->ReleaseResource(image);
115 // PPP_Instance implementation
116 static PP_Bool DidCreate(PP_Instance instance,
117 uint32_t,
118 const char* [],
119 const char* []) {
120 EXPECT_EQ(0, current_test_->pp_instance_);
121 current_test_->pp_instance_ = instance;
122 PP_Size size = {2, 1};
123 current_test_->graphics2d_ =
124 ppb_graphics2d_->Create(instance, &size, PP_TRUE);
125 ppb_instance_->BindGraphics(instance, current_test_->graphics2d_);
126 return PP_TRUE;
128 static void DidDestroy(PP_Instance instance) {
129 EXPECT_NE(0, current_test_->pp_instance_);
130 current_test_->PaintSomething();
131 ppb_core_->ReleaseResource(current_test_->graphics2d_);
132 current_test_->pp_instance_ = 0;
134 static void DidChangeView(PP_Instance, PP_Resource) {}
135 static void DidChangeFocus(PP_Instance, PP_Bool) {}
136 static PP_Bool HandleDocumentLoad(PP_Instance, PP_Resource) {
137 return PP_FALSE;
140 static PepperPluginInfo GetPluginInfo() {
141 PepperPluginInfo info;
142 info.is_internal = true;
143 info.path = base::FilePath(FILE_PATH_LITERAL("internal-always-throttle"));
144 info.name = "Always Throttle";
145 info.mime_types.push_back(
146 WebPluginMimeType("test/always-throttle", "", ""));
147 info.internal_entry_points.get_interface =
148 &PepperWebPluginImplBrowserTest::GetInterface;
149 info.internal_entry_points.initialize_module =
150 &PepperWebPluginImplBrowserTest::InitializeModule;
151 info.internal_entry_points.shutdown_module =
152 &PepperWebPluginImplBrowserTest::ShutdownModule;
153 return info;
156 class MockContentClient : public TestContentClient {
157 public:
158 void AddPepperPlugins(std::vector<PepperPluginInfo>* plugins) override {
159 plugins->push_back(GetPluginInfo());
162 class MockContentRendererClient : public ContentRendererClient {
163 public:
164 bool OverrideCreatePlugin(RenderFrame* render_frame,
165 blink::WebLocalFrame* frame,
166 const blink::WebPluginParams& params,
167 blink::WebPlugin** plugin) override {
168 current_test_->throttler_ = new PluginInstanceThrottlerImpl;
169 current_test_->throttler_->AddObserver(current_test_);
170 *plugin = render_frame->CreatePlugin(frame,
171 GetPluginInfo().ToWebPluginInfo(), params,
172 make_scoped_ptr(current_test_->throttler_));
173 return *plugin;
177 PluginInstanceThrottlerImpl* throttler_;
178 bool throttle_engaged_;
179 PP_Module pp_module_;
180 PP_Instance pp_instance_;
181 PP_Resource graphics2d_;
182 static PepperWebPluginImplBrowserTest* current_test_;
183 static const PPB_Core* ppb_core_;
184 static const PPB_Graphics2D* ppb_graphics2d_;
185 static const PPB_ImageData* ppb_image_data_;
186 static const PPB_Instance* ppb_instance_;
188 PepperWebPluginImplBrowserTest* PepperWebPluginImplBrowserTest::current_test_;
189 const PPB_Core* PepperWebPluginImplBrowserTest::ppb_core_;
190 const PPB_Graphics2D* PepperWebPluginImplBrowserTest::ppb_graphics2d_;
191 const PPB_ImageData* PepperWebPluginImplBrowserTest::ppb_image_data_;
192 const PPB_Instance* PepperWebPluginImplBrowserTest::ppb_instance_;
194 // This test simulates the behavior of a plugin that emits new frames during
195 // destruction. The throttler shouldn't engage and create a placeholder for
196 // a to-be destroyed plugin in such case. See crbug.com/483068
197 TEST_F(PepperWebPluginImplBrowserTest, NotEngageThrottleDuringDestroy) {
198 LoadHTML("<!DOCTYPE html><object type='test/always-throttle'></object>");
199 EXPECT_NE(0, pp_instance_);
200 LoadHTML("");
201 EXPECT_EQ(0, pp_instance_);
202 EXPECT_FALSE(throttle_engaged_);
205 } // unnamed namespace
207 } // namespace content