blob: 6aaacce4025806b3806827f581b50401e6ab6a32 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <sstream>
#include "base/android/jni_android.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/memory_mapped_file.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/persistent_histogram_allocator.h"
#include "base/system/sys_info.h"
#include "chrome/android/test_support_jni_headers/ServicificationBackgroundService_jni.h"
#include "chrome/browser/android/metrics/uma_session_stats.h"
#include "components/metrics/persistent_system_profile.h"
#include "components/variations/active_field_trials.h"
#include "third_party/metrics_proto/system_profile.pb.h"
// Verifies that the memory-mapped file for persistent histograms data exists
// and contains a valid SystemProfile.
jboolean
JNI_ServicificationBackgroundService_TestPersistentHistogramsOnDiskSystemProfile(
JNIEnv* env) {
base::GlobalHistogramAllocator* allocator =
base::GlobalHistogramAllocator::Get();
if (!allocator) {
LOG(ERROR) << "The GlobalHistogramAllocator is null!";
return false;
}
const base::FilePath& persistent_file_path =
allocator->GetPersistentLocation();
if (persistent_file_path.empty()) {
LOG(ERROR) << "The path of the persistent file is empty!";
return false;
}
base::File file(persistent_file_path,
base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!file.IsValid()) {
LOG(ERROR) << "The persistent file isn't valid!";
return false;
}
std::unique_ptr<base::MemoryMappedFile> mapped(new base::MemoryMappedFile());
if (!mapped->Initialize(std::move(file), base::MemoryMappedFile::READ_ONLY)) {
LOG(ERROR) << "Fails to Initialize the memory mapped file!";
return false;
}
if (!base::FilePersistentMemoryAllocator::IsFileAcceptable(
*mapped, true /* read_only */)) {
LOG(ERROR) << "The memory mapped file isn't acceptable!";
return false;
}
// Map the file and validate it.
std::unique_ptr<base::FilePersistentMemoryAllocator> memory_allocator =
std::make_unique<base::FilePersistentMemoryAllocator>(
std::move(mapped), 0, 0, base::StringPiece(), /* read_only */ true);
if (memory_allocator->GetMemoryState() ==
base::PersistentMemoryAllocator::MEMORY_DELETED) {
LOG(ERROR) << "The memory allocator state shouldn't be MEMORY_DELETED!";
return false;
}
if (memory_allocator->IsCorrupt()) {
LOG(ERROR) << "The memory allocator is corrupt!";
return false;
}
if (!metrics::PersistentSystemProfile::HasSystemProfile(*memory_allocator)) {
LOG(ERROR) << "There isn't a System Profile!";
return false;
}
metrics::SystemProfileProto system_profile_proto;
if (!metrics::PersistentSystemProfile::GetSystemProfile(
*memory_allocator, &system_profile_proto)) {
LOG(ERROR) << "Failed to get the System Profile!";
return false;
}
if (!system_profile_proto.has_os()) {
LOG(ERROR) << "The os info isn't set!";
return false;
}
const metrics::SystemProfileProto_OS& os = system_profile_proto.os();
if (!os.has_version()) {
LOG(ERROR) << "The os version isn't set!";
return false;
}
if (base::SysInfo::OperatingSystemVersion().compare(os.version()) != 0) {
LOG(ERROR) << "The os version doesn't match!";
return false;
}
std::vector<variations::ActiveGroupId> field_trial_ids;
variations::GetFieldTrialActiveGroupIds("", &field_trial_ids);
int expected_size = static_cast<int>(field_trial_ids.size());
// The active field trial "Foo" is guaranteed in the list.
if (expected_size <= 0) {
LOG(ERROR) << "Expect at least one active field trial!";
return false;
}
if (system_profile_proto.field_trial_size() != expected_size) {
LOG(ERROR) << "The size of field trials recorded in the System Profile"
<< " doesn't match the size of active field trials!";
return false;
}
return true;
}
// Returns whether a background session has started.
jboolean JNI_ServicificationBackgroundService_IsBackgroundSessionStart(
JNIEnv* env) {
return UmaSessionStats::IsBackgroundSessionStartForTesting();
}