Skip to content

Commit a172024

Browse files
committed
Extract Android drawing to a separate module.
1 parent a1dd0c9 commit a172024

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+289
-171
lines changed

demo/android-plot-view/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ val letsPlotVersion = extra["letsPlot.version"] as String
4343
val letsPlotKotlinVersion = extra["letsPlotKotlin.version"] as String
4444

4545
dependencies {
46-
implementation(project(":platf-skia"))
46+
implementation(project(":platf-android"))
4747
implementation(project(":demo-plot-shared"))
4848
implementation("org.jetbrains.lets-plot:lets-plot-kotlin-kernel:${letsPlotKotlinVersion}")
4949
implementation("org.jetbrains.lets-plot:lets-plot-common:$letsPlotVersion")

demo/android-svg-view/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ android {
4141
val letsPlotVersion = extra["letsPlot.version"] as String
4242

4343
dependencies {
44-
implementation(project(":platf-skia"))
44+
implementation(project(":platf-android"))
4545
implementation(project(":demo-svg-shared"))
4646
implementation("org.jetbrains.lets-plot:lets-plot-common:$letsPlotVersion")
4747
implementation("org.jetbrains.lets-plot:canvas:$letsPlotVersion")

demo/plot/shared/src/main/kotlin/plotSpec/MarkdownSpec.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class MarkdownSpec : PlotDemoSpec {
1616
}
1717

1818
fun mpgTitleOnly(): MutableMap<String, Any> {
19+
@Suppress("UNCHECKED_CAST")
1920
return JsonSupport.parseJson(
2021
"""
2122
|{
@@ -42,6 +43,7 @@ class MarkdownSpec : PlotDemoSpec {
4243
}
4344

4445
fun mpg(): MutableMap<String, Any> {
46+
@Suppress("UNCHECKED_CAST")
4547
return JsonSupport.parseJson(
4648
"""
4749
|{

gradle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ kotlin.mpp.androidSourceSetLayoutVersion=2
1414
org.jetbrains.compose.experimental.uikit.enabled=true
1515

1616
#Android
17+
kotlin.android.version=2.1.0
1718
agp.version=8.6.0
1819
android.useAndroidX=true
1920
android.compileSdk=35

lets-plot-compose/build.gradle.kts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ plugins {
1414

1515
val androidComposeBom = extra["androidx.compose.bom"] as String
1616
val skikoVersion = extra["skiko.version"] as String
17-
val composeVersion = extra["compose.version"] as String
1817
val letsPlotVersion = extra["letsPlot.version"] as String
1918
val letsPlotKotlinVersion = extra["letsPlotKotlin.version"] as String
2019
val kotlinLoggingVersion = extra["kotlinLogging.version"] as String
@@ -58,7 +57,7 @@ kotlin {
5857
implementation(project.dependencies.platform("androidx.compose:compose-bom:$androidComposeBom"))
5958
implementation("androidx.compose.ui:ui")
6059
implementation("androidx.compose.ui:ui-graphics")
61-
api(project(":platf-skia"))
60+
api(project(":platf-android"))
6261
compileOnly("org.jetbrains.lets-plot:plot-raster:${letsPlotVersion}")
6362
compileOnly("org.jetbrains.lets-plot:canvas:${letsPlotVersion}")
6463
}

platf-android/build.gradle.kts

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
import java.io.ByteArrayOutputStream
2+
import java.io.FileInputStream
3+
import java.util.*
4+
5+
/*
6+
* Copyright (c) 2023. JetBrains s.r.o.
7+
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
8+
*/
9+
10+
plugins {
11+
kotlin("multiplatform")
12+
id("com.android.library")
13+
`maven-publish`
14+
signing
15+
}
16+
17+
val letsPlotVersion = extra["letsPlot.version"] as String
18+
val assertjVersion = extra["assertj.version"] as String
19+
val junitVersion = extra["junit.version"] as String
20+
val espressoCoreVersion = extra["espresso.core.version"] as String
21+
22+
kotlin {
23+
jvm {
24+
compilations.all {
25+
kotlinOptions.jvmTarget = "11"
26+
}
27+
}
28+
29+
androidTarget {
30+
publishLibraryVariants("release")
31+
}
32+
33+
sourceSets {
34+
// commonMain {
35+
// dependencies {
36+
// compileOnly("org.jetbrains.skiko:skiko:$skikoVersion")
37+
//
38+
// compileOnly("org.jetbrains.lets-plot:commons:$letsPlotVersion")
39+
// compileOnly("org.jetbrains.lets-plot:datamodel:$letsPlotVersion")
40+
// compileOnly("org.jetbrains.lets-plot:plot-base:$letsPlotVersion")
41+
// compileOnly("org.jetbrains.lets-plot:plot-stem:$letsPlotVersion")
42+
// compileOnly("org.jetbrains.lets-plot:plot-builder:$letsPlotVersion")
43+
// }
44+
// }
45+
46+
// named("jvmMain") {
47+
// dependencies {
48+
// compileOnly("io.github.microutils:kotlin-logging-jvm:$kotlinLoggingVersion")
49+
// }
50+
// }
51+
52+
// named("jvmTest") {
53+
// dependencies {
54+
// implementation(kotlin("test"))
55+
// implementation("org.assertj:assertj-core:$assertjVersion")
56+
// implementation("org.jetbrains.skiko:skiko:$skikoVersion")
57+
// implementation("org.jetbrains.lets-plot:commons:$letsPlotVersion")
58+
// implementation("org.jetbrains.lets-plot:datamodel:$letsPlotVersion")
59+
// implementation("io.github.microutils:kotlin-logging:$kotlinLoggingVersion")
60+
// }
61+
// }
62+
63+
named("androidMain") {
64+
dependencies {
65+
compileOnly("org.jetbrains.lets-plot:commons:$letsPlotVersion")
66+
compileOnly("org.jetbrains.lets-plot:datamodel:$letsPlotVersion")
67+
compileOnly("org.jetbrains.lets-plot:canvas:$letsPlotVersion")
68+
compileOnly("org.jetbrains.lets-plot:plot-base:$letsPlotVersion")
69+
compileOnly("org.jetbrains.lets-plot:plot-builder:$letsPlotVersion")
70+
compileOnly("org.jetbrains.lets-plot:plot-stem:$letsPlotVersion")
71+
compileOnly("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion")
72+
}
73+
}
74+
75+
named("androidInstrumentedTest") {
76+
dependencies {
77+
implementation(kotlin("test"))
78+
implementation("androidx.test.ext:junit:$junitVersion")
79+
implementation("androidx.test.espresso:espresso-core:$espressoCoreVersion")
80+
81+
implementation("org.assertj:assertj-core:$assertjVersion")
82+
implementation("org.jetbrains.lets-plot:commons:$letsPlotVersion")
83+
implementation("org.jetbrains.lets-plot:datamodel:$letsPlotVersion")
84+
implementation("org.jetbrains.lets-plot:canvas:$letsPlotVersion")
85+
implementation("org.jetbrains.lets-plot:plot-base:$letsPlotVersion")
86+
implementation("org.jetbrains.lets-plot:plot-builder:$letsPlotVersion")
87+
implementation("org.jetbrains.lets-plot:plot-stem:$letsPlotVersion")
88+
implementation("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion")
89+
}
90+
}
91+
}
92+
}
93+
94+
android {
95+
namespace = "org.jetbrains.letsPlot.android.canvas"
96+
97+
compileSdk = (findProperty("android.compileSdk") as String).toInt()
98+
99+
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
100+
101+
defaultConfig {
102+
minSdk = (findProperty("android.minSdk") as String).toInt()
103+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
104+
}
105+
106+
buildTypes {
107+
getByName("release") {
108+
isMinifyEnabled = false // true - error: when compiling demo cant resolve classes
109+
// proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
110+
}
111+
}
112+
113+
compileOptions {
114+
sourceCompatibility = JavaVersion.VERSION_11
115+
targetCompatibility = JavaVersion.VERSION_11
116+
}
117+
118+
kotlin {
119+
jvmToolchain(11)
120+
}
121+
}
122+
123+
tasks.register("pullDebugImages") {
124+
doLast {
125+
val destDir = File(projectDir, "build/test-results/")
126+
destDir.mkdirs()
127+
128+
// 1. Load local.properties
129+
val localProperties = Properties()
130+
val localPropertiesFile = File(rootProject.projectDir, "local.properties")
131+
if (localPropertiesFile.exists()) {
132+
FileInputStream(localPropertiesFile).use { fis ->
133+
localProperties.load(fis)
134+
}
135+
}
136+
137+
// 2. Get sdk.dir from local.properties
138+
val sdkDir = localProperties.getProperty("sdk.dir") ?: System.getenv("ANDROID_HOME")
139+
?: System.getProperty("android.home")
140+
if (sdkDir == null) {
141+
throw GradleException("sdk.dir not found in local.properties and ANDROID_HOME or android.home not set")
142+
}
143+
144+
// 3. Construct adb executable path
145+
val adbPath = "$sdkDir/platform-tools/adb"
146+
val adbFile = File(adbPath)
147+
if (!adbFile.exists()) {
148+
throw GradleException("adb not found at $adbPath")
149+
}
150+
val adbExecutable = adbFile.absolutePath
151+
152+
// Get the list of connected devices using adb devices
153+
val adbDevicesOutput = ByteArrayOutputStream()
154+
exec {
155+
commandLine(adbExecutable, "devices", "-l")
156+
standardOutput = adbDevicesOutput
157+
isIgnoreExitValue = true
158+
}
159+
160+
val devicesOutput = adbDevicesOutput.toString()
161+
162+
val devices = devicesOutput.reader().readLines()
163+
.drop(1) // Skip the header line
164+
.filter { it.isNotBlank() && !it.startsWith("* daemon") } // Remove empty lines
165+
.map { it.split("\\s+".toRegex())[0] }
166+
167+
if (devices.isEmpty()) {
168+
println("No connected Android devices found.")
169+
return@doLast
170+
}
171+
172+
devices.forEach { deviceSerial ->
173+
println("Pulling images from device: $deviceSerial")
174+
175+
//The directory on device to pull from
176+
val devicePicturesDir =
177+
"/storage/emulated/0/Android/data/org.jetbrains.letsPlot.android.canvas.test/files/Pictures/"
178+
//The local directory to initially pull the images to
179+
val tempLocalDir = File(destDir, "temp_pictures")
180+
if (tempLocalDir.exists()) {
181+
tempLocalDir.deleteRecursively()
182+
}
183+
tempLocalDir.mkdirs()
184+
185+
// Pull the images from the device to the temporary directory
186+
exec {
187+
commandLine(
188+
adbExecutable,
189+
"-s",
190+
deviceSerial,
191+
"pull",
192+
devicePicturesDir,
193+
tempLocalDir.absolutePath
194+
)
195+
}
196+
197+
val tempPicturesDir = File(tempLocalDir, "Pictures")
198+
val diffImagesDir = File(destDir, "/diff_images/")
199+
if (diffImagesDir.exists()) {
200+
diffImagesDir.deleteRecursively()
201+
}
202+
diffImagesDir.mkdirs()
203+
204+
//Move files from temporary dir to destination dir
205+
tempPicturesDir.listFiles()?.forEach { file ->
206+
file.copyTo(File(diffImagesDir, file.name))
207+
}
208+
//Delete temporary dir
209+
tempLocalDir.deleteRecursively()
210+
}
211+
}
212+
}
213+
214+
215+
///////////////////////////////////////////////
216+
// Publishing
217+
///////////////////////////////////////////////
218+
219+
afterEvaluate {
220+
publishing {
221+
publications.forEach { pub ->
222+
with(pub as MavenPublication) {
223+
artifact(tasks.jarJavaDocs)
224+
225+
pom {
226+
name.set("Lets-Plot Compose - Android")
227+
description.set("Android drawing for Lets-Plot Compose plotting library.")
228+
url.set("https://github.com/JetBrains/lets-plot-compose")
229+
licenses {
230+
license {
231+
name.set("MIT")
232+
url.set("https://raw.githubusercontent.com/JetBrains/lets-plot-compose/master/LICENSE")
233+
}
234+
}
235+
developers {
236+
developer {
237+
id.set("jetbrains")
238+
name.set("JetBrains")
239+
email.set("lets-plot@jetbrains.com")
240+
}
241+
}
242+
scm {
243+
url.set("https://github.com/JetBrains/lets-plot-compose")
244+
}
245+
}
246+
}
247+
}
248+
249+
repositories {
250+
mavenLocal {
251+
url = uri("$rootDir/.maven-publish-dev-repo")
252+
}
253+
maven {
254+
// For SNAPSHOT publication use separate URL and credentials:
255+
if (version.toString().endsWith("-SNAPSHOT")) {
256+
url = uri(rootProject.project.extra["mavenSnapshotPublishUrl"].toString())
257+
258+
credentials {
259+
username = rootProject.project.extra["sonatypeUsername"].toString()
260+
password = rootProject.project.extra["sonatypePassword"].toString()
261+
}
262+
} else {
263+
url = uri(rootProject.project.extra["mavenReleasePublishUrl"].toString())
264+
}
265+
}
266+
}
267+
}
268+
}
269+
270+
signing {
271+
if (!(project.version as String).contains("SNAPSHOT")) {
272+
sign(publishing.publications)
273+
}
274+
}

0 commit comments

Comments
 (0)