Search in sources :

Example 1 with Abi

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);
    }
}
Also used : IDevice(com.android.ddmlib.IDevice) Abi(com.android.sdklib.devices.Abi) AndroidVersion(com.android.sdklib.AndroidVersion) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with Abi

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();
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) Abi(com.android.sdklib.devices.Abi) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with Abi

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);
}
Also used : MockPlatformTarget(com.android.sdklib.internal.androidTarget.MockPlatformTarget) IDevice(com.android.ddmlib.IDevice) Abi(com.android.sdklib.devices.Abi) AndroidVersion(com.android.sdklib.AndroidVersion)

Example 4 with Abi

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);
}
Also used : Abi(com.android.sdklib.devices.Abi) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Nullable(org.jetbrains.annotations.Nullable)

Example 5 with Abi

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);
    }
}
Also used : HyperlinkEvent(javax.swing.event.HyperlinkEvent) Abi(com.android.sdklib.devices.Abi) HyperlinkAdapter(com.intellij.ui.HyperlinkAdapter)

Aggregations

Abi (com.android.sdklib.devices.Abi)9 IDevice (com.android.ddmlib.IDevice)4 AndroidVersion (com.android.sdklib.AndroidVersion)4 MockPlatformTarget (com.android.sdklib.internal.androidTarget.MockPlatformTarget)3 NotNull (org.jetbrains.annotations.NotNull)3 Nullable (org.jetbrains.annotations.Nullable)2 Device (com.android.sdklib.devices.Device)1 SystemImageDescription (com.android.tools.idea.avdmanager.SystemImageDescription)1 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 ImmutableList (com.google.common.collect.ImmutableList)1 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)1 HyperlinkAdapter (com.intellij.ui.HyperlinkAdapter)1 File (java.io.File)1 HyperlinkEvent (javax.swing.event.HyperlinkEvent)1