Skip to content

Commit b877668

Browse files
authored
Merge branch 'develop' into dependabot/gradle/com.android.application-8.11.1
2 parents ee080df + a290c96 commit b877668

File tree

9 files changed

+570
-220
lines changed

9 files changed

+570
-220
lines changed

.circleci/config.yml

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: 2.1
22
orbs:
33
codecov: codecov/codecov@5.4.3
4-
ruby: circleci/ruby@2.0.0
4+
ruby: circleci/ruby@2.5.3
55

66
commands:
77
restore_gradle_cache:
@@ -10,10 +10,11 @@ commands:
1010
key: v1-gradle-wrapper-{{ arch }}-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}
1111
- restore_cache:
1212
key: v1-gradle-cache-{{ arch }}-{{ checksum "build.gradle.kts" }}-{{ checksum "settings.gradle.kts" }}-{{ checksum "gradle.properties" }}-{{ checksum "app/build.gradle.kts" }}-{{ checksum "gradle/libs.versions.toml" }}
13+
1314
restore_bundler_cache:
1415
steps:
1516
- restore_cache:
16-
key: v1-bundler-cache-{{ checksum "Gemfile.lock" }}
17+
key: v1-bundler-cache-{{ arch }}-{{ checksum "Gemfile.lock" }}
1718

1819
save_gradle_cache:
1920
steps:
@@ -25,41 +26,46 @@ commands:
2526
paths:
2627
- ~/.gradle/caches
2728
key: v1-gradle-cache-{{ arch }}-{{ checksum "build.gradle.kts" }}-{{ checksum "settings.gradle.kts" }}-{{ checksum "gradle.properties" }}-{{ checksum "app/build.gradle.kts" }}-{{ checksum "gradle/libs.versions.toml" }}
29+
2830
save_bundler_cache:
2931
steps:
3032
- save_cache:
3133
paths:
3234
- vendor/bundle
3335
key: v1-bundler-cache-{{ checksum "Gemfile.lock" }}
3436

37+
setup_android:
38+
steps:
39+
- checkout
40+
- restore_gradle_cache
41+
- restore_bundler_cache
42+
3543
executors:
3644
android-machine:
3745
machine:
38-
image: android:2024.01.1
46+
image: android:2024.11.1
3947
android-docker:
4048
docker:
41-
- image: cimg/android:2024.01
49+
- image: cimg/android:2025.04
4250

4351
jobs:
4452
android-test:
4553
executor: android-machine
4654
resource_class: large
4755
steps:
48-
- checkout
49-
- restore_gradle_cache
50-
- restore_bundler_cache
56+
- setup_android
5157
- ruby/install-deps:
5258
with-cache: true
5359
- run:
5460
name: Fastlane - run all tests with coverage report
5561
command: |
5662
bundle exec fastlane testDev
57-
bundle exec fastlane lint
63+
- run: ./gradlew lintDebug
5864
- save_gradle_cache
5965
- save_bundler_cache
6066
- run:
6167
name: Analyze on SonarCloud
62-
command: ./gradlew lintDebug sonar
68+
command: ./gradlew sonar
6369
- codecov/upload:
6470
files: app/build/mergedReportDir/jacocoTestReport/jacocoTestReport.xml
6571
- store_test_results:
@@ -71,14 +77,15 @@ jobs:
7177
executor: android-docker
7278
resource_class: large
7379
steps:
74-
- checkout
75-
- restore_gradle_cache
80+
- setup_android
7681
- run:
7782
name: Prepare Fastlane
7883
command: sudo bundle update
7984
- run:
8085
name: Distribute to Firebase AppTester Dev
8186
command: bundle exec fastlane distDev
87+
- save_gradle_cache
88+
- save_bundler_cache
8289
- store_artifacts:
8390
path: /home/circleci/project/app/build/outputs/apk/debug/app-debug.apk
8491
destination: fastlane-output-debug
@@ -87,8 +94,7 @@ jobs:
8794
executor: android-docker
8895
resource_class: large
8996
steps:
90-
- checkout
91-
- restore_gradle_cache
97+
- setup_android
9298
- run:
9399
name: Prepare Fastlane
94100
command: sudo bundle update
@@ -98,6 +104,8 @@ jobs:
98104
- run:
99105
name: Distribute to Firebase AppTester Prod
100106
command: bundle exec fastlane distProd
107+
- save_gradle_cache
108+
- save_bundler_cache
101109
- store_artifacts:
102110
path: /home/circleci/project/app/build/outputs/bundle/release/app-release.aab
103111
destination: fastlane-output-release
@@ -108,4 +116,7 @@ workflows:
108116
- android-test:
109117
context: SonarCloud
110118
- distribute-dev
111-
- distribute-internal-testing
119+
- distribute-internal-testing:
120+
requires:
121+
- android-test
122+

