Search in sources :

Example 6 with Manifest

use of org.jetbrains.android.dom.manifest.Manifest in project android by JetBrains.

the class AndroidUtils method getDepLibsPackages.

@NotNull
public static Set<String> getDepLibsPackages(Module module) {
    final Set<String> result = new HashSet<>();
    final HashSet<Module> visited = new HashSet<>();
    if (visited.add(module)) {
        for (AndroidFacet depFacet : getAllAndroidDependencies(module, true)) {
            final Manifest manifest = depFacet.getManifest();
            if (manifest != null) {
                String aPackage = manifest.getPackage().getValue();
                if (aPackage != null) {
                    result.add(aPackage);
                }
            }
        }
    }
    return result;
}
Also used : Module(com.intellij.openapi.module.Module) Manifest(org.jetbrains.android.dom.manifest.Manifest) AndroidFacet(org.jetbrains.android.facet.AndroidFacet) HashSet(com.intellij.util.containers.HashSet) NotNull(org.jetbrains.annotations.NotNull)

Example 7 with Manifest

use of org.jetbrains.android.dom.manifest.Manifest in project android by JetBrains.

the class AndroidResourceUtil method isManifestJavaFile.

public static boolean isManifestJavaFile(@NotNull AndroidFacet facet, @NotNull PsiFile file) {
    if (file.getName().equals(AndroidCommonUtils.MANIFEST_JAVA_FILE_NAME) && file instanceof PsiJavaFile) {
        final Manifest manifest = facet.getManifest();
        final PsiJavaFile javaFile = (PsiJavaFile) file;
        return manifest != null && javaFile.getPackageName().equals(manifest.getPackage().getValue());
    }
    return false;
}
Also used : Manifest(org.jetbrains.android.dom.manifest.Manifest)

Example 8 with Manifest

use of org.jetbrains.android.dom.manifest.Manifest in project android by JetBrains.

the class MergedManifest method syncWithReadPermission.

