diff --git a/android-common/src/com/android/tools/idea/AndroidEnvironmentUtils.kt b/android-common/src/com/android/tools/idea/AndroidEnvironmentUtils.kt index 1a27736f85ac..92f0aa45e06e 100644 --- a/android-common/src/com/android/tools/idea/AndroidEnvironmentUtils.kt +++ b/android-common/src/com/android/tools/idea/AndroidEnvironmentUtils.kt @@ -23,7 +23,8 @@ import org.jetbrains.android.facet.AndroidFacet /** * Returns true if called in Android Studio or if the project has an Android or an Apk facet. */ -fun isAndroidEnvironment(project: Project): Boolean = true +fun isAndroidEnvironment(project: Project): Boolean = + IdeInfo.getInstance().isAndroidStudio || project.hasAndroidOrApkFacet() /** * Checks if the project contains a module with an Android or an Apk facet. @@ -31,3 +32,9 @@ fun isAndroidEnvironment(project: Project): Boolean = true fun Project.hasAndroidOrApkFacet(): Boolean = ProjectFacetManager.getInstance(this).hasFacets(AndroidFacet.ID) || ApkFacetChecker.getInstance(this).hasApkFacet() +/** + * Checks if the project contains a module with an Android facet. + */ +fun Project.hasAndroidFacet(): Boolean = + ProjectFacetManager.getInstance(this).hasFacets(AndroidFacet.ID) + diff --git a/android-common/src/com/android/tools/idea/sdk/AndroidEnvironmentChecker.kt b/android-common/src/com/android/tools/idea/sdk/AndroidEnvironmentChecker.kt new file mode 100644 index 000000000000..8e8e550eba2c --- /dev/null +++ b/android-common/src/com/android/tools/idea/sdk/AndroidEnvironmentChecker.kt @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.tools.idea.sdk + +import com.android.tools.idea.isAndroidEnvironment +import com.intellij.openapi.diagnostic.debug +import com.intellij.openapi.diagnostic.thisLogger +import com.intellij.openapi.project.Project +import com.intellij.openapi.wm.ext.LibrarySearchHelper + +/** + * A [LibrarySearchHelper] that returns true if in an Android environment + * + * An Android environment is either Android Studio or IntelliJ with an Android facet. + * + * Android Tool Windows should use this instead of `ToolWindowFactory.isApplicable()` to enable + * themselves. This is because an IntelliJ project may start up as a non Android project but then + * turn into one if an Android Module is added. + * + * Unlike `ToolWindowFactory.isApplicable()`, `LibrarySearchHelper.isLibraryExists()` is reevaluated + * when the project changes. + */ +class AndroidEnvironmentChecker : LibrarySearchHelper { + override fun isLibraryExists(project: Project): Boolean { + val value = isAndroidEnvironment(project) + thisLogger().debug { "isLibraryExists -> $value" } + return value + } +} diff --git a/android-common/src/com/android/tools/idea/sdk/AndroidSdkLibrarySearcher.kt b/android-common/src/com/android/tools/idea/sdk/AndroidFacetChecker.kt similarity index 68% rename from android-common/src/com/android/tools/idea/sdk/AndroidSdkLibrarySearcher.kt rename to android-common/src/com/android/tools/idea/sdk/AndroidFacetChecker.kt index fcad3a87620f..70584170a3df 100644 --- a/android-common/src/com/android/tools/idea/sdk/AndroidSdkLibrarySearcher.kt +++ b/android-common/src/com/android/tools/idea/sdk/AndroidFacetChecker.kt @@ -15,11 +15,19 @@ */ package com.android.tools.idea.sdk +import com.android.tools.idea.hasAndroidFacet +import com.intellij.openapi.diagnostic.debug +import com.intellij.openapi.diagnostic.thisLogger import com.intellij.openapi.project.Project import com.intellij.openapi.wm.ext.LibrarySearchHelper -class AndroidSdkLibrarySearcher: LibrarySearchHelper { +/** + * A [LibrarySearchHelper] that checks for an Android Facet + */ +class AndroidFacetChecker : LibrarySearchHelper { override fun isLibraryExists(project: Project): Boolean { - return AndroidSdkPathStore.getInstance().androidSdkPath != null + val value = project.hasAndroidFacet() + thisLogger().debug { "isLibraryExists -> $value" } + return value } -} \ No newline at end of file +} diff --git a/android-common/src/com/android/tools/idea/sdk/AndroidOrApkFacetChecker.kt b/android-common/src/com/android/tools/idea/sdk/AndroidOrApkFacetChecker.kt new file mode 100644 index 000000000000..3234c8793f20 --- /dev/null +++ b/android-common/src/com/android/tools/idea/sdk/AndroidOrApkFacetChecker.kt @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.tools.idea.sdk + +import com.android.tools.idea.hasAndroidOrApkFacet +import com.intellij.openapi.diagnostic.debug +import com.intellij.openapi.diagnostic.thisLogger +import com.intellij.openapi.project.Project +import com.intellij.openapi.wm.ext.LibrarySearchHelper + +/** + * A [LibrarySearchHelper] that checks for an Android or APK Facet + */ +class AndroidOrApkFacetChecker : LibrarySearchHelper { + override fun isLibraryExists(project: Project): Boolean { + val value = project.hasAndroidOrApkFacet() + thisLogger().debug { "isLibraryExists -> $value" } + return value + } +} diff --git a/android-common/test/com/android/tools/idea/sdk/AndroidEnvironmentCheckerTest.kt b/android-common/test/com/android/tools/idea/sdk/AndroidEnvironmentCheckerTest.kt new file mode 100644 index 000000000000..5fcd526900e4 --- /dev/null +++ b/android-common/test/com/android/tools/idea/sdk/AndroidEnvironmentCheckerTest.kt @@ -0,0 +1,59 @@ +package com.android.tools.idea.sdk + +import com.android.testutils.MockitoKt.mock +import com.android.testutils.MockitoKt.whenever +import com.android.tools.idea.ApkFacetChecker +import com.android.tools.idea.IdeInfo +import com.google.common.truth.Truth.assertThat +import com.intellij.openapi.application.ApplicationManager +import com.intellij.testFramework.DisposableRule +import com.intellij.testFramework.ProjectRule +import com.intellij.testFramework.RuleChain +import com.intellij.testFramework.registerOrReplaceServiceInstance +import com.intellij.testFramework.replaceService +import org.junit.Rule +import org.junit.Test +import org.mockito.Mockito + +/** + * Tests for [AndroidEnvironmentChecker] + */ +class AndroidEnvironmentCheckerTest { + private val projectRule = ProjectRule() + private val project get() = projectRule.project + private val disposableRule = DisposableRule() + private val disposable get() = disposableRule.disposable + + @get:Rule + val rule = RuleChain(projectRule, disposableRule) + + private val mockIdeInfo by lazy { Mockito.spy(IdeInfo.getInstance()) } + private val mockApkFacetChecker = mock() + + @Test + fun isLibraryExists() { + assertThat(AndroidEnvironmentChecker().isLibraryExists(project)).isTrue() + } + + @Test + fun isLibraryExists_notAndroidStudio_withoutAndroidFacet() { + whenever(mockIdeInfo.isAndroidStudio).thenReturn(false) + whenever(mockApkFacetChecker.hasApkFacet()).thenReturn(false) + + ApplicationManager.getApplication().replaceService(IdeInfo::class.java, mockIdeInfo, disposable) + project.registerOrReplaceServiceInstance(ApkFacetChecker::class.java, mockApkFacetChecker, disposable) + + assertThat(AndroidEnvironmentChecker().isLibraryExists(project)).isFalse() + } + + @Test + fun isLibraryExists_notAndroidStudio_withAndroidFacet() { + whenever(mockIdeInfo.isAndroidStudio).thenReturn(false) + whenever(mockApkFacetChecker.hasApkFacet()).thenReturn(true) + + ApplicationManager.getApplication().replaceService(IdeInfo::class.java, mockIdeInfo, disposable) + project.registerOrReplaceServiceInstance(ApkFacetChecker::class.java, mockApkFacetChecker, disposable) + + assertThat(AndroidEnvironmentChecker().isLibraryExists(project)).isTrue() + } +} \ No newline at end of file diff --git a/android-common/test/com/android/tools/idea/sdk/AndroidFacetCheckerTest.kt b/android-common/test/com/android/tools/idea/sdk/AndroidFacetCheckerTest.kt new file mode 100644 index 000000000000..78bef4710da6 --- /dev/null +++ b/android-common/test/com/android/tools/idea/sdk/AndroidFacetCheckerTest.kt @@ -0,0 +1,47 @@ +package com.android.tools.idea.sdk + +import com.android.testutils.MockitoKt.whenever +import com.google.common.truth.Truth.assertThat +import com.intellij.facet.ProjectFacetManager +import com.intellij.testFramework.DisposableRule +import com.intellij.testFramework.ProjectRule +import com.intellij.testFramework.RuleChain +import com.intellij.testFramework.registerOrReplaceServiceInstance +import org.jetbrains.android.facet.AndroidFacet +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mockito.Mockito + +/** + * Tests for [AndroidFacetChecker] + */ +class AndroidFacetCheckerTest { + private val projectRule = ProjectRule() + private val project get() = projectRule.project + private val disposableRule = DisposableRule() + + private val mockProjectFacetManager by lazy { Mockito.spy(ProjectFacetManager.getInstance(project)) } + + @get:Rule + val rule = RuleChain(projectRule, disposableRule) + + @Before + fun setUp() { + project.registerOrReplaceServiceInstance(ProjectFacetManager::class.java, mockProjectFacetManager, disposableRule.disposable) + } + + @Test + fun isLibraryExists() { + whenever(mockProjectFacetManager.hasFacets(AndroidFacet.ID)).thenReturn(true) + + assertThat(AndroidFacetChecker().isLibraryExists(project)).isTrue() + } + + @Test + fun isLibraryExists_withoutAndroidFacet() { + whenever(mockProjectFacetManager.hasFacets(AndroidFacet.ID)).thenReturn(false) + + assertThat(AndroidFacetChecker().isLibraryExists(project)).isFalse() + } +} \ No newline at end of file diff --git a/android-common/test/com/android/tools/idea/sdk/AndroidOrApkFacetCheckerTest.kt b/android-common/test/com/android/tools/idea/sdk/AndroidOrApkFacetCheckerTest.kt new file mode 100644 index 000000000000..2352a81342db --- /dev/null +++ b/android-common/test/com/android/tools/idea/sdk/AndroidOrApkFacetCheckerTest.kt @@ -0,0 +1,61 @@ +package com.android.tools.idea.sdk + +import com.android.testutils.MockitoKt +import com.android.testutils.MockitoKt.whenever +import com.android.tools.idea.ApkFacetChecker +import com.google.common.truth.Truth.assertThat +import com.intellij.facet.ProjectFacetManager +import com.intellij.testFramework.DisposableRule +import com.intellij.testFramework.ProjectRule +import com.intellij.testFramework.RuleChain +import com.intellij.testFramework.registerOrReplaceServiceInstance +import org.jetbrains.android.facet.AndroidFacet +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mockito.Mockito + +/** + * Tests for [AndroidOrApkFacetChecker] + */ +class AndroidOrApkFacetCheckerTest { + private val projectRule = ProjectRule() + private val project get() = projectRule.project + private val disposableRule = DisposableRule() + + private val mockProjectFacetManager by lazy { Mockito.spy(ProjectFacetManager.getInstance(project)) } + private val mockApkFacetChecker = MockitoKt.mock() + + @get:Rule + val rule = RuleChain(projectRule, disposableRule) + + @Before + fun setUp() { + project.registerOrReplaceServiceInstance(ProjectFacetManager::class.java, mockProjectFacetManager, disposableRule.disposable) + project.registerOrReplaceServiceInstance(ApkFacetChecker::class.java, mockApkFacetChecker, disposableRule.disposable) + } + + @Test + fun isLibraryExists_hasAndroidFacet() { + whenever(mockProjectFacetManager.hasFacets(AndroidFacet.ID)).thenReturn(true) + whenever(mockApkFacetChecker.hasApkFacet()).thenReturn(false) + + assertThat(AndroidOrApkFacetChecker().isLibraryExists(project)).isTrue() + } + + @Test + fun isLibraryExists_hasApkFacet() { + whenever(mockProjectFacetManager.hasFacets(AndroidFacet.ID)).thenReturn(false) + whenever(mockApkFacetChecker.hasApkFacet()).thenReturn(true) + + assertThat(AndroidOrApkFacetChecker().isLibraryExists(project)).isTrue() + } + + @Test + fun isLibraryExists_withoutFacets() { + whenever(mockProjectFacetManager.hasFacets(AndroidFacet.ID)).thenReturn(false) + whenever(mockApkFacetChecker.hasApkFacet()).thenReturn(false) + + assertThat(AndroidOrApkFacetChecker().isLibraryExists(project)).isFalse() + } +} \ No newline at end of file diff --git a/android/src/com/android/tools/idea/ui/resourcemanager/META-INF/resources-explorer.xml b/android/src/com/android/tools/idea/ui/resourcemanager/META-INF/resources-explorer.xml index 136dde252738..adfebf0d8539 100644 --- a/android/src/com/android/tools/idea/ui/resourcemanager/META-INF/resources-explorer.xml +++ b/android/src/com/android/tools/idea/ui/resourcemanager/META-INF/resources-explorer.xml @@ -42,10 +42,11 @@ - + + librarySearchClass="com.android.tools.idea.sdk.AndroidFacetChecker" + factoryClass="com.android.tools.idea.ui.resourcemanager.ResourceExplorerToolFactory"/> diff --git a/android/testSrc/com/android/tools/idea/ui/resourcemanager/ResourceExplorerToolFactoryTest.kt b/android/testSrc/com/android/tools/idea/ui/resourcemanager/ResourceExplorerToolFactoryTest.kt new file mode 100644 index 000000000000..41272409ba7a --- /dev/null +++ b/android/testSrc/com/android/tools/idea/ui/resourcemanager/ResourceExplorerToolFactoryTest.kt @@ -0,0 +1,28 @@ +package com.android.tools.idea.ui.resourcemanager + +import com.android.tools.idea.sdk.AndroidEnvironmentChecker +import com.android.tools.idea.sdk.AndroidFacetChecker +import com.google.common.truth.Truth.assertThat +import com.intellij.openapi.wm.ext.LibraryDependentToolWindow +import com.intellij.testFramework.ProjectRule +import org.junit.Rule +import org.junit.Test +import kotlin.test.fail + +/** + * Tests for [ResourceExplorerToolFactory] + */ +class ResourceExplorerToolFactoryTest { + @get:Rule + val projectRule = ProjectRule() + + @Test + fun isLibraryToolWindow() { + val toolWindow = + LibraryDependentToolWindow.EXTENSION_POINT_NAME.extensions.find { it.id == "Resources Explorer" } + ?: fail("Tool window not found") + + assertThat(toolWindow.librarySearchClass) + .isEqualTo(AndroidFacetChecker::class.qualifiedName) + } +} \ No newline at end of file diff --git a/app-inspection/ide/src/META-INF/app-inspection.xml b/app-inspection/ide/src/META-INF/app-inspection.xml index bdfdfc3378e9..e2c9252dd09c 100644 --- a/app-inspection/ide/src/META-INF/app-inspection.xml +++ b/app-inspection/ide/src/META-INF/app-inspection.xml @@ -19,8 +19,9 @@ + org.intellij.intelliLang + - diff --git a/device-explorer/intellij.android.device-explorer.tests.iml b/device-explorer/intellij.android.device-explorer.tests.iml index 995b8853ced4..40aa5049c641 100644 --- a/device-explorer/intellij.android.device-explorer.tests.iml +++ b/device-explorer/intellij.android.device-explorer.tests.iml @@ -25,5 +25,6 @@ + \ No newline at end of file diff --git a/device-explorer/src/META-INF/intellij.android.device-explorer.xml b/device-explorer/src/META-INF/intellij.android.device-explorer.xml index 52d0ae6312e6..bb0d857f7598 100644 --- a/device-explorer/src/META-INF/intellij.android.device-explorer.xml +++ b/device-explorer/src/META-INF/intellij.android.device-explorer.xml @@ -32,11 +32,12 @@ - + + \ No newline at end of file diff --git a/device-explorer/src/com/android/tools/idea/device/explorer/DeviceExplorerToolWindowFactory.kt b/device-explorer/src/com/android/tools/idea/device/explorer/DeviceExplorerToolWindowFactory.kt index 18754a28baf1..7e8031fbcef4 100644 --- a/device-explorer/src/com/android/tools/idea/device/explorer/DeviceExplorerToolWindowFactory.kt +++ b/device-explorer/src/com/android/tools/idea/device/explorer/DeviceExplorerToolWindowFactory.kt @@ -38,7 +38,7 @@ import java.nio.file.Path class DeviceExplorerToolWindowFactory : DumbAware, ToolWindowFactory { override fun isApplicable(project: Project) = - StudioFlags.MERGED_DEVICE_FILE_EXPLORER_AND_DEVICE_MONITOR_TOOL_WINDOW_ENABLED.get() && isAndroidEnvironment(project) + StudioFlags.MERGED_DEVICE_FILE_EXPLORER_AND_DEVICE_MONITOR_TOOL_WINDOW_ENABLED.get() override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) { toolWindow.setIcon(StudioIcons.Shell.ToolWindows.DEVICE_EXPLORER) diff --git a/device-explorer/testSrc/com/android/tools/idea/device/explorer/DeviceExplorerToolWindowFactoryTest.kt b/device-explorer/testSrc/com/android/tools/idea/device/explorer/DeviceExplorerToolWindowFactoryTest.kt new file mode 100644 index 000000000000..02663c3d4bdd --- /dev/null +++ b/device-explorer/testSrc/com/android/tools/idea/device/explorer/DeviceExplorerToolWindowFactoryTest.kt @@ -0,0 +1,24 @@ +package com.android.tools.idea.device.explorer + +import com.android.tools.idea.sdk.AndroidEnvironmentChecker +import com.google.common.truth.Truth.assertThat +import com.intellij.openapi.wm.ext.LibraryDependentToolWindow +import com.intellij.testFramework.ProjectRule +import org.junit.Rule +import org.junit.Test + +/** + * Tests for [DeviceExplorerToolWindowFactory] + */ +class DeviceExplorerToolWindowFactoryTest { + @get:Rule + val projectRule = ProjectRule() + + @Test + fun isLibraryToolWindow() { + val toolWindow = LibraryDependentToolWindow.EXTENSION_POINT_NAME.extensions.find { it.id == "Device Explorer" } + ?: throw AssertionError("Tool window not found") + + assertThat(toolWindow.librarySearchClass).isEqualTo(AndroidEnvironmentChecker::class.qualifiedName) + } +} diff --git a/device-file-explorer-toolwindow/src/META-INF/android.device-file-explorer-toolwindow.xml b/device-file-explorer-toolwindow/src/META-INF/android.device-file-explorer-toolwindow.xml index 18355c2d378b..decb11ca8caf 100644 --- a/device-file-explorer-toolwindow/src/META-INF/android.device-file-explorer-toolwindow.xml +++ b/device-file-explorer-toolwindow/src/META-INF/android.device-file-explorer-toolwindow.xml @@ -38,10 +38,12 @@ serviceImplementation="com.android.tools.idea.file.explorer.toolwindow.DeviceExplorerFileManagerImpl" /> - + + \ No newline at end of file diff --git a/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/DeviceExplorerToolWindowFactory.java b/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/DeviceExplorerToolWindowFactory.java index 4f5850515d3c..b8c13bdc2b99 100644 --- a/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/DeviceExplorerToolWindowFactory.java +++ b/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/DeviceExplorerToolWindowFactory.java @@ -41,7 +41,6 @@ public class DeviceExplorerToolWindowFactory implements DumbAware, ToolWindowFac @Override public boolean isApplicable(@NotNull Project project) { return SystemProperties.getBooleanProperty(DEVICE_EXPLORER_ENABLED, true) && - isAndroidEnvironment(project) && !StudioFlags.MERGED_DEVICE_FILE_EXPLORER_AND_DEVICE_MONITOR_TOOL_WINDOW_ENABLED.get(); } diff --git a/device-file-explorer-toolwindow/testSrc/com/android/tools/idea/file/explorer/toolwindow/DeviceExplorerToolWindowFactoryTest.kt b/device-file-explorer-toolwindow/testSrc/com/android/tools/idea/file/explorer/toolwindow/DeviceExplorerToolWindowFactoryTest.kt new file mode 100644 index 000000000000..dfb59cee7e8e --- /dev/null +++ b/device-file-explorer-toolwindow/testSrc/com/android/tools/idea/file/explorer/toolwindow/DeviceExplorerToolWindowFactoryTest.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.tools.idea.file.explorer.toolwindow + +import com.android.tools.idea.sdk.AndroidEnvironmentChecker +import com.google.common.truth.Truth.assertThat +import com.intellij.openapi.wm.ext.LibraryDependentToolWindow +import com.intellij.testFramework.ProjectRule +import org.junit.Rule +import org.junit.Test + +/** + * Tests for [DeviceExplorerToolWindowFactory] + */ +class DeviceExplorerToolWindowFactoryTest { + @get:Rule + val projectRule = ProjectRule() + + @Test + fun isLibraryToolWindow() { + val toolWindow = LibraryDependentToolWindow.EXTENSION_POINT_NAME.extensions.find { it.id == "Device File Explorer" } + ?: throw AssertionError("Tool window not found") + + assertThat(toolWindow.librarySearchClass).isEqualTo(AndroidEnvironmentChecker::class.qualifiedName) + } +} diff --git a/device-manager-v2/src/META-INF/device-manager-v2.xml b/device-manager-v2/src/META-INF/device-manager-v2.xml index ae63f8363a6f..847564dc714f 100644 --- a/device-manager-v2/src/META-INF/device-manager-v2.xml +++ b/device-manager-v2/src/META-INF/device-manager-v2.xml @@ -15,8 +15,9 @@ --> + diff --git a/device-manager-v2/src/com/android/tools/idea/devicemanagerv2/DeviceManager2ToolWindowFactory.kt b/device-manager-v2/src/com/android/tools/idea/devicemanagerv2/DeviceManager2ToolWindowFactory.kt index faf9d939504b..9f5f1ddc462b 100644 --- a/device-manager-v2/src/com/android/tools/idea/devicemanagerv2/DeviceManager2ToolWindowFactory.kt +++ b/device-manager-v2/src/com/android/tools/idea/devicemanagerv2/DeviceManager2ToolWindowFactory.kt @@ -26,7 +26,7 @@ import com.intellij.ui.content.ContentFactory internal class DeviceManager2ToolWindowFactory : ToolWindowFactory, DumbAware { override fun isApplicable(project: Project): Boolean = - isAndroidEnvironment(project) && StudioFlags.UNIFIED_DEVICE_MANAGER_ENABLED.get() + StudioFlags.UNIFIED_DEVICE_MANAGER_ENABLED.get() override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) { val content = diff --git a/device-manager-v2/testSrc/com/android/tools/idea/devicemanagerv2/DeviceManager2ToolWindowFactoryTest.kt b/device-manager-v2/testSrc/com/android/tools/idea/devicemanagerv2/DeviceManager2ToolWindowFactoryTest.kt new file mode 100644 index 000000000000..5c4f7ff4fffc --- /dev/null +++ b/device-manager-v2/testSrc/com/android/tools/idea/devicemanagerv2/DeviceManager2ToolWindowFactoryTest.kt @@ -0,0 +1,26 @@ +package com.android.tools.idea.devicemanagerv2 + +import com.android.tools.idea.sdk.AndroidEnvironmentChecker +import com.intellij.openapi.wm.ext.LibraryDependentToolWindow +import com.intellij.testFramework.ProjectRule +import org.junit.Assert +import org.junit.Rule +import org.junit.Test + +/** Tests for [DeviceManager2ToolWindowFactory] */ +class DeviceManager2ToolWindowFactoryTest { + @get:Rule + val projectRule = ProjectRule() + + @Test + fun isLibraryToolWindow() { + val toolWindow = + LibraryDependentToolWindow.EXTENSION_POINT_NAME.extensions.find { it.id == "Device Manager 2" } + ?: throw AssertionError("Tool window not found") + + Assert.assertEquals( + toolWindow.librarySearchClass, + AndroidEnvironmentChecker::class.qualifiedName + ) + } +} diff --git a/device-manager/src/META-INF/device-manager.xml b/device-manager/src/META-INF/device-manager.xml index 1c52e189b2e6..3dfbe57cb277 100644 --- a/device-manager/src/META-INF/device-manager.xml +++ b/device-manager/src/META-INF/device-manager.xml @@ -15,8 +15,9 @@ --> + diff --git a/device-manager/src/com/android/tools/idea/devicemanager/DeviceManagerToolWindowFactory.java b/device-manager/src/com/android/tools/idea/devicemanager/DeviceManagerToolWindowFactory.java index d70fcdf7082a..16751e66d31a 100644 --- a/device-manager/src/com/android/tools/idea/devicemanager/DeviceManagerToolWindowFactory.java +++ b/device-manager/src/com/android/tools/idea/devicemanager/DeviceManagerToolWindowFactory.java @@ -53,11 +53,6 @@ private DeviceManagerToolWindowFactory() { myNewVirtualDevicePanel = newVirtualDevicePanel; } - @Override - public boolean isApplicable(@NotNull Project project) { - return AndroidEnvironmentUtils.isAndroidEnvironment(project); - } - @Override public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow window) { Disposable parent = Disposer.newDisposable("Device Manager parent"); diff --git a/device-manager/testSrc/com/android/tools/idea/devicemanager/DeviceManagerToolWindowFactoryTest.kt b/device-manager/testSrc/com/android/tools/idea/devicemanager/DeviceManagerToolWindowFactoryTest.kt index 930e11e25ffe..ef7bf284fda1 100644 --- a/device-manager/testSrc/com/android/tools/idea/devicemanager/DeviceManagerToolWindowFactoryTest.kt +++ b/device-manager/testSrc/com/android/tools/idea/devicemanager/DeviceManagerToolWindowFactoryTest.kt @@ -18,9 +18,11 @@ package com.android.tools.idea.devicemanager import com.android.tools.idea.devicemanager.physicaltab.PhysicalDevicePanel import com.android.tools.idea.devicemanager.virtualtab.VirtualDevicePanel import com.android.tools.idea.devicemanager.virtualtab.VirtualDeviceWatcher +import com.android.tools.idea.sdk.AndroidEnvironmentChecker import com.intellij.openapi.Disposable import com.intellij.openapi.project.Project import com.intellij.openapi.wm.ToolWindowFactory +import com.intellij.openapi.wm.ext.LibraryDependentToolWindow import com.intellij.testFramework.DisposableRule import com.intellij.testFramework.ProjectRule import com.intellij.toolWindow.ToolWindowHeadlessManagerImpl @@ -151,4 +153,12 @@ class DeviceManagerToolWindowFactoryTest { val tabs2 = toolWindow2.contentManager.contents[0].component as JBTabbedPane assertEquals("Physical", tabs2.getTitleAt(tabs2.selectedIndex)) } + + @Test + fun isLibraryToolWindow() { + val toolWindow = LibraryDependentToolWindow.EXTENSION_POINT_NAME.extensions.find { it.id == "Device Manager" } + ?: throw AssertionError("Tool window not found") + + assertEquals(toolWindow.librarySearchClass, AndroidEnvironmentChecker::class.qualifiedName) + } } diff --git a/layout-inspector/src/META-INF/layout-inspector.xml b/layout-inspector/src/META-INF/layout-inspector.xml index 0f4a87da892e..0d1932d2072a 100644 --- a/layout-inspector/src/META-INF/layout-inspector.xml +++ b/layout-inspector/src/META-INF/layout-inspector.xml @@ -36,11 +36,12 @@ - + diff --git a/layout-inspector/testSrc/com/android/tools/idea/layoutinspector/LayoutInspectorToolWindowFactoryTest.kt b/layout-inspector/testSrc/com/android/tools/idea/layoutinspector/LayoutInspectorToolWindowFactoryTest.kt index 683606bcb749..eb68e53a1e8a 100644 --- a/layout-inspector/testSrc/com/android/tools/idea/layoutinspector/LayoutInspectorToolWindowFactoryTest.kt +++ b/layout-inspector/testSrc/com/android/tools/idea/layoutinspector/LayoutInspectorToolWindowFactoryTest.kt @@ -34,6 +34,8 @@ import com.android.tools.idea.layoutinspector.ui.DeviceViewContentPanel import com.android.tools.idea.layoutinspector.ui.DeviceViewPanel import com.android.tools.idea.layoutinspector.ui.InspectorRenderSettings import com.android.tools.idea.layoutinspector.util.ReportingCountDownLatch +import com.android.tools.idea.sdk.AndroidEnvironmentChecker +import com.android.tools.idea.sdk.AndroidFacetChecker import com.android.tools.idea.testing.AndroidProjectRule import com.android.tools.idea.testing.ui.flatten import com.android.tools.idea.transport.TransportService @@ -48,6 +50,7 @@ import com.intellij.openapi.util.Disposer import com.intellij.openapi.wm.ToolWindow import com.intellij.openapi.wm.ToolWindowBalloonShowOptions import com.intellij.openapi.wm.ex.ToolWindowManagerListener +import com.intellij.openapi.wm.ext.LibraryDependentToolWindow import com.intellij.project.TestProjectManager import com.intellij.testFramework.ApplicationRule import com.intellij.testFramework.DisposableRule @@ -69,6 +72,7 @@ import org.mockito.Mockito.anyString import java.io.ByteArrayOutputStream import java.io.PrintStream import java.util.concurrent.TimeUnit +import kotlin.test.fail private val MODERN_PROCESS = MODERN_DEVICE.createProcess() private val LEGACY_PROCESS = LEGACY_DEVICE.createProcess() @@ -224,6 +228,18 @@ class LayoutInspectorToolWindowFactoryTest { val contentPanel = component.flatten(false).firstIsInstance() assertThat(inspector.renderLogic.renderSettings).isInstanceOf(InspectorRenderSettings::class.java) } + + @Test + fun isLibraryToolWindow() { + val toolWindow = + LibraryDependentToolWindow.EXTENSION_POINT_NAME.extensions.find { + it.id == "Layout Inspector" + } + ?: fail("Tool window not found") + + assertThat(toolWindow.librarySearchClass) + .isEqualTo(AndroidFacetChecker::class.qualifiedName) + } } @Ignore("b/205981893") diff --git a/logcat/src/META-INF/logcat.xml b/logcat/src/META-INF/logcat.xml index 78f000c24f4f..b3b39935e730 100644 --- a/logcat/src/META-INF/logcat.xml +++ b/logcat/src/META-INF/logcat.xml @@ -16,9 +16,10 @@ + ) = UniqueNameGenerator.generateUniqueName("Logcat", "", "", " (", ")") { !tabNames.contains(it) } diff --git a/logcat/testSrc/com/android/tools/idea/logcat/LogcatToolWindowFactoryTest.kt b/logcat/testSrc/com/android/tools/idea/logcat/LogcatToolWindowFactoryTest.kt index 781db40174fa..d3751c7fdcf4 100644 --- a/logcat/testSrc/com/android/tools/idea/logcat/LogcatToolWindowFactoryTest.kt +++ b/logcat/testSrc/com/android/tools/idea/logcat/LogcatToolWindowFactoryTest.kt @@ -18,9 +18,7 @@ package com.android.tools.idea.logcat import com.android.processmonitor.monitor.ProcessNameMonitor import com.android.processmonitor.monitor.testing.FakeProcessNameMonitor import com.android.testutils.MockitoKt.mock -import com.android.testutils.MockitoKt.whenever import com.android.tools.adtui.TreeWalker -import com.android.tools.idea.IdeInfo import com.android.tools.idea.logcat.LogcatPanelConfig.FormattingConfig import com.android.tools.idea.logcat.devices.Device import com.android.tools.idea.logcat.devices.DeviceComboBoxDeviceTrackerFactory @@ -32,12 +30,13 @@ import com.android.tools.idea.logcat.service.LogcatService import com.android.tools.idea.logcat.util.waitForCondition import com.android.tools.idea.run.ShowLogcatListener import com.android.tools.idea.run.ShowLogcatListener.DeviceInfo.PhysicalDeviceInfo +import com.android.tools.idea.sdk.AndroidEnvironmentChecker import com.android.tools.idea.testing.ProjectServiceRule import com.google.common.truth.Truth.assertThat import com.intellij.openapi.Disposable import com.intellij.openapi.actionSystem.ActionGroup -import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.util.Disposer +import com.intellij.openapi.wm.ext.LibraryDependentToolWindow import com.intellij.testFramework.DisposableRule import com.intellij.testFramework.EdtRule import com.intellij.testFramework.ProjectRule @@ -49,8 +48,8 @@ import com.intellij.toolWindow.ToolWindowHeadlessManagerImpl.MockToolWindow import org.junit.Before import org.junit.Rule import org.junit.Test -import org.mockito.Mockito.spy import org.mockito.Mockito.verify +import kotlin.test.fail @RunsInEdt @@ -82,14 +81,13 @@ class LogcatToolWindowFactoryTest { } @Test - fun isApplicable_nonAndroidEnvironment() { - val mockIdeInfo = spy(IdeInfo.getInstance()) - whenever(mockIdeInfo.isAndroidStudio).thenReturn(false) - ApplicationManager.getApplication().replaceService(IdeInfo::class.java, mockIdeInfo, disposableRule.disposable) + fun isLibraryToolWindow() { + val toolWindow = LibraryDependentToolWindow.EXTENSION_POINT_NAME.extensions.find { it.id == "Logcat" } ?: fail("Tool window not found") - assertThat(logcatToolWindowFactory().isApplicable(project)).isFalse() + assertThat(toolWindow.librarySearchClass).isEqualTo(AndroidEnvironmentChecker::class.qualifiedName) } + @Test fun generateTabName_noPreExistingNames() { assertThat(logcatToolWindowFactory().generateTabName(emptySet())).isEqualTo("Logcat") diff --git a/profilers-android/src/META-INF/profilers.xml b/profilers-android/src/META-INF/profilers.xml index c2d32883a363..77745e77f43c 100644 --- a/profilers-android/src/META-INF/profilers.xml +++ b/profilers-android/src/META-INF/profilers.xml @@ -15,8 +15,9 @@ --> + +