Home | History | Annotate | Download | only in streams_private
      1 // Copyright (c) 2012 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/extensions/api/streams_private/streams_private_api.h"
      6 
      7 #include "base/lazy_instance.h"
      8 #include "base/values.h"
      9 #include "chrome/browser/extensions/extension_tab_util.h"
     10 #include "chrome/common/extensions/api/streams_private.h"
     11 #include "content/public/browser/stream_handle.h"
     12 #include "extensions/browser/event_router.h"
     13 #include "extensions/browser/extension_function_registry.h"
     14 #include "extensions/browser/extension_registry.h"
     15 #include "net/http/http_response_headers.h"
     16 
     17 namespace {
     18 
     19 void CreateResponseHeadersDictionary(const net::HttpResponseHeaders* headers,
     20                                      base::DictionaryValue* result) {
     21   if (!headers)
     22     return;
     23 
     24   void* iter = NULL;
     25   std::string header_name;
     26   std::string header_value;
     27   while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) {
     28     base::Value* existing_value = NULL;
     29     if (result->Get(header_name, &existing_value)) {
     30       base::StringValue* existing_string_value =
     31           static_cast<base::StringValue*>(existing_value);
     32       existing_string_value->GetString()->append(", ").append(header_value);
     33     } else {
     34       result->SetString(header_name, header_value);
     35     }
     36   }
     37 }
     38 
     39 }  // namespace
     40 
     41 namespace extensions {
     42 
     43 namespace streams_private = api::streams_private;
     44 
     45 // static
     46 StreamsPrivateAPI* StreamsPrivateAPI::Get(content::BrowserContext* context) {
     47   return GetFactoryInstance()->Get(context);
     48 }
     49 
     50 StreamsPrivateAPI::StreamsPrivateAPI(content::BrowserContext* context)
     51     : browser_context_(context),
     52       extension_registry_observer_(this),
     53       weak_ptr_factory_(this) {
     54   extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
     55 }
     56 
     57 StreamsPrivateAPI::~StreamsPrivateAPI() {
     58 }
     59 
     60 void StreamsPrivateAPI::ExecuteMimeTypeHandler(
     61     const std::string& extension_id,
     62     content::WebContents* web_contents,
     63     scoped_ptr<content::StreamHandle> stream,
     64     const std::string& view_id,
     65     int64 expected_content_size) {
     66   // Create the event's arguments value.
     67   streams_private::StreamInfo info;
     68   info.mime_type = stream->GetMimeType();
     69   info.original_url = stream->GetOriginalURL().spec();
     70   info.stream_url = stream->GetURL().spec();
     71   info.tab_id = ExtensionTabUtil::GetTabId(web_contents);
     72 
     73   if (!view_id.empty()) {
     74     info.view_id.reset(new std::string(view_id));
     75   }
     76 
     77   int size = -1;
     78   if (expected_content_size <= INT_MAX)
     79     size = expected_content_size;
     80   info.expected_content_size = size;
     81 
     82   CreateResponseHeadersDictionary(stream->GetResponseHeaders().get(),
     83                                   &info.response_headers.additional_properties);
     84 
     85   scoped_ptr<Event> event(
     86       new Event(streams_private::OnExecuteMimeTypeHandler::kEventName,
     87                 streams_private::OnExecuteMimeTypeHandler::Create(info)));
     88 
     89   EventRouter::Get(browser_context_)
     90       ->DispatchEventToExtension(extension_id, event.Pass());
     91 
     92   GURL url = stream->GetURL();
     93   streams_[extension_id][url] = make_linked_ptr(stream.release());
     94 }
     95 
     96 void StreamsPrivateAPI::AbortStream(const std::string& extension_id,
     97                                     const GURL& stream_url,
     98                                     const base::Closure& callback) {
     99   StreamMap::iterator extension_it = streams_.find(extension_id);
    100   if (extension_it == streams_.end()) {
    101     callback.Run();
    102     return;
    103   }
    104 
    105   StreamMap::mapped_type* url_map = &extension_it->second;
    106   StreamMap::mapped_type::iterator url_it = url_map->find(stream_url);
    107   if (url_it == url_map->end()) {
    108     callback.Run();
    109     return;
    110   }
    111 
    112   url_it->second->AddCloseListener(callback);
    113   url_map->erase(url_it);
    114 }
    115 
    116 void StreamsPrivateAPI::OnExtensionUnloaded(
    117     content::BrowserContext* browser_context,
    118     const Extension* extension,
    119     UnloadedExtensionInfo::Reason reason) {
    120   streams_.erase(extension->id());
    121 }
    122 
    123 StreamsPrivateAbortFunction::StreamsPrivateAbortFunction() {
    124 }
    125 
    126 ExtensionFunction::ResponseAction StreamsPrivateAbortFunction::Run() {
    127   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    128   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &stream_url_));
    129   StreamsPrivateAPI::Get(browser_context())->AbortStream(
    130       extension_id(), GURL(stream_url_), base::Bind(
    131           &StreamsPrivateAbortFunction::OnClose, this));
    132   return RespondLater();
    133 }
    134 
    135 void StreamsPrivateAbortFunction::OnClose() {
    136   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    137   Respond(NoArguments());
    138 }
    139 
    140 static base::LazyInstance<BrowserContextKeyedAPIFactory<StreamsPrivateAPI> >
    141     g_factory = LAZY_INSTANCE_INITIALIZER;
    142 
    143 // static
    144 BrowserContextKeyedAPIFactory<StreamsPrivateAPI>*
    145 StreamsPrivateAPI::GetFactoryInstance() {
    146   return g_factory.Pointer();
    147 }
    148 
    149 }  // namespace extensions
    150