use of com.android.tools.idea.gradle.project.model.AndroidModuleModel in project android by JetBrains.
the class NlPreviewTest method testRenderingDynamicResources.
@Test
public void testRenderingDynamicResources() throws Exception {
// Opens a layout which contains dynamic resources (defined only in build.gradle)
// and checks that the values have been resolved correctly (both that there are no
// unresolved reference errors in the XML file, and that the rendered layout strings
// matches the expected overlay semantics); also edits these in the Gradle file and
// checks that the layout rendering is updated after a Gradle sync.
guiTest.importProjectAndWaitForProjectSyncToFinish("LayoutTest");
AndroidModuleModel androidModel = guiTest.ideFrame().getAndroidModel("app");
String modelVersion = androidModel.getAndroidProject().getModelVersion();
Revision version = Revision.parseRevision(modelVersion);
assumeTrue("This test tests behavior that starts working in 0.14.+", version.getMajor() != 0 || version.getMinor() >= 14);
EditorFixture editor = guiTest.ideFrame().getEditor();
String layoutFilePath = "app/src/main/res/layout/dynamic_layout.xml";
editor.open(layoutFilePath, EditorFixture.Tab.EDITOR);
NlPreviewFixture preview = editor.getLayoutPreview(true);
preview.waitForRenderToFinish();
assertFalse(preview.hasRenderErrors());
NlComponentFixture string1 = preview.findView("TextView", 0);
string1.requireAttribute(ANDROID_URI, ATTR_TEXT, "@string/dynamic_string1");
string1.requireViewClass("android.support.v7.widget.AppCompatTextView");
string1.requireActualText("String 1 defined only by defaultConfig");
NlComponentFixture string2 = preview.findView("TextView", 1);
string2.requireAttribute(ANDROID_URI, ATTR_TEXT, "@string/dynamic_string2");
string2.requireActualText("String 1 defined only by defaultConfig");
NlComponentFixture string3 = preview.findView("TextView", 2);
string3.requireAttribute(ANDROID_URI, ATTR_TEXT, "@string/dynamic_string3");
string3.requireActualText("String 3 defined by build type debug");
NlComponentFixture string4 = preview.findView("TextView", 3);
string4.requireAttribute(ANDROID_URI, ATTR_TEXT, "@string/dynamic_string4");
string4.requireActualText("String 4 defined by flavor free");
NlComponentFixture string5 = preview.findView("TextView", 4);
string5.requireAttribute(ANDROID_URI, ATTR_TEXT, "@string/dynamic_string5");
string5.requireActualText("String 5 defined by build type debug");
// Ensure that all the references are properly resolved
FileFixture file = guiTest.ideFrame().findExistingFileByRelativePath(layoutFilePath);
file.waitForCodeAnalysisHighlightCount(ERROR, 0);
editor.open("app/build.gradle", EditorFixture.Tab.EDITOR).moveBetween("String 1 defined only by ", "defaultConfig").enterText("edited ").awaitNotification("Gradle files have changed since last project sync. A project sync may be necessary for the IDE to work properly.").performAction("Sync Now").waitForGradleProjectSyncToFinish();
editor.open(layoutFilePath, EditorFixture.Tab.EDITOR);
preview.waitForRenderToFinish();
string1 = preview.findView("TextView", 0);
string1.requireActualText("String 1 defined only by edited defaultConfig");
file.waitForCodeAnalysisHighlightCount(ERROR, 0);
}
use of com.android.tools.idea.gradle.project.model.AndroidModuleModel in project android by JetBrains.
the class InstantRunConfigurable method updateLinkState.
private void updateLinkState() {
boolean isGradle = false;
boolean isCurrentPlugin = false;
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
if (project.isDefault()) {
continue;
}
for (Module module : ModuleManager.getInstance(project).getModules()) {
AndroidModuleModel model = AndroidModuleModel.get(module);
if (model != null) {
isGradle = true;
if (InstantRunGradleUtils.modelSupportsInstantRun(model)) {
isCurrentPlugin = true;
break;
}
}
}
}
myGradleLabel.setVisible(!isGradle);
myOldVersionLabel.setVisible(isGradle && !isCurrentPlugin);
boolean enabled = isGradle && isCurrentPlugin;
// allow turning off instant run even if the plugin is not the latest
myInstantRunCheckBox.setEnabled(isGradle);
enableIrOptions(enabled);
}
use of com.android.tools.idea.gradle.project.model.AndroidModuleModel in project android by JetBrains.
the class AndroidPluginInfo method find.
@Nullable
private static AndroidPluginInfo find(@NotNull Project project, boolean searchInBuildFilesOnly) {
Module appModule = null;
AndroidModuleModel appGradleModel = null;
VirtualFile pluginBuildFile = null;
if (!searchInBuildFilesOnly) {
for (Module module : ModuleManager.getInstance(project).getModules()) {
AndroidModuleModel gradleModel = AndroidModuleModel.get(module);
if (gradleModel != null && gradleModel.getProjectType() == PROJECT_TYPE_APP) {
// This is the 'app' module in the project.
appModule = module;
appGradleModel = gradleModel;
break;
}
}
}
GradleVersion pluginVersion = appGradleModel != null ? appGradleModel.getModelVersion() : null;
AndroidPluginGeneration pluginGeneration = null;
if (appModule != null) {
pluginGeneration = AndroidPluginGeneration.find(appModule);
if (pluginGeneration == COMPONENT) {
// "Experimental" plugin does not retrieve correct version yet.
pluginVersion = null;
}
}
boolean appModuleFound = appModule != null;
boolean pluginVersionFound = pluginVersion != null;
if (!appModuleFound || !pluginVersionFound) {
// Try to find 'app' module or plugin version by reading build.gradle files.
BuildFileSearchResult result = searchInBuildFiles(project, !appModuleFound);
if (result.appVirtualFile != null) {
appModule = findModuleForFile(result.appVirtualFile, project);
}
if (isNotEmpty(result.pluginVersion)) {
pluginVersion = GradleVersion.tryParse(result.pluginVersion);
}
if (pluginGeneration == null) {
pluginGeneration = result.pluginGeneration;
}
pluginBuildFile = result.pluginVirtualFile;
}
if (appModule != null && pluginGeneration != null) {
return new AndroidPluginInfo(appModule, pluginGeneration, pluginVersion, pluginBuildFile);
}
return null;
}
use of com.android.tools.idea.gradle.project.model.AndroidModuleModel in project android by JetBrains.
the class ProjectStructureUsageTracker method trackProjectStructure.
@VisibleForTesting
void trackProjectStructure(@NotNull Module[] modules) {
AndroidModuleModel appModel = null;
AndroidModuleModel libModel = null;
int appCount = 0;
int libCount = 0;
List<GradleLibrary> gradleLibraries = new ArrayList<>();
for (Module module : modules) {
AndroidModuleModel androidModel = AndroidModuleModel.get(module);
if (androidModel != null) {
if (androidModel.getProjectType() == PROJECT_TYPE_LIBRARY) {
libModel = androidModel;
libCount++;
continue;
}
appModel = androidModel;
appCount++;
GradleLibrary gradleLibrary = trackExternalDependenciesInAndroidApp(androidModel);
if (gradleLibrary != null) {
gradleLibraries.add(gradleLibrary);
}
}
}
// Ideally we would like to get data from an "app" module, but if the project does not have one (which would be unusual, we can use
// an Android library one.)
AndroidModuleModel model = appModel != null ? appModel : libModel;
if (model != null) {
List<GradleAndroidModule> gradleAndroidModules = new ArrayList<>();
List<GradleNativeAndroidModule> gradleNativeAndroidModules = new ArrayList<>();
String appId = AndroidStudioUsageTracker.anonymizeUtf8(model.getApplicationId());
AndroidProject androidProject = model.getAndroidProject();
GradleVersion gradleVersion = GradleVersions.getInstance().getGradleVersion(myProject);
if (gradleVersion == null) {
gradleVersion = new GradleVersion(0, 0, 0);
}
GradleModule gradleModule = GradleModule.newBuilder().setTotalModuleCount(modules.length).setAppModuleCount(appCount).setLibModuleCount(libCount).build();
for (Module module : modules) {
AndroidModuleModel androidModel = AndroidModuleModel.get(module);
if (androidModel != null) {
gradleAndroidModules.add(GradleAndroidModule.newBuilder().setModuleName(AndroidStudioUsageTracker.anonymizeUtf8(module.getName())).setSigningConfigCount(androidModel.getAndroidProject().getSigningConfigs().size()).setIsLibrary(androidModel.getProjectType() == PROJECT_TYPE_LIBRARY).setBuildTypeCount(androidModel.getBuildTypeNames().size()).setFlavorCount(androidModel.getProductFlavorNames().size()).setFlavorDimension(getFlavorDimensions(androidModel).size()).build());
}
boolean shouldReportNative = false;
NdkModuleModel ndkModuleModel = NdkModuleModel.get(module);
NativeBuildSystemType buildSystemType = NativeBuildSystemType.UNKNOWN_NATIVE_BUILD_SYSTEM_TYPE;
String moduleName = "";
if (ndkModuleModel != null) {
shouldReportNative = true;
if (ndkModuleModel.modelVersionIsAtLeast("2.2.0")) {
for (String buildSystem : ndkModuleModel.getAndroidProject().getBuildSystems()) {
buildSystemType = stringToBuildSystemType(buildSystem);
}
} else {
buildSystemType = NativeBuildSystemType.GRADLE_EXPERIMENTAL;
}
moduleName = AndroidStudioUsageTracker.anonymizeUtf8(ndkModuleModel.getModuleName());
} else if (androidModel != null && areNativeLibrariesPresent(androidModel.getAndroidProject())) {
shouldReportNative = true;
if (AndroidPluginGeneration.find(module) == COMPONENT) {
buildSystemType = NativeBuildSystemType.GRADLE_EXPERIMENTAL;
} else {
buildSystemType = NativeBuildSystemType.NDK_COMPILE;
}
}
if (shouldReportNative) {
gradleNativeAndroidModules.add(GradleNativeAndroidModule.newBuilder().setModuleName(moduleName).setBuildSystemType(buildSystemType).build());
}
}
UsageTracker.getInstance().log(AndroidStudioEvent.newBuilder().setCategory(EventCategory.GRADLE).setKind(AndroidStudioEvent.EventKind.GRADLE_BUILD_DETAILS).setGradleBuildDetails(GradleBuildDetails.newBuilder().setAppId(appId).setAndroidPluginVersion(androidProject.getModelVersion()).setGradleVersion(gradleVersion.toString()).setUserEnabledIr(InstantRunSettings.isInstantRunEnabled()).setModelSupportsIr(InstantRunGradleUtils.modelSupportsInstantRun(model)).setVariantSupportsIr(InstantRunGradleUtils.variantSupportsInstantRun(model)).addAllLibraries(gradleLibraries).addModules(gradleModule).addAllAndroidModules(gradleAndroidModules).addAllNativeAndroidModules(gradleNativeAndroidModules)));
}
}
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);
}
Aggregations