12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/webui/shared_resources_data_source.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted_memory.h"
93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/strings/string_util.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_restrictions.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_client.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/url_constants.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/mime_util.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/resources/grit/webui_resources_map.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kAppImagesPath[] = "images/apps/";
193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kAppImagesPath2x[] = "images/2x/apps/";
203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kReplacement[] = "../../resources/default_100_percent/common/";
223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kReplacement2x[] = "../../resources/default_200_percent/common/";
233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// This entire method is a hack introduced to be able to handle apps images
253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// that exist in the ui/resources directory. From JS/CSS, we still load the
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// image as if it were chrome://resources/images/apps/myappimage.png, if that
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// path doesn't exist, we check to see if it that image exists in the relative
283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// path to ui/resources instead.
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// TODO(rkc): Once we have a separate source for apps, remove this code.
303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool AppsRelativePathMatch(const std::string& path,
313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                           const std::string& compareto) {
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (StartsWithASCII(path, kAppImagesPath, false)) {
333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (compareto ==
343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        (kReplacement + path.substr(arraysize(kAppImagesPath) - 1)))
353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return true;
363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else if (StartsWithASCII(path, kAppImagesPath2x, false)) {
373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (compareto ==
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        (kReplacement2x + path.substr(arraysize(kAppImagesPath2x) - 1)))
393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return true;
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return false;
423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int PathToIDR(const std::string& path) {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int idr = -1;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < kWebuiResourcesSize; ++i) {
473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if ((path == kWebuiResources[i].name) ||
483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        AppsRelativePathMatch(path, kWebuiResources[i].name)) {
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      idr = kWebuiResources[i].value;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return idr;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SharedResourcesDataSource::SharedResourcesDataSource() {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SharedResourcesDataSource::~SharedResourcesDataSource() {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string SharedResourcesDataSource::GetSource() const {
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return content::kChromeUIResourcesHost;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SharedResourcesDataSource::StartDataRequest(
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& path,
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int render_process_id,
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int render_frame_id,
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::URLDataSource::GotDataCallback& callback) {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int idr = PathToIDR(path);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_NE(-1, idr) << " path: " << path;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::RefCountedStaticMemory> bytes(
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::GetContentClient()->GetDataResourceBytes(idr));
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback.Run(bytes.get());
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string SharedResourcesDataSource::GetMimeType(
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& path) const {
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Requests should not block on the disk!  On POSIX this goes to disk.
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://code.google.com/p/chromium/issues/detail?id=59849
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ThreadRestrictions::ScopedAllowIO allow_io;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string mime_type;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::GetMimeTypeFromFile(base::FilePath().AppendASCII(path), &mime_type);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return mime_type;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
92