Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 5 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/linked_ptr.h" | 10 #include "base/memory/linked_ptr.h" |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 287 // returned vector are only guaranteed valid so long as the vector of strings | 287 // returned vector are only guaranteed valid so long as the vector of strings |
| 288 // is not modified. | 288 // is not modified. |
| 289 scoped_array<const char*> StringVectorToArgArray( | 289 scoped_array<const char*> StringVectorToArgArray( |
| 290 const std::vector<std::string>& vector) { | 290 const std::vector<std::string>& vector) { |
| 291 scoped_array<const char*> array(new const char*[vector.size()]); | 291 scoped_array<const char*> array(new const char*[vector.size()]); |
| 292 for (size_t i = 0; i < vector.size(); ++i) | 292 for (size_t i = 0; i < vector.size(); ++i) |
| 293 array[i] = vector[i].c_str(); | 293 array[i] = vector[i].c_str(); |
| 294 return array.Pass(); | 294 return array.Pass(); |
| 295 } | 295 } |
| 296 | 296 |
| 297 // Creates a PP_Resource containing a PPB_Buffer_Impl, copies |data| into the | |
| 298 // buffer resource, and returns it. Returns a PP_Resource equal to 0 on | |
| 299 // failure. | |
| 300 PP_Resource MakeBufferResource(PP_Instance instance, | |
| 301 const std::string& data) { | |
| 302 if (data.empty()) | |
| 303 return 0; | |
| 304 | |
| 305 ScopedPPResource resource(PPB_Buffer_Impl::Create(instance, data.size())); | |
| 306 if (!resource.get()) | |
| 307 return 0; | |
| 308 | |
| 309 EnterResourceNoLock<PPB_Buffer_API> enter(resource, true); | |
| 310 if (enter.failed()) | |
| 311 return 0; | |
| 312 | |
| 313 BufferAutoMapper mapper(enter.object()); | |
| 314 if (!mapper.data() || mapper.size() < data.size()) | |
| 315 return 0; | |
| 316 memcpy(mapper.data(), data.data(), data.size()); | |
| 317 | |
| 318 // Add the resource to the tracker... | |
| 319 // TODO(tomfinegan): wild guess/no idea if this is right. | |
| 320 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(resource.get()); | |
| 321 | |
| 322 return resource.Release(); | |
| 323 } | |
| 324 | |
| 297 } // namespace | 325 } // namespace |
| 298 | 326 |
| 299 // static | 327 // static |
| 300 PluginInstance* PluginInstance::Create(PluginDelegate* delegate, | 328 PluginInstance* PluginInstance::Create(PluginDelegate* delegate, |
| 301 PluginModule* module) { | 329 PluginModule* module) { |
| 302 base::Callback<const void*(const char*)> get_plugin_interface_func = | 330 base::Callback<const void*(const char*)> get_plugin_interface_func = |
| 303 base::Bind(&PluginModule::GetPluginInterface, module); | 331 base::Bind(&PluginModule::GetPluginInterface, module); |
| 304 PPP_Instance_Combined* ppp_instance_combined = | 332 PPP_Instance_Combined* ppp_instance_combined = |
| 305 PPP_Instance_Combined::Create(get_plugin_interface_func); | 333 PPP_Instance_Combined::Create(get_plugin_interface_func); |
| 306 if (!ppp_instance_combined) | 334 if (!ppp_instance_combined) |
| 307 return NULL; | 335 return NULL; |
| 308 return new PluginInstance(delegate, module, ppp_instance_combined); | 336 return new PluginInstance(delegate, module, ppp_instance_combined); |
| 309 } | 337 } |
| 310 | 338 |
| 311 PluginInstance::PluginInstance( | 339 PluginInstance::PluginInstance( |
| 312 PluginDelegate* delegate, | 340 PluginDelegate* delegate, |
| 313 PluginModule* module, | 341 PluginModule* module, |
| 314 ::ppapi::PPP_Instance_Combined* instance_interface) | 342 ::ppapi::PPP_Instance_Combined* instance_interface) |
| 315 : delegate_(delegate), | 343 : delegate_(delegate), |
| 316 module_(module), | 344 module_(module), |
| 317 instance_interface_(instance_interface), | 345 instance_interface_(instance_interface), |
| 318 pp_instance_(0), | 346 pp_instance_(0), |
| 319 container_(NULL), | 347 container_(NULL), |
| 320 full_frame_(false), | 348 full_frame_(false), |
| 321 sent_initial_did_change_view_(false), | 349 sent_initial_did_change_view_(false), |
| 322 view_change_weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 350 view_change_weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 323 has_webkit_focus_(false), | 351 has_webkit_focus_(false), |
| 324 has_content_area_focus_(false), | 352 has_content_area_focus_(false), |
| 325 find_identifier_(-1), | 353 find_identifier_(-1), |
| 354 plugin_decryption_interface_(NULL), | |
| 326 plugin_find_interface_(NULL), | 355 plugin_find_interface_(NULL), |
| 327 plugin_input_event_interface_(NULL), | 356 plugin_input_event_interface_(NULL), |
| 328 plugin_messaging_interface_(NULL), | 357 plugin_messaging_interface_(NULL), |
| 329 plugin_mouse_lock_interface_(NULL), | 358 plugin_mouse_lock_interface_(NULL), |
| 330 plugin_pdf_interface_(NULL), | 359 plugin_pdf_interface_(NULL), |
| 331 plugin_private_interface_(NULL), | 360 plugin_private_interface_(NULL), |
| 332 plugin_selection_interface_(NULL), | 361 plugin_selection_interface_(NULL), |
| 333 plugin_textinput_interface_(NULL), | 362 plugin_textinput_interface_(NULL), |
| 334 plugin_zoom_interface_(NULL), | 363 plugin_zoom_interface_(NULL), |
| 335 checked_for_plugin_input_event_interface_(false), | 364 checked_for_plugin_input_event_interface_(false), |
| (...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 952 | 981 |
| 953 void PluginInstance::StopFind() { | 982 void PluginInstance::StopFind() { |
| 954 // Keep a reference on the stack. See NOTE above. | 983 // Keep a reference on the stack. See NOTE above. |
| 955 scoped_refptr<PluginInstance> ref(this); | 984 scoped_refptr<PluginInstance> ref(this); |
| 956 if (!LoadFindInterface()) | 985 if (!LoadFindInterface()) |
| 957 return; | 986 return; |
| 958 find_identifier_ = -1; | 987 find_identifier_ = -1; |
| 959 plugin_find_interface_->StopFind(pp_instance()); | 988 plugin_find_interface_->StopFind(pp_instance()); |
| 960 } | 989 } |
| 961 | 990 |
| 991 bool PluginInstance::LoadContentDecryptionModuleInterface() { | |
| 992 if (!plugin_decryption_interface_) { | |
| 993 plugin_decryption_interface_ = | |
| 994 static_cast<const PPP_ContentDecryptor_Dev*>( | |
| 995 module_->GetPluginInterface( | |
| 996 PPP_CONTENTDECRYPTOR_DEV_INTERFACE)); | |
| 997 } | |
| 998 return !!plugin_decryption_interface_; | |
| 999 } | |
| 1000 | |
| 962 bool PluginInstance::LoadFindInterface() { | 1001 bool PluginInstance::LoadFindInterface() { |
| 963 if (!plugin_find_interface_) { | 1002 if (!plugin_find_interface_) { |
| 964 plugin_find_interface_ = | 1003 plugin_find_interface_ = |
| 965 static_cast<const PPP_Find_Dev*>(module_->GetPluginInterface( | 1004 static_cast<const PPP_Find_Dev*>(module_->GetPluginInterface( |
| 966 PPP_FIND_DEV_INTERFACE)); | 1005 PPP_FIND_DEV_INTERFACE)); |
| 967 } | 1006 } |
| 968 | 1007 |
| 969 return !!plugin_find_interface_; | 1008 return !!plugin_find_interface_; |
| 970 } | 1009 } |
| 971 | 1010 |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1269 if (!LoadPdfInterface()) | 1308 if (!LoadPdfInterface()) |
| 1270 return; | 1309 return; |
| 1271 PP_PrivatePageTransformType transform_type = | 1310 PP_PrivatePageTransformType transform_type = |
| 1272 type == WebPlugin::RotationType90Clockwise ? | 1311 type == WebPlugin::RotationType90Clockwise ? |
| 1273 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CW : | 1312 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CW : |
| 1274 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CCW; | 1313 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CCW; |
| 1275 plugin_pdf_interface_->Transform(pp_instance(), transform_type); | 1314 plugin_pdf_interface_->Transform(pp_instance(), transform_type); |
| 1276 // NOTE: plugin instance may have been deleted. | 1315 // NOTE: plugin instance may have been deleted. |
| 1277 } | 1316 } |
| 1278 | 1317 |
| 1318 bool PluginInstance::GenerateKeyRequest(const std::string& key_system, | |
| 1319 const std::string& init_data) { | |
| 1320 if (!LoadContentDecryptionModuleInterface()) | |
| 1321 return false; | |
| 1322 | |
| 1323 if (key_system.empty()) | |
| 1324 return false; | |
| 1325 | |
| 1326 PP_Resource init_data_resource = 0; | |
| 1327 if (init_data.size()) { | |
| 1328 ScopedPPResource local_init_data(ScopedPPResource::PassRef(), | |
| 1329 MakeBufferResource(pp_instance(), | |
| 1330 init_data)); | |
| 1331 | |
| 1332 if (!local_init_data.get()) | |
| 1333 return false; | |
| 1334 init_data_resource = local_init_data.Release(); | |
| 1335 } | |
| 1336 | |
| 1337 return PP_ToBool(plugin_decryption_interface_->GenerateKeyRequest( | |
| 1338 pp_instance(), | |
| 1339 StringVar::StringToPPVar(key_system), | |
| 1340 init_data_resource)); | |
| 1341 } | |
| 1342 | |
| 1343 bool PluginInstance::AddKey(const std::string& session_id, | |
| 1344 const std::string& key) { | |
| 1345 if (!LoadContentDecryptionModuleInterface()) | |
| 1346 return false; | |
| 1347 | |
| 1348 StringVar session_id_var(session_id); | |
| 1349 if (session_id_var.value().size() < session_id.size()) | |
| 1350 return false; | |
| 1351 | |
| 1352 ScopedPPResource key_resource(ScopedPPResource::PassRef(), | |
| 1353 MakeBufferResource(pp_instance(), key)); | |
| 1354 if (!key_resource.get()) | |
| 1355 return false; | |
| 1356 | |
| 1357 return PP_ToBool(plugin_decryption_interface_->AddKey( | |
| 1358 pp_instance(), | |
| 1359 session_id_var.GetPPVar(), | |
| 1360 key_resource)); | |
| 1361 } | |
| 1362 | |
| 1363 bool PluginInstance::CancelKeyRequest(const std::string& session_id) { | |
| 1364 if (!LoadContentDecryptionModuleInterface()) | |
| 1365 return false; | |
| 1366 StringVar session_id_var(session_id); | |
| 1367 if (session_id_var.value().size() < session_id.size()) | |
| 1368 return false; | |
| 1369 return PP_ToBool(plugin_decryption_interface_->CancelKeyRequest( | |
| 1370 pp_instance(), | |
| 1371 session_id_var.GetPPVar())); | |
| 1372 } | |
| 1373 | |
| 1374 bool PluginInstance::Decrypt(const std::string& encrypted_block, | |
| 1375 const CDMStatusCB& callback) { | |
|
ddorwin
2012/07/28 01:43:26
Isn't this class going to need to take ownership o
| |
| 1376 if (!LoadContentDecryptionModuleInterface()) | |
| 1377 return false; | |
| 1378 ScopedPPResource encrypted_resource(ScopedPPResource::PassRef(), | |
| 1379 MakeBufferResource(pp_instance(), | |
| 1380 encrypted_block)); | |
| 1381 if (!encrypted_resource.get()) | |
| 1382 return false; | |
| 1383 // TODO(tomfinegan): wrap callback in PP_CompletionCallback and pass it to | |
| 1384 // the plugin. | |
| 1385 PP_CompletionCallback pp_callback = {NULL, NULL, 0}; | |
| 1386 return PP_ToBool(plugin_decryption_interface_->Decrypt(pp_instance(), | |
| 1387 encrypted_resource, | |
| 1388 pp_callback)); | |
|
ddorwin
2012/07/28 01:43:26
I think we need to eliminate the PP_CompletionCall
| |
| 1389 } | |
| 1390 | |
| 1391 bool PluginInstance::DecryptAndDecode(const std::string& encrypted_block, | |
| 1392 const CDMStatusCB& callback) { | |
| 1393 if (!LoadContentDecryptionModuleInterface()) | |
| 1394 return false; | |
| 1395 ScopedPPResource encrypted_resource(ScopedPPResource::PassRef(), | |
| 1396 MakeBufferResource(pp_instance(), | |
| 1397 encrypted_block)); | |
| 1398 if (!encrypted_resource.get()) | |
| 1399 return false; | |
| 1400 // TODO(tomfinegan): wrap callback in PP_CompletionCallback and pass it to | |
| 1401 // the plugin. | |
| 1402 PP_CompletionCallback pp_callback = {NULL, NULL, 0}; | |
| 1403 return PP_ToBool(plugin_decryption_interface_->DecryptAndDecode( | |
| 1404 pp_instance(), | |
| 1405 encrypted_resource, | |
| 1406 pp_callback)); | |
| 1407 } | |
| 1408 | |
| 1279 bool PluginInstance::FlashIsFullscreenOrPending() { | 1409 bool PluginInstance::FlashIsFullscreenOrPending() { |
| 1280 return fullscreen_container_ != NULL; | 1410 return fullscreen_container_ != NULL; |
| 1281 } | 1411 } |
| 1282 | 1412 |
| 1283 bool PluginInstance::IsFullscreenOrPending() { | 1413 bool PluginInstance::IsFullscreenOrPending() { |
| 1284 return desired_fullscreen_state_; | 1414 return desired_fullscreen_state_; |
| 1285 } | 1415 } |
| 1286 | 1416 |
| 1287 bool PluginInstance::SetFullscreen(bool fullscreen) { | 1417 bool PluginInstance::SetFullscreen(bool fullscreen) { |
| 1288 // Keep a reference on the stack. See NOTE above. | 1418 // Keep a reference on the stack. See NOTE above. |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1872 PP_Var PluginInstance::GetDefaultCharSet(PP_Instance instance) { | 2002 PP_Var PluginInstance::GetDefaultCharSet(PP_Instance instance) { |
| 1873 std::string encoding = delegate()->GetDefaultEncoding(); | 2003 std::string encoding = delegate()->GetDefaultEncoding(); |
| 1874 return StringVar::StringToPPVar(encoding); | 2004 return StringVar::StringToPPVar(encoding); |
| 1875 } | 2005 } |
| 1876 | 2006 |
| 1877 PP_Var PluginInstance::GetFontFamilies(PP_Instance instance) { | 2007 PP_Var PluginInstance::GetFontFamilies(PP_Instance instance) { |
| 1878 // No in-process implementation. | 2008 // No in-process implementation. |
| 1879 return PP_MakeUndefined(); | 2009 return PP_MakeUndefined(); |
| 1880 } | 2010 } |
| 1881 | 2011 |
| 2012 void PluginInstance::NeedKey(PP_Instance instance, | |
| 2013 PP_Var key_system_var, | |
| 2014 PP_Var session_id_var, | |
| 2015 PP_Resource init_data) { | |
| 2016 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); | |
| 2017 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); | |
| 2018 | |
| 2019 // TODO(tomfinegan): Where does the call to this method come from? Or, where | |
| 2020 // does it go for handling. I need to read more of the EME proposed spec, but | |
| 2021 // this is what I understand so far: | |
| 2022 // - JS app sends needkey before anything else when it knows that encrypted | |
| 2023 // data is going to be streamed to the user agent. | |
| 2024 // - OR is the media stack going to see something in the stream that looks | |
| 2025 // like init data, and then send NeedKey. If this is the case NeedKey | |
| 2026 // probably needs to move to the PPP interface. | |
| 2027 | |
| 2028 HostGlobals::Get()->GetVarTracker()->ReleaseVar(key_system_var); | |
| 2029 HostGlobals::Get()->GetVarTracker()->ReleaseVar(session_id_var); | |
| 2030 } | |
| 2031 | |
| 2032 void PluginInstance::KeyAdded(PP_Instance instance, | |
| 2033 PP_Var key_system, | |
| 2034 PP_Var session_id) { | |
| 2035 } | |
| 2036 | |
| 2037 void PluginInstance::KeyMessage(PP_Instance instance, | |
| 2038 PP_Var key_system_var, | |
| 2039 PP_Var session_id_var, | |
| 2040 PP_Resource message_resource, | |
| 2041 PP_Var default_url_var) { | |
| 2042 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); | |
| 2043 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); | |
| 2044 StringVar* default_url_string = StringVar::FromPPVar(default_url_var); | |
| 2045 | |
| 2046 if (!key_system_string || !session_id_string || !default_url_string) { | |
| 2047 // TODO(tomfinegan): KeyError here? | |
| 2048 return; | |
| 2049 } | |
| 2050 | |
| 2051 EnterResourceNoLock<PPB_Buffer_API> enter(message_resource, true); | |
| 2052 if (enter.failed()) { | |
| 2053 // TODO(tomfinegan): KeyError here? | |
| 2054 NOTREACHED(); | |
| 2055 return; | |
| 2056 } | |
| 2057 | |
| 2058 BufferAutoMapper mapper(enter.object()); | |
| 2059 if (!mapper.data() || !mapper.size()) { | |
| 2060 // TODO(tomfinegan): KeyError here? | |
| 2061 NOTREACHED(); | |
| 2062 return; | |
| 2063 } | |
| 2064 | |
| 2065 std::string message(reinterpret_cast<char*>(mapper.data()), mapper.size()); | |
| 2066 if (message.empty()) { | |
| 2067 // TODO(tomfinegan): KeyError here? | |
| 2068 NOTREACHED(); | |
| 2069 return; | |
| 2070 } | |
| 2071 | |
| 2072 // Release the PP_Vars. | |
| 2073 HostGlobals::Get()->GetVarTracker()->ReleaseVar(key_system_var); | |
| 2074 HostGlobals::Get()->GetVarTracker()->ReleaseVar(session_id_var); | |
| 2075 HostGlobals::Get()->GetVarTracker()->ReleaseVar(default_url_var); | |
| 2076 | |
| 2077 // Release the PP_Resource. | |
| 2078 // TODO(tomfinegan): Confirm that the buffer is freed. | |
| 2079 HostGlobals::Get()->GetResourceTracker()->ReleaseResource(message_resource); | |
| 2080 } | |
| 2081 | |
| 2082 void PluginInstance::KeyError(PP_Instance instance, | |
| 2083 PP_Var key_system_var, | |
| 2084 PP_Var session_id_var, | |
| 2085 uint16_t media_error, | |
| 2086 uint16_t system_error) { | |
| 2087 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); | |
| 2088 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); | |
| 2089 | |
| 2090 HostGlobals::Get()->GetVarTracker()->ReleaseVar(key_system_var); | |
|
ddorwin
2012/07/28 01:43:26
Are these releases necessary? Should it happen aut
| |
| 2091 HostGlobals::Get()->GetVarTracker()->ReleaseVar(session_id_var); | |
| 2092 } | |
| 2093 | |
| 2094 void PluginInstance::DeliverBlock(PP_Instance instance, | |
| 2095 PP_Resource decrypted_block, | |
| 2096 PP_CompletionCallback callback) { | |
| 2097 // TODO(tomfinegan): Determine where |decrypted_block| goes, and what | |
| 2098 // callback actually is (callback will likely be the result of some | |
| 2099 // base::Bind usage in the media stack. Hash this out with xhwang. | |
| 2100 // | |
| 2101 HostGlobals::Get()->GetResourceTracker()->ReleaseResource(decrypted_block); | |
| 2102 } | |
| 2103 | |
| 2104 void PluginInstance::DeliverFrame(PP_Instance instance, | |
| 2105 PP_Resource decrypted_frame, | |
| 2106 PP_CompletionCallback callback) { | |
| 2107 // Not implemented in v0.1 of the EME/CDM work. | |
| 2108 } | |
| 2109 | |
| 2110 void PluginInstance::DeliverSamples(PP_Instance instance, | |
| 2111 PP_Resource decrypted_samples, | |
| 2112 PP_CompletionCallback callback) { | |
| 2113 // Not implemented in v0.1 of the EME/CDM work. | |
| 2114 } | |
| 2115 | |
| 2116 | |
| 1882 void PluginInstance::NumberOfFindResultsChanged(PP_Instance instance, | 2117 void PluginInstance::NumberOfFindResultsChanged(PP_Instance instance, |
| 1883 int32_t total, | 2118 int32_t total, |
| 1884 PP_Bool final_result) { | 2119 PP_Bool final_result) { |
| 1885 DCHECK_NE(find_identifier_, -1); | 2120 DCHECK_NE(find_identifier_, -1); |
| 1886 delegate_->NumberOfFindResultsChanged(find_identifier_, total, | 2121 delegate_->NumberOfFindResultsChanged(find_identifier_, total, |
| 1887 PP_ToBool(final_result)); | 2122 PP_ToBool(final_result)); |
| 1888 } | 2123 } |
| 1889 | 2124 |
| 1890 void PluginInstance::SelectedFindResultChanged(PP_Instance instance, | 2125 void PluginInstance::SelectedFindResultChanged(PP_Instance instance, |
| 1891 int32_t index) { | 2126 int32_t index) { |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2243 screen_size_for_fullscreen_ = gfx::Size(); | 2478 screen_size_for_fullscreen_ = gfx::Size(); |
| 2244 WebElement element = container_->element(); | 2479 WebElement element = container_->element(); |
| 2245 element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_); | 2480 element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_); |
| 2246 element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_); | 2481 element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_); |
| 2247 element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_); | 2482 element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_); |
| 2248 element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_); | 2483 element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_); |
| 2249 } | 2484 } |
| 2250 | 2485 |
| 2251 } // namespace ppapi | 2486 } // namespace ppapi |
| 2252 } // namespace webkit | 2487 } // namespace webkit |
| OLD | NEW |