Skip to content

Commit 91d0972

Browse files
Merge pull request #140 from Grigory-Rylov/fix_crash_in_as_panda
fix crash in as panda while finding activity
2 parents cef3341 + 4bf1b2d commit 91d0972

6 files changed

Lines changed: 153 additions & 46 deletions

File tree

.github/workflows/build-plugin.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ jobs:
2525
run: chmod +x ./gradlew
2626

2727
- name: Build plugin
28-
run: ./gradlew buildPlugin
28+
run: |
29+
./gradlew :plugin:buildPlugin \
30+
-x :app:test \
31+
-x :app:compileTestKotlin \
32+
--no-daemon
2933
3034
- name: Get version from gradle.properties
3135
id: get_version
@@ -39,17 +43,18 @@ jobs:
3943
4044
- name: Create GitHub Release
4145
id: create_release
42-
uses: softprops/action-gh-release@v1
46+
uses: softprops/action-gh-release@v2
4347
env:
4448
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4549
with:
4650
tag_name: v${{ steps.get_version.outputs.version }}
4751
name: Release v${{ steps.get_version.outputs.version }}
4852
draft: false
4953
prerelease: false
54+
generate_release_notes: true
5055

5156
- name: Upload plugin artifact to release
52-
uses: softprops/action-gh-release@v1
57+
uses: softprops/action-gh-release@v2
5358
with:
5459
files: plugin/build/distributions/yamp_plugin_${{ steps.get_version.outputs.version }}.zip
5560
env:

.github/workflows/checks.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ jobs:
1111
runs-on: ubuntu-latest
1212
steps:
1313
- uses: actions/checkout@v4
14-
- name: Set up JDK 17
14+
- name: Set up JDK 21
1515
uses: actions/setup-java@v4
1616
with:
17-
java-version: "17"
17+
java-version: "21"
1818
distribution: "temurin"
1919

2020
- name: Validate Gradle wrapper

.github/workflows/pr_master.yaml

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,35 @@ jobs:
88
build:
99
runs-on: ubuntu-latest
1010
steps:
11-
- uses: actions/checkout@v3
12-
- name: Set up JDK 17
13-
uses: actions/setup-java@v3
11+
- uses: actions/checkout@v4
12+
13+
- name: Set up JDK 21
14+
uses: actions/setup-java@v4
1415
with:
15-
java-version: '17'
16-
distribution: 'temurin'
16+
java-version: "21"
17+
distribution: "temurin"
1718

1819
- name: Validate Gradle wrapper
19-
uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
20+
uses: gradle/actions/wrapper-validation@v4
2021

2122
- name: Build with Gradle
22-
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
23+
uses: gradle/actions/setup-gradle@v4
2324

24-
with:
25-
arguments: fatJar
25+
- name: Run fatJar
26+
run: ./gradlew fatJar
2627

27-
- name : Retrieve Version
28-
run: |
29-
echo "::set-output name=VERSION_NAME::$(${{github.workspace}}/gradlew -q printVersionName)"
28+
- name: Retrieve Version
3029
id: yamp_version
30+
run: |
31+
VERSION=$(./gradlew -q printVersionName)
32+
echo "VERSION_NAME=$VERSION" >> "$GITHUB_OUTPUT"
3133
3234
- name: Get version
33-
run:
34-
echo "version_name=${{steps.yamp_version.outputs.VERSION_NAME}}" >> $GITHUB_ENV
35+
run: echo "version_name=${{ steps.yamp_version.outputs.VERSION_NAME }}" >> $GITHUB_ENV
3536

36-
- run: echo ${{env.version_name}}
37+
- run: echo ${{ env.version_name }}
3738

38-
- uses: actions/upload-artifact@v3
39+
- uses: actions/upload-artifact@v4
3940
with:
40-
name: yamp-${{env.version_name}}
41+
name: yamp-${{ env.version_name }}
4142
path: app/build/libs

app/build.gradle

Lines changed: 20 additions & 4 deletions
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()) {
@@ -46,12 +59,12 @@ dependencies {
4659
testImplementation "junit:junit:4.12"
4760
testImplementation 'org.mockito:mockito-core:2.23.0'
4861
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0"
49-
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.2"
62+
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3"
63+
testImplementation "org.jetbrains.kotlin:kotlin-test-junit:1.9.22"
5064
}
5165
compileJava {
5266
options.compilerArgs << "-XDignore.symbol.file=true"
5367
options.fork = true
54-
options.forkOptions.executable = 'javac'
5568
}
5669

5770
task fatJar(type: Jar) {
@@ -86,7 +99,10 @@ if (OperatingSystem.current().isLinux()) {
8699
task buildInstaller(type: Exec) {
87100
dependsOn fatJar
88101
workingDir '.'
89-
println("Current WD: " + workingDir)
90102
commandLine "./${installerScript}"
91103
args version
104+
105+
doFirst {
106+
println("Current WD: " + workingDir)
107+
}
92108
}

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)