Skip to content

Commit 0ad4e1f

Browse files
committed
fix crash in as panda while finding activity
1 parent cef3341 commit 0ad4e1f

5 files changed

Lines changed: 123 additions & 24 deletions

File tree

.github/workflows/build-plugin.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,18 @@ jobs:
3939
4040
- name: Create GitHub Release
4141
id: create_release
42-
uses: softprops/action-gh-release@v1
42+
uses: softprops/action-gh-release@v2
4343
env:
4444
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4545
with:
4646
tag_name: v${{ steps.get_version.outputs.version }}
4747
name: Release v${{ steps.get_version.outputs.version }}
4848
draft: false
4949
prerelease: false
50+
generate_release_notes: true
5051

5152
- name: Upload plugin artifact to release
52-
uses: softprops/action-gh-release@v1
53+
uses: softprops/action-gh-release@v2
5354
with:
5455
files: plugin/build/distributions/yamp_plugin_${{ steps.get_version.outputs.version }}.zip
5556
env:

.github/workflows/pr_master.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535

3636
- run: echo ${{env.version_name}}
3737

38-
- uses: actions/upload-artifact@v3
38+
- uses: actions/upload-artifact@v4
3939
with:
4040
name: yamp-${{env.version_name}}
4141
path: app/build/libs

app/build.gradle

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,27 @@ plugins {
55
id 'org.jetbrains.kotlin.jvm'
66
}
77

8+
kotlin {
9+
jvmToolchain {
10+
languageVersion.set(JavaLanguageVersion.of(17))
11+
}
12+
}
13+
814
def properties(String key) {
915
return project.findProperty(key).toString()
1016
}
1117

1218
group = properties("pluginGroup")
1319
version = properties("yampVersion")
1420

15-
sourceCompatibility = 11
21+
sourceCompatibility = 17
22+
targetCompatibility = 17
23+
24+
java {
25+
toolchain {
26+
languageVersion.set(JavaLanguageVersion.of(17))
27+
}
28+
}
1629

