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