diff options
-rw-r--r-- | chrome/browser/extensions/extension_function_dispatcher.cc | 1 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_webstore_private_api.cc | 63 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_webstore_private_api.h | 23 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_webstore_private_apitest.cc | 70 | ||||
-rw-r--r-- | chrome/common/extensions/api/extension_api.json | 18 | ||||
-rw-r--r-- | content/browser/gpu/gpu_data_manager.cc | 32 | ||||
-rw-r--r-- | content/browser/gpu/gpu_data_manager.h | 5 | ||||
-rw-r--r-- | content/browser/gpu/gpu_process_host.cc | 10 | ||||
-rw-r--r-- | content/browser/gpu/gpu_process_host.h | 1 | ||||
-rw-r--r-- | content/browser/gpu/gpu_process_host_ui_shim.cc | 11 | ||||
-rw-r--r-- | content/browser/gpu/gpu_process_host_ui_shim.h | 3 |
11 files changed, 208 insertions, 29 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index c5891be..7805496 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -362,6 +362,7 @@ void FactoryRegistry::ResetFunctions() { RegisterFunction<BeginInstallWithManifestFunction>(); RegisterFunction<CompleteInstallFunction>(); RegisterFunction<SilentlyInstallFunction>(); + RegisterFunction<GetWebGLStatusFunction>(); // WebNavigation. RegisterFunction<GetFrameFunction>(); diff --git a/chrome/browser/extensions/extension_webstore_private_api.cc b/chrome/browser/extensions/extension_webstore_private_api.cc index d76da49..fd6f307d 100644 --- a/chrome/browser/extensions/extension_webstore_private_api.cc +++ b/chrome/browser/extensions/extension_webstore_private_api.cc @@ -491,3 +491,66 @@ bool SetStoreLoginFunction::RunImpl() { prefs->SetWebStoreLogin(login); return true; } + +GetWebGLStatusFunction::GetWebGLStatusFunction() {} +GetWebGLStatusFunction::~GetWebGLStatusFunction() {} + +// static +bool GetWebGLStatusFunction::IsWebGLAllowed(GpuDataManager* manager) { + bool webgl_allowed = true; + if (!manager->GpuAccessAllowed()) { + webgl_allowed = false; + } else { + uint32 blacklist_flags = manager->GetGpuFeatureFlags().flags(); + if (blacklist_flags & GpuFeatureFlags::kGpuFeatureWebgl) + webgl_allowed = false; + } + return webgl_allowed; +} + +void GetWebGLStatusFunction::OnGpuInfoUpdate() { + GpuDataManager* manager = GpuDataManager::GetInstance(); + manager->RemoveObserver(this); + bool webgl_allowed = IsWebGLAllowed(manager); + CreateResult(webgl_allowed); + SendResponse(true); + + // Matches the AddRef in RunImpl(). + Release(); +} + +void GetWebGLStatusFunction::CreateResult(bool webgl_allowed) { + result_.reset(Value::CreateStringValue( + webgl_allowed ? "webgl_allowed" : "webgl_blocked")); +} + +bool GetWebGLStatusFunction::RunImpl() { + bool finalized = true; +#if defined(OS_LINUX) + // On Windows and Mac, so far we can always make the final WebGL blacklisting + // decision based on partial GPU info; on Linux, we need to launch the GPU + // process to collect full GPU info and make the final decision. + finalized = false; +#endif + + GpuDataManager* manager = GpuDataManager::GetInstance(); + if (manager->complete_gpu_info_available()) + finalized = true; + + bool webgl_allowed = IsWebGLAllowed(manager); + if (!webgl_allowed) + finalized = true; + + if (finalized) { + CreateResult(webgl_allowed); + SendResponse(true); + } else { + // Matched with a Release in OnGpuInfoUpdate. + AddRef(); + + manager->AddObserver(this); + manager->RequestCompleteGpuInfoIfNeeded(); + } + return true; +} + diff --git a/chrome/browser/extensions/extension_webstore_private_api.h b/chrome/browser/extensions/extension_webstore_private_api.h index bb4c476..9a755ab 100644 --- a/chrome/browser/extensions/extension_webstore_private_api.h +++ b/chrome/browser/extensions/extension_webstore_private_api.h @@ -13,6 +13,7 @@ #include "chrome/browser/extensions/webstore_install_helper.h" #include "chrome/browser/extensions/webstore_installer.h" #include "chrome/common/net/gaia/google_service_auth_error.h" +#include "content/browser/gpu/gpu_data_manager.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -159,4 +160,26 @@ class SetStoreLoginFunction : public SyncExtensionFunction { DECLARE_EXTENSION_FUNCTION_NAME("webstorePrivate.setStoreLogin"); }; +class GetWebGLStatusFunction : public AsyncExtensionFunction, + public GpuDataManager::Observer { + public: + GetWebGLStatusFunction(); + + // Implementing GpuDataManager::Observer interface. + virtual void OnGpuInfoUpdate() OVERRIDE; + + protected: + virtual ~GetWebGLStatusFunction(); + virtual bool RunImpl() OVERRIDE; + + private: + void CreateResult(bool webgl_allowed); + + // A false return value is always valid, but a true one is only valid if full + // GPU info has been collected in a GPU process. + static bool IsWebGLAllowed(GpuDataManager* manager); + + DECLARE_EXTENSION_FUNCTION_NAME("webstorePrivate.getWebGLStatus"); +}; + #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBSTORE_PRIVATE_API_H_ diff --git a/chrome/browser/extensions/extension_webstore_private_apitest.cc b/chrome/browser/extensions/extension_webstore_private_apitest.cc index f5d015b..02d2bc4 100644 --- a/chrome/browser/extensions/extension_webstore_private_apitest.cc +++ b/chrome/browser/extensions/extension_webstore_private_apitest.cc @@ -8,6 +8,7 @@ #include "base/file_util.h" #include "base/stringprintf.h" #include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/browser/extensions/extension_function_test_utils.h" #include "chrome/browser/extensions/extension_install_dialog.h" #include "chrome/browser/extensions/extension_install_ui.h" #include "chrome/browser/extensions/extension_service.h" @@ -17,10 +18,15 @@ #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" +#include "chrome/test/base/test_launcher_utils.h" #include "chrome/test/base/ui_test_utils.h" +#include "content/browser/gpu/gpu_blacklist.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "net/base/mock_host_resolver.h" +#include "ui/gfx/gl/gl_switches.h" + +using namespace extension_function_test_utils; namespace { @@ -170,6 +176,34 @@ class ExtensionWebstorePrivateBundleTest std::vector<FilePath> test_crx_; }; +class ExtensionWebstoreGetWebGLStatusTest : public InProcessBrowserTest { + public: + void SetUpCommandLine(CommandLine* command_line) OVERRIDE { + // In linux, we need to launch GPU process to decide if WebGL is allowed. + // Run it on top of osmesa to avoid bot driver issues. +#if defined(OS_LINUX) + CHECK(test_launcher_utils::OverrideGLImplementation( + command_line, gfx::kGLImplementationOSMesaName)) << + "kUseGL must not be set multiple times!"; +#endif + } + + protected: + void RunTest(bool webgl_allowed) { + static const char kEmptyArgs[] = "[]"; + static const char kWebGLStatusAllowed[] = "webgl_allowed"; + static const char kWebGLStatusBlocked[] = "webgl_blocked"; + scoped_ptr<base::Value> result(RunFunctionAndReturnResult( + new GetWebGLStatusFunction(), kEmptyArgs, browser())); + EXPECT_EQ(base::Value::TYPE_STRING, result->GetType()); + StringValue* value = static_cast<StringValue*>(result.get()); + std::string webgl_status = ""; + EXPECT_TRUE(value && value->GetAsString(&webgl_status)); + EXPECT_STREQ(webgl_allowed ? kWebGLStatusAllowed : kWebGLStatusBlocked, + webgl_status.c_str()); + } +}; + // Test cases where the user accepts the install confirmation dialog. IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, InstallAccepted) { ASSERT_TRUE(RunInstallTest("accepted.html", "extension.crx")); @@ -229,3 +263,39 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateBundleTest, SilentlyInstall) { WebstorePrivateApi::SetTrustTestIDsForTesting(true); ASSERT_TRUE(RunPageTest(GetTestServerURL("silently_install.html").spec())); } + +// Tests getWebGLStatus function when WebGL is allowed. +IN_PROC_BROWSER_TEST_F(ExtensionWebstoreGetWebGLStatusTest, Allowed) { + bool webgl_allowed = true; + RunTest(webgl_allowed); +} + +// Tests getWebGLStatus function when WebGL is blacklisted. +IN_PROC_BROWSER_TEST_F(ExtensionWebstoreGetWebGLStatusTest, Blocked) { + static const std::string json_blacklist = + "{\n" + " \"name\": \"gpu blacklist\",\n" + " \"version\": \"1.0\",\n" + " \"entries\": [\n" + " {\n" + " \"id\": 1,\n" + " \"blacklist\": [\n" + " \"webgl\"\n" + " ]\n" + " }\n" + " ]\n" + "}"; + scoped_ptr<Version> os_version(Version::GetVersionFromString("1.0")); + GpuBlacklist* blacklist = new GpuBlacklist("1.0"); + + ASSERT_TRUE(blacklist->LoadGpuBlacklist( + json_blacklist, GpuBlacklist::kAllOs)); + GpuDataManager::GetInstance()->SetGpuBlacklist(blacklist); + GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags(); + EXPECT_EQ( + flags.flags(), static_cast<uint32>(GpuFeatureFlags::kGpuFeatureWebgl)); + + bool webgl_allowed = false; + RunTest(webgl_allowed); +} + diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json index 42b64f7..3fd638e 100644 --- a/chrome/common/extensions/api/extension_api.json +++ b/chrome/common/extensions/api/extension_api.json @@ -8088,6 +8088,24 @@ ] } ] + }, + { + "name": "getWebGLStatus", + "description": "Invokes a callback that returns whether WebGL is blacklisted or not.", + "parameters": [ + { + "name": "callback", + "type": "function", + "optional": "false", + "parameters": [ + { + "name": "webgl_status", + "type": "string", + "enum": ["webgl_allowed", "webgl_blocked"] + } + ] + } + ] } ] }, diff --git a/content/browser/gpu/gpu_data_manager.cc b/content/browser/gpu/gpu_data_manager.cc index 17895b3..c126fd2 100644 --- a/content/browser/gpu/gpu_data_manager.cc +++ b/content/browser/gpu/gpu_data_manager.cc @@ -196,6 +196,7 @@ void GpuDataManager::UserFlags::ApplyPolicies() { GpuDataManager::GpuDataManager() : complete_gpu_info_already_requested_(false), + complete_gpu_info_available_(false), observer_list_(new GpuDataManagerObserverList), software_rendering_(false) { Initialize(); @@ -208,7 +209,10 @@ void GpuDataManager::Initialize() { if (!user_flags_.skip_gpu_data_loading()) { content::GPUInfo gpu_info; gpu_info_collector::CollectPreliminaryGraphicsInfo(&gpu_info); - UpdateGpuInfo(gpu_info); + { + base::AutoLock auto_lock(gpu_info_lock_); + gpu_info_ = gpu_info; + } } #if defined(OS_MACOSX) @@ -229,7 +233,8 @@ GpuDataManager* GpuDataManager::GetInstance() { void GpuDataManager::RequestCompleteGpuInfoIfNeeded() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (complete_gpu_info_already_requested_) + + if (complete_gpu_info_already_requested_ || complete_gpu_info_available_) return; complete_gpu_info_already_requested_ = true; @@ -240,20 +245,20 @@ void GpuDataManager::RequestCompleteGpuInfoIfNeeded() { } void GpuDataManager::UpdateGpuInfo(const content::GPUInfo& gpu_info) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + complete_gpu_info_available_ = true; + complete_gpu_info_already_requested_ = true; { base::AutoLock auto_lock(gpu_info_lock_); if (!Merge(&gpu_info_, gpu_info)) return; - } - - NotifyGpuInfoUpdate(); - - { - base::AutoLock auto_lock(gpu_info_lock_); content::GetContentClient()->SetGpuInfo(gpu_info_); } UpdateGpuFeatureFlags(); + // We have to update GpuFeatureFlags before notify all the observers. + NotifyGpuInfoUpdate(); } const content::GPUInfo& GpuDataManager::gpu_info() const { @@ -555,13 +560,7 @@ void GpuDataManager::NotifyGpuInfoUpdate() { } void GpuDataManager::UpdateGpuFeatureFlags() { - if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&GpuDataManager::UpdateGpuFeatureFlags, - base::Unretained(this))); - return; - } + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); GpuBlacklist* gpu_blacklist = GetGpuBlacklist(); // We don't set a lock around modifying gpu_feature_flags_ since it's just an @@ -577,9 +576,6 @@ void GpuDataManager::UpdateGpuFeatureFlags() { GpuBlacklist::kOsAny, NULL, gpu_info_); } - // Notify clients that GpuInfo state has changed - NotifyGpuInfoUpdate(); - uint32 flags = gpu_feature_flags_.flags(); uint32 max_entry_id = gpu_blacklist->max_entry_id(); bool disabled = false; diff --git a/content/browser/gpu/gpu_data_manager.h b/content/browser/gpu/gpu_data_manager.h index 5880c2f..568b969 100644 --- a/content/browser/gpu/gpu_data_manager.h +++ b/content/browser/gpu/gpu_data_manager.h @@ -47,6 +47,10 @@ class CONTENT_EXPORT GpuDataManager { const content::GPUInfo& gpu_info() const; + bool complete_gpu_info_available() const { + return complete_gpu_info_available_; + } + // Returns status of various GPU features. This is two parted: // { // featureStatus: [] @@ -216,6 +220,7 @@ class CONTENT_EXPORT GpuDataManager { void EnableSoftwareRenderingIfNecessary(); bool complete_gpu_info_already_requested_; + bool complete_gpu_info_available_; GpuFeatureFlags gpu_feature_flags_; GpuFeatureFlags preliminary_gpu_feature_flags_; diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index a0ec307..25f5ffa 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc @@ -372,8 +372,6 @@ bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(GpuHostMsg_ChannelEstablished, OnChannelEstablished) IPC_MESSAGE_HANDLER(GpuHostMsg_CommandBufferCreated, OnCommandBufferCreated) IPC_MESSAGE_HANDLER(GpuHostMsg_DestroyCommandBuffer, OnDestroyCommandBuffer) - IPC_MESSAGE_HANDLER(GpuHostMsg_GraphicsInfoCollected, - OnGraphicsInfoCollected) IPC_MESSAGE_UNHANDLED(RouteOnUIThread(message)) IPC_END_MESSAGE_MAP() @@ -501,14 +499,6 @@ void GpuProcessHost::OnDestroyCommandBuffer( #endif // defined(TOOLKIT_USES_GTK) } -void GpuProcessHost::OnGraphicsInfoCollected(const content::GPUInfo& gpu_info) { - // OnGraphicsInfoCollected is sent back after the GPU process successfully - // initializes GL. - TRACE_EVENT0("test_gpu", "OnGraphicsInfoCollected"); - - GpuDataManager::GetInstance()->UpdateGpuInfo(gpu_info); -} - void GpuProcessHost::OnProcessLaunched() { // Send the GPU process handle to the UI thread before it has to // respond to any requests to establish a GPU channel. The response diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h index 9940b69..e0f9eec 100644 --- a/content/browser/gpu/gpu_process_host.h +++ b/content/browser/gpu/gpu_process_host.h @@ -102,7 +102,6 @@ class GpuProcessHost : public BrowserChildProcessHost, void OnCommandBufferCreated(const int32 route_id); void OnDestroyCommandBuffer( gfx::PluginWindowHandle window, int32 renderer_id, int32 render_view_id); - void OnGraphicsInfoCollected(const content::GPUInfo& gpu_info); bool LaunchGpuProcess(const std::string& channel_id); diff --git a/content/browser/gpu/gpu_process_host_ui_shim.cc b/content/browser/gpu/gpu_process_host_ui_shim.cc index fab719d..9fa2f9e 100644 --- a/content/browser/gpu/gpu_process_host_ui_shim.cc +++ b/content/browser/gpu/gpu_process_host_ui_shim.cc @@ -197,6 +197,8 @@ bool GpuProcessHostUIShim::OnControlMessageReceived( OnAcceleratedSurfaceBuffersSwapped) IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfacePostSubBuffer, OnAcceleratedSurfacePostSubBuffer) + IPC_MESSAGE_HANDLER(GpuHostMsg_GraphicsInfoCollected, + OnGraphicsInfoCollected) #if defined(TOOLKIT_USES_GTK) || defined(OS_WIN) IPC_MESSAGE_HANDLER(GpuHostMsg_ResizeView, OnResizeView) @@ -229,6 +231,15 @@ void GpuProcessHostUIShim::OnLogMessage( GpuDataManager::GetInstance()->AddLogMessage(dict); } +void GpuProcessHostUIShim::OnGraphicsInfoCollected( + const content::GPUInfo& gpu_info) { + // OnGraphicsInfoCollected is sent back after the GPU process successfully + // initializes GL. + TRACE_EVENT0("test_gpu", "OnGraphicsInfoCollected"); + + GpuDataManager::GetInstance()->UpdateGpuInfo(gpu_info); +} + #if defined(TOOLKIT_USES_GTK) || defined(OS_WIN) void GpuProcessHostUIShim::OnResizeView(int32 renderer_id, diff --git a/content/browser/gpu/gpu_process_host_ui_shim.h b/content/browser/gpu/gpu_process_host_ui_shim.h index da64174..15f7c5d 100644 --- a/content/browser/gpu/gpu_process_host_ui_shim.h +++ b/content/browser/gpu/gpu_process_host_ui_shim.h @@ -21,6 +21,7 @@ #include "base/threading/non_thread_safe.h" #include "content/common/content_export.h" #include "content/common/message_router.h" +#include "content/public/common/gpu_info.h" struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params; struct GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params; @@ -100,6 +101,8 @@ class GpuProcessHostUIShim gfx::Size size); #endif + void OnGraphicsInfoCollected(const content::GPUInfo& gpu_info); + void OnAcceleratedSurfaceBuffersSwapped( const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params); void OnAcceleratedSurfacePostSubBuffer( |