blob: 4a2221485cdd2c85b18a275e7a27f26c8abbb1f8 [file] [log] [blame]
// Copyright (c) 2012 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/browser/speech/chrome_speech_recognition_manager_delegate.h"
#include <string>
#include "base/bind.h"
#include "base/macros.h"
#include "base/task/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/speech_recognition_manager.h"
#include "content/public/browser/speech_recognition_session_context.h"
#include "content/public/browser/web_contents.h"
#include "third_party/blink/public/mojom/speech/speech_recognition_error.mojom.h"
#include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/extension_service.h"
#include "extensions/browser/view_type_utils.h"
#endif
using content::BrowserThread;
using content::SpeechRecognitionManager;
using content::WebContents;
namespace speech {
ChromeSpeechRecognitionManagerDelegate
::ChromeSpeechRecognitionManagerDelegate() {
}
ChromeSpeechRecognitionManagerDelegate
::~ChromeSpeechRecognitionManagerDelegate() {
}
void ChromeSpeechRecognitionManagerDelegate::OnRecognitionStart(
int session_id) {
}
void ChromeSpeechRecognitionManagerDelegate::OnAudioStart(int session_id) {
}
void ChromeSpeechRecognitionManagerDelegate::OnEnvironmentEstimationComplete(
int session_id) {
}
void ChromeSpeechRecognitionManagerDelegate::OnSoundStart(int session_id) {
}
void ChromeSpeechRecognitionManagerDelegate::OnSoundEnd(int session_id) {
}
void ChromeSpeechRecognitionManagerDelegate::OnAudioEnd(int session_id) {
}
void ChromeSpeechRecognitionManagerDelegate::OnRecognitionResults(
int session_id,
const std::vector<blink::mojom::SpeechRecognitionResultPtr>& result) {}
void ChromeSpeechRecognitionManagerDelegate::OnRecognitionError(
int session_id,
const blink::mojom::SpeechRecognitionError& error) {}
void ChromeSpeechRecognitionManagerDelegate::OnAudioLevelsChange(
int session_id, float volume, float noise_volume) {
}
void ChromeSpeechRecognitionManagerDelegate::OnRecognitionEnd(int session_id) {
}
void ChromeSpeechRecognitionManagerDelegate::CheckRecognitionIsAllowed(
int session_id,
base::OnceCallback<void(bool ask_user, bool is_allowed)> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
const content::SpeechRecognitionSessionContext& context =
SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
// Make sure that initiators (extensions/web pages) properly set the
// |render_process_id| field, which is needed later to retrieve the profile.
DCHECK_NE(context.render_process_id, 0);
int render_process_id = context.render_process_id;
int render_frame_id = context.render_frame_id;
if (context.embedder_render_process_id) {
// If this is a request originated from a guest, we need to re-route the
// permission check through the embedder (app).
render_process_id = context.embedder_render_process_id;
render_frame_id = context.embedder_render_frame_id;
}
// Check that the render frame type is appropriate, and whether or not we
// need to request permission from the user.
base::PostTask(FROM_HERE, {BrowserThread::UI},
base::BindOnce(&CheckRenderFrameType, std::move(callback),
render_process_id, render_frame_id));
}
content::SpeechRecognitionEventListener*
ChromeSpeechRecognitionManagerDelegate::GetEventListener() {
return this;
}
bool ChromeSpeechRecognitionManagerDelegate::FilterProfanities(
int render_process_id) {
content::RenderProcessHost* rph =
content::RenderProcessHost::FromID(render_process_id);
if (!rph) // Guard against race conditions on RPH lifetime.
return true;
return Profile::FromBrowserContext(rph->GetBrowserContext())->GetPrefs()->
GetBoolean(prefs::kSpeechRecognitionFilterProfanities);
}
// static.
void ChromeSpeechRecognitionManagerDelegate::CheckRenderFrameType(
base::OnceCallback<void(bool ask_user, bool is_allowed)> callback,
int render_process_id,
int render_frame_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
content::RenderFrameHost* render_frame_host =
content::RenderFrameHost::FromID(render_process_id, render_frame_id);
bool allowed = false;
bool check_permission = false;
if (!render_frame_host) {
// This happens for extensions. Manifest should be checked for permission.
allowed = true;
check_permission = false;
base::PostTask(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), check_permission, allowed));
return;
}
#if BUILDFLAG(ENABLE_EXTENSIONS)
WebContents* web_contents =
WebContents::FromRenderFrameHost(render_frame_host);
extensions::ViewType view_type = extensions::GetViewType(web_contents);
if (view_type == extensions::VIEW_TYPE_TAB_CONTENTS ||
view_type == extensions::VIEW_TYPE_APP_WINDOW ||
view_type == extensions::VIEW_TYPE_COMPONENT ||
view_type == extensions::VIEW_TYPE_EXTENSION_POPUP ||
view_type == extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
// If it is a tab, we can check for permission. For apps, this means
// manifest would be checked for permission.
allowed = true;
check_permission = true;
}
#else
// Otherwise this should be a regular tab contents.
allowed = true;
check_permission = true;
#endif
base::PostTask(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), check_permission, allowed));
}
} // namespace speech