blob: 6461df95b3228addfff0bed3425e690020a1c8fd [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 "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)
return false;
const base::FilePath& persistent_file_path =
allocator->GetPersistentLocation();
if (persistent_file_path.empty())
return false;
base::File file(persistent_file_path,
base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!file.IsValid())
return false;
std::unique_ptr<base::MemoryMappedFile> mapped(new base::MemoryMappedFile());
if (!mapped->Initialize(std::move(file), base::MemoryMappedFile::READ_ONLY))
return false;
if (!base::FilePersistentMemoryAllocator::IsFileAcceptable(
*mapped, true /* read_only */)) {
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;
}