#include "google_apis/google_api_keys.h"
#include <string>
#include "base/check_is_test.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/no_destructor.h"
#include "base/version_info/channel.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "google_apis/api_key_cache.h"
#include "google_apis/buildflags.h"
#include "google_apis/default_api_keys.h"
#if defined(USE_OFFICIAL_GOOGLE_API_KEYS)
#include "google_apis/internal/google_chrome_api_keys.h"
#include "google_apis/internal/metrics_signing_key.h"
#endif
namespace google_apis {
namespace {
#include "google_apis/default_api_keys-inc.cc"
std::atomic<ApiKeyCache*> g_api_key_cache_instance = nullptr;
ApiKeyCache& CreateLeakyApiKeyCacheInstance() {
static base::NoDestructor<ApiKeyCache> instance(
GetDefaultApiKeysFromDefinedValues());
ApiKeyCache* expected = nullptr;
g_api_key_cache_instance.compare_exchange_strong(expected, instance.get());
return *instance.get();
}
ApiKeyCache& GetApiKeyCacheInstance() {
if (!g_api_key_cache_instance) {
return CreateLeakyApiKeyCacheInstance();
}
return *g_api_key_cache_instance;
}
#if BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY)
ApiKeyCache& InitializeApiKeyCacheInstance() {
if (g_api_key_cache_instance) {
CHECK_IS_TEST();
}
return GetApiKeyCacheInstance();
}
#endif
}
const char kAPIKeysDevelopersHowToURL[] =
"https://www.chromium.org/developers/how-tos/api-keys";
bool HasAPIKeyConfigured() {
return GetApiKeyCacheInstance().HasAPIKeyConfigured();
}
const std::string& GetAPIKey(version_info::Channel channel) {
return channel == version_info::Channel::STABLE
? GetAPIKey()
: GetApiKeyCacheInstance().api_key_non_stable();
}
const std::string& GetAPIKey() {
return GetApiKeyCacheInstance().api_key();
}
const std::string& GetRemotingAPIKey() {
return GetApiKeyCacheInstance().api_key_remoting();
}
const std::string& GetSodaAPIKey() {
return GetApiKeyCacheInstance().api_key_soda();
}
#if !BUILDFLAG(IS_ANDROID)
const std::string& GetHatsAPIKey() {
return GetApiKeyCacheInstance().api_key_hats();
}
#endif
#if BUILDFLAG(IS_CHROMEOS)
const std::string& GetSharingAPIKey() {
return GetApiKeyCacheInstance().api_key_sharing();
}
const std::string& GetReadAloudAPIKey() {
return GetApiKeyCacheInstance().api_key_read_aloud();
}
const std::string& GetFresnelAPIKey() {
return GetApiKeyCacheInstance().api_key_fresnel();
}
const std::string& GetBocaAPIKey() {
return GetApiKeyCacheInstance().api_key_boca();
}
const std::string& GetCrosSystemGeoAPIKey() {
return GetApiKeyCacheInstance().api_key_cros_system_geo();
}
const std::string& GetCrosChromeGeoAPIKey() {
return GetApiKeyCacheInstance().api_key_cros_chrome_geo();
}
#endif
const std::string& GetMetricsKey() {
return GetApiKeyCacheInstance().metrics_key();
}
bool HasOAuthClientConfigured() {
return GetApiKeyCacheInstance().HasOAuthClientConfigured();
}
const std::string& GetOAuth2ClientID(OAuth2Client client) {
return GetApiKeyCacheInstance().GetClientID(client);
}
const std::string& GetOAuth2ClientSecret(OAuth2Client client) {
return GetApiKeyCacheInstance().GetClientSecret(client);
}
bool IsGoogleChromeAPIKeyUsed() {
#if defined(USE_OFFICIAL_GOOGLE_API_KEYS)
return true;
#else
return false;
#endif
}
#if BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY)
void InitializeAndOverrideAPIKey(const std::string& api_key) {
ApiKeyCache& cache = InitializeApiKeyCacheInstance();
cache.set_api_key(api_key);
}
void InitializeAndOverrideAPIKeyAndOAuthClient(
const std::string& api_key,
const std::string& client_id,
const std::string& client_secret) {
ApiKeyCache& cache = InitializeApiKeyCacheInstance();
cache.set_api_key(api_key);
for (size_t i = 0; i < google_apis::CLIENT_NUM_ITEMS; ++i) {
google_apis::OAuth2Client client =
static_cast<google_apis::OAuth2Client>(i);
cache.SetClientID(client, client_id);
cache.SetClientSecret(client, client_secret);
}
}
#endif
base::ScopedClosureRunner SetScopedApiKeyCacheForTesting(
ApiKeyCache* api_key_cache) {
CHECK(api_key_cache) << "Overriding with nullptr is not allowed.";
ApiKeyCache* previous_value =
g_api_key_cache_instance.exchange(api_key_cache);
return base::ScopedClosureRunner(base::BindOnce(
[](ApiKeyCache* previous_value) {
g_api_key_cache_instance = previous_value;
},
previous_value));
}
}