1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "android/avd/BugreportInfo.h"
17
18 #include "android/avd/info.h"
19 #include "android/avd/keys.h"
20 #include "android/base/StringFormat.h"
21 #include "android/base/StringView.h"
22 #include "android/base/files/IniFile.h"
23 #include "android/base/misc/StringUtils.h"
24 #include "android/base/system/System.h"
25 #include "android/emulation/ComponentVersion.h"
26 #include "android/emulation/ConfigDirs.h"
27 #include "android/emulation/CpuAccelerator.h"
28 #include "android/globals.h"
29 #include "android/metrics/StudioConfig.h"
30 #include "android/opengl/gpuinfo.h"
31 #include "android/update-check/VersionExtractor.h"
32 #include "android/utils/system.h"
33
34 using android::base::IniFile;
35 using android::base::StringAppendFormat;
36 using android::base::StringFormat;
37 using android::base::StringView;
38 using android::base::System;
39 using android::base::trim;
40 using android::base::Version;
41 using android::update_check::VersionExtractor;
42
43 namespace android {
44 namespace avd {
45
BugreportInfo()46 BugreportInfo::BugreportInfo() {
47 VersionExtractor vEx;
48 Version curEmuVersion = vEx.getCurrentVersion();
49 emulatorVer =
50 curEmuVersion.isValid() ? curEmuVersion.toString() : "Unknown";
51 android::CpuAccelerator accel = android::GetCurrentCpuAccelerator();
52 Version accelVersion = android::GetCurrentCpuAcceleratorVersion();
53 if (accelVersion.isValid()) {
54 hypervisorVer =
55 (StringFormat("%s %s", android::CpuAcceleratorToString(accel),
56 accelVersion.toString()));
57 }
58 char versionString[128];
59 int apiLevel = avdInfo_getApiLevel(android_avdInfo);
60 avdInfo_getFullApiName(apiLevel, versionString, 128);
61 androidVer = versionString;
62
63 Version studioVersion = android::studio::lastestAndroidStudioVersion();
64 androidStduioVer =
65 studioVersion.isValid() ? studioVersion.toString() : "Unknown";
66 deviceName = StringView(avdInfo_getName(android_avdInfo));
67 hostOsName = System::get()->getOsName();
68 sdkToolsVer = android::getCurrentSdkVersion(
69 android::ConfigDirs::getSdkRootDirectory(),
70 android::SdkComponentType::Tools)
71 .toString();
72 cpuModel = trim(android::GetCpuInfo().second);
73 const auto buildProps = avdInfo_getBuildProperties(android_avdInfo);
74 android::base::IniFile ini((const char*)buildProps->data, buildProps->size);
75 buildFingerprint = ini.getString("ro.build.fingerprint", "");
76 auto usage = System::get()->getMemUsage();
77 totalMem = StringFormat("%d", (int)(usage.total_phys_memory / 1048576.0f));
78
79 gpuListInfo = globalGpuInfoList().dump();
80
81 static constexpr StringView kAvdDetailsNoDisplayKeys[] = {
82 ABI_TYPE, CPU_ARCH, SKIN_NAME, SKIN_PATH,
83 SDCARD_SIZE, SDCARD_PATH, IMAGES_2};
84
85 if (const auto configIni = reinterpret_cast<const android::base::IniFile*>(
86 avdInfo_getConfigIni(android_avdInfo))) {
87 StringAppendFormat(&avdDetails, "Name: %s\n", deviceName);
88 auto cpuArch = avdInfo_getTargetCpuArch(android_avdInfo);
89 StringAppendFormat(&avdDetails, "CPU/ABI: %s\n", cpuArch);
90 AFREE(cpuArch);
91 StringAppendFormat(&avdDetails, "Path: %s\n",
92 avdInfo_getContentPath(android_avdInfo));
93 auto tag = avdInfo_getTag(android_avdInfo);
94 StringAppendFormat(&avdDetails, "Target: %s (API level %d)\n", tag,
95 avdInfo_getApiLevel(android_avdInfo));
96 AFREE((char*)tag);
97
98 char* skinName = nullptr;
99 char* skinDir = nullptr;
100 avdInfo_getSkinInfo(android_avdInfo, &skinName, &skinDir);
101 if (skinName) {
102 StringAppendFormat(&avdDetails, "Skin: %s\n", skinName);
103 AFREE(skinName);
104 }
105 AFREE(skinDir);
106
107 const char* sdcard = avdInfo_getSdCardSize(android_avdInfo);
108 if (!sdcard) {
109 sdcard = avdInfo_getSdCardPath(android_avdInfo);
110 }
111 if (!sdcard || !*sdcard) {
112 sdcard = android::base::strDup("<none>");
113 }
114 StringAppendFormat(&avdDetails, "SD Card: %s\n", sdcard);
115 AFREE((char*)sdcard);
116
117 if (configIni->hasKey(SNAPSHOT_PRESENT)) {
118 StringAppendFormat(
119 &avdDetails, "Snapshot: %s",
120 avdInfo_getSnapshotPresent(android_avdInfo) ? "yes" : "no");
121 }
122
123 for (const std::string& key : *configIni) {
124 const std::string& value = configIni->getString(key, "");
125 // check if the key is already displayed
126 if (std::find_if(std::begin(kAvdDetailsNoDisplayKeys),
127 std::end(kAvdDetailsNoDisplayKeys),
128 [&key](StringView noDisplayKey) {
129 return noDisplayKey == key;
130 }) == std::end(kAvdDetailsNoDisplayKeys)) {
131 StringAppendFormat(&avdDetails, "%s: %s\n", key, value);
132 }
133 }
134 }
135 }
136
dump()137 std::string BugreportInfo::dump() {
138 return StringFormat(R"(Please Read:
139 https://developer.android.com/studio/report-bugs.html#emulator-bugs
140
141 Android Studio Version: %s
142
143 Emulator Version (Emulator--> Extended Controls--> Emulator Version): %s
144 HAXM / KVM Version: %s
145
146 Android SDK Tools: %s
147
148 Host Operating System: %s
149
150 CPU Manufacturer: %s
151
152 RAM: %s MB
153
154 GPU: %s
155
156 Build Fingerprint: %s
157
158 AVD Details: %s
159 )",
160 androidStduioVer, emulatorVer, hypervisorVer,
161 sdkToolsVer, hostOsName, cpuModel, totalMem,
162 gpuListInfo, buildFingerprint, avdDetails);
163 }
164 } // namespace avd
165 } // namespace android
166