[refactor] More post-NSS WebCrypto cleanups (utility functions).
[chromium-blink-merge.git] / content / browser / devtools / protocol / system_info_handler.cc
blobaa32e58e928bbdda9c41784b205fd85d1de06189
1 // Copyright 2014 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 "content/browser/devtools/protocol/system_info_handler.h"
7 #include "base/bind.h"
8 #include "content/browser/gpu/compositor_util.h"
9 #include "content/public/browser/gpu_data_manager.h"
10 #include "gpu/config/gpu_info.h"
12 namespace content {
13 namespace devtools {
14 namespace system_info {
16 namespace {
18 using Response = DevToolsProtocolClient::Response;
20 // Give the GPU process a few seconds to provide GPU info.
21 const int kGPUInfoWatchdogTimeoutMs = 5000;
23 class AuxGPUInfoEnumerator : public gpu::GPUInfo::Enumerator {
24 public:
25 AuxGPUInfoEnumerator(base::DictionaryValue* dictionary)
26 : dictionary_(dictionary),
27 in_aux_attributes_(false) { }
29 void AddInt64(const char* name, int64 value) override {
30 if (in_aux_attributes_)
31 dictionary_->SetDouble(name, value);
34 void AddInt(const char* name, int value) override {
35 if (in_aux_attributes_)
36 dictionary_->SetInteger(name, value);
39 void AddString(const char* name, const std::string& value) override {
40 if (in_aux_attributes_)
41 dictionary_->SetString(name, value);
44 void AddBool(const char* name, bool value) override {
45 if (in_aux_attributes_)
46 dictionary_->SetBoolean(name, value);
49 void AddTimeDeltaInSecondsF(const char* name,
50 const base::TimeDelta& value) override {
51 if (in_aux_attributes_)
52 dictionary_->SetDouble(name, value.InSecondsF());
55 void BeginGPUDevice() override {}
57 void EndGPUDevice() override {}
59 void BeginVideoDecodeAcceleratorSupportedProfile() override {}
61 void EndVideoDecodeAcceleratorSupportedProfile() override {}
63 void BeginVideoEncodeAcceleratorSupportedProfile() override {}
65 void EndVideoEncodeAcceleratorSupportedProfile() override {}
67 void BeginAuxAttributes() override {
68 in_aux_attributes_ = true;
71 void EndAuxAttributes() override {
72 in_aux_attributes_ = false;
75 private:
76 base::DictionaryValue* dictionary_;
77 bool in_aux_attributes_;
80 scoped_refptr<GPUDevice> GPUDeviceToProtocol(
81 const gpu::GPUInfo::GPUDevice& device) {
82 return GPUDevice::Create()->set_vendor_id(device.vendor_id)
83 ->set_device_id(device.device_id)
84 ->set_vendor_string(device.vendor_string)
85 ->set_device_string(device.device_string);
88 } // namespace
90 class SystemInfoHandlerGpuObserver : public content::GpuDataManagerObserver {
91 public:
92 SystemInfoHandlerGpuObserver(base::WeakPtr<SystemInfoHandler> handler,
93 DevToolsCommandId command_id)
94 : handler_(handler),
95 command_id_(command_id),
96 observer_id_(++next_observer_id_)
98 if (handler_) {
99 handler_->AddActiveObserverId(observer_id_);
103 void OnGpuInfoUpdate() override {
104 UnregisterAndSendResponse();
107 void OnGpuProcessCrashed(base::TerminationStatus exit_code) override {
108 UnregisterAndSendResponse();
111 void UnregisterAndSendResponse() {
112 GpuDataManager::GetInstance()->RemoveObserver(this);
113 if (handler_.get()) {
114 if (handler_->RemoveActiveObserverId(observer_id_)) {
115 handler_->SendGetInfoResponse(command_id_);
118 delete this;
121 int GetObserverId() {
122 return observer_id_;
125 private:
126 base::WeakPtr<SystemInfoHandler> handler_;
127 DevToolsCommandId command_id_;
128 int observer_id_;
130 static int next_observer_id_;
133 int SystemInfoHandlerGpuObserver::next_observer_id_ = 0;
135 SystemInfoHandler::SystemInfoHandler()
136 : weak_factory_(this) {
139 SystemInfoHandler::~SystemInfoHandler() {
142 void SystemInfoHandler::SetClient(scoped_ptr<Client> client) {
143 client_.swap(client);
146 Response SystemInfoHandler::GetInfo(DevToolsCommandId command_id) {
147 std::string reason;
148 if (!GpuDataManager::GetInstance()->GpuAccessAllowed(&reason) ||
149 GpuDataManager::GetInstance()->IsEssentialGpuInfoAvailable()) {
150 // The GpuDataManager already has all of the information needed to make
151 // GPU-based blacklisting decisions. Post a task to give it to the
152 // client asynchronously.
154 // Waiting for complete GPU info in the if-test above seems to
155 // frequently hit internal timeouts in the launching of the unsandboxed
156 // GPU process in debug builds on Windows.
157 BrowserThread::PostTask(
158 BrowserThread::UI,
159 FROM_HERE,
160 base::Bind(&SystemInfoHandler::SendGetInfoResponse,
161 weak_factory_.GetWeakPtr(),
162 command_id));
163 } else {
164 // We will be able to get more information from the GpuDataManager.
165 // Register a transient observer with it to call us back when the
166 // information is available.
167 SystemInfoHandlerGpuObserver* observer = new SystemInfoHandlerGpuObserver(
168 weak_factory_.GetWeakPtr(), command_id);
169 BrowserThread::PostDelayedTask(
170 BrowserThread::UI,
171 FROM_HERE,
172 base::Bind(&SystemInfoHandler::ObserverWatchdogCallback,
173 weak_factory_.GetWeakPtr(),
174 observer->GetObserverId(),
175 command_id),
176 base::TimeDelta::FromMilliseconds(kGPUInfoWatchdogTimeoutMs));
177 GpuDataManager::GetInstance()->AddObserver(observer);
178 // There's no other method available to request just essential GPU info.
179 GpuDataManager::GetInstance()->RequestCompleteGpuInfoIfNeeded();
182 return Response::OK();
185 void SystemInfoHandler::SendGetInfoResponse(DevToolsCommandId command_id) {
186 gpu::GPUInfo gpu_info = GpuDataManager::GetInstance()->GetGPUInfo();
187 std::vector<scoped_refptr<GPUDevice>> devices;
188 devices.push_back(GPUDeviceToProtocol(gpu_info.gpu));
189 for (const auto& device : gpu_info.secondary_gpus)
190 devices.push_back(GPUDeviceToProtocol(device));
192 scoped_ptr<base::DictionaryValue> aux_attributes(new base::DictionaryValue);
193 AuxGPUInfoEnumerator enumerator(aux_attributes.get());
194 gpu_info.EnumerateFields(&enumerator);
196 scoped_refptr<GPUInfo> gpu = GPUInfo::Create()
197 ->set_devices(devices)
198 ->set_aux_attributes(aux_attributes.Pass())
199 ->set_feature_status(make_scoped_ptr(GetFeatureStatus()))
200 ->set_driver_bug_workarounds(GetDriverBugWorkarounds());
202 client_->SendGetInfoResponse(
203 command_id,
204 GetInfoResponse::Create()->set_gpu(gpu)
205 ->set_model_name(gpu_info.machine_model_name)
206 ->set_model_version(gpu_info.machine_model_version));
209 void SystemInfoHandler::AddActiveObserverId(int observer_id) {
210 base::AutoLock auto_lock(lock_);
211 active_observers_.insert(observer_id);
214 bool SystemInfoHandler::RemoveActiveObserverId(int observer_id) {
215 base::AutoLock auto_lock(lock_);
216 int num_removed = active_observers_.erase(observer_id);
217 return (num_removed != 0);
220 void SystemInfoHandler::ObserverWatchdogCallback(int observer_id,
221 DevToolsCommandId command_id) {
222 DCHECK_CURRENTLY_ON(BrowserThread::UI);
223 if (RemoveActiveObserverId(observer_id)) {
224 SendGetInfoResponse(command_id);
225 // For the time being we want to know about this event in the test logs.
226 LOG(ERROR) << "SystemInfoHandler: request for GPU info timed out!"
227 << " Most recent info sent.";
231 } // namespace system_info
232 } // namespace devtools
233 } // namespace content