Bug 1184142 - Support WebSpeech in GeckoView. r=snorp r=smaug

--HG--
extra : rebase_source : 81eb1ce2f67f70ee08908d69db54f8625df341cb
This commit is contained in:
Eitan Isaacson 2018-03-16 12:08:00 +02:00
parent 0ee918977a
commit f765d0d585
9 changed files with 811 additions and 0 deletions

View File

@ -0,0 +1,49 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ModuleUtils.h"
#include "SpeechSynthesisService.h"
using namespace mozilla::dom;
#define ANDROIDSPEECHSERVICE_CID \
{0x311b2dab, 0xf4d3, 0x4be4, {0x81, 0x23, 0x67, 0x32, 0x31, 0x3d, 0x95, 0xc2}}
#define ANDROIDSPEECHSERVICE_CONTRACTID "@mozilla.org/androidspeechsynth;1"
// Defines AndroidSpeechServiceConstructor
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(SpeechSynthesisService,
SpeechSynthesisService::GetInstanceForService)
// Defines kANDROIDSPEECHSERVICE_CID
NS_DEFINE_NAMED_CID(ANDROIDSPEECHSERVICE_CID);
static const mozilla::Module::CIDEntry kCIDs[] = {
{ &kANDROIDSPEECHSERVICE_CID, true, nullptr, SpeechSynthesisServiceConstructor },
{ nullptr }
};
static const mozilla::Module::ContractIDEntry kContracts[] = {
{ ANDROIDSPEECHSERVICE_CONTRACTID, &kANDROIDSPEECHSERVICE_CID },
{ nullptr }
};
static const mozilla::Module::CategoryEntry kCategories[] = {
{ "speech-synth-started", "Android Speech Synth", ANDROIDSPEECHSERVICE_CONTRACTID },
{ nullptr }
};
static const mozilla::Module kModule = {
mozilla::Module::kVersion,
kCIDs,
kContracts,
kCategories,
nullptr,
nullptr,
nullptr,
};
NSMODULE_DEFN(androidspeechsynth) = &kModule;

View File

