blob: 49bebc34091f9671da1de5f2c5326c99e79e6491 [file] [log] [blame]
// Copyright 2016 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
#include "metrics.h"
#include "android/base/async/ThreadLooper.h"
#include "android/base/memory/LazyInstance.h"
#include "android/base/StringFormat.h"
#include "android/base/StringView.h"
#include "android/base/system/System.h"
#include "android/base/Uuid.h"
#include "android/globals.h"
#include "android/opengl/emugl_config.h"
#include "android/opengl/gpuinfo.h"
#include "android/opengles.h"
#include "android/metrics/AdbLivenessChecker.h"
#include "android/metrics/MetricsReporter.h"
#include "android/metrics/PeriodicReporter.h"
#include "android/metrics/StudioConfig.h"
#include "android/metrics/proto/studio_stats.pb.h"
#include <utility>
using android::base::StringView;
using android::base::System;
using android::metrics::MetricsReporter;
using android::metrics::PeriodicReporter;
namespace {
// A struct to contain all metrics reporters we need to be running for the
// whole emulator livecycle.
// For now it's a single member, but soon to be more.
struct InstanceData {
android::metrics::AdbLivenessChecker::Ptr livenessChecker;
void reset() {
livenessChecker.reset();
}
};
static android::base::LazyInstance<InstanceData> sGlobalData = {};
} // namespace
bool android_metrics_start(const char* emulatorVersion,
const char* emulatorFullVersion,
const char* qemuVersion,
int controlConsolePort) {
MetricsReporter::start(android::base::Uuid::generate().toString(),
emulatorVersion, emulatorFullVersion, qemuVersion);
PeriodicReporter::start(&MetricsReporter::get(),
android::base::ThreadLooper::get());
// Start the ADB liveness monitor.
const auto emulatorName =
android::base::StringFormat("emulator-%d", controlConsolePort);
sGlobalData->livenessChecker = android::metrics::AdbLivenessChecker::create(
android::base::ThreadLooper::get(), &MetricsReporter::get(),
emulatorName, 20 * 1000);
sGlobalData->livenessChecker->start();
// Add a task that reports emulator's uptime (just in case that we don't
// have enough of other messages reported).
PeriodicReporter::get().addTask(
5 * 60 * 1000, // reporting period
[](android_studio::AndroidStudioEvent* event) {
// uptime fields are always filled for all events, so there's
// nothing to do here.
return true;
});
return true;
}
void android_metrics_stop() {
sGlobalData->reset();
PeriodicReporter::stop();
MetricsReporter::stop();
}
static android_studio::EmulatorDetails::GuestCpuArchitecture
toClearcutLogGuestArch(const char* hw_cpu_arch) {
using android_studio::EmulatorDetails;
static constexpr std::pair<StringView,
EmulatorDetails::GuestCpuArchitecture>
map[] = {
{"x86", EmulatorDetails::X86},
{"x86_64", EmulatorDetails::X86_64},
{"arm", EmulatorDetails::ARM},
{"arm64", EmulatorDetails::ARM_64},
{"mips", EmulatorDetails::MIPS},
{"mips64", EmulatorDetails::MIPS_64},
};
for (const auto& pair : map) {
if (pair.first == hw_cpu_arch) {
return pair.second;
}
}
return EmulatorDetails::UNKNOWN_GUEST_CPU_ARCHITECTURE;
}
static android_studio::ProductDetails::CpuArchitecture
toClearcutLogCpuArchitecture(int bitness) {
using android_studio::ProductDetails;
switch (bitness) {
case 32:
return ProductDetails::X86;
case 64:
return ProductDetails::X86_64;
default:
return ProductDetails::UNKNOWN_CPU_ARCHITECTURE;
}
}
static android_studio::ProductDetails::SoftwareLifeCycleChannel
toClearcutLogUpdateChannel(android::studio::UpdateChannel channel) {
using android::studio::UpdateChannel;
using android_studio::ProductDetails;
switch (channel) {
case UpdateChannel::Stable:
return ProductDetails::STABLE;
case UpdateChannel::Beta:
return ProductDetails::BETA;
case UpdateChannel::Dev:
return ProductDetails::DEV;
case UpdateChannel::Canary:
return ProductDetails::CANARY;
default:
return ProductDetails::UNKNOWN_LIFE_CYCLE_CHANNEL;
}
}
static android_studio::EmulatorDetails::EmulatorRenderer
toClearcutLogEmulatorRenderer(SelectedRenderer renderer) {
// As of now, the enum values are exactly the same. Watch out for changes!
return static_cast<android_studio::EmulatorDetails::EmulatorRenderer>(
static_cast<int>(renderer));
}
void android_metrics_report_common_info(bool openglAlive) {
MetricsReporter::get().report([openglAlive](
android_studio::AndroidStudioEvent* event) {
event->mutable_product_details()->set_channel(
toClearcutLogUpdateChannel(android::studio::updateChannel()));
event->mutable_product_details()->set_os_architecture(
toClearcutLogCpuArchitecture(System::get()->getHostBitness()));
event->mutable_emulator_details()->set_session_phase(
android_studio::EmulatorDetails::RUNNING_GENERAL);
event->mutable_emulator_details()->set_is_opengl_alive(openglAlive);
event->mutable_emulator_details()->set_guest_arch(
toClearcutLogGuestArch(android_hw->hw_cpu_arch));
event->mutable_emulator_details()->set_guest_api_level(
avdInfo_getApiLevel(android_avdInfo));
event->mutable_emulator_details()->set_renderer(
toClearcutLogEmulatorRenderer(
emuglConfig_get_renderer(android_hw->hw_gpu_mode)));
event->mutable_emulator_details()->set_guest_gpu_enabled(
android_hw->hw_gpu_enabled);
if (android_hw->hw_gpu_enabled) {
char* glVendor = nullptr;
char* glRenderer = nullptr;
char* glVersion = nullptr;
// This call is only sensible after android_startOpenglesRenderer()
// has been called.
android_getOpenglesHardwareStrings(&glVendor, &glRenderer,
&glVersion);
if (glVendor) {
event->mutable_emulator_details()
->mutable_guest_gl()
->set_vendor(glVendor);
free(glVendor);
}
if (glRenderer) {
event->mutable_emulator_details()
->mutable_guest_gl()
->set_renderer(glRenderer);
free(glRenderer);
}
if (glVersion) {
event->mutable_emulator_details()
->mutable_guest_gl()
->set_version(glVersion);
free(glVersion);
}
}
for (const GpuInfo& gpu : GpuInfoList::get()->infos) {
auto hostGpu = event->mutable_emulator_details()->add_host_gpu();
hostGpu->set_device_id(gpu.device_id);
hostGpu->set_make(gpu.make);
hostGpu->set_model(gpu.model);
hostGpu->set_renderer(gpu.renderer);
hostGpu->set_revision_id(gpu.revision_id);
hostGpu->set_version(gpu.version);
}
});
}