diff options
author | Alon Albert <aalbert@google.com> | 2022-08-02 09:18:15 -0700 |
---|---|---|
committer | Alon Albert <aalbert@google.com> | 2022-08-02 19:40:00 +0000 |
commit | b2b4c7dea041e47ce50c11d663adcb7e544cf685 (patch) | |
tree | 330803bca30ac41adc4f51ee824a948dc7839346 /logcat | |
parent | 056f882f1a253a0aa777fdac7e5684e3ea5c916e (diff) | |
download | idea-b2b4c7dea041e47ce50c11d663adcb7e544cf685.tar.gz |
Add a Banner When No Project Application IDs Are Detected
https://screenshot.googleplex.com/yfZkRCXjQKxPzYe.png
Bug: n/a
Test: Added
Change-Id: I3559ae80265ab3be111b7346e4ef1c4950f7b1a0
Diffstat (limited to 'logcat')
3 files changed, 99 insertions, 16 deletions
diff --git a/logcat/resources/messages/LogcatBundle.properties b/logcat/resources/messages/LogcatBundle.properties index 3d2dff61af6..2f1019410c6 100644 --- a/logcat/resources/messages/LogcatBundle.properties +++ b/logcat/resources/messages/LogcatBundle.properties @@ -1,4 +1,6 @@ logcat.main.panel.pause.banner.text=Logcat is paused +logcat.main.panel.no.application.ids.banner.text=Could not detect project package names. Is the project synced? +logcat.main.panel.no.application.ids.banner.sync.now=Sync now logcat.header.options.title=Logcat Format diff --git a/logcat/src/com/android/tools/idea/logcat/LogcatMainPanel.kt b/logcat/src/com/android/tools/idea/logcat/LogcatMainPanel.kt index d547f969e33..6ce0dd777df 100644 --- a/logcat/src/com/android/tools/idea/logcat/LogcatMainPanel.kt +++ b/logcat/src/com/android/tools/idea/logcat/LogcatMainPanel.kt @@ -49,6 +49,7 @@ import com.android.tools.idea.logcat.actions.ToggleFilterAction import com.android.tools.idea.logcat.devices.Device import com.android.tools.idea.logcat.filters.AndroidLogcatFilterHistory import com.android.tools.idea.logcat.filters.LogcatFilter +import com.android.tools.idea.logcat.filters.LogcatFilter.Companion.MY_PACKAGE import com.android.tools.idea.logcat.filters.LogcatFilterParser import com.android.tools.idea.logcat.filters.LogcatMasterFilter import com.android.tools.idea.logcat.folding.EditorFoldingDetector @@ -80,6 +81,8 @@ import com.android.tools.idea.logcat.util.createLogcatEditor import com.android.tools.idea.logcat.util.isCaretAtBottom import com.android.tools.idea.logcat.util.isScrollAtBottom import com.android.tools.idea.logcat.util.toggleFilterTerm +import com.android.tools.idea.projectsystem.ProjectSystemService +import com.android.tools.idea.projectsystem.ProjectSystemSyncManager.SyncReason.Companion.USER_REQUEST import com.android.tools.idea.run.ClearLogcatListener import com.android.tools.idea.ui.screenrecording.ScreenRecorderAction import com.android.tools.idea.ui.screenshot.DeviceArtScreenshotOptions @@ -134,8 +137,10 @@ import java.awt.event.MouseWheelEvent import java.time.ZoneId import java.util.concurrent.atomic.AtomicReference import javax.swing.BorderFactory +import javax.swing.GroupLayout import javax.swing.Icon import javax.swing.JComponent +import javax.swing.JPanel import kotlin.math.max // This is probably a massive overkill as we do not expect this many tags/packages in a real Logcat @@ -157,6 +162,8 @@ class LogcatMainPanelFactory { } } +private val BANNER_BORDER = BorderFactory.createCompoundBorder(Borders.customLine(JBColor.border(), 1, 1, 0, 1), Borders.empty(0, 5, 0, 0)) + /** * The top level Logcat panel. * @@ -174,7 +181,7 @@ internal class LogcatMainPanel( logcatColors: LogcatColors, state: LogcatPanelConfig?, private var logcatSettings: AndroidLogcatSettings = AndroidLogcatSettings.getInstance(), - androidProjectDetector: AndroidProjectDetector = AndroidProjectDetectorImpl(), + private var androidProjectDetector: AndroidProjectDetector = AndroidProjectDetectorImpl(), hyperlinkDetector: HyperlinkDetector? = null, foldingDetector: FoldingDetector? = null, adbSession: AdbSession = AdbLibService.getInstance(project).session, @@ -189,6 +196,7 @@ internal class LogcatMainPanel( @VisibleForTesting internal val editor: EditorEx = createLogcatEditor(project) private val pausedBanner = EditorNotificationPanel() + private val noApplicationIdsBanner = EditorNotificationPanel() private val document = editor.document private val documentAppender = DocumentAppender(project, document, logcatSettings.bufferSize) private val coroutineScope = AndroidCoroutineScope(this) @@ -266,12 +274,34 @@ internal class LogcatMainPanel( addToTop(headerPanel) addToLeft(toolbar.component) - val centerPanel = BorderLayoutPanel() - pausedBanner.text = LogcatBundle.message("logcat.main.panel.pause.banner.text") - pausedBanner.border = BorderFactory.createCompoundBorder(Borders.customLine(JBColor.border(), 1, 1, 0, 1), Borders.empty(0, 5, 0, 0)) - centerPanel.addToTop(pausedBanner) - centerPanel.addToCenter(editor.component) - pausedBanner.isVisible = false + pausedBanner.apply { + text = LogcatBundle.message("logcat.main.panel.pause.banner.text") + border = BANNER_BORDER + isVisible = false + } + noApplicationIdsBanner.apply { + text = LogcatBundle.message("logcat.main.panel.no.application.ids.banner.text") + createActionLabel(LogcatBundle.message("logcat.main.panel.no.application.ids.banner.sync.now")) { + ProjectSystemService.getInstance(project).projectSystem.getSyncManager().syncProject(USER_REQUEST) + } + border = BANNER_BORDER + isVisible = isMissingApplicationIds() + } + val centerPanel = JPanel(null).apply { + layout = GroupLayout(this).apply { + val height = pausedBanner.preferredSize.height + setVerticalGroup( + createSequentialGroup() + .addComponent(noApplicationIdsBanner, height, height, height) + .addComponent(pausedBanner, height, height, height) + .addComponent(editor.component)) + setHorizontalGroup( + createParallelGroup(GroupLayout.Alignment.CENTER) + .addComponent(noApplicationIdsBanner) + .addComponent(pausedBanner) + .addComponent(editor.component)) + } + } addToCenter(centerPanel) initScrollToEndStateHandling() @@ -292,7 +322,8 @@ internal class LogcatMainPanel( } }) messageBus.connect(this).subscribe(PROJECT_APPLICATION_IDS_CHANGED_TOPIC, ProjectApplicationIdsListener { - if (getFilter().contains(LogcatFilter.MY_PACKAGE)) { + if (getFilter().contains(MY_PACKAGE)) { + noApplicationIdsBanner.isVisible = isMissingApplicationIds() reloadMessages() } }) @@ -433,9 +464,18 @@ internal class LogcatMainPanel( @UiThread override fun applyFilter(logcatFilter: LogcatFilter?) { messageProcessor.logcatFilter = logcatFilter + noApplicationIdsBanner.isVisible = isMissingApplicationIds() reloadMessages() } + private fun isMissingApplicationIds(): Boolean { + return when { + !androidProjectDetector.isAndroidProject(project) -> false + getFilter().contains(MY_PACKAGE) && packageNamesProvider.getPackageNames().isEmpty() -> true + else -> false + } + } + @UiThread override fun reloadMessages() { document.setText("") @@ -649,7 +689,8 @@ internal class LogcatMainPanel( private fun isCaretAtBottom(): Boolean { return try { editor.isCaretAtBottom() - } catch (t: Throwable) { + } + catch (t: Throwable) { // Logging as error in order to see how prevalent this is in the wild. See b/239095674 LOGGER.error("Failed to check caret position directly. Using backup method.", t) caretLine >= document.lineCount - 1 diff --git a/logcat/testSrc/com/android/tools/idea/logcat/LogcatMainPanelTest.kt b/logcat/testSrc/com/android/tools/idea/logcat/LogcatMainPanelTest.kt index 7044b37f79f..4fd35476e88 100644 --- a/logcat/testSrc/com/android/tools/idea/logcat/LogcatMainPanelTest.kt +++ b/logcat/testSrc/com/android/tools/idea/logcat/LogcatMainPanelTest.kt @@ -162,9 +162,9 @@ class LogcatMainPanelTest { assertThat(logcatMainPanel.componentCount).isEqualTo(3) assertThat(borderLayout.getLayoutComponent(NORTH)).isInstanceOf(LogcatHeaderPanel::class.java) val centerComponent: JPanel = borderLayout.getLayoutComponent(CENTER) as JPanel - assertThat(centerComponent.components[0]).isInstanceOf(EditorNotificationPanel::class.java) - assertThat(centerComponent.components[0].isVisible).isFalse() - assertThat(centerComponent.components[1]).isSameAs(logcatMainPanel.editor.component) + assertThat(logcatMainPanel.findBanner("Logcat is paused").isVisible).isFalse() + assertThat(logcatMainPanel.findBanner("Could not detect project package names. Is the project synced?").isVisible).isFalse() + assertThat(centerComponent.components.find { it === logcatMainPanel.editor.component }).isNotNull() assertThat(borderLayout.getLayoutComponent(WEST)).isInstanceOf(ActionToolbar::class.java) val toolbar = borderLayout.getLayoutComponent(WEST) as ActionToolbar assertThat(toolbar.actions.mapToStrings()).containsExactly( @@ -986,10 +986,46 @@ class LogcatMainPanelTest { logcatMainPanel.pauseLogcat() - val banner = TreeWalker(logcatMainPanel).descendants().first { it is EditorNotificationPanel } as EditorNotificationPanel + assertThat(logcatMainPanel.findBanner("Logcat is paused").isVisible).isTrue() + } + + @Test + fun missingApplicationIds_showsBanner(): Unit = runBlocking { + val fakePackageNamesProvider = FakeProjectApplicationIdsProvider(project) + val logcatMainPanel = runInEdtAndGet { + logcatMainPanel(projectApplicationIdsProvider = fakePackageNamesProvider, filter = "package:mine") + } + + assertThat(logcatMainPanel.findBanner("Could not detect project package names. Is the project synced?").isVisible).isTrue() + } + + @Test + fun hasApplicationIds_doesNotShowBanner(): Unit = runBlocking { + val fakePackageNamesProvider = FakeProjectApplicationIdsProvider(project, "app1") + val logcatMainPanel = runInEdtAndGet { + logcatMainPanel(projectApplicationIdsProvider = fakePackageNamesProvider, filter = "package:mine") + } + + assertThat(logcatMainPanel.findBanner("Could not detect project package names. Is the project synced?").isVisible).isFalse() + } + + @Test + fun applicationIdsChange_bannerUpdates(): Unit = runBlocking { + val fakePackageNamesProvider = FakeProjectApplicationIdsProvider(project) + val logcatMainPanel = runInEdtAndGet { + logcatMainPanel(projectApplicationIdsProvider = fakePackageNamesProvider, filter = "package:mine") + } + val banner = logcatMainPanel.findBanner("Could not detect project package names. Is the project synced?") assertThat(banner.isVisible).isTrue() - assertThat(banner.text).isEqualTo("Logcat is paused") + + runInEdtAndWait { fakePackageNamesProvider.setApplicationIds("app1") } + assertThat(banner.isVisible).isFalse() + + runInEdtAndWait { + fakePackageNamesProvider.setApplicationIds() + } + assertThat(banner.isVisible).isTrue() } @Test @@ -1064,7 +1100,8 @@ class LogcatMainPanelTest { private fun logcatMainPanel( splitterPopupActionGroup: ActionGroup = EMPTY_GROUP, logcatColors: LogcatColors = LogcatColors(), - state: LogcatPanelConfig? = LogcatPanelConfig(device = null, FormattingConfig.Preset(STANDARD), filter = "", isSoftWrap = false), + filter: String = "", + state: LogcatPanelConfig? = LogcatPanelConfig(device = null, FormattingConfig.Preset(STANDARD), filter = filter, isSoftWrap = false), logcatSettings: AndroidLogcatSettings = AndroidLogcatSettings(), androidProjectDetector: AndroidProjectDetector = FakeAndroidProjectDetector(true), hyperlinkDetector: HyperlinkDetector? = null, @@ -1121,4 +1158,7 @@ private fun List<AnAction>.mapToStrings(indent: String = ""): List<String> { }.map { "$indent$it" } } -private fun waitForCondition(condition: () -> Boolean) = waitForCondition(TIMEOUT_SEC, SECONDS, condition)
\ No newline at end of file +private fun waitForCondition(condition: () -> Boolean) = waitForCondition(TIMEOUT_SEC, SECONDS, condition) + +private fun LogcatMainPanel.findBanner(text: String) = + TreeWalker(this).descendants().first { it is EditorNotificationPanel && it.text == text } as EditorNotificationPanel |