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 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 58 GpuBlacklistUpdater::~GpuBlacklistUpdater() { } 59 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 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