summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Gaillard <jgaillard@google.com>2022-06-21 21:49:54 +0100
committerJerome Gaillard <jgaillard@google.com>2022-06-22 15:16:41 +0000
commit8353bea0d1a3b8d14c93b47bfb61cb2e30f50a97 (patch)
tree85ac39edcd4c413cf2a2cf9fe4bc9c3db474209c
parent10f11a1026a082e4c1f2f863568376a6fc2de1ec (diff)
downloadidea-8353bea0d1a3b8d14c93b47bfb61cb2e30f50a97.tar.gz
Only run Wear relevant analyses when the device is a watch
This also makes sure to select the Wear devices category when opening Layout Validation in this case. Bug: 232544714 Test: tests added Change-Id: I72d737174731a27979952c6d2b4d294396a724f0
-rw-r--r--android-test-framework/testSrc/com/android/tools/idea/rendering/RenderTestUtil.java2
-rw-r--r--designer/src/com/android/tools/idea/common/error/DesignerCommonIssueNode.kt20
-rw-r--r--designer/src/com/android/tools/idea/uibuilder/visual/visuallint/VisualLintService.kt47
-rw-r--r--designer/testSrc/com/android/tools/idea/common/error/VisualLintIssueNodeTest.kt67
4 files changed, 115 insertions, 21 deletions
diff --git a/android-test-framework/testSrc/com/android/tools/idea/rendering/RenderTestUtil.java b/android-test-framework/testSrc/com/android/tools/idea/rendering/RenderTestUtil.java
index 1291267c2d2..ca1ae74ea6b 100644
--- a/android-test-framework/testSrc/com/android/tools/idea/rendering/RenderTestUtil.java
+++ b/android-test-framework/testSrc/com/android/tools/idea/rendering/RenderTestUtil.java
@@ -102,7 +102,7 @@ public class RenderTestUtil {
}
@NotNull
- private static Device findDeviceById(ConfigurationManager manager, String id) {
+ public static Device findDeviceById(ConfigurationManager manager, String id) {
for (Device device : manager.getDevices()) {
if (device.getId().equals(id)) {
return device;
diff --git a/designer/src/com/android/tools/idea/common/error/DesignerCommonIssueNode.kt b/designer/src/com/android/tools/idea/common/error/DesignerCommonIssueNode.kt
index 5220c161d57..2c66683f39d 100644
--- a/designer/src/com/android/tools/idea/common/error/DesignerCommonIssueNode.kt
+++ b/designer/src/com/android/tools/idea/common/error/DesignerCommonIssueNode.kt
@@ -15,6 +15,7 @@
*/
package com.android.tools.idea.common.error
+import com.android.ide.common.rendering.HardwareConfigHelper
import com.android.tools.idea.common.surface.navigateToComponent
import com.android.tools.idea.uibuilder.visual.ConfigurationSet
import com.android.tools.idea.uibuilder.visual.VisualizationToolWindowFactory
@@ -292,15 +293,19 @@ class VisualLintIssueNode(private val visualLintIssue: VisualLintRenderIssue, pa
val targetComponent = visualLintIssue.components
.filterNot { it.isVisualLintErrorSuppressed(visualLintIssue.type) }
.firstOrNull()
- val selectWindowSizeNavigatable = SelectWindowSizeDevicesNavigatable(project)
+ val openLayoutValidationNavigatable = if (HardwareConfigHelper.isWear(visualLintIssue.models.firstOrNull()?.configuration?.device)) {
+ SelectWearDevicesNavigatable(project)
+ } else {
+ SelectWindowSizeDevicesNavigatable(project)
+ }
if (targetComponent == null) {
- return selectWindowSizeNavigatable
+ return openLayoutValidationNavigatable
}
return object : Navigatable {
override fun navigate(requestFocus: Boolean) {
navigateToComponent(targetComponent, true)
- selectWindowSizeNavigatable.navigate(requestFocus)
+ openLayoutValidationNavigatable.navigate(requestFocus)
}
override fun canNavigate(): Boolean = project != null
override fun canNavigateToSource(): Boolean = project != null
@@ -309,9 +314,14 @@ class VisualLintIssueNode(private val visualLintIssue: VisualLintRenderIssue, pa
}
@VisibleForTesting
-class SelectWindowSizeDevicesNavigatable(project: Project): Navigatable {
+class SelectWindowSizeDevicesNavigatable(project: Project): OpenLayoutValidationNavigatable(project, ConfigurationSet.WindowSizeDevices)
+
+@VisibleForTesting
+class SelectWearDevicesNavigatable(project: Project): OpenLayoutValidationNavigatable(project, ConfigurationSet.WearDevices)
- private val task = { VisualizationToolWindowFactory.openAndSetConfigurationSet(project, ConfigurationSet.WindowSizeDevices) }
+@VisibleForTesting
+open class OpenLayoutValidationNavigatable(project: Project, configurationSetToSelect: ConfigurationSet) : Navigatable {
+ private val task = { VisualizationToolWindowFactory.openAndSetConfigurationSet(project, configurationSetToSelect) }
override fun navigate(requestFocus: Boolean) {
task()
diff --git a/designer/src/com/android/tools/idea/uibuilder/visual/visuallint/VisualLintService.kt b/designer/src/com/android/tools/idea/uibuilder/visual/visuallint/VisualLintService.kt
index bb5cbff6b44..4a710daf24e 100644
--- a/designer/src/com/android/tools/idea/uibuilder/visual/visuallint/VisualLintService.kt
+++ b/designer/src/com/android/tools/idea/uibuilder/visual/visuallint/VisualLintService.kt
@@ -15,6 +15,7 @@
*/
package com.android.tools.idea.uibuilder.visual.visuallint
+import com.android.ide.common.rendering.HardwareConfigHelper
import com.android.tools.idea.common.error.IssueModel
import com.android.tools.idea.common.model.ModelListener
import com.android.tools.idea.common.model.NlModel
@@ -25,6 +26,7 @@ import com.android.tools.idea.rendering.RenderResult
import com.android.tools.idea.rendering.RenderService
import com.android.tools.idea.rendering.errors.ui.RenderErrorModel
import com.android.tools.idea.uibuilder.scene.NlModelHierarchyUpdater.updateHierarchy
+import com.android.tools.idea.uibuilder.visual.WearDeviceModelsProvider
import com.android.tools.idea.uibuilder.visual.WindowSizeModelsProvider
import com.android.tools.idea.uibuilder.visual.analytics.VisualLintUsageTracker
import com.android.tools.idea.uibuilder.visual.visuallint.analyzers.AtfAnalyzer
@@ -36,6 +38,7 @@ import com.android.tools.idea.uibuilder.visual.visuallint.analyzers.LocaleAnalyz
import com.android.tools.idea.uibuilder.visual.visuallint.analyzers.LongTextAnalyzer
import com.android.tools.idea.uibuilder.visual.visuallint.analyzers.OverlapAnalyzer
import com.android.tools.idea.uibuilder.visual.visuallint.analyzers.TextFieldSizeAnalyzer
+import com.android.tools.idea.uibuilder.visual.visuallint.analyzers.WearMarginAnalyzer
import com.google.common.annotations.VisibleForTesting
import com.intellij.codeInsight.daemon.HighlightDisplayKey
import com.intellij.codeInspection.InspectionProfile
@@ -74,8 +77,10 @@ class VisualLintService(project: Project) {
/** Default issue provider for Visual Lint Service. */
val issueProvider = VisualLintIssueProvider(project)
- private val basicAnalyzers = listOf(BoundsAnalyzer, BottomNavAnalyzer, BottomAppBarAnalyzer, TextFieldSizeAnalyzer,
- OverlapAnalyzer, LongTextAnalyzer, ButtonSizeAnalyzer)
+ private val basicAnalyzers = listOf(BoundsAnalyzer, OverlapAnalyzer)
+ private val adaptiveAnalyzers = listOf(BottomNavAnalyzer, BottomAppBarAnalyzer, TextFieldSizeAnalyzer,
+ LongTextAnalyzer, ButtonSizeAnalyzer)
+ private val wearAnalyzers = listOf(WearMarginAnalyzer)
private val ignoredTypes: MutableList<VisualLintErrorType>
@@ -136,8 +141,11 @@ class VisualLintService(project: Project) {
}
displayingModel.addListener(listener)
try {
- val modelsToAnalyze = WindowSizeModelsProvider.createNlModels(displayingModel, displayingModel.file,
- displayingModel.facet)
+ val modelsToAnalyze = if (HardwareConfigHelper.isWear(displayingModel.configuration.device)) {
+ WearDeviceModelsProvider.createNlModels(displayingModel, displayingModel.file, displayingModel.facet)
+ } else {
+ WindowSizeModelsProvider.createNlModels(displayingModel, displayingModel.file, displayingModel.facet)
+ }
val latch = CountDownLatch(modelsToAnalyze.size)
for (model in modelsToAnalyze) {
inflate(model).handleAsync({ result, _ ->
@@ -165,17 +173,30 @@ class VisualLintService(project: Project) {
baseConfigIssues: VisualLintBaseConfigIssues,
tracker: VisualLintUsageTracker,
runningInBackground: Boolean = false) {
- basicAnalyzers.filter { !ignoredTypes.contains(it.type) }.forEach {
- val issues = it.analyze(result, model, tracker, runningInBackground)
- issueProvider.addAllIssues(it.type, issues)
- }
- if (VisualLintErrorType.LOCALE_TEXT !in ignoredTypes) {
- LocaleAnalyzer(baseConfigIssues).let {
- issueProvider.addAllIssues(it.type, it.analyze(result, model, tracker, runningInBackground))
+ runAnalyzers(basicAnalyzers, result, model, tracker, runningInBackground)
+ if (HardwareConfigHelper.isWear(model.configuration.device)) {
+ runAnalyzers(wearAnalyzers, result, model, tracker, runningInBackground)
+ } else {
+ runAnalyzers(adaptiveAnalyzers, result, model, tracker, runningInBackground)
+ if (VisualLintErrorType.LOCALE_TEXT !in ignoredTypes) {
+ LocaleAnalyzer(baseConfigIssues).let {
+ issueProvider.addAllIssues(it.type, it.analyze(result, model, tracker, runningInBackground))
+ }
+ }
+ if (StudioFlags.NELE_ATF_IN_VISUAL_LINT.get() && VisualLintErrorType.ATF !in ignoredTypes) {
+ AtfAnalyzer.analyze(result, model, issueProvider, runningInBackground)
}
}
- if (StudioFlags.NELE_ATF_IN_VISUAL_LINT.get() && VisualLintErrorType.ATF !in ignoredTypes) {
- AtfAnalyzer.analyze(result, model, issueProvider, runningInBackground)
+ }
+
+ private fun runAnalyzers(analyzers: List<VisualLintAnalyzer>,
+ result: RenderResult,
+ model: NlModel,
+ tracker: VisualLintUsageTracker,
+ runningInBackground: Boolean) {
+ analyzers.filter { !ignoredTypes.contains(it.type) }.forEach {
+ val issues = it.analyze(result, model, tracker, runningInBackground)
+ issueProvider.addAllIssues(it.type, issues)
}
}
}
diff --git a/designer/testSrc/com/android/tools/idea/common/error/VisualLintIssueNodeTest.kt b/designer/testSrc/com/android/tools/idea/common/error/VisualLintIssueNodeTest.kt
index 519112c9d47..91451a733ba 100644
--- a/designer/testSrc/com/android/tools/idea/common/error/VisualLintIssueNodeTest.kt
+++ b/designer/testSrc/com/android/tools/idea/common/error/VisualLintIssueNodeTest.kt
@@ -18,6 +18,8 @@ package com.android.tools.idea.common.error
import com.android.SdkConstants
import com.android.tools.idea.common.fixtures.ComponentDescriptor
import com.android.tools.idea.common.model.NlComponent
+import com.android.tools.idea.configurations.ConfigurationManager
+import com.android.tools.idea.rendering.RenderTestUtil
import com.android.tools.idea.testing.AndroidProjectRule
import com.android.tools.idea.testing.onEdt
import com.android.tools.idea.uibuilder.NlModelBuilderUtil
@@ -36,12 +38,11 @@ import org.junit.Rule
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
-import kotlin.test.assertNull
class VisualLintIssueNodeTest {
@JvmField
@Rule
- val rule = AndroidProjectRule.inMemory().onEdt()
+ val rule = AndroidProjectRule.withSdk().onEdt()
@RunsInEdt
@Test
@@ -107,6 +108,68 @@ class VisualLintIssueNodeTest {
val node = VisualLintIssueNode(issue, CommonIssueTestParentNode(rule.projectRule.project))
assertInstanceOf<SelectWindowSizeDevicesNavigatable>(node.getNavigatable())
}
+
+ @RunsInEdt
+ @Test
+ fun testNavigatableForWear() {
+ val configurationManager = ConfigurationManager.getOrCreateInstance(rule.projectRule.module)
+ val model = NlModelBuilderUtil.model(
+ rule.projectRule,
+ "layout",
+ "layout.xml",
+ ComponentDescriptor(SdkConstants.FRAME_LAYOUT)
+ .withBounds(0, 0, 1000, 1000)
+ .matchParentWidth()
+ .matchParentHeight()
+ .children(ComponentDescriptor(SdkConstants.TEXT_VIEW)
+ .width("100dp")
+ .height("20dp")
+ )
+ ).setDevice(RenderTestUtil.findDeviceById(configurationManager, "wearos_rect")).build()
+
+ val issue = createTestVisualLintRenderIssue(VisualLintErrorType.WEAR_MARGIN, model.components.first().children)
+ val node = VisualLintIssueNode(issue, CommonIssueTestParentNode(rule.projectRule.project))
+ val navigation = node.getNavigatable()
+ assertNotNull(navigation)
+
+ // This navigation should open Validation Tool and set configuration set to ConfigurationSet.WearDevices
+ val toolManager = VisualizationTestToolWindowManager(rule.project, rule.fixture.testRootDisposable)
+ rule.projectRule.replaceProjectService(ToolWindowManager::class.java, toolManager)
+ val toolWindow = ToolWindowManager.getInstance(rule.project).getToolWindow(VisualizationToolWindowFactory.TOOL_WINDOW_ID)!!
+ TestVisualizationContentProvider.createVisualizationForm(rule.project, toolWindow)
+ toolWindow.isAvailable = true
+
+ val content = VisualizationToolWindowFactory.getVisualizationContent(rule.project)!!
+ content.setConfigurationSet(ConfigurationSet.LargeFont)
+
+ navigation.navigate(false)
+ assertEquals(ConfigurationSet.WearDevices, content.getConfigurationSet())
+ }
+
+ @RunsInEdt
+ @Test
+ fun testNotNavigateToComponentWhenSuppressedForWear() {
+ val configurationManager = ConfigurationManager.getOrCreateInstance(rule.projectRule.module)
+ val errorType = VisualLintErrorType.WEAR_MARGIN
+ val model = NlModelBuilderUtil.model(
+ rule.projectRule,
+ "layout",
+ "layout.xml",
+ ComponentDescriptor(SdkConstants.FRAME_LAYOUT)
+ .withBounds(0, 0, 1000, 1000)
+ .matchParentWidth()
+ .matchParentHeight()
+ .children(ComponentDescriptor(SdkConstants.TEXT_VIEW)
+ .width("100dp")
+ .height("20dp")
+ .withAttribute(SdkConstants.TOOLS_URI, SdkConstants.ATTR_IGNORE, errorType.ignoredAttributeValue)
+ )
+ ).setDevice(RenderTestUtil.findDeviceById(configurationManager, "wearos_rect")).build()
+
+ val issue = createTestVisualLintRenderIssue(errorType, model.components.first().children)
+ val node = VisualLintIssueNode(issue, CommonIssueTestParentNode(rule.projectRule.project))
+ assertInstanceOf<SelectWearDevicesNavigatable>(node.getNavigatable())
+ }
}
private fun createTestVisualLintRenderIssue(type: VisualLintErrorType, components: MutableList<NlComponent>) : VisualLintRenderIssue {