diff --git a/.gitignore b/.gitignore index ce09f24..8485608 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,6 @@ build/ *.iml *.iws -.intellijPlatform/ \ No newline at end of file +.intellijPlatform/ + +.kotlin \ No newline at end of file diff --git a/.run/Run.run.xml b/.run/Run.run.xml new file mode 100644 index 0000000..4c81fef --- /dev/null +++ b/.run/Run.run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/RunLocal.run.xml b/.run/RunLocal.run.xml new file mode 100644 index 0000000..ff03938 --- /dev/null +++ b/.run/RunLocal.run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 438e76b..286a393 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { // Must match the Kotlin version bundled with the IDE // https://plugins.jetbrains.com/docs/intellij/using-kotlin.html#kotlin-standard-library // https://plugins.jetbrains.com/docs/intellij/android-studio-releases-list.html - id("org.jetbrains.kotlin.jvm") version "2.0.21" + id("org.jetbrains.kotlin.jvm") version "2.1.0" // https://github.com/JetBrains/intellij-platform-gradle-plugin id("org.jetbrains.intellij.platform") version "2.1.0" @@ -18,10 +18,9 @@ plugins { id("com.github.b3er.local.properties") version "1.1" // https://github.com/JetBrains/gradle-changelog-plugin - id("org.jetbrains.changelog") version "2.0.0" + id("org.jetbrains.changelog") version "2.2.1" } - repositories { mavenCentral() intellijPlatform { @@ -55,9 +54,8 @@ reckon { snapshotFromProp() } -java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 +kotlin { + jvmToolchain(21) } tasks.runIde { @@ -89,7 +87,7 @@ dependencies { } - implementation("org.jooq:joor-java-8:0.9.14") + implementation("org.jooq:joor:0.9.15") testImplementation("junit:junit:4.13.2") testImplementation("org.mockito:mockito-core:4.7.0") diff --git a/gradle.properties b/gradle.properties index 941ec88..444e8ad 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,10 +1,10 @@ # Android Studio Version # Get it from `list-studio-versions.sh` -ideVersion=2024.3.1.2 +ideVersion=2024.3.1.7 # Minimum Intellij PLatform version supported by this plugin # see https://plugins.jetbrains.com/docs/intellij/android-studio-releases-list.html -sinceBuild=242.23339 +sinceBuild=243.22562.145 # The path to a local Android Studio installation. # This will enable the `runLocalIde` task. @@ -16,4 +16,6 @@ sinceBuild=242.23339 kotlin.stdlib.default.dependency = false org.gradle.parallel=true -org.gradle.caching=true \ No newline at end of file +org.gradle.caching=true +org.gradle.jvmargs=-Xmx3072m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\\="-Xmx3072M" -XX\\:+UseParallelGC -XX:ReservedCodeCacheSize=512m +kotlin.code.style=official \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 171d876..c4c9271 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ +#Wed Dec 25 15:42:43 IST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/kotlin/com/developerphil/adbidea/Application.kt b/src/main/kotlin/com/developerphil/adbidea/Application.kt index fcac65c..73680bd 100644 --- a/src/main/kotlin/com/developerphil/adbidea/Application.kt +++ b/src/main/kotlin/com/developerphil/adbidea/Application.kt @@ -1,29 +1,37 @@ package com.developerphil.adbidea -import com.developerphil.adbidea.preference.accessor.PreferenceAccessorImpl import com.developerphil.adbidea.preference.ApplicationPreferences +import com.developerphil.adbidea.preference.accessor.PreferenceAccessorImpl import com.developerphil.adbidea.ui.NotificationHelper -import com.intellij.ide.plugins.PluginManager +import com.intellij.ide.plugins.PluginManagerCore import com.intellij.ide.util.PropertiesComponent -import com.intellij.openapi.components.ApplicationComponent +import com.intellij.openapi.components.Service +import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.extensions.PluginId import com.intellij.util.text.SemVer - -private val pluginPackage = "com.developerphil.adbidea" - // This is more of a service locator than a proper DI framework. // It's not used often enough in the codebase to warrant the complexity of a DI solution like dagger. -class Application : ApplicationComponent { +@Service +class Application { + + private val logger = Logger.getInstance(Application::class.java) + private val pluginPackage = "com.developerphil.adbidea" private val applicationPreferencesAccessor = PreferenceAccessorImpl(PropertiesComponent.getInstance()) private val applicationPreferences = ApplicationPreferences(applicationPreferencesAccessor) - override fun initComponent() { + init { try { - val version = PluginManager.getPlugin(PluginId.getId(pluginPackage))!!.version!! - applicationPreferences.savePreviousPluginVersion(SemVer.parseFromText(version)!!) + val pluginId = PluginId.getId(pluginPackage) + val pluginDescriptor = PluginManagerCore.getPlugin(pluginId) + val version = pluginDescriptor?.version + if (version != null) { + applicationPreferences.savePreviousPluginVersion(SemVer.parseFromText(version)!!) + } else { + logger.error("Plugin version is null for plugin ID: $pluginId") + } } catch (e: Exception) { NotificationHelper.error("Couldn't initialize ADB Idea: ${e.message}") } } -} +} \ No newline at end of file diff --git a/src/main/kotlin/com/developerphil/adbidea/ObjectGraph.kt b/src/main/kotlin/com/developerphil/adbidea/ObjectGraph.kt index ef2c34f..9d69c9a 100644 --- a/src/main/kotlin/com/developerphil/adbidea/ObjectGraph.kt +++ b/src/main/kotlin/com/developerphil/adbidea/ObjectGraph.kt @@ -1,10 +1,10 @@ package com.developerphil.adbidea -import com.developerphil.adbidea.preference.accessor.PreferenceAccessorImpl import com.developerphil.adbidea.adb.BridgeImpl import com.developerphil.adbidea.adb.DeviceResultFetcher import com.developerphil.adbidea.adb.UseSameDevicesHelper import com.developerphil.adbidea.preference.ProjectPreferences +import com.developerphil.adbidea.preference.accessor.PreferenceAccessorImpl import com.intellij.ide.util.PropertiesComponent import com.intellij.openapi.components.Service import com.intellij.openapi.project.Project @@ -13,7 +13,7 @@ import kotlinx.coroutines.CoroutineScope // This is more of a service locator than a proper DI framework. // It's not used often enough in the codebase to warrant the complexity of a DI solution like dagger. @Service(Service.Level.PROJECT) -class ObjectGraph(private val project: Project, private val coroutineScope: CoroutineScope) { +class ObjectGraph(private val project: Project, coroutineScope: CoroutineScope) { val deviceResultFetcher by lazy { DeviceResultFetcher(project, useSameDevicesHelper, bridge) } val projectPreferences: ProjectPreferences by lazy { ProjectPreferences(projectPreferenceAccessor) } diff --git a/src/main/kotlin/com/developerphil/adbidea/ReflectKt.kt b/src/main/kotlin/com/developerphil/adbidea/ReflectKt.kt index de7e7cf..317ac49 100644 --- a/src/main/kotlin/com/developerphil/adbidea/ReflectKt.kt +++ b/src/main/kotlin/com/developerphil/adbidea/ReflectKt.kt @@ -2,5 +2,5 @@ package com.developerphil.adbidea import org.joor.Reflect -inline fun on() = Reflect.on(T::class.java) +inline fun on() = Reflect.onClass(T::class.java) inline fun Reflect.asType() = this.`as`(T::class.java) \ No newline at end of file diff --git a/src/main/kotlin/com/developerphil/adbidea/action/QuickListAction.kt b/src/main/kotlin/com/developerphil/adbidea/action/QuickListAction.kt index daca188..aca3080 100644 --- a/src/main/kotlin/com/developerphil/adbidea/action/QuickListAction.kt +++ b/src/main/kotlin/com/developerphil/adbidea/action/QuickListAction.kt @@ -1,6 +1,5 @@ package com.developerphil.adbidea.action -import com.developerphil.adbidea.adb.AdbUtil import com.intellij.ide.actions.QuickSwitchSchemeAction import com.intellij.openapi.actionSystem.ActionManager import com.intellij.openapi.actionSystem.AnActionEvent diff --git a/src/main/kotlin/com/developerphil/adbidea/adb/AdbUtil.kt b/src/main/kotlin/com/developerphil/adbidea/adb/AdbUtil.kt index f658fd0..ab74d2b 100644 --- a/src/main/kotlin/com/developerphil/adbidea/adb/AdbUtil.kt +++ b/src/main/kotlin/com/developerphil/adbidea/adb/AdbUtil.kt @@ -8,7 +8,6 @@ import com.android.tools.idea.gradle.project.sync.GradleSyncState import com.developerphil.adbidea.adb.command.receiver.GenericReceiver import com.developerphil.adbidea.ui.NotificationHelper.info import com.intellij.openapi.project.Project -import org.joor.Reflect import java.io.IOException import java.util.concurrent.TimeUnit diff --git a/src/main/kotlin/com/developerphil/adbidea/adb/DeviceResultFetcher.kt b/src/main/kotlin/com/developerphil/adbidea/adb/DeviceResultFetcher.kt index c71770b..ee43fce 100644 --- a/src/main/kotlin/com/developerphil/adbidea/adb/DeviceResultFetcher.kt +++ b/src/main/kotlin/com/developerphil/adbidea/adb/DeviceResultFetcher.kt @@ -20,7 +20,7 @@ import org.jetbrains.android.facet.AndroidFacet import org.joor.Reflect -class DeviceResultFetcher constructor( +class DeviceResultFetcher( private val project: Project, private val useSameDevicesHelper: UseSameDevicesHelper, private val bridge: Bridge @@ -113,6 +113,6 @@ sealed class DeviceResult { val packageName: String ) : DeviceResult() - object Cancelled : DeviceResult() - object DeviceNotFound : DeviceResult() -} + data object Cancelled : DeviceResult() + data object DeviceNotFound : DeviceResult() +} \ No newline at end of file diff --git a/src/main/kotlin/com/developerphil/adbidea/adb/UseSameDevicesHelper.kt b/src/main/kotlin/com/developerphil/adbidea/adb/UseSameDevicesHelper.kt index 279e929..ae00231 100644 --- a/src/main/kotlin/com/developerphil/adbidea/adb/UseSameDevicesHelper.kt +++ b/src/main/kotlin/com/developerphil/adbidea/adb/UseSameDevicesHelper.kt @@ -3,7 +3,7 @@ package com.developerphil.adbidea.adb import com.android.ddmlib.IDevice import com.developerphil.adbidea.preference.ProjectPreferences -class UseSameDevicesHelper constructor(private val projectPreferences: ProjectPreferences, private val bridge: Bridge) { +class UseSameDevicesHelper(private val projectPreferences: ProjectPreferences, private val bridge: Bridge) { var previouslyConnectedDevices: List? = null diff --git a/src/main/kotlin/com/developerphil/adbidea/debugger/Debugger.kt b/src/main/kotlin/com/developerphil/adbidea/debugger/Debugger.kt index 45b0308..e86480b 100644 --- a/src/main/kotlin/com/developerphil/adbidea/debugger/Debugger.kt +++ b/src/main/kotlin/com/developerphil/adbidea/debugger/Debugger.kt @@ -2,10 +2,10 @@ package com.developerphil.adbidea.debugger import com.android.ddmlib.Client import com.android.ddmlib.IDevice -import com.android.tools.idea.execution.common.processhandler.AndroidProcessHandler import com.android.tools.idea.execution.common.debug.AndroidDebugger import com.android.tools.idea.execution.common.debug.AndroidDebuggerState import com.android.tools.idea.execution.common.debug.DebugSessionStarter +import com.android.tools.idea.execution.common.processhandler.AndroidProcessHandler import com.developerphil.adbidea.compatibility.BackwardCompatibleGetter import com.developerphil.adbidea.on import com.developerphil.adbidea.waitUntil @@ -45,7 +45,7 @@ class Debugger( terminateRunSessions(client) coroutineScope.launch { - DebugSessionStarter.attachDebuggerToClientAndShowTab( + DebugSessionStarter.attachDebuggerToClientAndShowTab( project, client, androidDebugger, @@ -107,6 +107,6 @@ private class RunningProcessesGetter( } override fun getPreviousImplementation(): Array { - return on().call("getInstance", project).call("getRunningProcesses").get>() + return on().call("getInstance", project).call("getRunningProcesses").get() } } diff --git a/src/main/kotlin/com/developerphil/adbidea/ui/ModuleChooserDialogHelper.kt b/src/main/kotlin/com/developerphil/adbidea/ui/ModuleChooserDialogHelper.kt index 3116993..bd82eb6 100644 --- a/src/main/kotlin/com/developerphil/adbidea/ui/ModuleChooserDialogHelper.kt +++ b/src/main/kotlin/com/developerphil/adbidea/ui/ModuleChooserDialogHelper.kt @@ -4,12 +4,10 @@ import com.intellij.ide.util.PropertiesComponent import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ui.configuration.ChooseModulesDialog -import com.intellij.ui.table.JBTable import com.intellij.util.ui.UIUtil import org.jetbrains.android.facet.AndroidFacet import java.awt.Component import java.awt.Dimension -import java.awt.geom.Dimension2D import javax.swing.JTable object ModuleChooserDialogHelper { diff --git a/src/main/kotlin/com/developerphil/adbidea/ui/MyDeviceChooser.kt b/src/main/kotlin/com/developerphil/adbidea/ui/MyDeviceChooser.kt index b2f5b1c..49f6182 100755 --- a/src/main/kotlin/com/developerphil/adbidea/ui/MyDeviceChooser.kt +++ b/src/main/kotlin/com/developerphil/adbidea/ui/MyDeviceChooser.kt @@ -74,7 +74,7 @@ class MyDeviceChooser( private val myRefreshingAlarm: Alarm private val myBridge: AndroidDebugBridge? private val myMinSdkVersion: ListenableFuture = - StudioAndroidModuleInfo.getInstance(myFacet).runtimeMinSdkVersion; + StudioAndroidModuleInfo.getInstance(myFacet).runtimeMinSdkVersion private val myProjectTarget: IAndroidTarget = getInstance(myFacet.module)?.target ?: error("Module [${myFacet.module.name}] already disposed") @@ -95,7 +95,7 @@ class MyDeviceChooser( */ private val myDetectedDevicesRef = AtomicReference(EMPTY_DEVICE_ARRAY) private val myPanel: JComponent - private val myDeviceTable: JBTable + private val myDeviceTable = JBTable() private var mySelectedRows: IntArray? = null private var hadUserInteraction = false private var previouslySelectedSerials: Array? = null @@ -180,7 +180,7 @@ class MyDeviceChooser( } }) } - if (!Arrays.equals(myDisplayedDevices, devices)) { + if (!myDisplayedDevices.contentEquals(devices)) { myDetectedDevicesRef.set(devices) ApplicationManager.getApplication() .invokeLater({ refreshTable() }, ModalityState.stateForComponent(myDeviceTable)) @@ -198,8 +198,8 @@ class MyDeviceChooser( } } myProcessSelectionFlag = false - myDeviceTable.setModel(MyDeviceTableModel(devices)) - if (selectedRows.size() == 0 && devices.size > 0) { + myDeviceTable.model = MyDeviceTableModel(devices) + if (selectedRows.size() == 0 && devices.isNotEmpty()) { myDeviceTable.selectionModel.setSelectionInterval(0, 0) } for (selectedRow in selectedRows.toNativeArray()) { @@ -219,7 +219,7 @@ class MyDeviceChooser( val preferredFocusComponent: JComponent get() = myDeviceTable - val panel: JComponent? + val panel: JComponent get() = myPanel val selectedDevices: Array @@ -336,12 +336,16 @@ class MyDeviceChooser( } override fun getColumnClass(columnIndex: Int): Class<*> { - return if (columnIndex == COMPATIBILITY_COLUMN_INDEX) { - LaunchCompatibility::class.java - } else if (columnIndex == DEVICE_NAME_COLUMN_INDEX) { - IDevice::class.java - } else { - String::class.java + return when (columnIndex) { + COMPATIBILITY_COLUMN_INDEX -> { + LaunchCompatibility::class.java + } + DEVICE_NAME_COLUMN_INDEX -> { + IDevice::class.java + } + else -> { + String::class.java + } } } @@ -409,7 +413,6 @@ class MyDeviceChooser( } init { - myDeviceTable = JBTable() myPanel = ScrollPaneFactory.createScrollPane(myDeviceTable) myPanel.preferredSize = Dimension(450, 220) myDeviceTable.model = MyDeviceTableModel(EMPTY_DEVICE_ARRAY) diff --git a/src/main/kotlin/com/developerphil/adbidea/ui/NotificationHelper.kt b/src/main/kotlin/com/developerphil/adbidea/ui/NotificationHelper.kt index 5b3492b..d541fb0 100644 --- a/src/main/kotlin/com/developerphil/adbidea/ui/NotificationHelper.kt +++ b/src/main/kotlin/com/developerphil/adbidea/ui/NotificationHelper.kt @@ -1,20 +1,50 @@ package com.developerphil.adbidea.ui -import com.intellij.notification.NotificationDisplayType import com.intellij.notification.NotificationGroup +import com.intellij.notification.NotificationGroupManager import com.intellij.notification.NotificationType object NotificationHelper { - private val INFO = NotificationGroup("ADB Idea (Logging)", NotificationDisplayType.NONE, true, null, null) - private val ERRORS = NotificationGroup("ADB Idea (Errors)", NotificationDisplayType.BALLOON, true, null, null) + fun info(message: String) { + sendNotification( + message, + NotificationType.INFORMATION, + NotificationGroupManager + .getInstance() + .getNotificationGroup("ADB Idea (Logging)") + ) + } - fun info(message: String) = sendNotification(message, NotificationType.INFORMATION, INFO) + // Function to send an error notification + fun error(message: String) { + sendNotification( + message, + NotificationType.ERROR, + NotificationGroupManager + .getInstance() + .getNotificationGroup("ADB Idea (Errors)") + ) + } - fun error(message: String) = sendNotification(message, NotificationType.ERROR, ERRORS) + // Helper function to create and display a notification + private fun sendNotification( + message: String, + notificationType: NotificationType, + notificationGroup: NotificationGroup, + ) { + // Create the notification without a listener + val notification = notificationGroup.createNotification( + "ADB IDEA", + escapeString(message), + notificationType, + ) - private fun sendNotification(message: String, notificationType: NotificationType, notificationGroup: NotificationGroup) { - notificationGroup.createNotification("ADB IDEA", escapeString(message), notificationType, null).notify(null) + // Display the notification + notification.notify(null) } - private fun escapeString(string: String) = string.replace("\n".toRegex(), "\n
") + private fun escapeString(string: String) = string.replace( + "\n".toRegex(), + "\n
" + ) } \ No newline at end of file diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 12d0a78..8233f91 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,13 @@ com.developerphil.adbidea ADB Idea Philippe Breault + + + + + +
    @@ -31,115 +37,91 @@ org.jetbrains.android - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - com.developerphil.adbidea.Application - - diff --git a/src/test/kotlin/com/developerphil/adbidea/adb/FakeDevice.kt b/src/test/kotlin/com/developerphil/adbidea/adb/FakeDevice.kt index 62e4318..dfa2b46 100644 --- a/src/test/kotlin/com/developerphil/adbidea/adb/FakeDevice.kt +++ b/src/test/kotlin/com/developerphil/adbidea/adb/FakeDevice.kt @@ -1,12 +1,7 @@ package com.developerphil.adbidea.adb import com.android.ddmlib.* -import com.android.ddmlib.log.LogReceiver -import com.android.sdklib.AndroidVersion -import java.io.File import java.lang.reflect.Proxy -import java.util.concurrent.Future -import java.util.concurrent.TimeUnit data class FakeDevice(private val serialNumber: String) : IDevice by stub() { override fun getSerialNumber(): String { diff --git a/src/test/kotlin/com/developerphil/adbidea/adb/UseSameDevicesHelperTest.kt b/src/test/kotlin/com/developerphil/adbidea/adb/UseSameDevicesHelperTest.kt index 19f68b4..6988011 100644 --- a/src/test/kotlin/com/developerphil/adbidea/adb/UseSameDevicesHelperTest.kt +++ b/src/test/kotlin/com/developerphil/adbidea/adb/UseSameDevicesHelperTest.kt @@ -1,11 +1,8 @@ -package com.developerphil.adbidea +package com.developerphil.adbidea.adb import com.android.ddmlib.IDevice -import com.developerphil.adbidea.preference.accessor.InMemoryPreferenceAccessor -import com.developerphil.adbidea.adb.Bridge -import com.developerphil.adbidea.adb.FakeDevice -import com.developerphil.adbidea.adb.UseSameDevicesHelper import com.developerphil.adbidea.preference.ProjectPreferences +import com.developerphil.adbidea.preference.accessor.InMemoryPreferenceAccessor import com.google.common.truth.Truth.assertThat import org.junit.Test