Search in sources :

Example 11 with BuildToolInfo

use of com.android.sdklib.BuildToolInfo in project kotlin by JetBrains.

the class ApiDetector method visitAttribute.

@Override
public void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute) {
    if (mApiDatabase == null) {
        return;
    }
    int attributeApiLevel = -1;
    if (ANDROID_URI.equals(attribute.getNamespaceURI())) {
        String name = attribute.getLocalName();
        if (!(name.equals(ATTR_LAYOUT_WIDTH) && !(name.equals(ATTR_LAYOUT_HEIGHT)) && !(name.equals(ATTR_ID)))) {
            //$NON-NLS-1$
            String owner = "android/R$attr";
            attributeApiLevel = mApiDatabase.getFieldVersion(owner, name);
            int minSdk = getMinSdk(context);
            if (attributeApiLevel > minSdk && attributeApiLevel > context.getFolderVersion() && attributeApiLevel > getLocalMinSdk(attribute.getOwnerElement()) && !isBenignUnusedAttribute(name) && !isAlreadyWarnedDrawableFile(context, attribute, attributeApiLevel)) {
                if (RtlDetector.isRtlAttributeName(name) || ATTR_SUPPORTS_RTL.equals(name)) {
                    // the resources differently.
                    if (name.equals(ATTR_PADDING_START)) {
                        BuildToolInfo buildToolInfo = context.getProject().getBuildTools();
                        Revision buildTools = buildToolInfo != null ? buildToolInfo.getRevision() : null;
                        boolean isOldBuildTools = buildTools != null && (buildTools.getMajor() < 23 || buildTools.getMajor() == 23 && buildTools.getMinor() == 0 && buildTools.getMicro() == 0);
                        if ((buildTools == null || isOldBuildTools) && viewMayExtendTextView(attribute.getOwnerElement())) {
                            Location location = context.getLocation(attribute);
                            String message = String.format("Attribute `%1$s` referenced here can result in a crash on " + "some specific devices older than API %2$d " + "(current min is %3$d)", attribute.getLocalName(), attributeApiLevel, minSdk);
                            //noinspection VariableNotUsedInsideIf
                            if (buildTools != null) {
                                message = String.format("Upgrade `buildToolsVersion` from " + "`%1$s` to at least `23.0.1`; if not, ", buildTools.toShortString()) + Character.toLowerCase(message.charAt(0)) + message.substring(1);
                            }
                            context.report(UNSUPPORTED, attribute, location, message);
                        }
                    }
                } else {
                    Location location = context.getLocation(attribute);
                    String message = String.format("Attribute `%1$s` is only used in API level %2$d and higher " + "(current min is %3$d)", attribute.getLocalName(), attributeApiLevel, minSdk);
                    context.report(UNUSED, attribute, location, message);
                }
            }
        }
        // since this will work just fine. See issue 67440 for more.
        if (name.equals("divider")) {
            return;
        }
    }
    String value = attribute.getValue();
    String owner = null;
    String name = null;
    String prefix;
    if (value.startsWith(ANDROID_PREFIX)) {
        prefix = ANDROID_PREFIX;
    } else if (value.startsWith(ANDROID_THEME_PREFIX)) {
        prefix = ANDROID_THEME_PREFIX;
        if (context.getResourceFolderType() == ResourceFolderType.DRAWABLE) {
            int api = 21;
            int minSdk = getMinSdk(context);
            if (api > minSdk && api > context.getFolderVersion() && api > getLocalMinSdk(attribute.getOwnerElement())) {
                Location location = context.getLocation(attribute);
                String message;
                message = String.format("Using theme references in XML drawables requires API level %1$d " + "(current min is %2$d)", api, minSdk);
                context.report(UNSUPPORTED, attribute, location, message);
                // API level 11
                return;
            }
        }
    } else if (value.startsWith(PREFIX_ANDROID) && ATTR_NAME.equals(attribute.getName()) && TAG_ITEM.equals(attribute.getOwnerElement().getTagName()) && attribute.getOwnerElement().getParentNode() != null && TAG_STYLE.equals(attribute.getOwnerElement().getParentNode().getNodeName())) {
        //$NON-NLS-1$
        owner = "android/R$attr";
        name = value.substring(PREFIX_ANDROID.length());
        prefix = null;
    } else if (value.startsWith(PREFIX_ANDROID) && ATTR_PARENT.equals(attribute.getName()) && TAG_STYLE.equals(attribute.getOwnerElement().getTagName())) {
        //$NON-NLS-1$
        owner = "android/R$style";
        name = getResourceFieldName(value.substring(PREFIX_ANDROID.length()));
        prefix = null;
    } else {
        return;
    }
    if (owner == null) {
        // Convert @android:type/foo into android/R$type and "foo"
        int index = value.indexOf('/', prefix.length());
        if (index != -1) {
            owner = //$NON-NLS-1$
            "android/R$" + value.substring(prefix.length(), index);
            name = getResourceFieldName(value.substring(index + 1));
        } else if (value.startsWith(ANDROID_THEME_PREFIX)) {
            //$NON-NLS-1$
            owner = "android/R$attr";
            name = value.substring(ANDROID_THEME_PREFIX.length());
        } else {
            return;
        }
    }
    int api = mApiDatabase.getFieldVersion(owner, name);
    int minSdk = getMinSdk(context);
    if (api > minSdk && api > context.getFolderVersion() && api > getLocalMinSdk(attribute.getOwnerElement())) {
        // used only for designtime previews
        if (TOOLS_URI.equals(attribute.getNamespaceURI())) {
            return;
        }
        //noinspection StatementWithEmptyBody
        if (attributeApiLevel >= api) {
        // The attribute will only be *read* on platforms >= attributeApiLevel.
        // If this isn't lower than the attribute reference's API level, it
        // won't be a problem
        } else if (attributeApiLevel > minSdk) {
            String attributeName = attribute.getLocalName();
            Location location = context.getLocation(attribute);
            String message = String.format("`%1$s` requires API level %2$d (current min is %3$d), but note " + "that attribute `%4$s` is only used in API level %5$d " + "and higher", name, api, minSdk, attributeName, attributeApiLevel);
            context.report(UNSUPPORTED, attribute, location, message);
        } else {
            Location location = context.getLocation(attribute);
            String message = String.format("`%1$s` requires API level %2$d (current min is %3$d)", value, api, minSdk);
            context.report(UNSUPPORTED, attribute, location, message);
        }
    }
}
Also used : Revision(com.android.repository.Revision) BuildToolInfo(com.android.sdklib.BuildToolInfo)

