// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/public/browser/desktop_media_id.h" #include #include #include "base/id_map.h" #include "base/macros.h" #include "base/memory/singleton.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" #if defined(USE_AURA) #include "ui/aura/window.h" // nogncheck #include "ui/aura/window_observer.h" // nogncheck #endif // defined(USE_AURA) namespace { #if defined(USE_AURA) class AuraWindowRegistry : public aura::WindowObserver { public: static AuraWindowRegistry* GetInstance() { return base::Singleton::get(); } int RegisterWindow(aura::Window* window) { IDMap::const_iterator it(®istered_windows_); for (; !it.IsAtEnd(); it.Advance()) { if (it.GetCurrentValue() == window) return it.GetCurrentKey(); } window->AddObserver(this); return registered_windows_.Add(window); } aura::Window* GetWindowById(int id) { return registered_windows_.Lookup(id); } private: friend struct base::DefaultSingletonTraits; AuraWindowRegistry() {} ~AuraWindowRegistry() override {} // WindowObserver overrides. void OnWindowDestroying(aura::Window* window) override { IDMap::iterator it(®istered_windows_); for (; !it.IsAtEnd(); it.Advance()) { if (it.GetCurrentValue() == window) { registered_windows_.Remove(it.GetCurrentKey()); return; } } NOTREACHED(); } IDMap registered_windows_; DISALLOW_COPY_AND_ASSIGN(AuraWindowRegistry); }; #endif // defined(USE_AURA) } // namespace namespace content { const char kScreenPrefix[] = "screen"; const char kWindowPrefix[] = "window"; #if defined(USE_AURA) // static DesktopMediaID DesktopMediaID::RegisterAuraWindow(DesktopMediaID::Type type, aura::Window* window) { DCHECK(type == TYPE_SCREEN || type == TYPE_WINDOW); DCHECK(window); DesktopMediaID media_id(type, kNullId); media_id.aura_id = AuraWindowRegistry::GetInstance()->RegisterWindow(window); return media_id; } // static aura::Window* DesktopMediaID::GetAuraWindowById(const DesktopMediaID& id) { return AuraWindowRegistry::GetInstance()->GetWindowById(id.aura_id); } #endif // defined(USE_AURA) bool DesktopMediaID::operator<(const DesktopMediaID& other) const { #if defined(USE_AURA) return std::tie(type, id, aura_id, web_contents_id) < std::tie(other.type, other.id, other.aura_id, other.web_contents_id); #else return std::tie(type, id, web_contents_id) < std::tie(other.type, other.id, other.web_contents_id); #endif } bool DesktopMediaID::operator==(const DesktopMediaID& other) const { #if defined(USE_AURA) return type == other.type && id == other.id && aura_id == other.aura_id && web_contents_id == other.web_contents_id; #else return type == other.type && id == other.id && web_contents_id == other.web_contents_id; #endif } // static // Input string should in format: // for WebContents: // web-contents-media-stream://"render_process_id":"render_process_id" // for no aura screen and window: screen:"window_id" or window:"window_id" // for aura screen and window: screen:"window_id:aura_id" or // window:"window_id:aura_id". DesktopMediaID DesktopMediaID::Parse(const std::string& str) { // For WebContents type. WebContentsMediaCaptureId web_id = WebContentsMediaCaptureId::Parse(str); if (!web_id.is_null()) return DesktopMediaID(TYPE_WEB_CONTENTS, 0, web_id); // For screen and window types. std::vector parts = base::SplitString( str, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); #if defined(USE_AURA) if (parts.size() != 3) return DesktopMediaID(); #else if (parts.size() != 2) return DesktopMediaID(); #endif Type type = TYPE_NONE; if (parts[0] == kScreenPrefix) { type = TYPE_SCREEN; } else if (parts[0] == kWindowPrefix) { type = TYPE_WINDOW; } else { return DesktopMediaID(); } int64_t id; if (!base::StringToInt64(parts[1], &id)) return DesktopMediaID(); DesktopMediaID media_id(type, id); #if defined(USE_AURA) int64_t aura_id; if (!base::StringToInt64(parts[2], &aura_id)) return DesktopMediaID(); media_id.aura_id = aura_id; #endif // defined(USE_AURA) return media_id; } std::string DesktopMediaID::ToString() const { std::string prefix; switch (type) { case TYPE_NONE: NOTREACHED(); return std::string(); case TYPE_SCREEN: prefix = kScreenPrefix; break; case TYPE_WINDOW: prefix = kWindowPrefix; break; case TYPE_WEB_CONTENTS: return web_contents_id.ToString(); break; } DCHECK(!prefix.empty()); // Screen and Window types. prefix.append(":"); prefix.append(base::Int64ToString(id)); #if defined(USE_AURA) prefix.append(":"); prefix.append(base::Int64ToString(aura_id)); #endif // defined(USE_AURA) return prefix; } } // namespace content