| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chromeos/ash/components/language_packs/language_pack_manager.h" |
| |
| #include <string> |
| #include <string_view> |
| #include <vector> |
| |
| #include "base/containers/flat_map.h" |
| #include "base/functional/bind.h" |
| #include "base/logging.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/run_loop.h" |
| #include "base/strings/strcat.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/task_environment.h" |
| #include "base/test/test_future.h" |
| #include "chromeos/ash/components/dbus/dlcservice/dlcservice.pb.h" |
| #include "chromeos/ash/components/dbus/dlcservice/dlcservice_client.h" |
| #include "chromeos/ash/components/dbus/dlcservice/fake_dlcservice_client.h" |
| #include "components/session_manager/core/fake_session_manager_delegate.h" |
| #include "components/session_manager/core/session_manager.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/cros_system_api/dbus/dlcservice/dbus-constants.h" |
| |
| using ::dlcservice::DlcState; |
| using ::testing::_; |
| using ::testing::AllOf; |
| using ::testing::Each; |
| using ::testing::Field; |
| using ::testing::FieldsAre; |
| using ::testing::Property; |
| using ::testing::ResultOf; |
| using ::testing::Return; |
| using ::testing::StartsWith; |
| using ::testing::WithArg; |
| |
| namespace ash::language_packs { |
| |
| namespace { |
| |
| constexpr char kFakeDlcId[] = "FakeDlc"; |
| constexpr char kSupportedLocale[] = "es"; |
| constexpr char kHistogramGetPackStateFeatureId[] = |
| "ChromeOS.LanguagePacks.GetPackState.FeatureId"; |
| constexpr char kHistogramInstallPackSuccess[] = |
| "ChromeOS.LanguagePacks.InstallPack.Success"; |
| constexpr char kHistogramInstallBasePackFeatureId[] = |
| "ChromeOS.LanguagePacks.InstallBasePack.FeatureId"; |
| constexpr char kHistogramOobeValidLocale[] = |
| "ChromeOS.LanguagePacks.Oobe.ValidLocale"; |
| constexpr char kHistogramUninstallCompleteSuccess[] = |
| "ChromeOS.LanguagePacks.UninstallComplete.Success"; |
| |
| // We need a mock callback so that we can check that it gets called. |
| class CallbackForTesting { |
| public: |
| OnInstallCompleteCallback GetInstallCallback() { |
| return base::BindOnce(&CallbackForTesting::Callback, |
| base::Unretained(this)); |
| } |
| |
| GetPackStateCallback GetPackStateCallback() { |
| return base::BindOnce(&CallbackForTesting::Callback, |
| base::Unretained(this)); |
| } |
| |
| OnUninstallCompleteCallback GetRemoveCallback() { |
| return base::BindOnce(&CallbackForTesting::Callback, |
| base::Unretained(this)); |
| } |
| |
| OnUpdatePacksForOobeCallback GetOobeCallback() { |
| return base::BindOnce(&CallbackForTesting::Callback, |
| base::Unretained(this)); |
| } |
| |
| MOCK_METHOD(void, Callback, (const PackResult&), ()); |
| }; |
| |
| class MockObserver : public LanguagePackManager::Observer { |
| public: |
| MOCK_METHOD(void, OnPackStateChanged, (const PackResult& pack_result)); |
| }; |
| |
| // Utility function that creates a DlcState with no error, populated with id |
| // corresponding to German handwriting recognition and path. |
| DlcState CreateInstalledState() { |
| DlcState output; |
| output.set_state(dlcservice::DlcState_State_INSTALLED); |
| output.set_id("handwriting-de"); |
| output.set_root_path("/path"); |
| return output; |
| } |
| |
| DlcState CreateTtsInstalledState(const std::string& locale) { |
| DlcState output; |
| output.set_state(dlcservice::DlcState_State_INSTALLED); |
| if (locale == "en-us") { |
| // Note that en-US has ID ending in "-d" while all other TTS DLCs have |
| // ID ending in "-c". |
| output.set_id("tts-en-us-d"); |
| } else { |
| output.set_id(base::StrCat({"tts-", locale, "-c"})); |
| } |
| output.set_root_path("/path"); |
| return output; |
| } |
| |
| } // namespace |
| |
| class LanguagePackManagerTest : public testing::Test { |
| public: |
| void SetUp() override { |
| session_manager_ = std::make_unique<session_manager::SessionManager>( |
| std::make_unique<session_manager::FakeSessionManagerDelegate>()); |
| |
| ResetPackResult(); |
| |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| void InstallTestCallback(const PackResult& pack_result) { |
| pack_result_ = pack_result; |
| } |
| |
| void GetPackStateTestCallback(const PackResult& pack_result) { |
| pack_result_ = pack_result; |
| } |
| |
| void RemoveTestCallback(const PackResult& pack_result) { |
| pack_result_ = pack_result; |
| } |
| |
| void OobeTestCallback(const PackResult& pack_result) { |
| pack_result_ = pack_result; |
| } |
| |
| protected: |
| PackResult pack_result_; |
| FakeDlcserviceClient dlcservice_client_; |
| std::unique_ptr<session_manager::SessionManager> session_manager_; |
| |
| private: |
| base::test::SingleThreadTaskEnvironment task_environment_; |
| |
| void ResetPackResult() { |
| PackResult temp = PackResult(); |
| pack_result_ = temp; |
| } |
| }; |
| |
| TEST_F(LanguagePackManagerTest, InstallSuccessTest) { |
| dlcservice_client_.set_install_error(dlcservice::kErrorNone); |
| dlcservice_client_.set_install_root_path("/path"); |
| |
| // Test UMA metrics: pre-condition. |
| base::HistogramTester histogram_tester; |
| histogram_tester.ExpectBucketCount( |
| kHistogramInstallPackSuccess, FeatureSuccessEnum::kHandwritingSuccess, 0); |
| histogram_tester.ExpectBucketCount( |
| kHistogramInstallPackSuccess, FeatureSuccessEnum::kHandwritingFailure, 0); |
| |
| // We need to use an existing Pack ID, so that we do get a result back. |
| LanguagePackManager::InstallPack( |
| kHandwritingFeatureId, kSupportedLocale, |
| base::BindOnce(&LanguagePackManagerTest::InstallTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kNone); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kInstalled); |
| EXPECT_EQ(pack_result_.path, "/path"); |
| EXPECT_EQ(pack_result_.feature_id, kHandwritingFeatureId); |
| EXPECT_EQ(pack_result_.language_code, kSupportedLocale); |
| |
| // Test UMA metrics: post-condition. |
| histogram_tester.ExpectBucketCount( |
| kHistogramInstallPackSuccess, FeatureSuccessEnum::kHandwritingSuccess, 1); |
| histogram_tester.ExpectBucketCount( |
| kHistogramInstallPackSuccess, FeatureSuccessEnum::kHandwritingFailure, 0); |
| } |
| |
| TEST_F(LanguagePackManagerTest, InstallFailureTest) { |
| dlcservice_client_.set_install_error(dlcservice::kErrorInternal); |
| |
| // Test UMA metrics: pre-condition. |
| base::HistogramTester histogram_tester; |
| histogram_tester.ExpectBucketCount( |
| kHistogramInstallPackSuccess, FeatureSuccessEnum::kHandwritingSuccess, 0); |
| histogram_tester.ExpectBucketCount( |
| kHistogramInstallPackSuccess, FeatureSuccessEnum::kHandwritingFailure, 0); |
| |
| // We need to use an existing Pack ID, so that we do get a result back. |
| LanguagePackManager::InstallPack( |
| kHandwritingFeatureId, kSupportedLocale, |
| base::BindOnce(&LanguagePackManagerTest::InstallTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kOther); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kUnknown); |
| |
| // Test UMA metrics: post-condition. |
| histogram_tester.ExpectBucketCount( |
| kHistogramInstallPackSuccess, FeatureSuccessEnum::kHandwritingSuccess, 0); |
| histogram_tester.ExpectBucketCount( |
| kHistogramInstallPackSuccess, FeatureSuccessEnum::kHandwritingFailure, 1); |
| } |
| |
| TEST_F(LanguagePackManagerTest, InstallWrongIdTest) { |
| // Note: no UMA metrics are reconded in this case, because there is no call to |
| // DLC Service, hence no success nor failure. |
| |
| LanguagePackManager::InstallPack( |
| kFakeDlcId, kSupportedLocale, |
| base::BindOnce(&LanguagePackManagerTest::InstallTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kWrongId); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kUnknown); |
| } |
| |
| // Check that the callback is actually called. |
| TEST_F(LanguagePackManagerTest, InstallCallbackTest) { |
| dlcservice_client_.set_install_error(dlcservice::kErrorNone); |
| dlcservice_client_.set_install_root_path("/path"); |
| |
| testing::StrictMock<CallbackForTesting> callback; |
| EXPECT_CALL(callback, Callback(_)); |
| |
| LanguagePackManager::InstallPack(kFakeDlcId, kSupportedLocale, |
| callback.GetInstallCallback()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(LanguagePackManagerTest, GetPackStateSuccessTest) { |
| dlcservice_client_.set_get_dlc_state_error( |
| GetDlcIdForLanguagePack(kHandwritingFeatureId, kSupportedLocale).value(), |
| dlcservice::kErrorNone); |
| |
| dlcservice::DlcState dlc_state; |
| dlc_state.set_state(dlcservice::DlcState_State_INSTALLED); |
| dlc_state.set_is_verified(true); |
| dlc_state.set_root_path("/path"); |
| dlcservice_client_.set_dlc_state( |
| GetDlcIdForLanguagePack(kHandwritingFeatureId, kSupportedLocale).value(), |
| dlc_state); |
| |
| // Test UMA metrics: pre-condition. |
| base::HistogramTester histogram_tester; |
| histogram_tester.ExpectBucketCount(kHistogramGetPackStateFeatureId, |
| FeatureIdsEnum::kHandwriting, 0); |
| |
| // We need to use an existing Pack ID, so that we do get a result back. |
| LanguagePackManager::GetPackState( |
| kHandwritingFeatureId, kSupportedLocale, |
| base::BindOnce(&LanguagePackManagerTest::GetPackStateTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kNone); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kInstalled); |
| EXPECT_EQ(pack_result_.path, "/path"); |
| EXPECT_EQ(pack_result_.feature_id, kHandwritingFeatureId); |
| EXPECT_EQ(pack_result_.language_code, kSupportedLocale); |
| |
| // Test UMA metrics: post-condition. |
| histogram_tester.ExpectBucketCount(kHistogramGetPackStateFeatureId, |
| FeatureIdsEnum::kHandwriting, 1); |
| } |
| |
| TEST_F(LanguagePackManagerTest, GetPackStateSuccessNotInstalledButVerified) { |
| std::string dlc_id = |
| GetDlcIdForLanguagePack(kHandwritingFeatureId, kSupportedLocale).value(); |
| dlcservice_client_.set_get_dlc_state_error(dlc_id, dlcservice::kErrorNone); |
| dlcservice::DlcState dlc_state; |
| dlc_state.set_id(dlc_id); |
| dlc_state.set_state(dlcservice::DlcState_State_NOT_INSTALLED); |
| dlc_state.set_is_verified(true); |
| dlcservice_client_.set_install_root_path("/path"); |
| dlcservice_client_.set_dlc_state(dlc_id, dlc_state); |
| |
| LanguagePackManager::GetPackState( |
| kHandwritingFeatureId, kSupportedLocale, |
| base::BindOnce(&LanguagePackManagerTest::GetPackStateTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kNone); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kInstalled); |
| EXPECT_EQ(pack_result_.path, "/path"); |
| EXPECT_EQ(pack_result_.feature_id, kHandwritingFeatureId); |
| EXPECT_EQ(pack_result_.language_code, kSupportedLocale); |
| base::test::TestFuture<std::string_view, const dlcservice::DlcsWithContent&> |
| future; |
| dlcservice_client_.GetExistingDlcs(future.GetCallback()); |
| const dlcservice::DlcsWithContent& dlcs = future.Get<1>(); |
| EXPECT_THAT( |
| dlcs.dlc_infos(), |
| ElementsAre(Property( |
| "id", &dlcservice::DlcsWithContent::DlcInfo::id, |
| *GetDlcIdForLanguagePack(kHandwritingFeatureId, kSupportedLocale)))); |
| } |
| |
| TEST_F(LanguagePackManagerTest, GetPackStateFailureTest) { |
| dlcservice_client_.set_get_dlc_state_error( |
| GetDlcIdForLanguagePack(kHandwritingFeatureId, kSupportedLocale).value(), |
| dlcservice::kErrorInternal); |
| |
| // Test UMA metrics: pre-condition. |
| base::HistogramTester histogram_tester; |
| histogram_tester.ExpectBucketCount(kHistogramGetPackStateFeatureId, |
| FeatureIdsEnum::kHandwriting, 0); |
| |
| // We need to use an existing Pack ID, so that we do get a result back. |
| LanguagePackManager::GetPackState( |
| kHandwritingFeatureId, kSupportedLocale, |
| base::BindOnce(&LanguagePackManagerTest::GetPackStateTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kOther); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kUnknown); |
| |
| // Test UMA metrics: post-condition. |
| histogram_tester.ExpectBucketCount(kHistogramGetPackStateFeatureId, |
| FeatureIdsEnum::kHandwriting, 1); |
| } |
| |
| TEST_F(LanguagePackManagerTest, GetPackStateWrongIdTest) { |
| // Note: no UMA metrics are reconded in this case, because there is no call to |
| // DLC Service, hence no success nor failure. |
| |
| LanguagePackManager::GetPackState( |
| kFakeDlcId, kSupportedLocale, |
| base::BindOnce(&LanguagePackManagerTest::GetPackStateTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kWrongId); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kUnknown); |
| } |
| |
| // Check that the callback is actually called. |
| TEST_F(LanguagePackManagerTest, GetPackStateCallbackTest) { |
| dlcservice_client_.set_get_dlc_state_error(kFakeDlcId, |
| dlcservice::kErrorNone); |
| |
| testing::StrictMock<CallbackForTesting> callback; |
| EXPECT_CALL(callback, Callback(_)); |
| |
| LanguagePackManager::GetPackState(kFakeDlcId, kSupportedLocale, |
| callback.GetPackStateCallback()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(LanguagePackManagerTest, RemovePackSuccessTest) { |
| dlcservice_client_.set_uninstall_error(dlcservice::kErrorNone); |
| |
| // Test UMA metrics: pre-condition. |
| base::HistogramTester histogram_tester; |
| histogram_tester.ExpectBucketCount(kHistogramUninstallCompleteSuccess, |
| 1 /* True */, 0); |
| histogram_tester.ExpectBucketCount(kHistogramUninstallCompleteSuccess, |
| 0 /* False */, 0); |
| |
| // We need to use an existing Pack ID, so that we do get a result back. |
| LanguagePackManager::RemovePack( |
| kHandwritingFeatureId, kSupportedLocale, |
| base::BindOnce(&LanguagePackManagerTest::RemoveTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kNone); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kNotInstalled); |
| EXPECT_EQ(pack_result_.feature_id, kHandwritingFeatureId); |
| EXPECT_EQ(pack_result_.language_code, kSupportedLocale); |
| |
| // Test UMA metrics: post-condition. |
| histogram_tester.ExpectBucketCount(kHistogramUninstallCompleteSuccess, |
| 1 /* True */, 1); |
| histogram_tester.ExpectBucketCount(kHistogramUninstallCompleteSuccess, |
| 0 /* False */, 0); |
| } |
| |
| TEST_F(LanguagePackManagerTest, RemovePackFailureTest) { |
| dlcservice_client_.set_uninstall_error(dlcservice::kErrorInternal); |
| |
| // Test UMA metrics: pre-condition. |
| base::HistogramTester histogram_tester; |
| histogram_tester.ExpectBucketCount(kHistogramUninstallCompleteSuccess, |
| 1 /* True */, 0); |
| histogram_tester.ExpectBucketCount(kHistogramUninstallCompleteSuccess, |
| 0 /* False */, 0); |
| |
| // We need to use an existing Pack ID, so that we do get a result back. |
| LanguagePackManager::RemovePack( |
| kHandwritingFeatureId, kSupportedLocale, |
| base::BindOnce(&LanguagePackManagerTest::RemoveTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kOther); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kUnknown); |
| |
| // Test UMA metrics: post-condition. |
| histogram_tester.ExpectBucketCount(kHistogramUninstallCompleteSuccess, |
| 1 /* True */, 0); |
| histogram_tester.ExpectBucketCount(kHistogramUninstallCompleteSuccess, |
| 0 /* False */, 1); |
| } |
| |
| TEST_F(LanguagePackManagerTest, RemovePackWrongIdTest) { |
| // Note: no UMA metrics are reconded in this case, because there is no call to |
| // DLC Service, hence no success nor failure. |
| |
| LanguagePackManager::RemovePack( |
| kFakeDlcId, kSupportedLocale, |
| base::BindOnce(&LanguagePackManagerTest::RemoveTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kWrongId); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kUnknown); |
| } |
| |
| // Check that the callback is actually called. |
| TEST_F(LanguagePackManagerTest, RemovePackCallbackTest) { |
| dlcservice_client_.set_uninstall_error(dlcservice::kErrorNone); |
| |
| testing::StrictMock<CallbackForTesting> callback; |
| EXPECT_CALL(callback, Callback(_)); |
| |
| LanguagePackManager::RemovePack(kFakeDlcId, kSupportedLocale, |
| callback.GetRemoveCallback()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(LanguagePackManagerTest, InstallObserverTest) { |
| LanguagePackManager manager; |
| |
| dlcservice_client_.set_install_error(dlcservice::kErrorNone); |
| dlcservice_client_.set_install_root_path("/path"); |
| const DlcState dlc_state = CreateInstalledState(); |
| MockObserver observer; |
| |
| EXPECT_CALL(observer, OnPackStateChanged(_)).Times(0); |
| dlcservice_client_.NotifyObserversForTest(dlc_state); |
| |
| // Add an Observer and expect it to be notified. |
| manager.AddObserver(&observer); |
| EXPECT_CALL(observer, OnPackStateChanged(_)) |
| .With( |
| FieldsAre(AllOf(Field(&PackResult::feature_id, kHandwritingFeatureId), |
| Field(&PackResult::language_code, "de")))) |
| .Times(1); |
| dlcservice_client_.NotifyObserversForTest(dlc_state); |
| } |
| |
| TEST_F(LanguagePackManagerTest, RemoveObserverTest) { |
| LanguagePackManager manager; |
| |
| dlcservice_client_.set_install_error(dlcservice::kErrorNone); |
| dlcservice_client_.set_install_root_path("/path"); |
| const DlcState dlc_state = CreateInstalledState(); |
| MockObserver observer; |
| |
| // Add an Observer and expect it to be notified. |
| manager.AddObserver(&observer); |
| EXPECT_CALL(observer, OnPackStateChanged(_)) |
| .With( |
| FieldsAre(AllOf(Field(&PackResult::feature_id, kHandwritingFeatureId), |
| Field(&PackResult::language_code, "de")))) |
| .Times(1); |
| dlcservice_client_.NotifyObserversForTest(dlc_state); |
| |
| // Remove the Observer and there should be no more notifications. |
| manager.RemoveObserver(&observer); |
| EXPECT_CALL(observer, OnPackStateChanged(_)).Times(0); |
| dlcservice_client_.NotifyObserversForTest(dlc_state); |
| |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| // Check that all supported locales are available. |
| TEST_F(LanguagePackManagerTest, CheckAllLocalesAvailable) { |
| // Handwriting Recognition. |
| const std::vector<std::string> handwriting({ |
| "am", "ar", "be", "bg", "bn", "ca", "cs", "da", "de", "el", "en", |
| "es", "et", "fa", "fi", "fil", "fr", "ga", "gu", "hi", "hr", "hu", |
| "hy", "id", "is", "it", "iw", "ja", "ka", "kk", "km", "kn", "ko", |
| "lo", "lt", "lv", "ml", "mn", "mr", "ms", "mt", "my", "ne", "nl", |
| "no", "or", "pa", "pl", "pt", "ro", "ru", "si", "sk", "sl", "sr", |
| "sv", "ta", "te", "th", "ti", "tr", "uk", "ur", "vi", "zh", "zh-HK", |
| }); |
| for (const auto& locale : handwriting) { |
| EXPECT_TRUE( |
| LanguagePackManager::IsPackAvailable(kHandwritingFeatureId, locale)); |
| } |
| |
| // TTS. |
| const std::vector<std::string> tts({ |
| "bn-bd", "cs-cz", "da-dk", "de-de", "el-gr", "en-au", "en-gb", |
| "en-us", "es-es", "es-us", "fi-fi", "fil-ph", "fr-fr", "hi-in", |
| "hu-hu", "id-id", "it-it", "ja-jp", "km-kh", "ko-kr", "nb-no", |
| "ne-np", "nl-nl", "pl-pl", "pt-br", "si-lk", "sk-sk", "sv-se", |
| "th-th", "tr-tr", "uk-ua", "vi-vn", "yue-hk", |
| }); |
| for (const auto& locale : tts) { |
| EXPECT_TRUE(LanguagePackManager::IsPackAvailable(kTtsFeatureId, locale)); |
| } |
| |
| const std::vector<std::string> fonts = {"ja", "ko"}; |
| EXPECT_THAT(fonts, Each(ResultOf( |
| "Font pack availability", |
| [](const std::string& locale) { |
| return LanguagePackManager::IsPackAvailable( |
| kFontsFeatureId, locale); |
| }, |
| true))); |
| } |
| |
| TEST_F(LanguagePackManagerTest, IsPackAvailableFalseTest) { |
| // Correct ID, wrong language (Welsh). |
| bool available = |
| LanguagePackManager::IsPackAvailable(kHandwritingFeatureId, "cy"); |
| EXPECT_FALSE(available); |
| |
| // ID doesn't exists. |
| available = LanguagePackManager::IsPackAvailable("foo", "fr"); |
| EXPECT_FALSE(available); |
| } |
| |
| TEST_F(LanguagePackManagerTest, InstallBasePackSuccess) { |
| dlcservice_client_.set_install_error(dlcservice::kErrorNone); |
| dlcservice_client_.set_install_root_path("/path"); |
| |
| // Test UMA metrics: pre-condition. |
| base::HistogramTester histogram_tester; |
| histogram_tester.ExpectBucketCount(kHistogramInstallBasePackFeatureId, |
| FeatureIdsEnum::kHandwriting, 0); |
| |
| // We need to use an existing Pack ID, so that we do get a result back. |
| LanguagePackManager::InstallBasePack( |
| kHandwritingFeatureId, |
| base::BindOnce(&LanguagePackManagerTest::InstallTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kNone); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kInstalled); |
| EXPECT_EQ(pack_result_.path, "/path"); |
| EXPECT_EQ(pack_result_.feature_id, kHandwritingFeatureId); |
| |
| // Test UMA metrics: post-condition. |
| histogram_tester.ExpectBucketCount(kHistogramInstallBasePackFeatureId, |
| FeatureIdsEnum::kHandwriting, 1); |
| } |
| |
| TEST_F(LanguagePackManagerTest, InstallBasePackFailureTestFailure) { |
| dlcservice_client_.set_install_error(dlcservice::kErrorInternal); |
| |
| // Test UMA metrics: pre-condition. |
| base::HistogramTester histogram_tester; |
| histogram_tester.ExpectBucketCount(kHistogramInstallBasePackFeatureId, |
| FeatureIdsEnum::kHandwriting, 0); |
| |
| // We need to use an existing Pack ID, so that we do get a result back. |
| LanguagePackManager::InstallBasePack( |
| kHandwritingFeatureId, |
| base::BindOnce(&LanguagePackManagerTest::InstallTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kOther); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kUnknown); |
| |
| // Test UMA metrics: post-condition. |
| histogram_tester.ExpectBucketCount(kHistogramInstallBasePackFeatureId, |
| FeatureIdsEnum::kHandwriting, 1); |
| } |
| |
| // If we are not in OOBE nothing should happen. |
| TEST_F(LanguagePackManagerTest, UpdatePacksForOobeNotOobeTest) { |
| // Set session as user logged in. |
| session_manager_->SetSessionState(session_manager::SessionState::ACTIVE); |
| dlcservice_client_.set_install_error(dlcservice::kErrorNone); |
| dlcservice_client_.set_install_root_path("/path"); |
| |
| testing::StrictMock<CallbackForTesting> callback; |
| EXPECT_CALL(callback, Callback(_)).Times(0); |
| |
| LanguagePackManager::UpdatePacksForOobe(kSupportedLocale, |
| callback.GetInstallCallback()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(LanguagePackManagerTest, UpdatePacksForOobeSuccessTest) { |
| session_manager_->SetSessionState(session_manager::SessionState::OOBE); |
| |
| dlcservice_client_.set_install_error(dlcservice::kErrorNone); |
| dlcservice_client_.set_install_root_path("/path"); |
| |
| // Test UMA metrics: pre-condition. |
| base::HistogramTester histogram_tester; |
| histogram_tester.ExpectBucketCount(kHistogramOobeValidLocale, 1 /* True */, |
| 0); |
| histogram_tester.ExpectBucketCount(kHistogramOobeValidLocale, 0 /* False */, |
| 0); |
| |
| LanguagePackManager::UpdatePacksForOobe( |
| "en-au", base::BindOnce(&LanguagePackManagerTest::OobeTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kNone); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kInstalled); |
| EXPECT_EQ(pack_result_.path, "/path"); |
| EXPECT_EQ(pack_result_.feature_id, kTtsFeatureId); |
| EXPECT_EQ(pack_result_.language_code, "en-au"); |
| |
| // Test UMA metrics: post-condition. |
| histogram_tester.ExpectBucketCount(kHistogramOobeValidLocale, 1 /* True */, |
| 1); |
| histogram_tester.ExpectBucketCount(kHistogramOobeValidLocale, 0 /* False */, |
| 0); |
| } |
| |
| TEST_F(LanguagePackManagerTest, UpdatePacksForOobeSuccess2Test) { |
| session_manager_->SetSessionState(session_manager::SessionState::OOBE); |
| |
| dlcservice_client_.set_install_error(dlcservice::kErrorNone); |
| dlcservice_client_.set_install_root_path("/path"); |
| |
| // Test UMA metrics: pre-condition. |
| base::HistogramTester histogram_tester; |
| histogram_tester.ExpectBucketCount(kHistogramOobeValidLocale, 1 /* True */, |
| 0); |
| histogram_tester.ExpectBucketCount(kHistogramOobeValidLocale, 0 /* False */, |
| 0); |
| |
| LanguagePackManager::UpdatePacksForOobe( |
| "it-it", base::BindOnce(&LanguagePackManagerTest::OobeTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kNone); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kInstalled); |
| EXPECT_EQ(pack_result_.path, "/path"); |
| EXPECT_EQ(pack_result_.feature_id, kTtsFeatureId); |
| EXPECT_EQ(pack_result_.language_code, "it"); |
| |
| // Test UMA metrics: post-condition. |
| histogram_tester.ExpectBucketCount(kHistogramOobeValidLocale, 1 /* True */, |
| 1); |
| histogram_tester.ExpectBucketCount(kHistogramOobeValidLocale, 0 /* False */, |
| 0); |
| } |
| |
| TEST_F(LanguagePackManagerTest, UpdatePacksForOobeWrongLocaleTest) { |
| session_manager_->SetSessionState(session_manager::SessionState::OOBE); |
| |
| dlcservice_client_.set_install_error(dlcservice::kErrorNone); |
| dlcservice_client_.set_install_root_path("/path"); |
| |
| // Test UMA metrics: pre-condition. |
| base::HistogramTester histogram_tester; |
| histogram_tester.ExpectBucketCount(kHistogramOobeValidLocale, 1 /* True */, |
| 0); |
| histogram_tester.ExpectBucketCount(kHistogramOobeValidLocale, 0 /* False */, |
| 0); |
| |
| LanguagePackManager::UpdatePacksForOobe( |
| "xxx", base::BindOnce(&LanguagePackManagerTest::OobeTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kWrongId); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kUnknown); |
| |
| // Test UMA metrics: post-condition. |
| histogram_tester.ExpectBucketCount(kHistogramOobeValidLocale, 1 /* True */, |
| 0); |
| histogram_tester.ExpectBucketCount(kHistogramOobeValidLocale, 0 /* False */, |
| 1); |
| } |
| |
| TEST_F(LanguagePackManagerTest, UpdatePacksForOobeFailureTest) { |
| session_manager_->SetSessionState(session_manager::SessionState::OOBE); |
| |
| dlcservice_client_.set_install_error(dlcservice::kErrorInternal); |
| |
| LanguagePackManager::UpdatePacksForOobe( |
| "es-es", base::BindOnce(&LanguagePackManagerTest::OobeTestCallback, |
| base::Unretained(this))); |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(pack_result_.operation_error, PackResult::ErrorCode::kOther); |
| EXPECT_EQ(pack_result_.pack_state, PackResult::StatusCode::kUnknown); |
| } |
| |
| struct TestCase { |
| std::string dlc_locale; |
| std::string language_pack_locale; |
| }; |
| |
| class LanguagePackManagerTtsTest |
| : public LanguagePackManagerTest, |
| public testing::WithParamInterface<TestCase> {}; |
| |
| INSTANTIATE_TEST_SUITE_P(, |
| LanguagePackManagerTtsTest, |
| ::testing::Values(TestCase("en-us", "en-us"), |
| TestCase("yue-hk", "yue"), |
| TestCase("bn-bd", "bn"))); |
| |
| TEST_P(LanguagePackManagerTtsTest, InstallTtsObserverTest) { |
| LanguagePackManager manager; |
| MockObserver observer; |
| manager.AddObserver(&observer); |
| dlcservice_client_.set_install_error(dlcservice::kErrorNone); |
| dlcservice_client_.set_install_root_path("/path"); |
| |
| std::string dlc_locale = GetParam().dlc_locale; |
| std::string language_pack_locale = GetParam().language_pack_locale; |
| const DlcState dlc_state = CreateTtsInstalledState(dlc_locale); |
| EXPECT_CALL(observer, |
| OnPackStateChanged(AllOf( |
| Field(&PackResult::feature_id, kTtsFeatureId), |
| Field(&PackResult::language_code, language_pack_locale)))) |
| .Times(1); |
| dlcservice_client_.NotifyObserversForTest(dlc_state); |
| |
| manager.RemoveObserver(&observer); |
| } |
| |
| } // namespace ash::language_packs |