Example 12 with BuildToolInfo

use of com.android.sdklib.BuildToolInfo in project android by JetBrains.

the class AndroidDxWrapper method execute.

@SuppressWarnings({ "IOResourceOpenedButNotSafelyClosed" })
public static Map<AndroidCompilerMessageKind, List<String>> execute(@NotNull Module module, @NotNull IAndroidTarget target, @NotNull String outputDir, @NotNull String[] compileTargets, @NotNull String additionalVmParams, int maxHeapSize, boolean optimize) {
    BuildToolInfo buildToolInfo = target.getBuildToolInfo();
    if (buildToolInfo == null) {
        return Collections.singletonMap(AndroidCompilerMessageKind.ERROR, Collections.singletonList("No Build Tools in the Android SDK."));
    }
    String outFile = outputDir + File.separatorChar + AndroidCommonUtils.CLASSES_FILE_NAME;
    final Map<AndroidCompilerMessageKind, List<String>> messages = new HashMap<AndroidCompilerMessageKind, List<String>>(2);
    messages.put(AndroidCompilerMessageKind.ERROR, new ArrayList<String>());
    messages.put(AndroidCompilerMessageKind.INFORMATION, new ArrayList<String>());
    messages.put(AndroidCompilerMessageKind.WARNING, new ArrayList<String>());
    String dxJarPath = buildToolInfo.getPath(BuildToolInfo.PathId.DX_JAR);
    File dxJar = new File(dxJarPath);
    if (!dxJar.isFile()) {
        messages.get(AndroidCompilerMessageKind.ERROR).add(AndroidBundle.message("android.file.not.exist.error", dxJarPath));
        return messages;
    }
    JavaParameters parameters = new JavaParameters();
    Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
    // dex runs after simple java compilation, so JDK must be specified
    assert sdk != null;
    parameters.setJdk(sdk);
    parameters.setMainClass(AndroidDxRunner.class.getName());
    ParametersList programParamList = parameters.getProgramParametersList();
    programParamList.add(dxJarPath);
    programParamList.add(outFile);
    programParamList.add("--optimize", Boolean.toString(optimize));
    programParamList.addAll(compileTargets);
    programParamList.add("--exclude");
    ParametersList vmParamList = parameters.getVMParametersList();
    if (additionalVmParams.length() > 0) {
        vmParamList.addParametersString(additionalVmParams);
    }
    if (!AndroidCommonUtils.hasXmxParam(vmParamList.getParameters())) {
        vmParamList.add("-Xmx" + maxHeapSize + "M");
    }
    final PathsList classPath = parameters.getClassPath();
    classPath.add(PathUtil.getJarPathForClass(AndroidDxRunner.class));
    classPath.add(PathUtil.getJarPathForClass(FileUtilRt.class));
    // delete file to check if it will exist after dex compilation
    if (!new File(outFile).delete()) {
        LOG.info("Cannot delete file " + outFile);
    }
    Process process;
    try {
        parameters.setUseDynamicClasspath(true);
        GeneralCommandLine commandLine = parameters.toCommandLine();
        LOG.info(commandLine.getCommandLineString());
        process = commandLine.createProcess();
        AndroidCommonUtils.handleDexCompilationResult(process, commandLine.getCommandLineString(), outFile, messages, false);
    } catch (ExecutionException e) {
        messages.get(AndroidCompilerMessageKind.ERROR).add("ExecutionException: " + e.getMessage());
        LOG.info(e);
        return messages;
    }
    return messages;
}
Also used : BuildToolInfo(com.android.sdklib.BuildToolInfo) HashMap(com.intellij.util.containers.HashMap) AndroidCompilerMessageKind(org.jetbrains.android.util.AndroidCompilerMessageKind) PathsList(com.intellij.util.PathsList) PathsList(com.intellij.util.PathsList) ArrayList(java.util.ArrayList) List(java.util.List) FileUtilRt(com.intellij.openapi.util.io.FileUtilRt) Sdk(com.intellij.openapi.projectRoots.Sdk) ExecutionException(com.intellij.execution.ExecutionException) File(java.io.File)

