| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/constants/geolocation_access_level.h" |
| #include "base/synchronization/condition_variable.h" |
| #include "base/test/repeating_test_future.h" |
| #include "base/test/test_future.h" |
| #include "base/timer/timer.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/browser_process_platform_part.h" |
| #include "chrome/browser/lacros/browser_test_util.h" |
| #include "chrome/browser/lacros/geolocation/system_geolocation_source_lacros.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "chromeos/crosapi/mojom/geolocation.mojom.h" |
| #include "chromeos/crosapi/mojom/prefs.mojom-test-utils.h" |
| #include "chromeos/crosapi/mojom/prefs.mojom.h" |
| #include "chromeos/lacros/lacros_service.h" |
| #include "content/public/test/browser_test.h" |
| #include "mojo/public/cpp/bindings/pending_receiver.h" |
| #include "mojo/public/cpp/bindings/receiver_set.h" |
| #include "services/device/public/cpp/geolocation/geolocation_manager.h" |
| |
| namespace { |
| |
| class SystemGeolocationSourceLacrosTests : public InProcessBrowserTest { |
| public: |
| // InProcessBrowserTest: |
| void SetUp() override { |
| // The tests work only if the privacy hub flags are passed to ash. |
| StartUniqueAshChrome( |
| /*enabled_features=*/{"CrosPrivacyHubV0", "CrosPrivacyHub"}, |
| /*disabled_features=*/{}, |
| /*additional_cmdline_switches=*/{}, |
| /*bug_number_and_reason=*/ |
| {"b/267681869 Switch to shared ash when clipboard " |
| "history refresh is enabled by default"}); |
| |
| InProcessBrowserTest::SetUp(); |
| } |
| |
| // Checks whether the required crosapi elements are available in Ash. |
| // Ash may not be compatible due to a version skew. |
| // TODO(b/313605503): remove in M123 |
| bool AshIsCompatible() const { |
| auto& prefs = |
| chromeos::LacrosService::Get()->GetRemote<crosapi::mojom::Prefs>(); |
| |
| base::test::TestFuture<std::optional<::base::Value>> future; |
| prefs->GetPref(crosapi::mojom::PrefPath::kUserGeolocationAccessLevel, |
| future.GetCallback()); |
| |
| auto out_value = future.Take(); |
| return out_value.has_value() && out_value->is_int(); |
| } |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(SystemGeolocationSourceLacrosTests, PrefChange) { |
| if (!AshIsCompatible()) { |
| // As we are adding the crosapi change to ash in the same commit, we may be |
| // missing the Pref when run with older versions of ash. Hence we'll skip |
| // this test when the ash is not compatible. |
| GTEST_SKIP() << "Skipping as the Ash is not compatible with this test."; |
| } |
| |
| auto& prefs = |
| chromeos::LacrosService::Get()->GetRemote<crosapi::mojom::Prefs>(); |
| |
| // By default, the geolocation is allowed in ash. |
| base::test::TestFuture<std::optional<::base::Value>> future; |
| prefs->GetPref(crosapi::mojom::PrefPath::kUserGeolocationAccessLevel, |
| future.GetCallback()); |
| |
| auto out_value = future.Take(); |
| ASSERT_TRUE(out_value.has_value()); |
| |
| EXPECT_EQ( |
| static_cast<ash::GeolocationAccessLevel>(out_value.value().GetInt()), |
| ash::GeolocationAccessLevel::kAllowed); |
| |
| // Set up the system source to save the pref changes into a future object |
| base::test::TestFuture<device::LocationSystemPermissionStatus> status; |
| |
| device::GeolocationManager::GetInstance() |
| ->SystemGeolocationSourceForTest() |
| .RegisterPermissionUpdateCallback( |
| base::BindRepeating(status.GetRepeatingCallback())); |
| |
| // Wait for status to be asynchronously updated. |
| // Initial value should be to allow. |
| EXPECT_EQ(device::LocationSystemPermissionStatus::kAllowed, status.Take()); |
| // Change the value in ash. |
| base::test::TestFuture<void> set_future; |
| prefs->SetPref( |
| crosapi::mojom::PrefPath::kUserGeolocationAccessLevel, |
| ::base::Value(static_cast<int>(ash::GeolocationAccessLevel::kDisallowed)), |
| set_future.GetCallback()); |
| EXPECT_TRUE(set_future.Wait()); |
| set_future.Clear(); |
| |
| // Check that the change in pref was registered. |
| EXPECT_EQ(device::LocationSystemPermissionStatus::kDenied, status.Take()); |
| |
| // Change the value in ash. |
| prefs->SetPref( |
| crosapi::mojom::PrefPath::kUserGeolocationAccessLevel, |
| ::base::Value(static_cast<int>(ash::GeolocationAccessLevel::kAllowed)), |
| set_future.GetCallback()); |
| EXPECT_TRUE(set_future.Wait()); |
| set_future.Clear(); |
| |
| // Check that the change in pref was registered. |
| EXPECT_EQ(device::LocationSystemPermissionStatus::kAllowed, status.Take()); |
| |
| // Change the value in ash. |
| prefs->SetPref(crosapi::mojom::PrefPath::kUserGeolocationAccessLevel, |
| ::base::Value(static_cast<int>( |
| ash::GeolocationAccessLevel::kOnlyAllowedForSystem)), |
| set_future.GetCallback()); |
| EXPECT_TRUE(set_future.Wait()); |
| set_future.Clear(); |
| |
| // Check that the change in pref was registered. |
| EXPECT_EQ(device::LocationSystemPermissionStatus::kDenied, status.Take()); |
| } |
| |
| // This works only if the privacy hub flags are passed to ash. |
| IN_PROC_BROWSER_TEST_F(SystemGeolocationSourceLacrosTests, |
| IntegrationToBrowser) { |
| if (!AshIsCompatible()) { |
| // As we are adding the crosapi change to ash in the same commit, we may be |
| // missing the Pref when run with older versions of ash. Hence we'll skip |
| // this test when the preference is not available. |
| GTEST_SKIP() << "Skipping as the Ash is not compatible with this test."; |
| } |
| |
| class Observer : public device::GeolocationManager::PermissionObserver { |
| public: |
| // device::GeolocationManager::PermissionObserver: |
| void OnSystemPermissionUpdated( |
| device::LocationSystemPermissionStatus status) override { |
| status_.GetRepeatingCallback().Run(std::move(status)); |
| } |
| base::test::TestFuture<device::LocationSystemPermissionStatus> status_; |
| }; |
| |
| device::GeolocationManager* manager = |
| device::GeolocationManager::GetInstance(); |
| ASSERT_TRUE(manager); |
| |
| Observer observer; |
| manager->AddObserver(&observer); |
| |
| base::test::TestFuture<std::optional<::base::Value>> future; |
| auto& prefs = |
| chromeos::LacrosService::Get()->GetRemote<crosapi::mojom::Prefs>(); |
| |
| // By default, the the geolocation is allowed in ash. |
| prefs->GetPref(crosapi::mojom::PrefPath::kUserGeolocationAccessLevel, |
| future.GetCallback()); |
| |
| // As we are adding the crosapi change to ash in the same commit, we may be |
| // missing the Pref when run with older versions of ash. Hence we'll skip this |
| // test when the preference is not available. |
| auto out_value = future.Take(); |
| if (!out_value.has_value()) { |
| GTEST_SKIP() << "Skipping as the geolocation pref is not available in the " |
| "current version of Ash"; |
| } |
| |
| // Initial value should be to allow. |
| EXPECT_EQ(out_value.value().GetInt(), |
| static_cast<int>(ash::GeolocationAccessLevel::kAllowed)); |
| EXPECT_EQ(device::LocationSystemPermissionStatus::kAllowed, |
| manager->GetSystemPermission()); |
| |
| // Change the value in ash. |
| base::test::TestFuture<void> set_future; |
| prefs->SetPref( |
| crosapi::mojom::PrefPath::kUserGeolocationAccessLevel, |
| ::base::Value(static_cast<int>(ash::GeolocationAccessLevel::kDisallowed)), |
| set_future.GetCallback()); |
| EXPECT_TRUE(set_future.Wait()); |
| set_future.Clear(); |
| |
| // Check that the change in pref was registered. |
| EXPECT_EQ(device::LocationSystemPermissionStatus::kDenied, |
| observer.status_.Take()); |
| |
| // Change the value in ash. |
| prefs->SetPref( |
| crosapi::mojom::PrefPath::kUserGeolocationAccessLevel, |
| ::base::Value(static_cast<int>(ash::GeolocationAccessLevel::kAllowed)), |
| set_future.GetCallback()); |
| EXPECT_TRUE(set_future.Wait()); |
| set_future.Clear(); |
| |
| // Check that the change in pref was registered. |
| EXPECT_EQ(device::LocationSystemPermissionStatus::kAllowed, |
| observer.status_.Take()); |
| |
| // Observer needs to be removed here because it is allocated on stack. |
| manager->RemoveObserver(&observer); |
| } |
| |
| } // namespace |