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