blob: 7ab5164cd259debb2799f9d85c39cc5497a61295 [file] [log] [blame]
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "cobalt/h5vcc/h5vcc_accessibility.h"
#include "base/command_line.h"
#include "base/message_loop.h"
#include "cobalt/accessibility/starboard_tts_engine.h"
#include "cobalt/accessibility/tts_engine.h"
#include "cobalt/accessibility/tts_logger.h"
#include "cobalt/base/accessibility_settings_changed_event.h"
#include "cobalt/browser/switches.h"
#include "starboard/accessibility.h"
#include "starboard/memory.h"
namespace cobalt {
namespace h5vcc {
namespace {
bool ShouldForceTextToSpeech() {
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
// Check for a command-line override to enable TTS.
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(browser::switches::kUseTTS)) {
return true;
}
#endif // defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
return false;
}
#if SB_HAS(SPEECH_SYNTHESIS)
bool IsTextToSpeechEnabled() {
// Check if the tts feature is enabled in Starboard.
SbAccessibilityTextToSpeechSettings tts_settings = {0};
// Check platform settings.
if (SbAccessibilityGetTextToSpeechSettings(&tts_settings)) {
return tts_settings.has_text_to_speech_setting &&
tts_settings.is_text_to_speech_enabled;
}
return false;
}
#endif // SB_HAS(SPEECH_SYNTHESIS)
} // namespace
H5vccAccessibility::H5vccAccessibility(
base::EventDispatcher* event_dispatcher,
const scoped_refptr<dom::Window>& window,
dom::MutationObserverTaskManager* mutation_observer_task_manager)
: event_dispatcher_(event_dispatcher) {
message_loop_proxy_ = base::MessageLoopProxy::current();
event_dispatcher_->AddEventCallback(
base::AccessibilitySettingsChangedEvent::TypeId(),
base::Bind(&H5vccAccessibility::OnApplicationEvent,
base::Unretained(this)));
if (ShouldForceTextToSpeech()) {
#if SB_HAS(SPEECH_SYNTHESIS)
// Create a StarboardTTSEngine if the platform has speech synthesis.
tts_engine_.reset(new accessibility::StarboardTTSEngine());
#else
tts_engine_.reset(new accessibility::TTSLogger());
#endif
}
#if SB_HAS(SPEECH_SYNTHESIS)
if (!tts_engine_ && IsTextToSpeechEnabled()) {
// Create a StarboardTTSEngine if TTS is enabled.
tts_engine_.reset(new accessibility::StarboardTTSEngine());
}
#endif
if (tts_engine_) {
screen_reader_.reset(new accessibility::ScreenReader(
window->document(), tts_engine_.get(), mutation_observer_task_manager));
}
}
bool H5vccAccessibility::built_in_screen_reader() const {
return screen_reader_ && screen_reader_->enabled();
}
void H5vccAccessibility::set_built_in_screen_reader(bool value) {
if (!screen_reader_) {
LOG(WARNING) << "h5vcc.accessibility.builtInScreenReader: not available";
return;
}
screen_reader_->set_enabled(value);
}
bool H5vccAccessibility::high_contrast_text() const {
SbAccessibilityDisplaySettings settings;
SbMemorySet(&settings, 0, sizeof(settings));
if (!SbAccessibilityGetDisplaySettings(&settings)) {
return false;
}
return settings.is_high_contrast_text_enabled;
}
bool H5vccAccessibility::text_to_speech() const {
SbAccessibilityTextToSpeechSettings settings;
SbMemorySet(&settings, 0, sizeof(settings));
if (!SbAccessibilityGetTextToSpeechSettings(&settings)) {
return false;
}
return settings.has_text_to_speech_setting &&
settings.is_text_to_speech_enabled;
}
void H5vccAccessibility::AddHighContrastTextListener(
const H5vccAccessibilityCallbackHolder& holder) {
DCHECK_EQ(base::MessageLoopProxy::current(), message_loop_proxy_);
high_contrast_text_listener_.reset(
new H5vccAccessibilityCallbackReference(this, holder));
}
void H5vccAccessibility::OnApplicationEvent(const base::Event* event) {
UNREFERENCED_PARAMETER(event);
// This method should be called from the application event thread.
DCHECK_NE(base::MessageLoopProxy::current(), message_loop_proxy_);
message_loop_proxy_->PostTask(
FROM_HERE, base::Bind(&H5vccAccessibility::InternalOnApplicationEvent,
base::Unretained(this)));
}
void H5vccAccessibility::InternalOnApplicationEvent() {
DCHECK_EQ(base::MessageLoopProxy::current(), message_loop_proxy_);
if (high_contrast_text_listener_) {
high_contrast_text_listener_->value().Run();
}
}
} // namespace h5vcc
} // namespace cobalt