Example 13 with BuildToolInfo

use of com.android.sdklib.BuildToolInfo in project android by JetBrains.

the class GradleImport method getBuildToolsVersion.

String getBuildToolsVersion() {
    AndroidSdkHandler sdkHandler = AndroidSdkHandler.getInstance(mySdkLocation);
    StudioLoggerProgressIndicator progress = new StudioLoggerProgressIndicator(getClass());
    BuildToolInfo buildTool = sdkHandler.getLatestBuildTool(progress, false);
    if (buildTool == null) {
        buildTool = sdkHandler.getLatestBuildTool(progress, true);
    }
    if (buildTool != null) {
        return buildTool.getRevision().toString();
    }
    return CURRENT_BUILD_TOOLS_VERSION;
}
Also used : StudioLoggerProgressIndicator(com.android.tools.idea.sdk.progress.StudioLoggerProgressIndicator) BuildToolInfo(com.android.sdklib.BuildToolInfo) AndroidSdkHandler(com.android.sdklib.repository.AndroidSdkHandler)

Example 14 with BuildToolInfo

use of com.android.sdklib.BuildToolInfo in project android by JetBrains.

the class LintIdeClient method getBuildTools.

@Override
@Nullable
public BuildToolInfo getBuildTools(@NonNull com.android.tools.lint.detector.api.Project project) {
    if (project.isGradleProject()) {
        Module module = getModule();
        if (module != null) {
            AndroidModuleModel model = AndroidModuleModel.get(module);
            if (model != null) {
                GradleVersion version = model.getModelVersion();
                if (version != null && version.isAtLeast(2, 1, 0)) {
                    String buildToolsVersion = model.getAndroidProject().getBuildToolsVersion();
                    AndroidSdkHandler sdk = getSdk();
                    if (sdk != null) {
                        try {
                            Revision revision = Revision.parseRevision(buildToolsVersion);
                            BuildToolInfo buildToolInfo = sdk.getBuildToolInfo(revision, getRepositoryLogger());
                            if (buildToolInfo != null) {
                                return buildToolInfo;
                            }
                        } catch (NumberFormatException ignore) {
                        // Fall through and use the latest
                        }
                    }
                }
            }
        }
    }
    return super.getBuildTools(project);
}
Also used : Revision(com.android.repository.Revision) BuildToolInfo(com.android.sdklib.BuildToolInfo) AndroidModuleModel(com.android.tools.idea.gradle.project.model.AndroidModuleModel) AndroidSdkHandler(com.android.sdklib.repository.AndroidSdkHandler) Module(com.intellij.openapi.module.Module) GradleVersion(com.android.ide.common.repository.GradleVersion) Nullable(org.jetbrains.annotations.Nullable)

