blob: 4cfb4835ed03bafc375205b6ba8c39e2381c3c03 [file] [log] [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif
#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 "build/chromeos_buildflags.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 {
// Import `GetDefaultApiKeysFromDefinedValues()` definition based on the current
// preprocessor directives.
#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());
// `g_api_key_cache_instance` is always assigned to the same value but it
// might happen simultaneously from multiple threads, so use atomics.
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)
// Explicitly creates the global API key cache.
//
// Expects that `g_api_key_cache_instance` is null, as this function must be
// called before any prior usage of the global API key cache.
ApiKeyCache& InitializeApiKeyCacheInstance() {
// Tests need to override the global instance of the API key cache, so it
// is not feasible to check that `g_api_key_cache_instance` is null in
// tests.
if (g_api_key_cache_instance) {
CHECK_IS_TEST(base::NotFatalUntil::M133);
}
return GetApiKeyCacheInstance();
}
#endif // BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY)
} // namespace
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_ASH)
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();
}
#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 // BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY)
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));
}
} // namespace google_apis