blob: 800ca6dcddb7a0776bfd2a9002aae66045a98abb [file] [log] [blame]
// Copyright 2017 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.
package io.flutter.plugins.deviceinfo;
import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.provider.Settings;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* The implementation of {@link MethodChannel.MethodCallHandler} for the plugin. Responsible for
* receiving method calls from method channel.
*/
class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler {
private final ContentResolver contentResolver;
private final PackageManager packageManager;
/** Substitute for missing values. */
private static final String[] EMPTY_STRING_LIST = new String[] {};
/** Constructs DeviceInfo. {@code contentResolver} and {@code packageManager} must not be null. */
MethodCallHandlerImpl(ContentResolver contentResolver, PackageManager packageManager) {
this.contentResolver = contentResolver;
this.packageManager = packageManager;
}
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if (call.method.equals("getAndroidDeviceInfo")) {
Map<String, Object> build = new HashMap<>();
build.put("board", Build.BOARD);
build.put("bootloader", Build.BOOTLOADER);
build.put("brand", Build.BRAND);
build.put("device", Build.DEVICE);
build.put("display", Build.DISPLAY);
build.put("fingerprint", Build.FINGERPRINT);
build.put("hardware", Build.HARDWARE);
build.put("host", Build.HOST);
build.put("id", Build.ID);
build.put("manufacturer", Build.MANUFACTURER);
build.put("model", Build.MODEL);
build.put("product", Build.PRODUCT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
build.put("supported32BitAbis", Arrays.asList(Build.SUPPORTED_32_BIT_ABIS));
build.put("supported64BitAbis", Arrays.asList(Build.SUPPORTED_64_BIT_ABIS));
build.put("supportedAbis", Arrays.asList(Build.SUPPORTED_ABIS));
} else {
build.put("supported32BitAbis", Arrays.asList(EMPTY_STRING_LIST));
build.put("supported64BitAbis", Arrays.asList(EMPTY_STRING_LIST));
build.put("supportedAbis", Arrays.asList(EMPTY_STRING_LIST));
}
build.put("tags", Build.TAGS);
build.put("type", Build.TYPE);
build.put("isPhysicalDevice", !isEmulator());
build.put("androidId", getAndroidId());
build.put("systemFeatures", Arrays.asList(getSystemFeatures()));
Map<String, Object> version = new HashMap<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
version.put("baseOS", Build.VERSION.BASE_OS);
version.put("previewSdkInt", Build.VERSION.PREVIEW_SDK_INT);
version.put("securityPatch", Build.VERSION.SECURITY_PATCH);
}
version.put("codename", Build.VERSION.CODENAME);
version.put("incremental", Build.VERSION.INCREMENTAL);
version.put("release", Build.VERSION.RELEASE);
version.put("sdkInt", Build.VERSION.SDK_INT);
build.put("version", version);
result.success(build);
} else {
result.notImplemented();
}
}
private String[] getSystemFeatures() {
FeatureInfo[] featureInfos = packageManager.getSystemAvailableFeatures();
if (featureInfos == null) {
return EMPTY_STRING_LIST;
}
String[] features = new String[featureInfos.length];
for (int i = 0; i < featureInfos.length; i++) {
features[i] = featureInfos[i].name;
}
return features;
}
/**
* Returns the Android hardware device ID that is unique between the device + user and app
* signing. This key will change if the app is uninstalled or its data is cleared. Device factory
* reset will also result in a value change.
*
* @return The android ID
*/
@SuppressLint("HardwareIds")
private String getAndroidId() {
return Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID);
}
/**
* A simple emulator-detection based on the flutter tools detection logic and a couple of legacy
* detection systems
*/
private boolean isEmulator() {
return (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
|| Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.startsWith("unknown")
|| Build.HARDWARE.contains("goldfish")
|| Build.HARDWARE.contains("ranchu")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.MANUFACTURER.contains("Genymotion")
|| Build.PRODUCT.contains("sdk_google")
|| Build.PRODUCT.contains("google_sdk")
|| Build.PRODUCT.contains("sdk")
|| Build.PRODUCT.contains("sdk_x86")
|| Build.PRODUCT.contains("vbox86p")
|| Build.PRODUCT.contains("emulator")
|| Build.PRODUCT.contains("simulator");
}
}