blob: 18492c28046c564a27946e844f6b816673b9b585 [file] [log] [blame]
// 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.
#include "base/android/android_info.h"
#include <cstring>
#include <mutex>
#include <string>
#include <variant>
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/check.h"
#include "base/compiler_specific.h"
#include "base/no_destructor.h"
#include "base/strings/string_number_conversions.h"
// Must come after all headers that specialize FromJniType() / ToJniType().
#include "base/build_info_jni/AndroidInfo_jni.h"
#if __ANDROID_API__ >= 29
// .aidl based NDK generation is only available when our min SDK level is 29 or
// higher.
#include "aidl/org/chromium/base/IAndroidInfo.h"
using aidl::org::chromium::base::IAndroidInfo;
#endif
#if __ANDROID_API__ < 29
struct IAndroidInfo {
const std::string abiName;
const std::string androidBuildFp;
const std::string androidBuildId;
const std::string board;
const std::string brand;
const std::string buildType;
const std::string codename;
const std::string device;
const std::string hardware;
bool isDebugAndroid;
const std::string manufacturer;
const std::string model;
int sdkInt;
const std::string securityPatch;
// Available only on android S+. For S-, this method returns empty string.
const std::string socManufacturer;
const std::string versionIncremental;
};
#endif
namespace base::android::android_info {
namespace {
static std::optional<IAndroidInfo>& get_holder() {
static base::NoDestructor<std::optional<IAndroidInfo>> holder;
return *holder;
}
const IAndroidInfo& get_android_info() {
const std::optional<IAndroidInfo>& holder = get_holder();
if (!holder.has_value()) {
Java_AndroidInfo_nativeReadyForFields(AttachCurrentThread());
}
return *holder;
}
} // namespace
void Set(const IAndroidInfo& info) {
std::optional<IAndroidInfo>& holder = get_holder();
DCHECK(!holder.has_value());
holder.emplace(info);
}
static void JNI_AndroidInfo_FillFields(JNIEnv* env,
std::string& brand,
std::string& device,
std::string& buildId,
std::string& manufacturer,
std::string& model,
std::string& type,
std::string& board,
std::string& androidBuildFingerprint,
std::string& versionIncremental,
std::string& hardware,
std::string& codename,
std::string& socManufacturer,
std::string& supportedAbis,
jint sdkInt,
jboolean isDebugAndroid,
std::string& securityPatch) {
Set(IAndroidInfo{.abiName = supportedAbis,
.androidBuildFp = androidBuildFingerprint,
.androidBuildId = buildId,
.board = board,
.brand = brand,
.buildType = type,
.codename = codename,
.device = device,
.hardware = hardware,
.isDebugAndroid = static_cast<bool>(isDebugAndroid),
.manufacturer = manufacturer,
.model = model,
.sdkInt = sdkInt,
.securityPatch = securityPatch,
.socManufacturer = socManufacturer,
.versionIncremental = versionIncremental});
}
const std::string& device() {
return get_android_info().device;
}
const std::string& manufacturer() {
return get_android_info().manufacturer;
}
const std::string& model() {
return get_android_info().model;
}
const std::string& brand() {
return get_android_info().brand;
}
const std::string& android_build_id() {
return get_android_info().androidBuildId;
}
const std::string& build_type() {
return get_android_info().buildType;
}
const std::string& board() {
return get_android_info().board;
}
const std::string& android_build_fp() {
return get_android_info().androidBuildFp;
}
int sdk_int() {
return get_android_info().sdkInt;
}
bool is_debug_android() {
return get_android_info().isDebugAndroid;
}
const std::string& version_incremental() {
return get_android_info().versionIncremental;
}
const std::string& hardware() {
return get_android_info().hardware;
}
const std::string& codename() {
return get_android_info().codename;
}
// Available only on android S+. For S-, this method returns empty string.
const std::string& soc_manufacturer() {
return get_android_info().socManufacturer;
}
const std::string& abi_name() {
return get_android_info().abiName;
}
const std::string& security_patch() {
return get_android_info().securityPatch;
}
} // namespace base::android::android_info