use of com.android.sdklib.devices.Abi in project android by JetBrains.
the class LaunchCompatibility method canRunOnDevice.
/**
* Returns whether an application with the given requirements can be run on the given device.
*
* @param minSdkVersion minSdkVersion specified by the application
* @param projectTarget android target corresponding to the targetSdkVersion
* @param requiredFeatures required list of hardware features
* @param device the device to check compatibility against
* @return a {@link ThreeState} indicating whether the application can be run on the device, and a reason if it isn't
* compatible.
*/
@NotNull
public static LaunchCompatibility canRunOnDevice(@NotNull AndroidVersion minSdkVersion, @NotNull IAndroidTarget projectTarget, @NotNull EnumSet<IDevice.HardwareFeature> requiredFeatures, @Nullable Set<String> supportedAbis, @NotNull AndroidDevice device) {
// check if the device has the required minApi
// note that in cases where targetSdk is a preview platform, gradle sets minsdk to be the same as targetsdk,
// so as to only allow running on those systems
AndroidVersion deviceVersion = device.getVersion();
if (!deviceVersion.equals(AndroidVersion.DEFAULT) && !deviceVersion.canRun(minSdkVersion)) {
String reason = String.format("minSdk(%1$s) %3$s deviceSdk(%2$s)", minSdkVersion, deviceVersion, minSdkVersion.getCodename() == null ? ">" : "!=");
return new LaunchCompatibility(ThreeState.NO, reason);
}
// check if the device provides the required features
for (IDevice.HardwareFeature feature : requiredFeatures) {
if (!device.supportsFeature(feature)) {
return new LaunchCompatibility(ThreeState.NO, "missing feature: " + feature);
}
}
// non-watch apks to be installed on it.
if (device.supportsFeature(IDevice.HardwareFeature.WATCH)) {
if (!requiredFeatures.contains(IDevice.HardwareFeature.WATCH)) {
return new LaunchCompatibility(ThreeState.NO, "missing uses-feature watch, non-watch apks cannot be launched on a watch");
}
}
// Verify that the device ABI matches one of the target ABIs for JNI apps.
if (supportedAbis != null) {
Set<String> deviceAbis = Sets.newLinkedHashSet();
for (Abi abi : device.getAbis()) {
deviceAbis.add(abi.toString());
}
if (!supportedAbis.isEmpty() && Sets.intersection(supportedAbis, deviceAbis).isEmpty()) {
return new LaunchCompatibility(ThreeState.NO, "Device supports " + Joiner.on(", ").join(deviceAbis) + ", but APK only supports " + Joiner.on(", ").join(supportedAbis));
}
}
// we are done with checks for platform targets
if (projectTarget.isPlatform()) {
return YES;
}
// Add-ons specify a list of libraries. We need to check that the required libraries are available on the device.
// See AddOnTarget#canRunOn
List<IAndroidTarget.OptionalLibrary> additionalLibs = projectTarget.getAdditionalLibraries();
if (additionalLibs.isEmpty()) {
return YES;
}
String targetName = projectTarget.getName();
if (GOOGLE_APIS_TARGET_NAME.equals(targetName)) {
// We'll assume that Google APIs are available on all devices.
return YES;
} else {
// Unsure because we don't have an easy way of determining whether those libraries are on a device
return new LaunchCompatibility(ThreeState.UNSURE, "unsure if device supports addon: " + targetName);
}
}
use of com.android.sdklib.devices.Abi in project android by JetBrains.
the class ConnectedAndroidDevice method getAbis.
@NotNull
@Override
public List<Abi> getAbis() {
List<String> abis = myDevice.getAbis();
ImmutableList.Builder<Abi> builder = ImmutableList.builder();
for (String abi : abis) {
Abi a = Abi.getEnum(abi);
if (a != null) {
builder.add(a);
}
}
return builder.build();
}
use of com.android.sdklib.devices.Abi in project android by JetBrains.
the class LaunchCompatibilityTest method testIncompatibleAbiFilter.
public void testIncompatibleAbiFilter() {
AndroidVersion minSdkVersion = new AndroidVersion(8, null);
MockPlatformTarget projectTarget = new MockPlatformTarget(14, 0);
EnumSet<IDevice.HardwareFeature> requiredFeatures = EnumSet.noneOf(IDevice.HardwareFeature.class);
Set<String> supportedAbis = ImmutableSet.of(Abi.X86_64.toString());
List<Abi> deviceAbis = ImmutableList.of(Abi.ARMEABI, Abi.ARMEABI_V7A, Abi.ARM64_V8A);
LaunchCompatibility compatibility = LaunchCompatibility.canRunOnDevice(minSdkVersion, projectTarget, requiredFeatures, supportedAbis, createMockDevice(8, null, false, deviceAbis));
assertEquals(new LaunchCompatibility(ThreeState.NO, "Device supports armeabi, armeabi-v7a, arm64-v8a, but APK only supports x86_64"), compatibility);
}
use of com.android.sdklib.devices.Abi in project android by JetBrains.
the class AvdManagerConnection method handleAccelerationError.
/**
* Handle the {@link AccelerationErrorCode} found when attempting to start an AVD.
* @param project
* @param error
* @return a future with a device that was launched delayed, or null if startAvd should proceed to start the AVD.
*/
@Nullable
private ListenableFuture<IDevice> handleAccelerationError(@Nullable final Project project, @NotNull final AvdInfo info, @NotNull AccelerationErrorCode error) {
switch(error) {
case ALREADY_INSTALLED:
return null;
case TOOLS_UPDATE_REQUIRED:
case PLATFORM_TOOLS_UPDATE_ADVISED:
case SYSTEM_IMAGE_UPDATE_ADVISED:
// Do not block emulator from running if we need updates (run with degradated performance):
return null;
case NO_EMULATOR_INSTALLED:
// report this error below
break;
default:
Abi abi = Abi.getEnum(info.getAbiType());
boolean isAvdIntel = abi == Abi.X86 || abi == Abi.X86_64;
if (!isAvdIntel) {
// Do not block Arm and Mips emulators from running without an accelerator:
return null;
}
// report all other errors
break;
}
String accelerator = SystemInfo.isLinux ? "KVM" : "Intel HAXM";
int result = Messages.showOkCancelDialog(project, String.format("%1$s is required to run this AVD.\n%2$s\n\n%3$s\n", accelerator, error.getProblem(), error.getSolutionMessage()), error.getSolution().getDescription(), AllIcons.General.WarningDialog);
if (result != Messages.OK || error.getSolution() == AccelerationErrorSolution.SolutionCode.NONE) {
return Futures.immediateFailedFuture(new RuntimeException("Could not start AVD"));
}
final SettableFuture<ListenableFuture<IDevice>> future = SettableFuture.create();
Runnable retry = () -> future.set(startAvd(project, info));
Runnable cancel = () -> future.setException(new RuntimeException("Retry after fixing problem by hand"));
Runnable action = AccelerationErrorSolution.getActionForFix(error, project, retry, cancel);
ApplicationManager.getApplication().invokeLater(action);
return Futures.dereference(future);
}
use of com.android.sdklib.devices.Abi in project android by JetBrains.
the class HaxmAlert method refresh.
private void refresh() {
if (myImageDescription == null) {
setVisible(false);
return;
}
boolean hasLink = false;
StringBuilder warningTextBuilder = new StringBuilder();
AccelerationErrorCode accelerationError = getAccelerationState(false);
if (accelerationError != AccelerationErrorCode.ALREADY_INSTALLED) {
hasLink = true;
warningTextBuilder.append(accelerationError.getProblem());
warningTextBuilder.append("<br>");
myErrorInstructionsLink.setHyperlinkText(accelerationError.getSolution().getDescription());
if (myErrorLinkListener != null) {
myErrorInstructionsLink.removeHyperlinkListener(myErrorLinkListener);
}
Runnable refresh = new Runnable() {
@Override
public void run() {
refresh();
}
};
final Runnable action = AccelerationErrorSolution.getActionForFix(accelerationError, null, refresh, null);
myErrorLinkListener = new HyperlinkAdapter() {
@Override
protected void hyperlinkActivated(HyperlinkEvent e) {
action.run();
}
};
myErrorInstructionsLink.addHyperlinkListener(myErrorLinkListener);
myErrorInstructionsLink.setToolTipText(accelerationError.getSolution() != NONE ? accelerationError.getSolutionMessage() : null);
}
if (myImageDescription.getVersion().getApiLevel() < SdkVersionInfo.LOWEST_ACTIVE_API) {
if (warningTextBuilder.length() > 0) {
warningTextBuilder.append("<br>");
}
warningTextBuilder.append("This API Level is Deprecated<br>");
}
Abi abi = Abi.getEnum(myImageDescription.getAbiType());
if (abi != Abi.X86 && abi != Abi.X86_64) {
if (warningTextBuilder.length() > 0) {
warningTextBuilder.append("<br>");
}
warningTextBuilder.append("Consider using an x86 system image on a x86 host for better emulation performance.<br>");
}
if (!TAGS_WITH_GOOGLE_API.contains(myImageDescription.getTag())) {
if (warningTextBuilder.length() > 0) {
warningTextBuilder.append("<br>");
}
warningTextBuilder.append("Consider using a system image with Google APIs to enable testing with Google Play Services.");
}
String warningText = warningTextBuilder.toString();
if (!warningText.isEmpty()) {
warningTextBuilder.insert(0, "<html>");
warningTextBuilder.append("</html>");
myWarningMessage.setText(warningTextBuilder.toString().replaceAll("\n", "<br>"));
setVisible(true);
myErrorInstructionsLink.setVisible(hasLink);
} else {
setVisible(false);
}
}
Aggregations