protected void syncWithReadPermission() {
    AndroidFacet facet = AndroidFacet.getInstance(myModule);
    assert facet != null : "Attempt to obtain manifest info from a non Android module: " + myModule.getName();
    if (myManifestFile == null) {
        myManifestFile = ManifestInfo.ManifestFile.create(facet);
    }
    // Check to see if our data is up to date
    boolean refresh = myManifestFile.refresh();
    if (!refresh) {
        // Already have up to date data
        return;
    }
    myActivityAttributesMap = new HashMap<String, ActivityAttributes>();
    myManifestTheme = null;
    myTargetSdk = AndroidVersion.DEFAULT;
    myMinSdk = AndroidVersion.DEFAULT;
    //$NON-NLS-1$
    myPackage = "";
    //$NON-NLS-1$
    myApplicationId = "";
    myVersionCode = null;
    myApplicationIcon = null;
    myApplicationLabel = null;
    myApplicationSupportsRtl = false;
    myNodeKeys = null;
    myActivities = Lists.newArrayList();
    myActivityAliases = Lists.newArrayListWithExpectedSize(4);
    myServices = Lists.newArrayListWithExpectedSize(4);
    Set<String> permissions = Sets.newHashSetWithExpectedSize(30);
    Set<String> revocable = Sets.newHashSetWithExpectedSize(2);
    try {
        Document document = myManifestFile.getXmlDocument();
        if (document == null) {
            return;
        }
        myDocument = document;
        myManifestFiles = myManifestFile.getManifestFiles();
        Element root = document.getDocumentElement();
        if (root == null) {
            return;
        }
        myApplicationId = getAttributeValue(root, null, ATTRIBUTE_PACKAGE);
        // The package comes from the main manifest, NOT from the merged manifest.
        Manifest manifest = facet.getManifest();
        myPackage = manifest == null ? myApplicationId : manifest.getPackage().getValue();
        String versionCode = getAttributeValue(root, ANDROID_URI, SdkConstants.ATTR_VERSION_CODE);
        try {
            myVersionCode = Integer.valueOf(versionCode);
        } catch (NumberFormatException ignored) {
        }
        Node node = root.getFirstChild();
        while (node != null) {
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                String nodeName = node.getNodeName();
                if (NODE_APPLICATION.equals(nodeName)) {
                    Element application = (Element) node;
                    myApplicationIcon = getAttributeValue(application, ANDROID_URI, ATTRIBUTE_ICON);
                    myApplicationLabel = getAttributeValue(application, ANDROID_URI, ATTRIBUTE_LABEL);
                    myManifestTheme = getAttributeValue(application, ANDROID_URI, ATTRIBUTE_THEME);
                    myApplicationSupportsRtl = VALUE_TRUE.equals(getAttributeValue(application, ANDROID_URI, ATTRIBUTE_SUPPORTS_RTL));
                    String debuggable = getAttributeValue(application, ANDROID_URI, ATTRIBUTE_DEBUGGABLE);
                    myApplicationDebuggable = debuggable == null ? null : VALUE_TRUE.equals(debuggable);
                    Node child = node.getFirstChild();
                    while (child != null) {
                        if (child.getNodeType() == Node.ELEMENT_NODE) {
                            String childNodeName = child.getNodeName();
                            if (NODE_ACTIVITY.equals(childNodeName)) {
                                Element element = (Element) child;
                                ActivityAttributes attributes = new ActivityAttributes(element, myApplicationId);
                                myActivityAttributesMap.put(attributes.getName(), attributes);
                                myActivities.add(element);
                            } else if (NODE_ACTIVITY_ALIAS.equals(childNodeName)) {
                                myActivityAliases.add((Element) child);
                            } else if (NODE_SERVICE.equals(childNodeName)) {
                                myServices.add((Element) child);
                            }
                        }
                        child = child.getNextSibling();
                    }
                } else if (NODE_USES_SDK.equals(nodeName)) {
                    // Look up target SDK
                    Element usesSdk = (Element) node;
                    myMinSdk = getApiVersion(usesSdk, ATTRIBUTE_MIN_SDK_VERSION, AndroidVersion.DEFAULT);
                    myTargetSdk = getApiVersion(usesSdk, ATTRIBUTE_TARGET_SDK_VERSION, myMinSdk);
                } else if (TAG_USES_PERMISSION.equals(nodeName) || TAG_USES_PERMISSION_SDK_23.equals(nodeName) || TAG_USES_PERMISSION_SDK_M.equals(nodeName)) {
                    Element element = (Element) node;
                    String name = element.getAttributeNS(ANDROID_URI, ATTR_NAME);
                    if (!name.isEmpty()) {
                        permissions.add(name);
                    }
                } else if (nodeName.equals(TAG_PERMISSION)) {
                    Element element = (Element) node;
                    String protectionLevel = element.getAttributeNS(ANDROID_URI, ATTR_PROTECTION_LEVEL);
                    if (VALUE_DANGEROUS.equals(protectionLevel)) {
                        String name = element.getAttributeNS(ANDROID_URI, ATTR_NAME);
                        if (!name.isEmpty()) {
                            revocable.add(name);
                        }
                    }
                }
            }
            node = node.getNextSibling();
        }
        myPermissionHolder = new ModulePermissions(ImmutableSet.copyOf(permissions), ImmutableSet.copyOf(revocable));
    } catch (ProcessCanceledException e) {
        // clear the file, to make sure we reload everything on next call to this method
        myManifestFile = null;
        myDocument = null;
        throw e;
    } catch (Exception e) {
        Logger.getInstance(MergedManifest.class).warn("Could not read Manifest data", e);
    }
}
Also used : Element(org.w3c.dom.Element) Node(org.w3c.dom.Node) XmlNode(com.android.manifmerger.XmlNode) Document(org.w3c.dom.Document) AndroidManifest(com.android.xml.AndroidManifest) Manifest(org.jetbrains.android.dom.manifest.Manifest) AndroidFacet(org.jetbrains.android.facet.AndroidFacet) ProcessCanceledException(com.intellij.openapi.progress.ProcessCanceledException) ProcessCanceledException(com.intellij.openapi.progress.ProcessCanceledException)

