Home | History | Annotate | Download | only in media
      1 // Copyright 2013 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/media/desktop_streams_registry.h"
      6 
      7 #include "base/base64.h"
      8 #include "base/location.h"
      9 #include "base/time/time.h"
     10 #include "content/public/browser/browser_thread.h"
     11 #include "crypto/random.h"
     12 
     13 namespace {
     14 
     15 const int kStreamIdLengthBytes = 16;
     16 
     17 const int kApprovedStreamTimeToLiveSeconds = 10;
     18 
     19 std::string GenerateRandomStreamId() {
     20   char buffer[kStreamIdLengthBytes];
     21   crypto::RandBytes(buffer, arraysize(buffer));
     22   std::string result;
     23   base::Base64Encode(base::StringPiece(buffer, arraysize(buffer)),
     24                      &result);
     25   return result;
     26 }
     27 
     28 }  // namespace
     29 
     30 DesktopStreamsRegistry::DesktopStreamsRegistry() {}
     31 DesktopStreamsRegistry::~DesktopStreamsRegistry() {}
     32 
     33 std::string DesktopStreamsRegistry::RegisterStream(
     34     int render_process_id,
     35     int render_frame_id,
     36     const GURL& origin,
     37     const content::DesktopMediaID& source,
     38     const std::string& extension_name) {
     39   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     40 
     41   std::string id = GenerateRandomStreamId();
     42   DCHECK(approved_streams_.find(id) == approved_streams_.end());
     43   ApprovedDesktopMediaStream& stream = approved_streams_[id];
     44   stream.render_process_id = render_process_id;
     45   stream.render_frame_id = render_frame_id;
     46   stream.origin = origin;
     47   stream.source = source;
     48   stream.extension_name = extension_name;
     49 
     50   content::BrowserThread::PostDelayedTask(
     51       content::BrowserThread::UI, FROM_HERE,
     52       base::Bind(&DesktopStreamsRegistry::CleanupStream,
     53                  base::Unretained(this), id),
     54       base::TimeDelta::FromSeconds(kApprovedStreamTimeToLiveSeconds));
     55 
     56   return id;
     57 }
     58 
     59 content::DesktopMediaID DesktopStreamsRegistry::RequestMediaForStreamId(
     60     const std::string& id,
     61     int render_process_id,
     62     int render_frame_id,
     63     const GURL& origin,
     64     std::string* extension_name) {
     65   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     66 
     67   StreamsMap::iterator it = approved_streams_.find(id);
     68 
     69   // Verify that if there is a request with the specified ID it was created for
     70   // the same origin and the same renderer.
     71   if (it == approved_streams_.end() ||
     72       render_process_id != it->second.render_process_id ||
     73       render_frame_id != it->second.render_frame_id ||
     74       origin != it->second.origin) {
     75     return content::DesktopMediaID();
     76   }
     77 
     78   content::DesktopMediaID result = it->second.source;
     79   *extension_name = it->second.extension_name;
     80   approved_streams_.erase(it);
     81   return result;
     82 }
     83 
     84 void DesktopStreamsRegistry::CleanupStream(const std::string& id) {
     85   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     86   approved_streams_.erase(id);
     87 }
     88 
     89 DesktopStreamsRegistry::ApprovedDesktopMediaStream::ApprovedDesktopMediaStream()
     90     : render_process_id(-1), render_frame_id(-1) {}
     91