Gemfile.lock

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ GEM
1010
artifactory (3.0.17)
1111
atomos (0.1.3)
1212
aws-eventstream (1.4.0)
13-
aws-partitions (1.1125.0)
14-
aws-sdk-core (3.226.2)
13+
aws-partitions (1.1131.0)
14+
aws-sdk-core (3.226.3)
1515
aws-eventstream (~> 1, >= 1.3.0)
1616
aws-partitions (~> 1, >= 1.992.0)
1717
aws-sigv4 (~> 1.9)
@@ -21,7 +21,7 @@ GEM
2121
aws-sdk-kms (1.106.0)
2222
aws-sdk-core (~> 3, >= 3.225.0)
2323
aws-sigv4 (~> 1.5)
24-
aws-sdk-s3 (1.192.0)
24+
aws-sdk-s3 (1.193.0)
2525
aws-sdk-core (~> 3, >= 3.225.0)
2626
aws-sdk-kms (~> 1)
2727
aws-sigv4 (~> 1.5)
@@ -164,13 +164,13 @@ GEM
164164
httpclient (2.9.0)
165165
mutex_m
166166
jmespath (1.6.2)
167-
json (2.12.2)
167+
json (2.13.0)
168168
jwt (2.10.2)
169169
base64
170170
logger (1.7.0)
171171
mini_magick (4.13.2)
172172
mini_mime (1.1.5)
173-
multi_json (1.15.0)
173+
multi_json (1.17.0)
174174
multipart-post (2.4.1)
175175
mutex_m (0.3.0)
176176
nanaimo (0.4.0)

app/build.gradle.kts

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import java.io.FileInputStream
2-
import java.util.*
2+
import java.util.Base64
3+
import java.util.Properties
34

