1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Use of this source code is governed by a BSD-style license that can be
3dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// found in the LICENSE file.
4dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/web_resource/gpu_blacklist_updater.h"
6dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/logging.h"
8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/values.h"
9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/browser_process.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/gpu_data_manager.h"
11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/prefs/pref_service.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/prefs/scoped_user_pref_update.h"
13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/profiles/profile.h"
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/profiles/profile_manager.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/chrome_version_info.h"
16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/common/pref_names.h"
17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/gpu_blacklist.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "grit/browser_resources.h"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/base/resource/resource_bundle.h"
22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennamespace {
24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Delay on first fetch so we don't interfere with startup.
26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const int kStartGpuBlacklistFetchDelay = 6000;
27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Delay between calls to update the gpu blacklist (48 hours).
29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const int kCacheUpdateDelay = 48 * 60 * 60 * 1000;
30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}  // namespace
32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst char* GpuBlacklistUpdater::kDefaultGpuBlacklistURL =
34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    "https://dl.google.com/dl/edgedl/chrome/gpu/software_rendering_list.json";
35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
36dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenGpuBlacklistUpdater::GpuBlacklistUpdater()
37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    : WebResourceService(ProfileManager::GetDefaultProfile(),
38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                         g_browser_process->local_state(),
39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                         GpuBlacklistUpdater::kDefaultGpuBlacklistURL,
40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                         false,  // don't append locale to URL
41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                         NotificationType::NOTIFICATION_TYPE_COUNT,
42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                         prefs::kGpuBlacklistUpdate,
43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                         kStartGpuBlacklistFetchDelay,
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                         kCacheUpdateDelay),
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      gpu_blacklist_cache_(NULL) {
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PrefService* local_state = g_browser_process->local_state();
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // If we bring up chrome normally, prefs should never be NULL; however, we
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // we handle the case where local_state == NULL for certain tests.
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (local_state) {
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    local_state->RegisterDictionaryPref(prefs::kGpuBlacklist);
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    gpu_blacklist_cache_ = local_state->GetDictionary(prefs::kGpuBlacklist);
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(gpu_blacklist_cache_);
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  LoadGpuBlacklist();
56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
58dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenGpuBlacklistUpdater::~GpuBlacklistUpdater() { }
59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid GpuBlacklistUpdater::Unpack(const DictionaryValue& parsed_json) {
61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DictionaryPrefUpdate update(prefs_, prefs::kGpuBlacklist);
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DictionaryValue* gpu_blacklist_cache = update.Get();
64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(gpu_blacklist_cache);
65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  gpu_blacklist_cache->Clear();
66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  gpu_blacklist_cache->MergeDictionary(&parsed_json);
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  LoadGpuBlacklist();
69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GpuBlacklistUpdater::LoadGpuBlacklist() {
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<GpuBlacklist> gpu_blacklist;
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We first load it from the browser resources, and then check if the cached
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // version is more up-to-date.
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  static const base::StringPiece gpu_blacklist_json(
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ResourceBundle::GetSharedInstance().GetRawDataResource(
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          IDR_GPU_BLACKLIST));
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  chrome::VersionInfo version_info;
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string chrome_version_string =
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      version_info.is_valid() ? version_info.Version() : "0";
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  gpu_blacklist.reset(new GpuBlacklist(chrome_version_string));
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!gpu_blacklist->LoadGpuBlacklist(gpu_blacklist_json.as_string(), true))
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  uint16 version_major, version_minor;
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool succeed = gpu_blacklist->GetVersion(&version_major, &version_minor);
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(succeed);
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  VLOG(1) << "Using software rendering list version "
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          << version_major << "." << version_minor;
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (gpu_blacklist_cache_) {
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    uint16 cached_version_major, cached_version_minor;
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (GpuBlacklist::GetVersion(*gpu_blacklist_cache_,
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 &cached_version_major,
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 &cached_version_minor)) {
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (gpu_blacklist.get() != NULL) {
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        uint16 current_version_major, current_version_minor;
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (gpu_blacklist->GetVersion(&current_version_major,
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                      &current_version_minor) &&
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            (cached_version_major > current_version_major ||
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen             (cached_version_major == current_version_major &&
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              cached_version_minor > current_version_minor))) {
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          chrome::VersionInfo version_info;
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          std::string chrome_version_string =
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              version_info.is_valid() ? version_info.Version() : "0";
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          GpuBlacklist* updated_list = new GpuBlacklist(chrome_version_string);
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          if (updated_list->LoadGpuBlacklist(*gpu_blacklist_cache_, true)) {
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            gpu_blacklist.reset(updated_list);
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            VLOG(1) << "Using software rendering list version "
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                << cached_version_major << "." << cached_version_minor;
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          } else {
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            delete updated_list;
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          }
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Need to initialize GpuDataManager to load the current GPU blacklist,
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // collect preliminary GPU info, and run through GPU blacklist.
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GpuDataManager* gpu_data_manager = GpuDataManager::GetInstance();
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  gpu_data_manager->UpdateGpuBlacklist(gpu_blacklist.release());
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
126