summaryrefslogtreecommitdiff
path: root/chromium/chrome/common/media_router/media_source.cc
blob: dbad598d35fab42702657cdd34352120eea1a609 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2015 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 "chrome/common/media_router/media_source.h"

#include <algorithm>
#include <array>
#include <cstdio>
#include <ostream>
#include <string>

#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "chrome/common/media_router/media_source.h"
#include "url/gurl.h"

namespace media_router {

namespace {

// Prefixes used to format and detect various protocols' media source URNs.
// See: https://www.ietf.org/rfc/rfc3406.txt
constexpr char kTabMediaUrnFormat[] = "urn:x-org.chromium.media:source:tab:%d";
constexpr char kDesktopMediaUrn[] = "urn:x-org.chromium.media:source:desktop";
constexpr char kTabRemotingUrnFormat[] =
    "urn:x-org.chromium.media:source:tab_content_remoting:%d";

// List of non-http(s) schemes that are allowed in a Presentation URL.
constexpr std::array<const char* const, 5> kAllowedSchemes{
    {kCastPresentationUrlScheme, kCastDialPresentationUrlScheme,
     kDialPresentationUrlScheme, kRemotePlaybackPresentationUrlScheme, "test"}};

bool IsSchemeAllowed(const GURL& url) {
  return url.SchemeIsHTTPOrHTTPS() ||
         std::any_of(
             kAllowedSchemes.begin(), kAllowedSchemes.end(),
             [&url](const char* const scheme) { return url.SchemeIs(scheme); });
}

}  // namespace

bool IsLegacyCastPresentationUrl(const GURL& url) {
  return base::StartsWith(url.spec(), kLegacyCastPresentationUrlPrefix,
                          base::CompareCase::INSENSITIVE_ASCII);
}

bool IsValidPresentationUrl(const GURL& url) {
  return url.is_valid() && IsSchemeAllowed(url);
}

bool IsAutoJoinPresentationId(const std::string& presentation_id) {
  return presentation_id == kAutoJoinPresentationId;
}

MediaSource::MediaSource() = default;

MediaSource::MediaSource(const MediaSource::Id& source_id) : id_(source_id) {
  GURL url(source_id);
  if (IsValidPresentationUrl(url))
    url_ = url;
}

MediaSource::MediaSource(const GURL& presentation_url)
    : id_(presentation_url.spec()), url_(presentation_url) {}

MediaSource::~MediaSource() = default;

// static
MediaSource MediaSource::ForTab(int tab_id) {
  return MediaSource(base::StringPrintf(kTabMediaUrnFormat, tab_id));
}

// static
MediaSource MediaSource::ForTabContentRemoting(int tab_id) {
  return MediaSource(base::StringPrintf(kTabRemotingUrnFormat, tab_id));
}

// static
MediaSource MediaSource::ForDesktop() {
  return MediaSource(std::string(kDesktopMediaUrn));
}

// static
MediaSource MediaSource::ForPresentationUrl(const GURL& presentation_url) {
  return MediaSource(presentation_url);
}

bool MediaSource::IsDesktopMirroringSource() const {
  return base::StartsWith(id(), kDesktopMediaUrn, base::CompareCase::SENSITIVE);
}

bool MediaSource::IsTabMirroringSource() const {
  int tab_id;
  return std::sscanf(id_.c_str(), kTabMediaUrnFormat, &tab_id) == 1 &&
         tab_id > 0;
}

bool MediaSource::IsMirroringSource() const {
  return IsDesktopMirroringSource() || IsTabMirroringSource();
}

bool MediaSource::IsCastPresentationUrl() const {
  return url_.SchemeIs(kCastPresentationUrlScheme) ||
         IsLegacyCastPresentationUrl(url_);
}

int MediaSource::TabId() const {
  int tab_id;
  if (sscanf(id_.c_str(), kTabMediaUrnFormat, &tab_id) == 1)
    return tab_id;
  else if (sscanf(id_.c_str(), kTabRemotingUrnFormat, &tab_id) == 1)
    return tab_id;
  else
    return -1;
}

bool MediaSource::IsValid() const {
  return TabId() > 0 || IsDesktopMirroringSource() ||
         IsValidPresentationUrl(GURL(id_));
}

bool MediaSource::IsDialSource() const {
  return url_.SchemeIs(kCastDialPresentationUrlScheme);
}

std::string MediaSource::AppNameFromDialSource() const {
  return IsDialSource() ? url_.path() : "";
}

}  // namespace media_router