1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_REGIONAL_CAPABILITIES_REGIONAL_CAPABILITIES_SERVICE_H_
#define COMPONENTS_REGIONAL_CAPABILITIES_REGIONAL_CAPABILITIES_SERVICE_H_
#include <optional>
#include <vector>
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ref.h"
#include "base/memory/weak_ptr.h"
#include "components/country_codes/country_codes.h"
#include "components/keyed_service/core/keyed_service.h"
#if BUILDFLAG(IS_ANDROID)
#include "base/android/scoped_java_ref.h"
#endif
class PrefService;
namespace TemplateURLPrepopulateData {
struct PrepopulatedEngine;
}
namespace regional_capabilities {
class CountryIdHolder;
// Service for managing the state related to Search Engine Choice (mostly
// for the country information).
//
// Various kinds of countries:
// - Variations country: Obtained from the variations service, this is the one
// we get through the experiment framework. Exists in 2 variants: "Latest"
// (changes once per run) and "Permanent" (changes at each milestone). See
// `variations::VariationsService` for more details.
// - Device country: Represents the country with which the device is associated
// and is provided by OS-level APIs. See `country_codes::GetCurrentCountryID`
// for the common way we access it. Some platforms (Android or ChromeOS,
// notably) need some alternative ways to obtain a more accurate values.
// - Profile country: The country that the `RegionalCapabilitiesService`
// considers to apply to the current profile, and that is used to compute the
// capabilities. It is persisted to profile prefs, and how it gets updated
// varies by platform.
class RegionalCapabilitiesService : public KeyedService {
public:
// Helper that is responsible for providing the service with country data,
// that could be coming from platform-specific or //chrome layer sources.
class Client {
public:
using CountryIdCallback =
base::OnceCallback<void(country_codes::CountryId)>;
virtual ~Client() = default;
// See `VariationsService::GetLatestCountry()`. Exposed through the
// `Client` interface to abstract away platform-specific ways to access
// the service.
virtual country_codes::CountryId GetVariationsLatestCountryId() = 0;
// Synchronously returns a country that could be used as the device country
// for the current run.
// Is called by the service when `FetchCountryId` does not complete
// synchronously.
virtual country_codes::CountryId GetFallbackCountryId() = 0;
// Fetches country associated with the device via OS-level APIs, and
// when/if successfully obtained, returns it by running
// `country_id_fetched_callback`.
// If it is not run synchronously, `GetFallbackCountryId()` will be used by
// the service for the current run.
virtual void FetchCountryId(
CountryIdCallback country_id_fetched_callback) = 0;
};
RegionalCapabilitiesService(
PrefService& profile_prefs,
std::unique_ptr<Client> regional_capabilities_client);
~RegionalCapabilitiesService() override;
// Returns the country ID to use in the context of regional checks.
// Can be overridden using `switches::kSearchEngineChoiceCountry`.
// Note: Access to the raw value is restricted, see `CountryIdHolder` for
// more details.
CountryIdHolder GetCountryId();
std::vector<const TemplateURLPrepopulateData::PrepopulatedEngine*>
GetRegionalPrepopulatedEngines();
// Returns whether the profile country is a EEA member.
//
// Testing note: To control the value this returns in manual or automated
// tests, see `switches::kSearchEngineChoiceCountry`.
bool IsInEeaCountry();
// Clears the country id cache to be able to change countries multiple times
// in tests.
void ClearCountryIdCacheForTesting();
#if BUILDFLAG(IS_ANDROID)
// -- JNI Interface ---------------------------------------------------------
// Returns a reference to the Java-side `RegionalCapabilitiesService`, lazily
// creating it if needed.
base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
// If the Java-side service has been created, commands it to destroy itself.
void DestroyJavaObject();
// See `IsInEeaCountry()`.
jboolean IsInEeaCountry(JNIEnv* env);
// -- JNI Interface End -----------------------------------------------------
#endif
private:
country_codes::CountryId GetCountryIdInternal();
void InitializeCountryIdCache();
std::optional<country_codes::CountryId> GetPersistedCountryId();
void TrySetPersistedCountryId(country_codes::CountryId country_id);
const raw_ref<PrefService> profile_prefs_;
const std::unique_ptr<Client> client_;
// Used to ensure that the value returned from `GetCountryId` never changes
// in runtime (different runs can still return different values, though).
std::optional<country_codes::CountryId> country_id_cache_;
#if BUILDFLAG(IS_ANDROID)
// Corresponding Java object.
base::android::ScopedJavaGlobalRef<jobject> java_ref_;
#endif
base::WeakPtrFactory<RegionalCapabilitiesService> weak_ptr_factory_{this};
};
} // namespace regional_capabilities
#endif // COMPONENTS_REGIONAL_CAPABILITIES_REGIONAL_CAPABILITIES_SERVICE_H_
|