@ -0,0 +1,245 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SpeechSynthesisService.h"
#include <android/log.h>
#include "nsXULAppAPI.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/nsSynthVoiceRegistry.h"
#include "mozilla/jni/Utils.h"
#include "mozilla/Preferences.h"
#define ALOG(args...) \
__android_log_print(ANDROID_LOG_INFO, "GeckoSpeechSynthesis", ##args)
namespace mozilla {
namespace dom {
StaticRefPtr<SpeechSynthesisService> SpeechSynthesisService::sSingleton;
class AndroidSpeechCallback final : public nsISpeechTaskCallback
{
public:
AndroidSpeechCallback()
{
}
NS_DECL_ISUPPORTS
NS_IMETHOD OnResume() override { return NS_OK; }
NS_IMETHOD OnPause() override { return NS_OK; }
NS_IMETHOD OnCancel() override
{
java::SpeechSynthesisService::Stop();
return NS_OK;
}
NS_IMETHOD OnVolumeChanged(float aVolume) override { return NS_OK; }
private:
~AndroidSpeechCallback() {}
};
NS_IMPL_ISUPPORTS(AndroidSpeechCallback, nsISpeechTaskCallback)
NS_IMPL_ISUPPORTS(SpeechSynthesisService, nsISpeechService)
void
SpeechSynthesisService::Setup()
{
ALOG("SpeechSynthesisService::Setup");
if (!Preferences::GetBool("media.webspeech.synth.enabled") ||
Preferences::GetBool("media.webspeech.synth.test")) {
return;
}
if (!jni::IsAvailable()) {
NS_WARNING("Failed to initialize speech synthesis");
return;
}
Init();
java::SpeechSynthesisService::InitSynth();
}
// nsISpeechService
NS_IMETHODIMP
SpeechSynthesisService::Speak(const nsAString& aText,
const nsAString& aUri,
float aVolume,
float aRate,
float aPitch,
nsISpeechTask* aTask)
{
if (mTask) {
NS_WARNING("Service only supports one speech task at a time.");
return NS_ERROR_NOT_AVAILABLE;
}
RefPtr<AndroidSpeechCallback> callback = new AndroidSpeechCallback();
nsresult rv = aTask->Setup(callback);
if (NS_FAILED(rv)) {
return rv;
}
jni::String::LocalRef utteranceId =
java::SpeechSynthesisService::Speak(aUri, aText, aRate, aPitch, aVolume);
if (!utteranceId) {
return NS_ERROR_NOT_AVAILABLE;
}
mTaskUtteranceId = utteranceId->ToCString();
mTask = aTask;
mTaskTextLength = aText.Length();
mTaskTextOffset = 0;
return NS_OK;
}
SpeechSynthesisService*
SpeechSynthesisService::GetInstance(bool aCreate)
{
if (XRE_GetProcessType() != GeckoProcessType_Default) {
MOZ_ASSERT(
false,
"SpeechSynthesisService can only be started on main gecko process");
return nullptr;
}
if (!sSingleton && aCreate) {
sSingleton = new SpeechSynthesisService();
sSingleton->Setup();
ClearOnShutdown(&sSingleton);
}
return sSingleton;
}
already_AddRefed<SpeechSynthesisService>
SpeechSynthesisService::GetInstanceForService()
{
MOZ_ASSERT(NS_IsMainThread());
RefPtr<SpeechSynthesisService> sapiService = GetInstance();
return sapiService.forget();
}
// JNI
void
SpeechSynthesisService::RegisterVoice(jni::String::Param aUri,
jni::String::Param aName,
jni::String::Param aLocale,
bool aIsNetwork,
bool aIsDefault)
{
nsSynthVoiceRegistry* registry = nsSynthVoiceRegistry::GetInstance();
SpeechSynthesisService* service = SpeechSynthesisService::GetInstance(false);
// This service can only speak one utterance at a time, so we set
// aQueuesUtterances to true in order to track global state and schedule
// access to this service.
DebugOnly<nsresult> rv = registry->AddVoice(service,
aUri->ToString(),
aName->ToString(),
aLocale->ToString(),
!aIsNetwork,
true);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to add voice");
if (aIsDefault) {
DebugOnly<nsresult> rv = registry->SetDefaultVoice(aUri->ToString(), true);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to set voice as default");
}
}
void
SpeechSynthesisService::DoneRegisteringVoices()
{
nsSynthVoiceRegistry* registry = nsSynthVoiceRegistry::GetInstance();
registry->NotifyVoicesChanged();
}
void
SpeechSynthesisService::DispatchStart(jni::String::Param aUtteranceId)
{
if (sSingleton) {
MOZ_ASSERT(sSingleton->mTaskUtteranceId.Equals(aUtteranceId->ToCString()));
nsCOMPtr<nsISpeechTask> task = sSingleton->mTask;
if (task) {
sSingleton->mTaskStartTime = TimeStamp::Now();
DebugOnly<nsresult> rv = task->DispatchStart();
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Unable to dispatch start");
}
}
}
void
SpeechSynthesisService::DispatchEnd(jni::String::Param aUtteranceId)
{
if (sSingleton) {
// In API older than 23, we will sometimes call this function
// without providing an utterance ID.
MOZ_ASSERT(!aUtteranceId ||
sSingleton->mTaskUtteranceId.Equals(aUtteranceId->ToCString()));
nsCOMPtr<nsISpeechTask> task = sSingleton->mTask;
sSingleton->mTask = nullptr;
if (task) {
TimeStamp startTime = sSingleton->mTaskStartTime;
DebugOnly<nsresult> rv = task->DispatchEnd(
(TimeStamp::Now() - startTime).ToSeconds(), sSingleton->mTaskTextLength);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Unable to dispatch start");
}
}
}
void
SpeechSynthesisService::DispatchError(jni::String::Param aUtteranceId)
{
if (sSingleton) {
MOZ_ASSERT(sSingleton->mTaskUtteranceId.Equals(aUtteranceId->ToCString()));
nsCOMPtr<nsISpeechTask> task = sSingleton->mTask;
sSingleton->mTask = nullptr;
if (task) {
TimeStamp startTime = sSingleton->mTaskStartTime;
DebugOnly<nsresult> rv = task->DispatchError(
(TimeStamp::Now() - startTime).ToSeconds(), sSingleton->mTaskTextOffset);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Unable to dispatch start");
}
}
}
void
SpeechSynthesisService::DispatchBoundary(jni::String::Param aUtteranceId,
int32_t aStart,
int32_t aEnd)
{
if (sSingleton) {
MOZ_ASSERT(sSingleton->mTaskUtteranceId.Equals(aUtteranceId->ToCString()));
nsCOMPtr<nsISpeechTask> task = sSingleton->mTask;
if (task) {
TimeStamp startTime = sSingleton->mTaskStartTime;
sSingleton->mTaskTextOffset = aStart;
DebugOnly<nsresult> rv =
task->DispatchBoundary(NS_LITERAL_STRING("word"),
(TimeStamp::Now() - startTime).ToSeconds(),
aStart,
aEnd - aStart,
1);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Unable to dispatch boundary");
}
}
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,72 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SpeechSynthesisService_h
#define mozilla_dom_SpeechSynthesisService_h
#include "GeneratedJNINatives.h"
#include "nsISpeechService.h"
#include "mozilla/StaticPtr.h"
namespace mozilla {
namespace dom {
class SpeechSynthesisService final
: public nsISpeechService
, public java::SpeechSynthesisService::Natives<SpeechSynthesisService>
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISPEECHSERVICE
SpeechSynthesisService(){};
void Setup();
static void DoneRegisteringVoices();
static void RegisterVoice(jni::String::Param aUri,
jni::String::Param aName,
jni::String::Param aLocale,
bool aIsNetwork,
bool aIsDefault);
static void DispatchStart(jni::String::Param aUtteranceId);
static void DispatchEnd(jni::String::Param aUtteranceId);
static void DispatchError(jni::String::Param aUtteranceId);
static void DispatchBoundary(jni::String::Param aUtteranceId,
int32_t aStart,
int32_t aEnd);
static SpeechSynthesisService* GetInstance(bool aCreate = true);
static already_AddRefed<SpeechSynthesisService> GetInstanceForService();
static StaticRefPtr<SpeechSynthesisService> sSingleton;
private:
virtual ~SpeechSynthesisService(){};
nsCOMPtr<nsISpeechTask> mTask;
// Unique ID assigned to utterance when it is sent to system service.
nsCString mTaskUtteranceId;
// Time stamp from the moment the utterance is started.
TimeStamp mTaskStartTime;
// Length of text of the utterance.
uint32_t mTaskTextLength;
// Current offset in characters of what has been spoken.
uint32_t mTaskTextOffset;
};
} // namespace dom
} // namespace mozilla
#endif

View File

@ -0,0 +1,15 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.dom += ['SpeechSynthesisService.h']
UNIFIED_SOURCES += [
'AndroidSpeechModule.cpp',
'SpeechSynthesisService.cpp'
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'

View File

@ -48,6 +48,9 @@ if CONFIG['MOZ_WEBSPEECH']:
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
DIRS += ['cocoa']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
DIRS += ['android']
if CONFIG['MOZ_SYNTH_SPEECHD']:
DIRS += ['speechd']

View File

@ -0,0 +1,159 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil -*- */
/* vim: set ts=20 sts=4 et sw=4: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.util.ThreadUtils;
import android.content.Context;
import android.os.Build;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.util.Log;
import java.lang.System;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;
public class SpeechSynthesisService {
private static final String LOGTAG = "GeckoSpeechSynthesis";
private static TextToSpeech sTTS;
@WrapForJNI(calledFrom = "gecko")
public static void initSynth() {
if (sTTS != null) {
return;
}
final Context ctx = GeckoAppShell.getApplicationContext();
sTTS = new TextToSpeech(ctx, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if (status != TextToSpeech.SUCCESS) {
Log.w(LOGTAG, "Failed to initialize TextToSpeech");
return;
}
setUtteranceListener();
registerVoicesByLocale();
}
});
}
private static void registerVoicesByLocale() {
ThreadUtils.postToBackgroundThread(new Runnable() {
@Override
public void run() {
Locale defaultLocale = sTTS.getDefaultLanguage();
for (Locale locale : getAvailableLanguages()) {
final Set<String> features = sTTS.getFeatures(locale);
boolean isLocal = features.contains(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS);
String localeStr = locale.toString();
registerVoice("moz-tts:android:" + localeStr, locale.getDisplayName(), localeStr.replace("_", "-"), !isLocal, defaultLocale == locale);
}
doneRegisteringVoices();
}
});
}
private static Set<Locale> getAvailableLanguages() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return sTTS.getAvailableLanguages();
}
Set<Locale> locales = new HashSet<Locale>();
for (Locale locale : Locale.getAvailableLocales()) {
if (locale.getVariant().isEmpty() && sTTS.isLanguageAvailable(locale) > 0) {
locales.add(locale);
}
}
return locales;
}
@WrapForJNI(dispatchTo = "gecko")
private static native void registerVoice(String uri, String name, String locale, boolean isNetwork, boolean isDefault);
@WrapForJNI(dispatchTo = "gecko")
private static native void doneRegisteringVoices();
@WrapForJNI(calledFrom = "gecko")
public static String speak(final String uri, final String text, float rate, float pitch, float volume) {
HashMap<String, String> params = new HashMap<String, String>();
final String utteranceId = UUID.randomUUID().toString();
params.put(TextToSpeech.Engine.KEY_PARAM_VOLUME, Float.toString(volume));
params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utteranceId);
sTTS.setLanguage(new Locale(uri.substring("moz-tts:android:".length())));
sTTS.setSpeechRate(rate);
sTTS.setPitch(pitch);
int result = sTTS.speak(text, TextToSpeech.QUEUE_FLUSH, params);
if (result != TextToSpeech.SUCCESS) {
return null;
}
return utteranceId;
}
private static void setUtteranceListener() {
sTTS.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onDone(String utteranceId) {
dispatchEnd(utteranceId);
}
@Override
public void onError(String utteranceId) {
dispatchError(utteranceId);
}
@Override
public void onStart(String utteranceId) {
dispatchStart(utteranceId);
}
@Override
public void onStop(String utteranceId, boolean interrupted) {
if (interrupted) {
dispatchEnd(utteranceId);
} else {
// utterance isn't started yet.
dispatchError(utteranceId);
}
}
public void onRangeStart (String utteranceId, int start, int end, int frame) {
dispatchBoundary(utteranceId, start, end);
}
});
}
@WrapForJNI(dispatchTo = "gecko")
private static native void dispatchStart(String utteranceId);
@WrapForJNI(dispatchTo = "gecko")
private static native void dispatchEnd(String utteranceId);
@WrapForJNI(dispatchTo = "gecko")
private static native void dispatchError(String utteranceId);
@WrapForJNI(dispatchTo = "gecko")
private static native void dispatchBoundary(String utteranceId, int start, int end);
@WrapForJNI(calledFrom = "gecko")
public static void stop() {
sTTS.stop();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Android M has onStop method. If Android L or above, dispatch
// event
dispatchEnd(null);
}
}
}

View File

@ -326,6 +326,41 @@ const JNINativeMethod ScreenManagerHelper::Natives<Impl>::methods[] = {
::template Wrap<&Impl::RemoveDisplay>)
};
template<class Impl>
class SpeechSynthesisService::Natives : public mozilla::jni::NativeImpl<SpeechSynthesisService, Impl>
{
public:
static const JNINativeMethod methods[6];
};
template<class Impl>
const JNINativeMethod SpeechSynthesisService::Natives<Impl>::methods[] = {
mozilla::jni::MakeNativeMethod<SpeechSynthesisService::DispatchBoundary_t>(
mozilla::jni::NativeStub<SpeechSynthesisService::DispatchBoundary_t, Impl>
::template Wrap<&Impl::DispatchBoundary>),
mozilla::jni::MakeNativeMethod<SpeechSynthesisService::DispatchEnd_t>(
mozilla::jni::NativeStub<SpeechSynthesisService::DispatchEnd_t, Impl>
::template Wrap<&Impl::DispatchEnd>),
mozilla::jni::MakeNativeMethod<SpeechSynthesisService::DispatchError_t>(
mozilla::jni::NativeStub<SpeechSynthesisService::DispatchError_t, Impl>
::template Wrap<&Impl::DispatchError>),
mozilla::jni::MakeNativeMethod<SpeechSynthesisService::DispatchStart_t>(
mozilla::jni::NativeStub<SpeechSynthesisService::DispatchStart_t, Impl>
::template Wrap<&Impl::DispatchStart>),
mozilla::jni::MakeNativeMethod<SpeechSynthesisService::DoneRegisteringVoices_t>(
mozilla::jni::NativeStub<SpeechSynthesisService::DoneRegisteringVoices_t, Impl>
::template Wrap<&Impl::DoneRegisteringVoices>),
mozilla::jni::MakeNativeMethod<SpeechSynthesisService::RegisterVoice_t>(
mozilla::jni::NativeStub<SpeechSynthesisService::RegisterVoice_t, Impl>
::template Wrap<&Impl::RegisterVoice>)
};
template<class Impl>
class SurfaceTextureListener::Natives : public mozilla::jni::NativeImpl<SurfaceTextureListener, Impl>
{

View File

@ -1017,6 +1017,51 @@ constexpr char ScreenManagerHelper::AddDisplay_t::signature[];
constexpr char ScreenManagerHelper::RemoveDisplay_t::name[];
constexpr char ScreenManagerHelper::RemoveDisplay_t::signature[];
const char SpeechSynthesisService::name[] =
"org/mozilla/gecko/SpeechSynthesisService";
constexpr char SpeechSynthesisService::DispatchBoundary_t::name[];
constexpr char SpeechSynthesisService::DispatchBoundary_t::signature[];
constexpr char SpeechSynthesisService::DispatchEnd_t::name[];
constexpr char SpeechSynthesisService::DispatchEnd_t::signature[];
constexpr char SpeechSynthesisService::DispatchError_t::name[];
constexpr char SpeechSynthesisService::DispatchError_t::signature[];
constexpr char SpeechSynthesisService::DispatchStart_t::name[];
constexpr char SpeechSynthesisService::DispatchStart_t::signature[];
constexpr char SpeechSynthesisService::DoneRegisteringVoices_t::name[];
constexpr char SpeechSynthesisService::DoneRegisteringVoices_t::signature[];
constexpr char SpeechSynthesisService::InitSynth_t::name[];
constexpr char SpeechSynthesisService::InitSynth_t::signature[];
auto SpeechSynthesisService::InitSynth() -> void
{
return mozilla::jni::Method<InitSynth_t>::Call(SpeechSynthesisService::Context(), nullptr);
}
constexpr char SpeechSynthesisService::RegisterVoice_t::name[];
constexpr char SpeechSynthesisService::RegisterVoice_t::signature[];
constexpr char SpeechSynthesisService::Speak_t::name[];
constexpr char SpeechSynthesisService::Speak_t::signature[];
auto SpeechSynthesisService::Speak(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1, float a2, float a3, float a4) -> mozilla::jni::String::LocalRef
{
return mozilla::jni::Method<Speak_t>::Call(SpeechSynthesisService::Context(), nullptr, a0, a1, a2, a3, a4);
}
constexpr char SpeechSynthesisService::Stop_t::name[];
constexpr char SpeechSynthesisService::Stop_t::signature[];
auto SpeechSynthesisService::Stop() -> void
{
return mozilla::jni::Method<Stop_t>::Call(SpeechSynthesisService::Context(), nullptr);
}
const char SurfaceTextureListener::name[] =
"org/mozilla/gecko/SurfaceTextureListener";

View File

@ -3095,6 +3095,194 @@ public:
template<class Impl> class Natives;
};
class SpeechSynthesisService : public mozilla::jni::ObjectBase<SpeechSynthesisService>
{
public:
static const char name[];
explicit SpeechSynthesisService(const Context& ctx) : ObjectBase<SpeechSynthesisService>(ctx) {}
struct DispatchBoundary_t {
typedef SpeechSynthesisService Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
mozilla::jni::String::Param,
int32_t,
int32_t> Args;
static constexpr char name[] = "dispatchBoundary";
static constexpr char signature[] =
"(Ljava/lang/String;II)V";
static const bool isStatic = true;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::ANY;
static const mozilla::jni::DispatchTarget dispatchTarget =
mozilla::jni::DispatchTarget::GECKO;
};
struct DispatchEnd_t {
typedef SpeechSynthesisService Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
mozilla::jni::String::Param> Args;
static constexpr char name[] = "dispatchEnd";
static constexpr char signature[] =
"(Ljava/lang/String;)V";
static const bool isStatic = true;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::ANY;
static const mozilla::jni::DispatchTarget dispatchTarget =
mozilla::jni::DispatchTarget::GECKO;
};
struct DispatchError_t {
typedef SpeechSynthesisService Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
mozilla::jni::String::Param> Args;
static constexpr char name[] = "dispatchError";
static constexpr char signature[] =
"(Ljava/lang/String;)V";
static const bool isStatic = true;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::ANY;
static const mozilla::jni::DispatchTarget dispatchTarget =
mozilla::jni::DispatchTarget::GECKO;
};
struct DispatchStart_t {
typedef SpeechSynthesisService Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
mozilla::jni::String::Param> Args;
static constexpr char name[] = "dispatchStart";
static constexpr char signature[] =
"(Ljava/lang/String;)V";
static const bool isStatic = true;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::ANY;
static const mozilla::jni::DispatchTarget dispatchTarget =
mozilla::jni::DispatchTarget::GECKO;
};
struct DoneRegisteringVoices_t {
typedef SpeechSynthesisService Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<> Args;
static constexpr char name[] = "doneRegisteringVoices";
static constexpr char signature[] =
"()V";
static const bool isStatic = true;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::ANY;
static const mozilla::jni::DispatchTarget dispatchTarget =
mozilla::jni::DispatchTarget::GECKO;
};
struct InitSynth_t {
typedef SpeechSynthesisService Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<> Args;
static constexpr char name[] = "initSynth";
static constexpr char signature[] =
"()V";
static const bool isStatic = true;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::GECKO;
static const mozilla::jni::DispatchTarget dispatchTarget =
mozilla::jni::DispatchTarget::CURRENT;
};
static auto InitSynth() -> void;
struct RegisterVoice_t {
typedef SpeechSynthesisService Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
mozilla::jni::String::Param,
mozilla::jni::String::Param,
mozilla::jni::String::Param,
bool,
bool> Args;
static constexpr char name[] = "registerVoice";
static constexpr char signature[] =
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZ)V";
static const bool isStatic = true;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::ANY;
static const mozilla::jni::DispatchTarget dispatchTarget =
mozilla::jni::DispatchTarget::GECKO;
};
struct Speak_t {
typedef SpeechSynthesisService Owner;
typedef mozilla::jni::String::LocalRef ReturnType;
typedef mozilla::jni::String::Param SetterType;
typedef mozilla::jni::Args<
mozilla::jni::String::Param,
mozilla::jni::String::Param,
float,
float,
float> Args;
static constexpr char name[] = "speak";
static constexpr char signature[] =
"(Ljava/lang/String;Ljava/lang/String;FFF)Ljava/lang/String;";
static const bool isStatic = true;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::GECKO;
static const mozilla::jni::DispatchTarget dispatchTarget =
mozilla::jni::DispatchTarget::CURRENT;
};
static auto Speak(mozilla::jni::String::Param, mozilla::jni::String::Param, float, float, float) -> mozilla::jni::String::LocalRef;
struct Stop_t {
typedef SpeechSynthesisService Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<> Args;
static constexpr char name[] = "stop";
static constexpr char signature[] =
"()V";
static const bool isStatic = true;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::GECKO;
static const mozilla::jni::DispatchTarget dispatchTarget =
mozilla::jni::DispatchTarget::CURRENT;
};
static auto Stop() -> void;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::ANY;
template<class Impl> class Natives;
};
class SurfaceTextureListener : public mozilla::jni::ObjectBase<SurfaceTextureListener>
{
public: