172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/theme_source.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted_memory.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h" 921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/resources_util.h" 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/themes/theme_service.h" 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/themes/theme_service_factory.h" 13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/ntp_resource_cache.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h" 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h" 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h" 1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/theme_provider.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// use a resource map rather than hard-coded strings. 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char* kNewTabCSSPath = "css/newtab.css"; 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char* kNewIncognitoTabCSSPath = "css/newincognitotab.css"; 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic std::string StripQueryParams(const std::string& path) { 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL path_url = GURL(std::string(chrome::kChromeUIScheme) + "://" + 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string(chrome::kChromeUIThemePath) + "/" + path); 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return path_url.path().substr(1); // path() always includes a leading '/'. 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// ThemeSource, public: 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 33dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenThemeSource::ThemeSource(Profile* profile) 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : DataSource(chrome::kChromeUIThemePath, MessageLoop::current()), 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_(profile->GetOriginalProfile()) { 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch css_bytes_ = profile_->GetNTPResourceCache()->GetNewTabCSS( 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile->IsOffTheRecord()); 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 40dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenThemeSource::~ThemeSource() { 413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ThemeSource::StartDataRequest(const std::string& path, 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool is_incognito, 45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int request_id) { 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Our path may include cachebuster arguments, so trim them off. 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string uncached_path = StripQueryParams(path); 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (uncached_path == kNewTabCSSPath || 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uncached_path == kNewIncognitoTabCSSPath) { 51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK((uncached_path == kNewTabCSSPath && !is_incognito) || 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (uncached_path == kNewIncognitoTabCSSPath && is_incognito)); 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendResponse(request_id, css_bytes_); 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int resource_id = ResourcesUtil::GetThemeResourceId(uncached_path); 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (resource_id != -1) { 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendThemeBitmap(request_id, resource_id); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't have any data to send back. 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendResponse(request_id, NULL); 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstd::string ThemeSource::GetMimeType(const std::string& path) const { 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string uncached_path = StripQueryParams(path); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (uncached_path == kNewTabCSSPath || 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uncached_path == kNewIncognitoTabCSSPath) { 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return "text/css"; 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return "image/png"; 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 79dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenMessageLoop* ThemeSource::MessageLoopForRequestPath( 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& path) const { 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string uncached_path = StripQueryParams(path); 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (uncached_path == kNewTabCSSPath || 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uncached_path == kNewIncognitoTabCSSPath) { 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We generated and cached this when we initialized the object. We don't 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // have to go back to the UI thread to send the data. 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If it's not a themeable image, we don't need to go to the UI thread. 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int resource_id = ResourcesUtil::GetThemeResourceId(uncached_path); 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!ThemeService::IsThemeableImage(resource_id)) 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return DataSource::MessageLoopForRequestPath(path); 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool ThemeSource::ShouldReplaceExistingSource() const { 99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We currently get the css_bytes_ in the ThemeSource constructor, so we need 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // to recreate the source itself when a theme changes. 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// ThemeSource, private: 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ThemeSource::SendThemeBitmap(int request_id, int resource_id) { 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (ThemeService::IsThemeableImage(resource_id)) { 109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ui::ThemeProvider* tp = ThemeServiceFactory::GetForProfile(profile_); 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(tp); 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<RefCountedMemory> image_data(tp->GetRawData(resource_id)); 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendResponse(request_id, image_data); 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendResponse(request_id, rb.LoadDataResourceBytes(resource_id)); 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 121