Example 15 with BuildToolInfo

use of com.android.sdklib.BuildToolInfo in project android by JetBrains.

the class ExportSignedPackageWizard method createAndAlignApk.

private void createAndAlignApk(final String apkPath) {
    AndroidPlatform platform = getFacet().getConfiguration().getAndroidPlatform();
    assert platform != null;
    String sdkPath = platform.getSdkData().getLocation().getPath();
    String zipAlignPath = AndroidCommonUtils.getZipAlign(sdkPath, platform.getTarget());
    File zipalign = new File(zipAlignPath);
    if (!zipalign.isFile()) {
        BuildToolInfo buildTool = platform.getTarget().getBuildToolInfo();
        if (buildTool != null) {
            zipAlignPath = buildTool.getPath(BuildToolInfo.PathId.ZIP_ALIGN);
            zipalign = new File(zipAlignPath);
        }
    }
    final boolean runZipAlign = zipalign.isFile();
    File destFile = null;
    try {
        destFile = runZipAlign ? FileUtil.createTempFile("android", ".apk") : new File(apkPath);
        createApk(destFile);
    } catch (Exception e) {
        showErrorInDispatchThread(e.getMessage());
    }
    if (destFile == null) {
        return;
    }
    if (runZipAlign) {
        File realDestFile = new File(apkPath);
        String message = AndroidCommonUtils.executeZipAlign(zipAlignPath, destFile, realDestFile);
        if (message != null) {
            showErrorInDispatchThread(message);
            return;
        }
    }
    invokeLaterIfNeeded(new Runnable() {

        @Override
        public void run() {
            String title = AndroidBundle.message("android.export.package.wizard.title");
            Project project = getProject();
            File apkFile = new File(apkPath);
            VirtualFile vApkFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(apkFile);
            if (vApkFile != null) {
                vApkFile.refresh(true, false);
            }
            if (!runZipAlign) {
                Messages.showWarningDialog(project, AndroidCommonBundle.message("android.artifact.building.cannot.find.zip.align.error"), title);
            }
            if (ShowFilePathAction.isSupported()) {
                if (Messages.showOkCancelDialog(project, AndroidBundle.message("android.export.package.success.message", apkFile.getName()), title, RevealFileAction.getActionName(), IdeBundle.message("action.close"), Messages.getInformationIcon()) == Messages.OK) {
                    ShowFilePathAction.openFile(apkFile);
                }
            } else {
                Messages.showInfoMessage(project, AndroidBundle.message("android.export.package.success.message", apkFile), title);
            }
        }
    });
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) AndroidProject(com.android.builder.model.AndroidProject) Project(com.intellij.openapi.project.Project) BuildToolInfo(com.android.sdklib.BuildToolInfo) AndroidPlatform(org.jetbrains.android.sdk.AndroidPlatform) VirtualFile(com.intellij.openapi.vfs.VirtualFile) File(java.io.File) CommitStepException(com.intellij.ide.wizard.CommitStepException) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException)

Aggregations

BuildToolInfo (com.android.sdklib.BuildToolInfo)20 File (java.io.File)11 AndroidSdkHandler (com.android.sdklib.repository.AndroidSdkHandler)7 StudioLoggerProgressIndicator (com.android.tools.idea.sdk.progress.StudioLoggerProgressIndicator)6 Revision (com.android.repository.Revision)4 VirtualFile (com.intellij.openapi.vfs.VirtualFile)3 HashMap (com.intellij.util.containers.HashMap)3 ArrayList (java.util.ArrayList)3 AndroidCompilerMessageKind (org.jetbrains.android.util.AndroidCompilerMessageKind)3 FileUtilRt (com.intellij.openapi.util.io.FileUtilRt)2 IOException (java.io.IOException)2 GradleException (org.gradle.api.GradleException)2 Nullable (org.jetbrains.annotations.Nullable)2 AaptOptions (com.android.build.gradle.internal.dsl.AaptOptions)1 SymbolLoader (com.android.builder.internal.SymbolLoader)1 SymbolWriter (com.android.builder.internal.SymbolWriter)1 AaptV1 (com.android.builder.internal.aapt.v1.AaptV1)1 PngProcessMode (com.android.builder.internal.aapt.v1.AaptV1.PngProcessMode)1 AndroidLibrary (com.android.builder.model.AndroidLibrary)1 AndroidProject (com.android.builder.model.AndroidProject)1