blob: 754948382b8fcc3f51c6f77c25e2fb48d0e9740a [file] [log] [blame]
/*
* Copyright (C) 2016 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.
*/
package com.android.tools.analytics;
import com.android.annotations.VisibleForTesting;
import com.google.wireless.android.sdk.stats.AndroidStudioStats;
import com.google.wireless.android.sdk.stats.AndroidStudioStats.DeviceInfo.ApplicationBinaryInterface;
import com.google.wireless.android.sdk.stats.AndroidStudioStats.ProductDetails;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** Calculates common pieces of metrics data, used in various Android DevTools. */
public class CommonMetricsData {
@VisibleForTesting
/**
* Detects and returns the OS architecture: x86, x86_64, ppc. This may differ or be equal to the
* JVM architecture in the sense that a 64-bit OS can run a 32-bit JVM.
*/
public static ProductDetails.CpuArchitecture getOsArchitecture() {
ProductDetails.CpuArchitecture jvmArchitecture = getJvmArchitecture();
if (jvmArchitecture == ProductDetails.CpuArchitecture.X86) {
// This is the misleading case: the JVM is 32-bit but the OS
// might be either 32 or 64. We can't tell just from this
// property.
// Macs are always on 64-bit, so we just need to figure it
// out for Windows and Linux.
String os = System.getProperty("os.name").toLowerCase();
if (os.startsWith("win")) { //$NON-NLS-1$
// When WOW64 emulates a 32-bit environment under a 64-bit OS,
// it sets PROCESSOR_ARCHITEW6432 to AMD64 or IA64 accordingly.
// Ref: http://msdn.microsoft.com/en-us/library/aa384274(v=vs.85).aspx
String w6432 = Environment.getInstance().getVariable("PROCESSOR_ARCHITEW6432");
if (w6432 != null && w6432.contains("64")) {
return ProductDetails.CpuArchitecture.X86_64;
}
} else if (os.startsWith("linux")) {
// Let's try the obvious. This works in Ubuntu and Debian
String s = Environment.getInstance().getVariable("HOSTTYPE");
return cpuArchitectureFromString(s);
}
}
return jvmArchitecture;
}
/**
* Gets the JVM Architecture, NOTE this might not be the same as OS architecture. See {@link
* #getOsArchitecture()} if OS architecture is needed.
*/
public static ProductDetails.CpuArchitecture getJvmArchitecture() {
String arch = System.getProperty("os.arch");
return cpuArchitectureFromString(arch);
}
/**
* Builds a {@link ProductDetails.CpuArchitecture} instance based on the provided string (e.g.
* "x86_64").
*/
public static ProductDetails.CpuArchitecture cpuArchitectureFromString(String cpuArchitecture) {
if (cpuArchitecture == null || cpuArchitecture.length() == 0) {
return ProductDetails.CpuArchitecture.UNKNOWN_CPU_ARCHITECTURE;
}
if (cpuArchitecture.equalsIgnoreCase("x86_64")
|| cpuArchitecture.equalsIgnoreCase("ia64")
|| cpuArchitecture.equalsIgnoreCase("amd64")) {
return ProductDetails.CpuArchitecture.X86_64;
}
if (cpuArchitecture.equalsIgnoreCase("x86")) {
return ProductDetails.CpuArchitecture.X86;
}
if (cpuArchitecture.length() == 4
&& cpuArchitecture.charAt(0) == 'i'
&& cpuArchitecture.indexOf("86") == 2) {
// Any variation of iX86 counts as x86 (i386, i486, i686).
return ProductDetails.CpuArchitecture.X86;
}
return ProductDetails.CpuArchitecture.UNKNOWN_CPU_ARCHITECTURE;
}
/** Gets a normalized version of the os name that this code is running on. */
public static String getOsName() {
String os = System.getProperty("os.name");
if (os == null || os.length() == 0) {
return "unknown";
}
String osLower = os.toLowerCase(Locale.US);
if (osLower.startsWith("mac")) {
os = "macosx";
} else if (osLower.startsWith("win")) { //$NON-NLS-1$
os = "windows";
} else if (osLower.startsWith("linux")) { //$NON-NLS-1$
os = "linux";
} else if (os.length() > 32) {
// Unknown -- send it verbatim so we can see it
// but protect against arbitrarily long values
os = os.substring(0, 32);
}
return os;
}
/**
* Extracts the major os version that this code is running on in the form of '[0-9]+\.[0-9]+'
*/
public static String getMajorOsVersion() {
Pattern p = Pattern.compile("(\\d+)\\.(\\d+).*");
String osVers = System.getProperty("os.version");
if (osVers != null && osVers.length() > 0) {
Matcher m = p.matcher(osVers);
if (m.matches()) {
return m.group(1) + '.' + m.group(2);
}
}
return null;
}
public static ApplicationBinaryInterface applicationBinaryInterfaceFromString(String value) {
if (value == null) {
return ApplicationBinaryInterface.UNKNOWN_ABI;
}
switch (value) {
case "armeabi-v6j":
return ApplicationBinaryInterface.ARME_ABI_V6J;
case "armeabi-v6l":
return ApplicationBinaryInterface.ARME_ABI_V6L;
case "armeabi-v7a":
return ApplicationBinaryInterface.ARME_ABI_V7A;
case "armeabi":
return ApplicationBinaryInterface.ARME_ABI;
case "arm64-v8a":
return ApplicationBinaryInterface.ARM64_V8A_ABI;
case "mips":
return ApplicationBinaryInterface.MIPS_ABI;
case "mips-r2":
return ApplicationBinaryInterface.MIPS_R2_ABI;
case "x86":
return ApplicationBinaryInterface.X86_ABI;
case "x86_64":
return ApplicationBinaryInterface.X86_64_ABI;
default:
return ApplicationBinaryInterface.UNKNOWN_ABI;
}
}
}