blob: 5d55104336e5a5bfafd45550fcabfea8e05a4f68 [file] [log] [blame]
Evan Liu45289592024-03-21 17:46:121// Copyright 2024 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "components/soda/soda_util.h"
6
Evan Liub2b7f6d2024-08-05 22:55:487#include <string>
8
9#include "base/feature_list.h"
Evan Liu45289592024-03-21 17:46:1210#include "build/build_config.h"
Evan Liub2b7f6d2024-08-05 22:55:4811#include "components/soda/constants.h"
12#include "components/soda/soda_installer.h"
13#include "media/base/media_switches.h"
Evan Liu68919fc2025-03-06 20:38:1814#include "media/mojo/mojom/speech_recognizer.mojom.h"
Evan Liub2b7f6d2024-08-05 22:55:4815#include "ui/base/l10n/l10n_util.h"
Evan Liu45289592024-03-21 17:46:1216
Maksim Sisov764f01d2024-12-18 08:34:4217#if BUILDFLAG(IS_CHROMEOS)
Evan Liu45289592024-03-21 17:46:1218#include "ash/constants/ash_features.h"
Lei Zhang33c34e42024-05-06 18:59:1219#include "base/feature_list.h"
Evan Liu45289592024-03-21 17:46:1220#endif
21
Evan Liu45289592024-03-21 17:46:1222#if BUILDFLAG(IS_WIN)
23#include "base/win/windows_version.h"
24#endif
25
Lei Zhang33c34e42024-05-06 18:59:1226#if BUILDFLAG(IS_LINUX) && defined(ARCH_CPU_X86_FAMILY)
27#include "base/cpu.h"
28#endif
29
Evan Liu45289592024-03-21 17:46:1230namespace speech {
31
Lei Zhang33c34e42024-05-06 18:59:1232namespace {
33
34#if BUILDFLAG(IS_CHROMEOS)
35bool IsSupportedChromeOS() {
Maksim Sisov764f01d2024-12-18 08:34:4236 // Some Chrome OS devices do not support on-device speech.
37 return base::FeatureList::IsEnabled(
38 ash::features::kOnDeviceSpeechRecognition);
Lei Zhang33c34e42024-05-06 18:59:1239}
40#endif // BUILDFLAG(IS_CHROMEOS)
Evan Liu45289592024-03-21 17:46:1241
42#if BUILDFLAG(IS_LINUX)
Lei Zhang33c34e42024-05-06 18:59:1243bool IsSupportedLinux() {
44#if defined(ARCH_CPU_X86_FAMILY)
Evan Liu45289592024-03-21 17:46:1245 // Check if the CPU has the required instruction set to run the Speech
46 // On-Device API (SODA) library.
47 static bool has_sse41 = base::CPU().has_sse41();
Lei Zhang33c34e42024-05-06 18:59:1248 return has_sse41;
49#else
50 // Other architectures are not supported.
51 return false;
52#endif // defined(ARCH_CPU_X86_FAMILY)
53}
54#endif // BUILDFLAG(IS_LINUX)
Evan Liu45289592024-03-21 17:46:1255
Lei Zhang33c34e42024-05-06 18:59:1256#if BUILDFLAG(IS_WIN)
57bool IsSupportedWin() {
58#if defined(ARCH_CPU_ARM64)
Evan Liu45289592024-03-21 17:46:1259 // The Speech On-Device API (SODA) component does not support Windows on
60 // arm64.
61 return false;
62#else
63 return true;
Lei Zhang33c34e42024-05-06 18:59:1264#endif // defined(ARCH_CPU_ARM64)
65}
66#endif // BUILDFLAG(IS_WIN)
67
68} // namespace
69
70bool IsOnDeviceSpeechRecognitionSupported() {
71#if BUILDFLAG(IS_CHROMEOS)
72 return IsSupportedChromeOS();
73#elif BUILDFLAG(IS_LINUX)
74 return IsSupportedLinux();
75#elif BUILDFLAG(IS_WIN)
76 return IsSupportedWin();
77#else
78 return true;
Evan Liu45289592024-03-21 17:46:1279#endif
80}
81
Evan Liu68919fc2025-03-06 20:38:1882media::mojom::AvailabilityStatus IsOnDeviceSpeechRecognitionAvailable(
83 const std::string& language) {
Evan Liub2b7f6d2024-08-05 22:55:4884 if (!base::FeatureList::IsEnabled(media::kOnDeviceWebSpeech) ||
85 !IsOnDeviceSpeechRecognitionSupported()) {
Evan Liu68919fc2025-03-06 20:38:1886 return media::mojom::AvailabilityStatus::kUnavailable;
Evan Liub2b7f6d2024-08-05 22:55:4887 }
88
89 speech::SodaInstaller* soda_installer = speech::SodaInstaller::GetInstance();
90 DCHECK(soda_installer);
91
92 // Check whether the language supported.
93 bool is_language_supported = false;
94 speech::LanguageCode lang_code = speech::LanguageCode::kNone;
95 for (auto const& available_lang : soda_installer->GetAvailableLanguages()) {
96 if (l10n_util::GetLanguage(available_lang) ==
97 l10n_util::GetLanguage(language)) {
98 is_language_supported = true;
99 lang_code = speech::GetLanguageCode(available_lang);
100 break;
101 }
102 }
103
104 if (!is_language_supported) {
Evan Liu68919fc2025-03-06 20:38:18105 return media::mojom::AvailabilityStatus::kUnavailable;
Evan Liub2b7f6d2024-08-05 22:55:48106 }
107
Evan Liu68919fc2025-03-06 20:38:18108 if (soda_installer->IsSodaInstalled(lang_code)) {
109 return media::mojom::AvailabilityStatus::kAvailable;
Evan Liub2b7f6d2024-08-05 22:55:48110 }
111
Evan Liu68919fc2025-03-06 20:38:18112 if (soda_installer->IsLanguageEnabled(language)) {
113 // By this point the language must be either be available but not yet
114 // installed or currently downloading.
115 if (soda_installer->IsSodaLanguageDownloading(
116 speech::GetLanguageCode(language))) {
117 return media::mojom::AvailabilityStatus::kDownloading;
118 }
Evan Liub2b7f6d2024-08-05 22:55:48119
Evan Liu68919fc2025-03-06 20:38:18120 return media::mojom::AvailabilityStatus::kDownloadable;
121 }
122
123 return media::mojom::AvailabilityStatus::kUnavailable;
Evan Liub2b7f6d2024-08-05 22:55:48124}
125
Evan Liu45289592024-03-21 17:46:12126} // namespace speech