45
plugins {
56
id("com.android.application")
@@ -110,6 +111,35 @@ tasks.register<JacocoReport>("jacocoTestReport") {
110111
csv.required.set(false)
111112
}
112113

114+
val fileFilter = listOf(
115+
"**/R.class",
116+
"**/MainActivity.*",
117+
"**/R$*.class", "**/BuildConfig.*", "**/Manifest*.*",
118+
"**/*Test*.*", "android/**/*.*",
119+
"**/Dagger*.*", "**/*_Hilt*.*", "**/*Hilt*.*",
120+
)
121+
val kotlinDebugTree = fileTree(layout.buildDirectory.dir("tmp/kotlin-classes/debug")) { exclude(fileFilter) }
122+
val mainKotlinSrc = layout.projectDirectory.dir("src/main/kotlin")
123+
sourceDirectories.from(files(mainKotlinSrc))
124+
classDirectories.from(files(kotlinDebugTree))
125+
executionData.from(fileTree(layout.buildDirectory) {
126+
include(
127+
"outputs/managed_device_code_coverage/**/*.ec",
128+
"outputs/unit_test_code_coverage/**/*.exec",
129+
)
130+
})
131+
}
132+
133+
tasks.register<JacocoReport>("jacocoUiOnly") {
134+
135+
dependsOn("pixel2api30DebugAndroidTest")
136+
137+
reports {
138+
xml.required.set(true)
139+
html.required.set(true)
140+
csv.required.set(false)
141+
}
142+
113143
val fileFilter = listOf(
114144
"**/R.class", "**/R$*.class", "**/BuildConfig.*", "**/Manifest*.*",
115145
"**/*Test*.*", "android/**/*.*",
@@ -123,7 +153,6 @@ tasks.register<JacocoReport>("jacocoTestReport") {
123153
classDirectories.from(files(javaDebugTree, kotlinDebugTree))
124154
executionData.from(fileTree(layout.buildDirectory) {
125155
include(
126-
"outputs/unit_test_code_coverage/**/*.exec",
127156
"outputs/managed_device_code_coverage/**/*.ec",
128157
"outputs/managed_device_code_coverage/**/*.exec"
129158
)
@@ -224,7 +253,6 @@ dependencies {
224253

225254
// Firebase
226255
implementation(platform(libs.firebase.bom))
227-
implementation(libs.firebase.analytics.ktx)
228256
implementation(libs.firebase.crashlytics.ktx)
229257

230258
// Dependency Injection

app/src/androidTest/java/org/kabiri/android/usbterminal/MainActivityAndroidTest.kt

Lines changed: 38 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,15 @@ import org.junit.Rule
1515
import org.junit.Test
1616
import org.junit.runner.RunWith
1717

18-
1918
@RunWith(AndroidJUnit4::class)
2019
internal class MainActivityAndroidTest {
21-
2220
@get:Rule
2321
var rule = activityScenarioRule<MainActivity>()
2422

2523
private fun ensureMenuIsAccessible(
2624
menuItemId: Int,
2725
onVisible: () -> Unit,
28-
onOverflow: () -> Unit
26+
onOverflow: () -> Unit,
2927
) {
3028
try {
3129
// Try to find the menu item first
@@ -49,57 +47,53 @@ internal class MainActivityAndroidTest {
4947
}
5048

5149
@Test
52-
fun checkActionMenuItemSettingsIsDisplayed() = ensureMenuIsAccessible(
53-
menuItemId = R.id.actionSettings,
54-
onVisible = {
55-
56-
// assert
57-
onView(withId(R.id.actionSettings)).check(matches(isDisplayed()))
58-
},
59-
onOverflow = {
60-
61-
// assert
62-
onView(withText(R.string.title_settings)).check(matches(isDisplayed()))
63-
}
64-
)
50+
fun checkActionMenuItemSettingsIsDisplayed() =
51+
ensureMenuIsAccessible(
52+
menuItemId = R.id.actionSettings,
53+
onVisible = {
54+
// assert
55+
onView(withId(R.id.actionSettings)).check(matches(isDisplayed()))
56+
},
57+
onOverflow = {
58+
// assert
59+
onView(withText(R.string.title_settings)).check(matches(isDisplayed()))
60+
},
61+
)
6562

6663
@Test
67-
fun checkActionMenuItemConnectIsDisplayed() = ensureMenuIsAccessible(
68-
menuItemId = R.id.actionSettings,
69-
onVisible = {
70-
71-
// assert
72-
onView(withId(R.id.actionConnect)).check(matches(isDisplayed()))
73-
},
74-
onOverflow = {
75-
76-
// assert
77-
onView(withText(R.string.title_connect)).check(matches(isDisplayed()))
78-
}
79-
)
64+
fun checkActionMenuItemConnectIsDisplayed() =
65+
ensureMenuIsAccessible(
66+
menuItemId = R.id.actionSettings,
67+
onVisible = {
68+
// assert
69+
onView(withId(R.id.actionConnect)).check(matches(isDisplayed()))
70+
},
71+
onOverflow = {
72+
// assert
73+
onView(withText(R.string.title_connect)).check(matches(isDisplayed()))
74+
},
75+
)
8076

8177
@Test
82-
fun checkActionMenuItemDisconnectIsDisplayed() = ensureMenuIsAccessible(
83-
menuItemId = R.id.actionSettings,
84-
onVisible = {
85-
86-
// assert
87-
onView(withId(R.id.actionDisconnect)).check(matches(isDisplayed()))
88-
},
89-
onOverflow = {
90-
91-
// assert
92-
onView(withText(R.string.title_disconnect)).check(matches(isDisplayed()))
93-
}
94-
)
78+
fun checkActionMenuItemDisconnectIsDisplayed() =
79+
ensureMenuIsAccessible(
80+
menuItemId = R.id.actionSettings,
81+
onVisible = {
82+
// assert
83+
onView(withId(R.id.actionDisconnect)).check(matches(isDisplayed()))
84+
},
85+
onOverflow = {
86+
// assert
87+
onView(withText(R.string.title_disconnect)).check(matches(isDisplayed()))
88+
},
89+
)
9590

9691
@Test
9792
fun clickingSettingsOpensSettingsBottomSheet() {
9893
// arrange
9994
ensureMenuIsAccessible(
10095
menuItemId = R.id.actionSettings,
10196
onVisible = {
102-
10397
// act
10498
onView(withId(R.id.actionSettings)).perform(click())
10599

@@ -112,7 +106,7 @@ internal class MainActivityAndroidTest {
112106

113107
// assert
114108
onView(withId(R.id.composeViewSettingContent)).check(matches(isDisplayed()))
115-
}
109+
},
116110
)
117111
}
118112
}

app/src/main/java/org/kabiri/android/usbterminal/MainActivity.kt

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,21 @@ import androidx.core.view.WindowInsetsCompat
1919
import androidx.lifecycle.lifecycleScope
2020
import dagger.hilt.android.AndroidEntryPoint
2121
import kotlinx.coroutines.launch
22-
import org.kabiri.android.usbterminal.util.scrollToLastLine
2322
import org.kabiri.android.usbterminal.ui.setting.SettingModalBottomSheet
2423
import org.kabiri.android.usbterminal.ui.setting.SettingViewModel
24+
import org.kabiri.android.usbterminal.util.scrollToLastLine
2525
import org.kabiri.android.usbterminal.viewmodel.MainActivityViewModel
2626

27+
private const val TAG = "MainActivity"
28+
2729
@AndroidEntryPoint
2830
class MainActivity : AppCompatActivity() {
29-
30-
companion object {
31-
private const val TAG = "MainActivity"
32-
}
33-
3431
private val viewModel by viewModels<MainActivityViewModel>()
3532
private val settingViewModel by viewModels<SettingViewModel>()
3633

3734
override fun onCreate(savedInstanceState: Bundle?) {
3835
super.onCreate(savedInstanceState)
36+
viewModel.startObservingUsbDevice()
3937
setContentView(R.layout.activity_main)
4038

4139
// avoid system navbar or soft keyboard overlapping the content.
@@ -67,9 +65,11 @@ class MainActivity : AppCompatActivity() {
6765
fun sendCommand() {
6866
val input = etInput.text.toString()
6967
// append the input to console
70-
if (viewModel.serialWrite(input))
71-
etInput.setText("") // clear the terminal input.
72-
else Log.e(TAG, "The message was not sent to Arduino")
68+
if (viewModel.serialWrite(input)) {
69+
etInput.setText("")
70+
} else {
71+
Log.e(TAG, "The message was not sent to Arduino")
72+
}
7373
}
7474

7575
// send the command to device when the button is clicked.
@@ -83,7 +83,9 @@ class MainActivity : AppCompatActivity() {
8383
event.action == KeyEvent.ACTION_DOWN)) {
8484
sendCommand()
8585
true
86-
} else false
86+
} else {
87+
false
88+
}
8789
}
8890
}
8991

0 commit comments

Comments
 (0)