Example 9 with Manifest

use of org.jetbrains.android.dom.manifest.Manifest in project android by JetBrains.

the class AndroidAutogenerator method runAapt.

private static void runAapt(@NotNull final AndroidFacet facet, @NotNull final CompileContext context, boolean force) {
    final Module module = facet.getModule();
    final AptAutogenerationItem item = ApplicationManager.getApplication().runReadAction(new Computable<AptAutogenerationItem>() {

        @Nullable
        @Override
        public AptAutogenerationItem compute() {
            if (module.isDisposed() || module.getProject().isDisposed()) {
                return null;
            }
            final VirtualFile manifestFile = AndroidRootUtil.getManifestFileForCompiler(facet);
            if (manifestFile == null) {
                context.addMessage(CompilerMessageCategory.ERROR, AndroidBundle.message("android.compilation.error.manifest.not.found", module.getName()), null, -1, -1);
                return null;
            }
            final Manifest manifest = AndroidUtils.loadDomElement(module, manifestFile, Manifest.class);
            if (manifest == null) {
                context.addMessage(CompilerMessageCategory.ERROR, "Cannot parse file", manifestFile.getUrl(), -1, -1);
                return null;
            }
            String packageName = manifest.getPackage().getValue();
            if (packageName != null) {
                packageName = packageName.trim();
            }
            if (packageName == null || packageName.length() <= 0) {
                context.addMessage(CompilerMessageCategory.ERROR, AndroidBundle.message("package.not.found.error"), manifestFile.getUrl(), -1, -1);
                return null;
            }
            if (!AndroidUtils.isValidAndroidPackageName(packageName)) {
                context.addMessage(CompilerMessageCategory.ERROR, AndroidBundle.message("not.valid.package.name.error", packageName), manifestFile.getUrl(), -1, -1);
                return null;
            }
            final String sourceRootPath = AndroidRootUtil.getAptGenSourceRootPath(facet);
            if (sourceRootPath == null) {
                context.addMessage(CompilerMessageCategory.ERROR, AndroidBundle.message("android.compilation.error.apt.gen.not.specified", module.getName()), null, -1, -1);
                return null;
            }
            final Map<String, String> genFilePath2Package = new HashMap<String, String>();
            final String packageDir = packageName.replace('.', '/') + '/';
            genFilePath2Package.put(packageDir + AndroidCommonUtils.MANIFEST_JAVA_FILE_NAME, packageName);
            genFilePath2Package.put(packageDir + AndroidCommonUtils.R_JAVA_FILENAME, packageName);
            return new AptAutogenerationItem(packageName, sourceRootPath, genFilePath2Package);
        }
    });
    if (item == null) {
        return;
    }
    if (force) {
        final Set<VirtualFile> filesToCheck = new HashSet<VirtualFile>();
        for (String genFileRelPath : item.myGenFileRelPath2package.keySet()) {
            final String genFileFullPath = item.myOutputDirOsPath + '/' + genFileRelPath;
            if (new File(genFileFullPath).exists()) {
                final VirtualFile genFile = LocalFileSystem.getInstance().findFileByPath(genFileFullPath);
                if (genFile != null) {
                    filesToCheck.add(genFile);
                }
            }
        }
        if (!ensureFilesWritable(module.getProject(), filesToCheck)) {
            return;
        }
    }
    File tempOutDir = null;
    try {
        // Aapt generation can be very long, so we generate it in temp directory first
        tempOutDir = FileUtil.createTempDirectory("android_apt_autogeneration", "tmp");
        generateStubClasses(item.myPackage, tempOutDir, AndroidUtils.R_CLASS_NAME, AndroidUtils.MANIFEST_CLASS_NAME);
        for (String genFileRelPath : item.myGenFileRelPath2package.keySet()) {
            final File srcFile = new File(tempOutDir.getPath() + '/' + genFileRelPath);
            if (srcFile.isFile()) {
                final File dstFile = new File(item.myOutputDirOsPath + '/' + genFileRelPath);
                if (dstFile.exists()) {
                    if (!force) {
                        continue;
                    }
                    if (!FileUtil.delete(dstFile)) {
                        ApplicationManager.getApplication().runReadAction(new Runnable() {

                            @Override
                            public void run() {
                                if (module.isDisposed() || module.getProject().isDisposed()) {
                                    return;
                                }
                                context.addMessage(CompilerMessageCategory.ERROR, "Cannot delete " + FileUtil.toSystemDependentName(dstFile.getPath()), null, -1, -1);
                            }
                        });
                    }
                }
                FileUtil.rename(srcFile, dstFile);
            }
        }
        for (Map.Entry<String, String> entry : item.myGenFileRelPath2package.entrySet()) {
            final String path = item.myOutputDirOsPath + '/' + entry.getKey();
            final String aPackage = entry.getValue();
            final File file = new File(path);
            CompilerUtil.refreshIOFile(file);
            removeAllFilesWithSameName(module, file, item.myOutputDirOsPath);
            removeDuplicateClasses(module, aPackage, file, item.myOutputDirOsPath);
        }
        final VirtualFile genSourceRoot = LocalFileSystem.getInstance().findFileByPath(item.myOutputDirOsPath);
        if (genSourceRoot != null) {
            genSourceRoot.refresh(false, true);
        }
        facet.clearAutogeneratedFiles(AndroidAutogeneratorMode.AAPT);
        for (String relPath : item.myGenFileRelPath2package.keySet()) {
            final VirtualFile genFile = LocalFileSystem.getInstance().findFileByPath(item.myOutputDirOsPath + '/' + relPath);
            if (genFile != null && genFile.exists()) {
                facet.markFileAutogenerated(AndroidAutogeneratorMode.AAPT, genFile);
            }
        }
    } catch (final IOException e) {
        LOG.info(e);
        ApplicationManager.getApplication().runReadAction(new Runnable() {

            @Override
            public void run() {
                if (module.getProject().isDisposed())
                    return;
                context.addMessage(CompilerMessageCategory.ERROR, "I/O error: " + e.getMessage(), null, -1, -1);
            }
        });
    } finally {
        if (tempOutDir != null) {
            FileUtil.delete(tempOutDir);
        }
    }
}
Also used : IOException(java.io.IOException) Manifest(org.jetbrains.android.dom.manifest.Manifest) Module(com.intellij.openapi.module.Module) HashMap(com.intellij.util.containers.HashMap) File(java.io.File) Nullable(org.jetbrains.annotations.Nullable) HashSet(com.intellij.util.containers.HashSet)

