use of com.android.tools.idea.gradle.project.model.AndroidModuleModel in project android by JetBrains.
the class ProjectProfileSelectionDialog method createProjectStructureTree.
private void createProjectStructureTree() {
CheckboxTree.CheckboxTreeCellRenderer renderer = new CheckboxTree.CheckboxTreeCellRenderer() {
@Override
public void customizeRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
if (value instanceof DefaultMutableTreeNode) {
Object data = ((DefaultMutableTreeNode) value).getUserObject();
ColoredTreeCellRenderer textRenderer = getTextRenderer();
if (data instanceof ModuleTreeElement) {
ModuleTreeElement moduleElement = (ModuleTreeElement) data;
textRenderer.append(moduleElement.myModule.getName());
if (!moduleElement.myConflicts.isEmpty()) {
boolean allResolved = true;
for (Conflict conflict : moduleElement.myConflicts) {
if (!conflict.isResolved()) {
allResolved = false;
break;
}
}
SimpleTextAttributes attributes = allResolved ? UNRESOLVED_ATTRIBUTES : SimpleTextAttributes.GRAY_ATTRIBUTES;
textRenderer.append(" ");
textRenderer.append(myConflicts.size() == 1 ? "[Conflict]" : "[Conflicts]", attributes);
}
textRenderer.setIcon(AllIcons.Actions.Module);
} else if (data instanceof String) {
textRenderer.append((String) data, SimpleTextAttributes.REGULAR_ITALIC_ATTRIBUTES);
textRenderer.setIcon(AndroidIcons.Variant);
} else if (data instanceof DependencyTreeElement) {
DependencyTreeElement dependency = (DependencyTreeElement) data;
textRenderer.append(dependency.myModule.getName());
if (!StringUtil.isEmpty(dependency.myVariant)) {
textRenderer.append(" (" + dependency.myVariant + ")", SimpleTextAttributes.GRAY_ATTRIBUTES);
}
Icon icon = dependency.myConflict != null ? AllIcons.RunConfigurations.TestFailed : AllIcons.RunConfigurations.TestPassed;
textRenderer.setIcon(icon);
}
}
}
};
CheckedTreeNode rootNode = new FilterAwareCheckedTreeNode(null);
ModuleManager moduleManager = ModuleManager.getInstance(myProject);
Module[] modules = moduleManager.getModules();
Arrays.sort(modules, ModulesAlphaComparator.INSTANCE);
Map<String, Module> modulesByGradlePath = Maps.newHashMap();
for (Module module : modules) {
String gradlePath = GradleUtil.getGradlePath(module);
if (StringUtil.isEmpty(gradlePath)) {
// We always want to include it, therefore we don't give users a chance to uncheck it in the "Project Structure" pane.
continue;
}
modulesByGradlePath.put(gradlePath, module);
ModuleTreeElement moduleElement = new ModuleTreeElement(module);
CheckedTreeNode moduleNode = new FilterAwareCheckedTreeNode(moduleElement);
rootNode.add(moduleNode);
AndroidModuleModel androidModel = AndroidModuleModel.get(module);
if (androidModel == null) {
continue;
}
Multimap<String, DependencyTreeElement> dependenciesByVariant = HashMultimap.create();
for (Variant variant : androidModel.getAndroidProject().getVariants()) {
for (AndroidLibrary library : getDirectLibraryDependencies(variant, androidModel)) {
gradlePath = library.getProject();
if (gradlePath == null) {
continue;
}
Module dependency = modulesByGradlePath.get(gradlePath);
if (dependency == null) {
dependency = GradleUtil.findModuleByGradlePath(myProject, gradlePath);
}
if (dependency == null) {
continue;
}
Conflict conflict = getConflict(dependency);
modulesByGradlePath.put(gradlePath, dependency);
DependencyTreeElement dependencyElement = new DependencyTreeElement(dependency, gradlePath, library.getProjectVariant(), conflict);
dependenciesByVariant.put(variant.getName(), dependencyElement);
}
}
List<String> variantNames = Lists.newArrayList(dependenciesByVariant.keySet());
Collections.sort(variantNames);
List<String> consolidatedVariants = Lists.newArrayList();
List<String> variantsToSkip = Lists.newArrayList();
int variantCount = variantNames.size();
for (int i = 0; i < variantCount; i++) {
String variant1 = variantNames.get(i);
if (variantsToSkip.contains(variant1)) {
continue;
}
Collection<DependencyTreeElement> set1 = dependenciesByVariant.get(variant1);
for (int j = i + 1; j < variantCount; j++) {
String variant2 = variantNames.get(j);
Collection<DependencyTreeElement> set2 = dependenciesByVariant.get(variant2);
if (set1.equals(set2)) {
variantsToSkip.add(variant2);
if (!consolidatedVariants.contains(variant1)) {
consolidatedVariants.add(variant1);
}
consolidatedVariants.add(variant2);
}
}
String variantName = variant1;
if (!consolidatedVariants.isEmpty()) {
variantName = Joiner.on(", ").join(consolidatedVariants);
}
DefaultMutableTreeNode variantNode = new DefaultMutableTreeNode(variantName);
moduleNode.add(variantNode);
List<DependencyTreeElement> dependencyElements = Lists.newArrayList(set1);
Collections.sort(dependencyElements);
for (DependencyTreeElement dependencyElement : dependencyElements) {
if (dependencyElement.myConflict != null) {
moduleElement.addConflict(dependencyElement.myConflict);
}
variantNode.add(new DefaultMutableTreeNode(dependencyElement));
}
consolidatedVariants.clear();
}
}
myProjectStructureTree = new CheckboxTreeView(renderer, rootNode) {
@Override
protected void onNodeStateChanged(@NotNull CheckedTreeNode node) {
Module module = null;
Object data = node.getUserObject();
if (data instanceof ModuleTreeElement) {
module = ((ModuleTreeElement) data).myModule;
}
if (module == null) {
return;
}
boolean updated = false;
Enumeration variantNodes = myConflictTree.myRoot.children();
while (variantNodes.hasMoreElements()) {
Object child = variantNodes.nextElement();
if (!(child instanceof CheckedTreeNode)) {
continue;
}
CheckedTreeNode variantNode = (CheckedTreeNode) child;
Enumeration moduleNodes = variantNode.children();
while (moduleNodes.hasMoreElements()) {
child = moduleNodes.nextElement();
if (!(child instanceof CheckedTreeNode)) {
continue;
}
CheckedTreeNode moduleNode = (CheckedTreeNode) child;
data = moduleNode.getUserObject();
if (!(data instanceof Conflict.AffectedModule)) {
continue;
}
Conflict.AffectedModule affected = (Conflict.AffectedModule) data;
boolean checked = node.isChecked();
if (module.equals(affected.getTarget()) && moduleNode.isChecked() != checked) {
affected.setSelected(checked);
moduleNode.setChecked(checked);
updated = true;
}
}
}
if (updated) {
repaintAll();
}
}
};
myProjectStructureTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
myProjectStructureTree.setRootVisible(false);
}
use of com.android.tools.idea.gradle.project.model.AndroidModuleModel in project android by JetBrains.
the class BuildVariantView method updateContents.
public void updateContents() {
GradleSyncState syncState = GradleSyncState.getInstance(myProject);
if (syncState.isSyncInProgress() && !syncState.isSyncSkipped()) {
projectImportStarted();
return;
}
final List<Object[]> rows = Lists.newArrayList();
final List<BuildVariantItem[]> variantNamesPerRow = Lists.newArrayList();
for (Module module : getGradleModulesWithAndroidProjects()) {
AndroidFacet androidFacet = AndroidFacet.getInstance(module);
NdkFacet ndkFacet = NdkFacet.getInstance(module);
// getGradleModules() returns only relevant modules.
assert androidFacet != null || ndkFacet != null;
String variantName = null;
if (androidFacet != null) {
JpsAndroidModuleProperties facetProperties = androidFacet.getProperties();
variantName = facetProperties.SELECTED_BUILD_VARIANT;
}
BuildVariantItem[] variantNames = getVariantItems(module);
if (variantNames != null) {
if (androidFacet != null) {
AndroidModuleModel androidModel = AndroidModuleModel.get(module);
// AndroidModel may be null when applying a quick fix (e.g. "Fix Gradle version")
if (androidModel != null) {
variantName = androidModel.getSelectedVariant().getName();
}
} else {
// As only the modules backed by either AndroidGradleModel or NativeAndroidGradleModel are shown in the Build Variants View,
// when a module is not backed by AndroidGradleModel, it surely contains a valid NativeAndroidGradleModel.
NdkModuleModel ndkModuleModel = NdkModuleModel.get(module);
if (ndkModuleModel != null) {
variantName = ndkModuleModel.getSelectedVariant().getName();
}
}
variantNamesPerRow.add(variantNames);
}
if (variantName != null) {
Object[] row = { module, variantName };
rows.add(row);
}
}
Runnable setModelTask = () -> getVariantsTable().setModel(rows, variantNamesPerRow);
Application application = ApplicationManager.getApplication();
if (application.isDispatchThread()) {
setModelTask.run();
} else {
application.invokeLater(setModelTask);
}
}
use of com.android.tools.idea.gradle.project.model.AndroidModuleModel in project android by JetBrains.
the class GradleApkProvider method getApks.
@Override
@NotNull
public Collection<ApkInfo> getApks(@NotNull IDevice device) throws ApkProvisionException {
AndroidModuleModel androidModel = AndroidModuleModel.get(myFacet);
if (androidModel == null) {
LOG.warn("Android model is null. Sync might have failed");
return Collections.emptyList();
}
Variant selectedVariant = androidModel.getSelectedVariant();
List<ApkInfo> apkList = Lists.newArrayList();
// install apk (note that variant.getOutputFile() will point to a .aar in the case of a library)
int projectType = androidModel.getProjectType();
if (projectType == PROJECT_TYPE_APP || projectType == PROJECT_TYPE_INSTANTAPP) {
File apk = getApk(selectedVariant, device);
apkList.add(new ApkInfo(apk, myApplicationIdProvider.getPackageName()));
}
if (myTest) {
AndroidArtifact testArtifactInfo = androidModel.getAndroidTestArtifactInSelectedVariant();
if (testArtifactInfo != null) {
AndroidArtifactOutput output = GradleUtil.getOutput(testArtifactInfo);
File testApk = output.getMainOutputFile().getOutputFile();
String testPackageName = myApplicationIdProvider.getTestPackageName();
// Cannot be null if initialized.
assert testPackageName != null;
apkList.add(new ApkInfo(testApk, testPackageName));
}
if (androidModel.getFeatures().isTestedTargetVariantsSupported()) {
apkList.addAll(0, getTargetedApks(selectedVariant, device));
}
}
return apkList;
}
use of com.android.tools.idea.gradle.project.model.AndroidModuleModel in project android by JetBrains.
the class GradleApplicationIdProvider method getTestPackageName.
@Override
public String getTestPackageName() throws ApkProvisionException {
AndroidModuleModel androidModel = AndroidModuleModel.get(myFacet);
// This is a Gradle project, there must be an AndroidGradleModel.
assert androidModel != null;
// In the case of Gradle projects, either the merged flavor provides a test package name,
// or we just append ".test" to the source package name
Variant selectedVariant = androidModel.getSelectedVariant();
String testPackageName = selectedVariant.getMergedFlavor().getTestApplicationId();
return (testPackageName != null) ? testPackageName : getPackageName() + DEFAULT_TEST_PACKAGE_SUFFIX;
}
use of com.android.tools.idea.gradle.project.model.AndroidModuleModel in project android by JetBrains.
the class AndroidLintGlobalInspectionContext method performPreRunActivities.
@Override
public void performPreRunActivities(@NotNull List<Tools> globalTools, @NotNull List<Tools> localTools, @NotNull final GlobalInspectionContext context) {
final Project project = context.getProject();
// Running a single inspection that's not lint? If so don't run lint
if (localTools.isEmpty() && globalTools.size() == 1) {
Tools tool = globalTools.get(0);
if (!tool.getShortName().startsWith(LINT_INSPECTION_PREFIX)) {
return;
}
}
if (!ProjectFacetManager.getInstance(project).hasFacets(AndroidFacet.ID)) {
return;
}
List<Issue> issues = AndroidLintExternalAnnotator.getIssuesFromInspections(project, null);
if (issues.size() == 0) {
return;
}
// If running a single check by name, turn it on if it's off by default.
if (localTools.isEmpty() && globalTools.size() == 1) {
Tools tool = globalTools.get(0);
String id = tool.getShortName().substring(LINT_INSPECTION_PREFIX.length());
Issue issue = new LintIdeIssueRegistry().getIssue(id);
if (issue != null && !issue.isEnabledByDefault()) {
issues = Collections.singletonList(issue);
issue.setEnabledByDefault(true);
// And turn it back off again in cleanup
myEnabledIssue = issue;
}
}
final Map<Issue, Map<File, List<ProblemData>>> problemMap = new HashMap<>();
AnalysisScope scope = context.getRefManager().getScope();
if (scope == null) {
scope = AndroidLintLintBaselineInspection.ourRerunScope;
if (scope == null) {
return;
}
}
final LintIdeClient client = LintIdeClient.forBatch(project, problemMap, scope, issues);
final LintDriver lint = new LintDriver(new LintIdeIssueRegistry(), client);
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
if (indicator != null) {
ProgressWrapper.unwrap(indicator).setText("Running Android Lint");
}
EnumSet<Scope> lintScope;
//noinspection ConstantConditions
if (!LintIdeProject.SUPPORT_CLASS_FILES) {
lintScope = EnumSet.copyOf(Scope.ALL);
// Can't run class file based checks
lintScope.remove(Scope.CLASS_FILE);
lintScope.remove(Scope.ALL_CLASS_FILES);
lintScope.remove(Scope.JAVA_LIBRARIES);
} else {
lintScope = Scope.ALL;
}
List<VirtualFile> files = null;
final List<Module> modules = Lists.newArrayList();
int scopeType = scope.getScopeType();
switch(scopeType) {
case AnalysisScope.MODULE:
{
SearchScope searchScope = ReadAction.compute(scope::toSearchScope);
if (searchScope instanceof ModuleWithDependenciesScope) {
ModuleWithDependenciesScope s = (ModuleWithDependenciesScope) searchScope;
if (!s.isSearchInLibraries()) {
modules.add(s.getModule());
}
}
break;
}
case AnalysisScope.FILE:
case AnalysisScope.VIRTUAL_FILES:
case AnalysisScope.UNCOMMITTED_FILES:
{
files = Lists.newArrayList();
SearchScope searchScope = scope.toSearchScope();
if (searchScope instanceof LocalSearchScope) {
final LocalSearchScope localSearchScope = (LocalSearchScope) searchScope;
final PsiElement[] elements = localSearchScope.getScope();
final List<VirtualFile> finalFiles = files;
ApplicationManager.getApplication().runReadAction(() -> {
for (PsiElement element : elements) {
if (element instanceof PsiFile) {
// should be the case since scope type is FILE
Module module = ModuleUtilCore.findModuleForPsiElement(element);
if (module != null && !modules.contains(module)) {
modules.add(module);
}
VirtualFile virtualFile = ((PsiFile) element).getVirtualFile();
if (virtualFile != null) {
if (virtualFile instanceof StringsVirtualFile) {
StringsVirtualFile f = (StringsVirtualFile) virtualFile;
if (!modules.contains(f.getFacet().getModule())) {
modules.add(f.getFacet().getModule());
}
} else {
finalFiles.add(virtualFile);
}
}
}
}
});
} else {
final List<VirtualFile> finalList = files;
scope.accept(new PsiElementVisitor() {
@Override
public void visitFile(PsiFile file) {
VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile != null) {
finalList.add(virtualFile);
}
}
});
}
if (files.isEmpty()) {
files = null;
} else {
// Lint will compute it lazily based on actual files in the request
lintScope = null;
}
break;
}
case AnalysisScope.PROJECT:
{
modules.addAll(Arrays.asList(ModuleManager.getInstance(project).getModules()));
break;
}
case AnalysisScope.CUSTOM:
case AnalysisScope.MODULES:
case AnalysisScope.DIRECTORY:
{
// Handled by the getNarrowedComplementaryScope case below
break;
}
case AnalysisScope.INVALID:
break;
default:
Logger.getInstance(this.getClass()).warn("Unexpected inspection scope " + scope + ", " + scopeType);
}
if (modules.isEmpty()) {
for (Module module : ModuleManager.getInstance(project).getModules()) {
if (scope.containsModule(module)) {
modules.add(module);
}
}
if (modules.isEmpty() && files != null) {
for (VirtualFile file : files) {
Module module = ModuleUtilCore.findModuleForFile(file, project);
if (module != null && !modules.contains(module)) {
modules.add(module);
}
}
}
if (modules.isEmpty()) {
AnalysisScope narrowed = scope.getNarrowedComplementaryScope(project);
for (Module module : ModuleManager.getInstance(project).getModules()) {
if (narrowed.containsModule(module)) {
modules.add(module);
}
}
}
}
LintRequest request = new LintIdeRequest(client, project, files, modules, false);
request.setScope(lintScope);
// Baseline analysis?
myBaseline = null;
for (Module module : modules) {
AndroidModuleModel model = AndroidModuleModel.get(module);
if (model != null) {
GradleVersion version = model.getModelVersion();
if (version != null && version.isAtLeast(2, 3, 0, "beta", 2, true)) {
LintOptions options = model.getAndroidProject().getLintOptions();
try {
File baselineFile = options.getBaselineFile();
if (baselineFile != null && !AndroidLintLintBaselineInspection.ourSkipBaselineNextRun) {
if (!baselineFile.isAbsolute()) {
String path = module.getProject().getBasePath();
if (path != null) {
baselineFile = new File(FileUtil.toSystemDependentName(path), baselineFile.getPath());
}
}
myBaseline = new LintBaseline(client, baselineFile);
lint.setBaseline(myBaseline);
if (!baselineFile.isFile()) {
myBaseline.setWriteOnClose(true);
} else if (AndroidLintLintBaselineInspection.ourUpdateBaselineNextRun) {
myBaseline.setRemoveFixed(true);
myBaseline.setWriteOnClose(true);
}
}
} catch (Throwable unsupported) {
// During 2.3 development some builds may have this method, others may not
}
}
break;
}
}
lint.analyze(request);
AndroidLintLintBaselineInspection.clearNextRunState();
myResults = problemMap;
}
Aggregations