blob: 1395acc243f48eef1edcb5b7102eafdd6a54a8a3 [file] [log] [blame]
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/desktop_capture/desktop_capture_api.h"
#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "net/base/url_util.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
namespace extensions {
namespace {
const char kDesktopCaptureApiNoTabIdError[] =
"targetTab doesn't have id field set.";
const char kDesktopCaptureApiNoUrlError[] =
"targetTab doesn't have URL field set.";
const char kDesktopCaptureApiInvalidOriginError[] =
"targetTab.url is not a valid URL.";
const char kDesktopCaptureApiInvalidTabIdError[] = "Invalid tab specified.";
const char kDesktopCaptureApiTabUrlNotSecure[] =
"URL scheme for the specified tab is not secure.";
const char kTargetTabRequiredFromServiceWorker[] =
"A target tab is required when called from a service worker context.";
} // namespace
DesktopCaptureChooseDesktopMediaFunction::
DesktopCaptureChooseDesktopMediaFunction() {
}
DesktopCaptureChooseDesktopMediaFunction::
~DesktopCaptureChooseDesktopMediaFunction() {
}
ExtensionFunction::ResponseAction
DesktopCaptureChooseDesktopMediaFunction::Run() {
EXTENSION_FUNCTION_VALIDATE(args().size() > 0);
const auto& request_id_value = args()[0];
EXTENSION_FUNCTION_VALIDATE(request_id_value.is_int());
request_id_ = request_id_value.GetInt();
DesktopCaptureRequestsRegistry::GetInstance()->AddRequest(source_process_id(),
request_id_, this);
mutable_args().erase(args().begin());
absl::optional<api::desktop_capture::ChooseDesktopMedia::Params> params =
api::desktop_capture::ChooseDesktopMedia::Params::Create(args());
EXTENSION_FUNCTION_VALIDATE(params);
// |target_render_frame_host| is the RenderFrameHost for which the stream is
// created, and will also be used to determine where to show the picker's UI.
content::RenderFrameHost* target_render_frame_host = nullptr;
std::u16string target_name;
GURL origin;
if (params->target_tab) {
if (!params->target_tab->url) {
return RespondNow(Error(kDesktopCaptureApiNoUrlError));
}
origin = GURL(*(params->target_tab->url)).DeprecatedGetOriginAsURL();
if (!origin.is_valid()) {
return RespondNow(Error(kDesktopCaptureApiInvalidOriginError));
}
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
::switches::kAllowHttpScreenCapture) &&
!network::IsUrlPotentiallyTrustworthy(origin)) {
return RespondNow(Error(kDesktopCaptureApiTabUrlNotSecure));
}
target_name = base::UTF8ToUTF16(network::IsUrlPotentiallyTrustworthy(origin)
? net::GetHostAndOptionalPort(origin)
: origin.spec());
if (!params->target_tab->id ||
*params->target_tab->id == api::tabs::TAB_ID_NONE) {
return RespondNow(Error(kDesktopCaptureApiNoTabIdError));
}
content::WebContents* web_contents = nullptr;
if (!ExtensionTabUtil::GetTabById(
*(params->target_tab->id),
Profile::FromBrowserContext(browser_context()), true,
&web_contents)) {
return RespondNow(Error(kDesktopCaptureApiInvalidTabIdError));
}
// The |target_render_frame_host| is the main frame of the tab that
// was requested for capture.
target_render_frame_host = web_contents->GetPrimaryMainFrame();
} else {
origin = extension()->url();
target_name = base::UTF8ToUTF16(GetExtensionTargetName());
target_render_frame_host = render_frame_host();
}
if (!target_render_frame_host)
return RespondNow(Error(kTargetTabRequiredFromServiceWorker));
const bool exclude_system_audio =
params->options &&
params->options->system_audio ==
api::desktop_capture::SYSTEM_AUDIO_PREFERENCE_ENUM_EXCLUDE;
const bool exclude_self_browser_surface =
params->options &&
params->options->self_browser_surface ==
api::desktop_capture::SELF_CAPTURE_PREFERENCE_ENUM_EXCLUDE;
const bool suppress_local_audio_playback_intended =
params->options &&
params->options->suppress_local_audio_playback_intended;
return Execute(params->sources, exclude_system_audio,
exclude_self_browser_surface,
suppress_local_audio_playback_intended,
target_render_frame_host, origin, target_name);
}
std::string DesktopCaptureChooseDesktopMediaFunction::GetExtensionTargetName()
const {
return GetCallerDisplayName();
}
DesktopCaptureCancelChooseDesktopMediaFunction::
DesktopCaptureCancelChooseDesktopMediaFunction() {}
DesktopCaptureCancelChooseDesktopMediaFunction::
~DesktopCaptureCancelChooseDesktopMediaFunction() {}
} // namespace extensions