1730
java.sourceSets.main.java {
1831
if (OperatingSystem.current().isMacOsX()) {

gradle.properties

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
kotlin.code.style=official
22

3+
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError
4+
35
studioCompilePath=/Applications/Android Studio.app/Contents
46
#studioCompilePath=/Applications/Android Studio Preview.app/Contents
57

@@ -8,7 +10,7 @@ studioCompilePath=/Applications/Android Studio.app/Contents
810

911
pluginGroup = com.github.grishberg
1012
pluginName = android-methods-profiler
11-
yampVersion = 25.08.29
13+
yampVersion = 26.04.05
1214

1315
# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
1416
# for insight into build numbers and IntelliJ Platform versions.
@@ -17,6 +19,7 @@ sinceBuild=243.22562.145
1719

1820
# IntelliJ Platform Properties -> https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties
1921
platformType = AI
22+
#localASVersion=/Applications/Android Studio.app/Contents
2023
#TODO: set to 2025.1.1.2
2124
platformVersion=2024.3.1.7
2225
androidPluginVersion=243.22562.218

plugin/src/main/kotlin/com/github/grishberg/profiler/androidstudio/PluginProjectInfo.kt

Lines changed: 101 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
package com.github.grishberg.profiler.androidstudio
22

3-
import com.android.ddmlib.IDevice
43
import com.android.tools.idea.model.AndroidModel
5-
import com.android.tools.idea.run.activity.ActivityLocator
6-
import com.android.tools.idea.run.activity.DefaultActivityLocator
74
import com.github.grishberg.profiler.common.AppLogger
8-
import com.intellij.facet.FacetManager
9-
import com.intellij.openapi.module.ModuleManager
105
import com.github.grishberg.profiler.ui.dialogs.recorder.ProjectInfo
6+
import com.intellij.facet.FacetManager
117
import com.intellij.openapi.application.ApplicationManager
8+
import com.intellij.openapi.module.ModuleManager
129
import com.intellij.openapi.project.Project
13-
import com.intellij.openapi.util.ThrowableComputable
10+
import java.io.File
11+
import javax.xml.parsers.DocumentBuilderFactory
1412
import org.jetbrains.android.facet.AndroidFacet
15-
import org.jetbrains.android.sdk.AndroidSdkUtils
13+
import org.w3c.dom.Document
14+
import org.w3c.dom.Element
15+
import org.w3c.dom.NodeList
1616

1717
class PluginProjectInfo(
1818
project: Project, private val logger: AppLogger
@@ -22,16 +22,15 @@ class PluginProjectInfo(
2222
override val activityName: String?
2323

2424
init {
25-
val facets = try{
25+
val facets = try {
2626
getAndroidFacets(project)
2727
} catch (e: Exception) {
2828
logger.e("getAndroidFacets error", e)
2929
emptyList()
3030
}
3131
packageName = createPackageName(facets)
32-
val devices = AndroidSdkUtils.getDebugBridge(project)?.devices ?: emptyArray()
3332
activityName = try {
34-
getDefaultActivityName(facets, devices)
33+
getDefaultActivityName(facets)
3534
} catch (e: Exception) {
3635
logger.e("PluginProjectInfo: Error while fetching getDefaultActivityName", e)
3736
null
@@ -62,15 +61,98 @@ class PluginProjectInfo(
6261
return null
6362
}
6463

65-
@Throws(ActivityLocator.ActivityLocatorException::class)
66-
private fun getDefaultActivityName(facets: List<AndroidFacet>, devices: Array<IDevice>): String? {
64+
@Throws(Exception::class)
65+
private fun getDefaultActivityName(facets: List<AndroidFacet>): String? {
6766
val facet = facets.firstOrNull() ?: return null
68-
val device = devices.firstOrNull() ?: return null
69-
return ApplicationManager.getApplication()
70-
.runReadAction(ThrowableComputable<String, ActivityLocator.ActivityLocatorException?> {
71-
DefaultActivityLocator(
72-
facet
73-
).getQualifiedActivityName(device)
74-
})
67+
return ApplicationManager.getApplication().runReadAction<String?> {
68+
try {
69+
val manifestFile = findManifestFileReflection(facet)
70+
if (manifestFile == null || !manifestFile.exists()) {
71+
logger.d("Manifest file not found")
72+
return@runReadAction null
73+
}
74+
val factory = DocumentBuilderFactory.newInstance()
75+
val builder = factory.newDocumentBuilder()
76+
val document: Document = builder.parse(manifestFile)
77+
val activities: NodeList = document.getElementsByTagName("activity")
78+
for (i in 0 until activities.length) {
79+
val activity = activities.item(i) as Element
80+
val intentFilters = activity.getElementsByTagName("intent-filter")
81+
for (j in 0 until intentFilters.length) {
82+
val intentFilter = intentFilters.item(j) as Element
83+
val actions = intentFilter.getElementsByTagName("action")
84+
val categories = intentFilter.getElementsByTagName("category")
85+
var hasMainAction = false
86+
var hasLauncherCategory = false
87+
for (k in 0 until actions.length) {
88+
val actionNode = actions.item(k) as Element
89+
val actionName = actionNode.getAttribute("android:name")
90+
if (actionName == "android.intent.action.MAIN") {
91+
hasMainAction = true
92+
}
93+
}
94+
for (k in 0 until categories.length) {
95+
val categoryNode = categories.item(k) as Element
96+
val categoryName = categoryNode.getAttribute("android:name")
97+
if (categoryName == "android.intent.category.LAUNCHER") {
98+
hasLauncherCategory = true
99+
}
100+
}
101+
if (hasMainAction && hasLauncherCategory) {
102+
val activityName = activity.getAttribute("android:name")
103+
if (activityName.isNotEmpty()) {
104+
logger.d("Found default activity: $activityName")
105+
return@runReadAction activityName
106+
}
107+
}
108+
}
109+
}
110+
logger.d("No default activity found in manifest")
111+
null
112+
} catch (e: Throwable) {
113+
logger.e("Error while parsing manifest", e)
114+
null
115+
}
116+
}
117+
}
118+
119+
private fun findManifestFileReflection(facet: AndroidFacet): File? {
120+
try {
121+
val sourceProviderClass = Class.forName("org.jetbrains.android.facet.AndroidFacet\$SourceProvider")
122+
val sourceProviderGetter = sourceProviderClass.getMethod("getSourceProvider")
123+
val sourceProvider = sourceProviderGetter.invoke(facet)
124+
if (sourceProvider != null) {
125+
val allSourceFilesMethod = sourceProvider.javaClass.getMethod("getAllSourceFiles")
126+
127+
@Suppress("UNCHECKED_CAST") val allSourceFiles =
128+
allSourceFilesMethod.invoke(sourceProvider) as List<File>
129+
for (file in allSourceFiles) {
130+
if (file.name == "AndroidManifest.xml") {
131+
logger.d("Found manifest via sourceProvider reflection")
132+
return file
133+
}
134+
}
135+
}
136+
} catch (e: Throwable) {
137+
logger.d("sourceProvider reflection failed: ${e.message}")
138+
}
139+
140+
try {
141+
val manifestClass = Class.forName("org.jetbrains.android.dom.manifest.Manifest")
142+
val manifestGetter = AndroidFacet::class.java.getMethod("getManifest")
143+
val manifest = manifestGetter.invoke(facet)
144+
if (manifest != null) {
145+
val xmlFileGetter = manifestClass.getMethod("getXmlFile")
146+
val xmlFile = xmlFileGetter.invoke(manifest) as? File
147+
if (xmlFile != null) {
148+
logger.d("Found manifest via manifest.xmlFile reflection")
149+
return xmlFile
150+
}
151+
}
152+
} catch (e: Throwable) {
153+
logger.d("manifest.xmlFile reflection failed: ${e.message}")
154+
}
155+
156+
return null
75157
}
76158
}

0 commit comments

Comments
 (0)