/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "android/avd/BugreportInfo.h" #include "android/avd/info.h" #include "android/avd/keys.h" #include "android/base/StringFormat.h" #include "android/base/StringView.h" #include "android/base/files/IniFile.h" #include "android/base/misc/StringUtils.h" #include "android/base/system/System.h" #include "android/emulation/ComponentVersion.h" #include "android/emulation/ConfigDirs.h" #include "android/emulation/CpuAccelerator.h" #include "android/globals.h" #include "android/metrics/StudioConfig.h" #include "android/opengl/gpuinfo.h" #include "android/update-check/VersionExtractor.h" #include "android/utils/system.h" using android::base::IniFile; using android::base::StringAppendFormat; using android::base::StringFormat; using android::base::StringView; using android::base::System; using android::base::trim; using android::base::Version; using android::update_check::VersionExtractor; namespace android { namespace avd { BugreportInfo::BugreportInfo() { VersionExtractor vEx; Version curEmuVersion = vEx.getCurrentVersion(); emulatorVer = curEmuVersion.isValid() ? curEmuVersion.toString() : "Unknown"; android::CpuAccelerator accel = android::GetCurrentCpuAccelerator(); Version accelVersion = android::GetCurrentCpuAcceleratorVersion(); if (accelVersion.isValid()) { hypervisorVer = (StringFormat("%s %s", android::CpuAcceleratorToString(accel), accelVersion.toString())); } char versionString[128]; int apiLevel = avdInfo_getApiLevel(android_avdInfo); avdInfo_getFullApiName(apiLevel, versionString, 128); androidVer = versionString; Version studioVersion = android::studio::lastestAndroidStudioVersion(); androidStduioVer = studioVersion.isValid() ? studioVersion.toString() : "Unknown"; deviceName = StringView(avdInfo_getName(android_avdInfo)); hostOsName = System::get()->getOsName(); sdkToolsVer = android::getCurrentSdkVersion( android::ConfigDirs::getSdkRootDirectory(), android::SdkComponentType::Tools) .toString(); cpuModel = trim(android::GetCpuInfo().second); const auto buildProps = avdInfo_getBuildProperties(android_avdInfo); android::base::IniFile ini((const char*)buildProps->data, buildProps->size); buildFingerprint = ini.getString("ro.build.fingerprint", ""); auto usage = System::get()->getMemUsage(); totalMem = StringFormat("%d", (int)(usage.total_phys_memory / 1048576.0f)); gpuListInfo = globalGpuInfoList().dump(); static constexpr StringView kAvdDetailsNoDisplayKeys[] = { ABI_TYPE, CPU_ARCH, SKIN_NAME, SKIN_PATH, SDCARD_SIZE, SDCARD_PATH, IMAGES_2}; if (const auto configIni = reinterpret_cast( avdInfo_getConfigIni(android_avdInfo))) { StringAppendFormat(&avdDetails, "Name: %s\n", deviceName); auto cpuArch = avdInfo_getTargetCpuArch(android_avdInfo); StringAppendFormat(&avdDetails, "CPU/ABI: %s\n", cpuArch); AFREE(cpuArch); StringAppendFormat(&avdDetails, "Path: %s\n", avdInfo_getContentPath(android_avdInfo)); auto tag = avdInfo_getTag(android_avdInfo); StringAppendFormat(&avdDetails, "Target: %s (API level %d)\n", tag, avdInfo_getApiLevel(android_avdInfo)); AFREE((char*)tag); char* skinName = nullptr; char* skinDir = nullptr; avdInfo_getSkinInfo(android_avdInfo, &skinName, &skinDir); if (skinName) { StringAppendFormat(&avdDetails, "Skin: %s\n", skinName); AFREE(skinName); } AFREE(skinDir); const char* sdcard = avdInfo_getSdCardSize(android_avdInfo); if (!sdcard) { sdcard = avdInfo_getSdCardPath(android_avdInfo); } if (!sdcard || !*sdcard) { sdcard = android::base::strDup(""); } StringAppendFormat(&avdDetails, "SD Card: %s\n", sdcard); AFREE((char*)sdcard); if (configIni->hasKey(SNAPSHOT_PRESENT)) { StringAppendFormat( &avdDetails, "Snapshot: %s", avdInfo_getSnapshotPresent(android_avdInfo) ? "yes" : "no"); } for (const std::string& key : *configIni) { const std::string& value = configIni->getString(key, ""); // check if the key is already displayed if (std::find_if(std::begin(kAvdDetailsNoDisplayKeys), std::end(kAvdDetailsNoDisplayKeys), [&key](StringView noDisplayKey) { return noDisplayKey == key; }) == std::end(kAvdDetailsNoDisplayKeys)) { StringAppendFormat(&avdDetails, "%s: %s\n", key, value); } } } } std::string BugreportInfo::dump() { return StringFormat(R"(Please Read: https://developer.android.com/studio/report-bugs.html#emulator-bugs Android Studio Version: %s Emulator Version (Emulator--> Extended Controls--> Emulator Version): %s HAXM / KVM Version: %s Android SDK Tools: %s Host Operating System: %s CPU Manufacturer: %s RAM: %s MB GPU: %s Build Fingerprint: %s AVD Details: %s )", androidStduioVer, emulatorVer, hypervisorVer, sdkToolsVer, hostOsName, cpuModel, totalMem, gpuListInfo, buildFingerprint, avdDetails); } } // namespace avd } // namespace android