13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file.
43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/media/desktop_streams_registry.h"
63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/base64.h"
83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/location.h"
93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/time/time.h"
103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "crypto/random.h"
123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace {
143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kStreamIdLengthBytes = 16;
163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kApprovedStreamTimeToLiveSeconds = 10;
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)std::string GenerateRandomStreamId() {
203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  char buffer[kStreamIdLengthBytes];
213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  crypto::RandBytes(buffer, arraysize(buffer));
223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string result;
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::Base64Encode(base::StringPiece(buffer, arraysize(buffer)),
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     &result);
253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return result;
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}  // namespace
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)DesktopStreamsRegistry::DesktopStreamsRegistry() {}
313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)DesktopStreamsRegistry::~DesktopStreamsRegistry() {}
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)std::string DesktopStreamsRegistry::RegisterStream(
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int render_process_id,
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int render_frame_id,
363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const GURL& origin,
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const content::DesktopMediaID& source,
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& extension_name) {
393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string id = GenerateRandomStreamId();
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(approved_streams_.find(id) == approved_streams_.end());
433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ApprovedDesktopMediaStream& stream = approved_streams_[id];
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  stream.render_process_id = render_process_id;
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  stream.render_frame_id = render_frame_id;
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  stream.origin = origin;
473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  stream.source = source;
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  stream.extension_name = extension_name;
493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  content::BrowserThread::PostDelayedTask(
513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      content::BrowserThread::UI, FROM_HERE,
523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      base::Bind(&DesktopStreamsRegistry::CleanupStream,
533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                 base::Unretained(this), id),
543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      base::TimeDelta::FromSeconds(kApprovedStreamTimeToLiveSeconds));
553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return id;
573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)content::DesktopMediaID DesktopStreamsRegistry::RequestMediaForStreamId(
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& id,
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int render_process_id,
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int render_frame_id,
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const GURL& origin,
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    std::string* extension_name) {
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StreamsMap::iterator it = approved_streams_.find(id);
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Verify that if there is a request with the specified ID it was created for
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // the same origin and the same renderer.
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (it == approved_streams_.end() ||
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      render_process_id != it->second.render_process_id ||
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      render_frame_id != it->second.render_frame_id ||
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      origin != it->second.origin) {
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return content::DesktopMediaID();
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  content::DesktopMediaID result = it->second.source;
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  *extension_name = it->second.extension_name;
803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  approved_streams_.erase(it);
813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return result;
823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void DesktopStreamsRegistry::CleanupStream(const std::string& id) {
853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  approved_streams_.erase(id);
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)DesktopStreamsRegistry::ApprovedDesktopMediaStream::ApprovedDesktopMediaStream()
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : render_process_id(-1), render_frame_id(-1) {}
91