summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc1
-rw-r--r--chrome/browser/extensions/extension_webstore_private_api.cc63
-rw-r--r--chrome/browser/extensions/extension_webstore_private_api.h23
-rw-r--r--chrome/browser/extensions/extension_webstore_private_apitest.cc70
-rw-r--r--chrome/common/extensions/api/extension_api.json18
-rw-r--r--content/browser/gpu/gpu_data_manager.cc32
-rw-r--r--content/browser/gpu/gpu_data_manager.h5
-rw-r--r--content/browser/gpu/gpu_process_host.cc10
-rw-r--r--content/browser/gpu/gpu_process_host.h1
-rw-r--r--content/browser/gpu/gpu_process_host_ui_shim.cc11
-rw-r--r--content/browser/gpu/gpu_process_host_ui_shim.h3
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(