Example 10 with Manifest

use of org.jetbrains.android.dom.manifest.Manifest in project android by JetBrains.

the class AndroidAutogenerator method runBuildConfigGenerator.

private static void runBuildConfigGenerator(@NotNull final AndroidFacet facet, @NotNull final CompileContext context) {
    final Module module = facet.getModule();
    final BuildconfigAutogenerationItem item = ApplicationManager.getApplication().runReadAction(new Computable<BuildconfigAutogenerationItem>() {

        @Nullable
        @Override
        public BuildconfigAutogenerationItem compute() {
            if (module.isDisposed() || module.getProject().isDisposed()) {
                return null;
            }
            final String sourceRootPath = AndroidRootUtil.getBuildconfigGenSourceRootPath(facet);
            if (sourceRootPath == null) {
                return null;
            }
            final VirtualFile manifestFile = AndroidRootUtil.getManifestFileForCompiler(facet);
            if (manifestFile == null) {
                context.addMessage(CompilerMessageCategory.ERROR, AndroidBundle.message("android.compilation.error.manifest.not.found", module.getName()), null, -1, -1);
                return null;
            }
            final Manifest manifest = AndroidUtils.loadDomElement(module, manifestFile, Manifest.class);
            if (manifest == null) {
                context.addMessage(CompilerMessageCategory.ERROR, "Cannot parse file", manifestFile.getUrl(), -1, -1);
                return null;
            }
            String packageName = manifest.getPackage().getValue();
            if (packageName != null) {
                packageName = packageName.trim();
            }
            if (packageName == null || packageName.length() <= 0) {
                context.addMessage(CompilerMessageCategory.ERROR, AndroidBundle.message("package.not.found.error"), manifestFile.getUrl(), -1, -1);
                return null;
            }
            if (!AndroidUtils.isValidAndroidPackageName(packageName)) {
                context.addMessage(CompilerMessageCategory.ERROR, AndroidBundle.message("not.valid.package.name.error", packageName), manifestFile.getUrl(), -1, -1);
                return null;
            }
            return new BuildconfigAutogenerationItem(packageName, FileUtil.toSystemDependentName(sourceRootPath));
        }
    });
    if (item == null) {
        return;
    }
    try {
        // hack for IDEA-100046: we need to avoid reporting "condition is always 'true'
        // from data flow inspection, so use non-constant value here
        generateStubClass(item.myPackage, new File(item.mySourceRootOsPath), "BuildConfig", "  public final static boolean DEBUG = Boolean.parseBoolean(null);\n");
        final VirtualFile genSourceRoot = LocalFileSystem.getInstance().findFileByPath(item.mySourceRootOsPath);
        if (genSourceRoot != null) {
            genSourceRoot.refresh(false, true);
        }
        facet.clearAutogeneratedFiles(AndroidAutogeneratorMode.BUILDCONFIG);
        final VirtualFile genFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(item.mySourceRootOsPath + '/' + item.myPackage.replace('.', '/') + '/' + BuildConfigGenerator.BUILD_CONFIG_NAME);
        if (genFile != null && genFile.exists()) {
            facet.markFileAutogenerated(AndroidAutogeneratorMode.BUILDCONFIG, genFile);
        }
    } catch (final IOException e) {
        LOG.info(e);
        ApplicationManager.getApplication().runReadAction(new Runnable() {

            @Override
            public void run() {
                if (module.getProject().isDisposed())
                    return;
                context.addMessage(CompilerMessageCategory.ERROR, "I/O error: " + e.getMessage(), null, -1, -1);
            }
        });
    }
}
Also used : IOException(java.io.IOException) Module(com.intellij.openapi.module.Module) Manifest(org.jetbrains.android.dom.manifest.Manifest) File(java.io.File) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

Manifest (org.jetbrains.android.dom.manifest.Manifest)29 AndroidFacet (org.jetbrains.android.facet.AndroidFacet)14 Module (com.intellij.openapi.module.Module)10 Nullable (org.jetbrains.annotations.Nullable)7 XmlElement (com.intellij.psi.xml.XmlElement)6 HashSet (com.intellij.util.containers.HashSet)5 NotNull (org.jetbrains.annotations.NotNull)5 Project (com.intellij.openapi.project.Project)4 VirtualFile (com.intellij.openapi.vfs.VirtualFile)4 File (java.io.File)4 MergedManifest (com.android.tools.idea.model.MergedManifest)3 IOException (java.io.IOException)3 AndroidManifest (com.android.xml.AndroidManifest)2 ProcessCanceledException (com.intellij.openapi.progress.ProcessCanceledException)2 Pair (com.intellij.openapi.util.Pair)2 PsiFile (com.intellij.psi.PsiFile)2 HashMap (com.intellij.util.containers.HashMap)2 GenericAttributeValue (com.intellij.util.xml.GenericAttributeValue)2 Application (org.jetbrains.android.dom.manifest.Application)2 ManifestElementWithRequiredName (org.jetbrains.android.dom.manifest.ManifestElementWithRequiredName)2