Skip to content

Commit 1ca0085

Browse files
authored
Merge branch 'android:main' into java-to-kotlin
2 parents 9b488bf + 61f0adf commit 1ca0085

File tree

21 files changed

+357
-180
lines changed

21 files changed

+357
-180
lines changed

app-nia-catalog/dependencies/releaseRuntimeClasspath.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,10 @@ io.coil-kt:coil-compose-base:2.5.0
9393
io.coil-kt:coil-compose:2.5.0
9494
io.coil-kt:coil:2.5.0
9595
javax.inject:javax.inject:1
96-
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.21
96+
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.22
9797
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10
9898
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10
99-
org.jetbrains.kotlin:kotlin-stdlib:1.9.21
99+
org.jetbrains.kotlin:kotlin-stdlib:1.9.22
100100
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3
101101
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3
102102
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ dependencies {
9393
implementation(libs.androidx.core.splashscreen)
9494
implementation(libs.androidx.tracing.ktx)
9595
implementation(libs.androidx.lifecycle.runtimeCompose)
96+
implementation(libs.androidx.compose.runtime.tracing)
9697
implementation(libs.androidx.compose.material3.windowSizeClass)
9798
implementation(libs.androidx.navigation.compose)
9899
implementation(libs.androidx.profileinstaller)

app/dependencies/prodReleaseRuntimeClasspath.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ androidx.compose.material:material-ripple:1.6.1
3434
androidx.compose.runtime:runtime-android:1.6.1
3535
androidx.compose.runtime:runtime-saveable-android:1.6.1
3636
androidx.compose.runtime:runtime-saveable:1.6.1
37+
androidx.compose.runtime:runtime-tracing:1.0.0-beta01
3738
androidx.compose.runtime:runtime:1.6.1
3839
androidx.compose.ui:ui-android:1.6.1
3940
androidx.compose.ui:ui-geometry-android:1.6.1
@@ -109,6 +110,7 @@ androidx.sqlite:sqlite-framework:2.4.0
109110
androidx.sqlite:sqlite:2.4.0
110111
androidx.startup:startup-runtime:1.1.1
111112
androidx.tracing:tracing-ktx:1.3.0-alpha02
113+
androidx.tracing:tracing-perfetto:1.0.0
112114
androidx.tracing:tracing:1.3.0-alpha02
113115
androidx.vectordrawable:vectordrawable-animated:1.1.0
114116
androidx.vectordrawable:vectordrawable:1.1.0
@@ -188,10 +190,10 @@ io.github.aakira:napier-android:1.4.1
188190
io.github.aakira:napier:1.4.1
189191
javax.inject:javax.inject:1
190192
org.checkerframework:checker-qual:3.12.0
191-
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.21
193+
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.22
192194
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10
193195
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10
194-
org.jetbrains.kotlin:kotlin-stdlib:1.9.21
196+
org.jetbrains.kotlin:kotlin-stdlib:1.9.22
195197
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3
196198
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3
197199
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3

app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationUiTest.kt

Lines changed: 23 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,17 @@ package com.google.samples.apps.nowinandroid.ui
1919
import androidx.compose.foundation.layout.BoxWithConstraints
2020
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
2121
import androidx.compose.material3.windowsizeclass.WindowSizeClass
22+
import androidx.compose.runtime.Composable
2223
import androidx.compose.ui.test.assertIsDisplayed
2324
import androidx.compose.ui.test.junit4.createAndroidComposeRule
2425
import androidx.compose.ui.test.onNodeWithTag
26+
import androidx.compose.ui.unit.Dp
2527
import androidx.compose.ui.unit.DpSize
2628
import androidx.compose.ui.unit.dp
2729
import com.google.accompanist.testharness.TestHarness
2830
import com.google.samples.apps.nowinandroid.core.data.repository.CompositeUserNewsResourceRepository
2931
import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor
32+
import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor
3033
import com.google.samples.apps.nowinandroid.core.rules.GrantPostNotificationsPermissionRule
3134
import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepository
3235
import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository
@@ -81,6 +84,9 @@ class NavigationUiTest {
8184
@Inject
8285
lateinit var networkMonitor: NetworkMonitor
8386

87+
@Inject
88+
lateinit var timeZoneMonitor: TimeZoneMonitor
89+
8490
@Before
8591
fun setup() {
8692
hiltRule.inject()
@@ -91,13 +97,7 @@ class NavigationUiTest {
9197
composeTestRule.setContent {
9298
TestHarness(size = DpSize(400.dp, 400.dp)) {
9399
BoxWithConstraints {
94-
NiaApp(
95-
windowSizeClass = WindowSizeClass.calculateFromSize(
96-
DpSize(maxWidth, maxHeight),
97-
),
98-
networkMonitor = networkMonitor,
99-
userNewsResourceRepository = userNewsResourceRepository,
100-
)
100+
NiaApp(fakeAppState(maxWidth, maxHeight))
101101
}
102102
}
103103
}
@@ -111,13 +111,7 @@ class NavigationUiTest {
111111
composeTestRule.setContent {
112112
TestHarness(size = DpSize(610.dp, 400.dp)) {
113113
BoxWithConstraints {
114-
NiaApp(
115-
windowSizeClass = WindowSizeClass.calculateFromSize(
116-
DpSize(maxWidth, maxHeight),
117-
),
118-
networkMonitor = networkMonitor,
119-
userNewsResourceRepository = userNewsResourceRepository,
120-
)
114+
NiaApp(fakeAppState(maxWidth, maxHeight))
121115
}
122116
}
123117
}
@@ -131,13 +125,7 @@ class NavigationUiTest {
131125
composeTestRule.setContent {
132126
TestHarness(size = DpSize(900.dp, 400.dp)) {
133127
BoxWithConstraints {
134-
NiaApp(
135-
windowSizeClass = WindowSizeClass.calculateFromSize(
136-
DpSize(maxWidth, maxHeight),
137-
),
138-
networkMonitor = networkMonitor,
139-
userNewsResourceRepository = userNewsResourceRepository,
140-
)
128+
NiaApp(fakeAppState(maxWidth, maxHeight))
141129
}
142130
}
143131
}
@@ -151,13 +139,7 @@ class NavigationUiTest {
151139
composeTestRule.setContent {
152140
TestHarness(size = DpSize(400.dp, 500.dp)) {
153141
BoxWithConstraints {
154-
NiaApp(
155-
windowSizeClass = WindowSizeClass.calculateFromSize(
156-
DpSize(maxWidth, maxHeight),
157-
),
158-
networkMonitor = networkMonitor,
159-
userNewsResourceRepository = userNewsResourceRepository,
160-
)
142+
NiaApp(fakeAppState(maxWidth, maxHeight))
161143
}
162144
}
163145
}
@@ -171,13 +153,7 @@ class NavigationUiTest {
171153
composeTestRule.setContent {
172154
TestHarness(size = DpSize(610.dp, 500.dp)) {
173155
BoxWithConstraints {
174-
NiaApp(
175-
windowSizeClass = WindowSizeClass.calculateFromSize(
176-
DpSize(maxWidth, maxHeight),
177-
),
178-
networkMonitor = networkMonitor,
179-
userNewsResourceRepository = userNewsResourceRepository,
180-
)
156+
NiaApp(fakeAppState(maxWidth, maxHeight))
181157
}
182158
}
183159
}
@@ -191,13 +167,7 @@ class NavigationUiTest {
191167
composeTestRule.setContent {
192168
TestHarness(size = DpSize(900.dp, 500.dp)) {
193169
BoxWithConstraints {
194-
NiaApp(
195-
windowSizeClass = WindowSizeClass.calculateFromSize(
196-
DpSize(maxWidth, maxHeight),
197-
),
198-
networkMonitor = networkMonitor,
199-
userNewsResourceRepository = userNewsResourceRepository,
200-
)
170+
NiaApp(fakeAppState(maxWidth, maxHeight))
201171
}
202172
}
203173
}
@@ -211,13 +181,7 @@ class NavigationUiTest {
211181
composeTestRule.setContent {
212182
TestHarness(size = DpSize(400.dp, 1000.dp)) {
213183
BoxWithConstraints {
214-
NiaApp(
215-
windowSizeClass = WindowSizeClass.calculateFromSize(
216-
DpSize(maxWidth, maxHeight),
217-
),
218-
networkMonitor = networkMonitor,
219-
userNewsResourceRepository = userNewsResourceRepository,
220-
)
184+
NiaApp(fakeAppState(maxWidth, maxHeight))
221185
}
222186
}
223187
}
@@ -231,13 +195,7 @@ class NavigationUiTest {
231195
composeTestRule.setContent {
232196
TestHarness(size = DpSize(610.dp, 1000.dp)) {
233197
BoxWithConstraints {
234-
NiaApp(
235-
windowSizeClass = WindowSizeClass.calculateFromSize(
236-
DpSize(maxWidth, maxHeight),
237-
),
238-
networkMonitor = networkMonitor,
239-
userNewsResourceRepository = userNewsResourceRepository,
240-
)
198+
NiaApp(fakeAppState(maxWidth, maxHeight))
241199
}
242200
}
243201
}
@@ -251,18 +209,20 @@ class NavigationUiTest {
251209
composeTestRule.setContent {
252210
TestHarness(size = DpSize(900.dp, 1000.dp)) {
253211
BoxWithConstraints {
254-
NiaApp(
255-
windowSizeClass = WindowSizeClass.calculateFromSize(
256-
DpSize(maxWidth, maxHeight),
257-
),
258-
networkMonitor = networkMonitor,
259-
userNewsResourceRepository = userNewsResourceRepository,
260-
)
212+
NiaApp(fakeAppState(maxWidth, maxHeight))
261213
}
262214
}
263215
}
264216

265217
composeTestRule.onNodeWithTag("NiaNavRail").assertIsDisplayed()
266218
composeTestRule.onNodeWithTag("NiaBottomBar").assertDoesNotExist()
267219
}
220+
221+
@Composable
222+
private fun fakeAppState(maxWidth: Dp, maxHeight: Dp) = rememberNiaAppState(
223+
windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(maxWidth, maxHeight)),
224+
networkMonitor = networkMonitor,
225+
userNewsResourceRepository = userNewsResourceRepository,
226+
timeZoneMonitor = timeZoneMonitor,
227+
)
268228
}

app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ import com.google.samples.apps.nowinandroid.core.data.repository.CompositeUserNe
3434
import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepository
3535
import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository
3636
import com.google.samples.apps.nowinandroid.core.testing.util.TestNetworkMonitor
37+
import com.google.samples.apps.nowinandroid.core.testing.util.TestTimeZoneMonitor
3738
import kotlinx.coroutines.flow.collect
3839
import kotlinx.coroutines.launch
3940
import kotlinx.coroutines.test.UnconfinedTestDispatcher
4041
import kotlinx.coroutines.test.runTest
42+
import kotlinx.datetime.TimeZone
4143
import org.junit.Rule
4244
import org.junit.Test
4345
import kotlin.test.assertEquals
@@ -59,6 +61,8 @@ class NiaAppStateTest {
5961
// Create the test dependencies.
6062
private val networkMonitor = TestNetworkMonitor()
6163

64+
private val timeZoneMonitor = TestTimeZoneMonitor()
65+
6266
private val userNewsResourceRepository =
6367
CompositeUserNewsResourceRepository(TestNewsRepository(), TestUserDataRepository())
6468

@@ -78,6 +82,7 @@ class NiaAppStateTest {
7882
windowSizeClass = getCompactWindowClass(),
7983
networkMonitor = networkMonitor,
8084
userNewsResourceRepository = userNewsResourceRepository,
85+
timeZoneMonitor = timeZoneMonitor,
8186
)
8287
}
8388

@@ -100,6 +105,7 @@ class NiaAppStateTest {
100105
windowSizeClass = getCompactWindowClass(),
101106
networkMonitor = networkMonitor,
102107
userNewsResourceRepository = userNewsResourceRepository,
108+
timeZoneMonitor = timeZoneMonitor,
103109
)
104110
}
105111

@@ -118,6 +124,7 @@ class NiaAppStateTest {
118124
windowSizeClass = getCompactWindowClass(),
119125
networkMonitor = networkMonitor,
120126
userNewsResourceRepository = userNewsResourceRepository,
127+
timeZoneMonitor = timeZoneMonitor,
121128
)
122129
}
123130

@@ -134,6 +141,7 @@ class NiaAppStateTest {
134141
windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(800.dp, 800.dp)),
135142
networkMonitor = networkMonitor,
136143
userNewsResourceRepository = userNewsResourceRepository,
144+
timeZoneMonitor = timeZoneMonitor,
137145
)
138146
}
139147

@@ -150,6 +158,7 @@ class NiaAppStateTest {
150158
windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(900.dp, 1200.dp)),
151159
networkMonitor = networkMonitor,
152160
userNewsResourceRepository = userNewsResourceRepository,
161+
timeZoneMonitor = timeZoneMonitor,
153162
)
154163
}
155164

@@ -166,6 +175,7 @@ class NiaAppStateTest {
166175
windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(900.dp, 1200.dp)),
167176
networkMonitor = networkMonitor,
168177
userNewsResourceRepository = userNewsResourceRepository,
178+
timeZoneMonitor = timeZoneMonitor,
169179
)
170180
}
171181

@@ -177,6 +187,27 @@ class NiaAppStateTest {
177187
)
178188
}
179189

190+
@Test
191+
fun niaAppState_differentTZ_withTimeZoneMonitorChange() = runTest(UnconfinedTestDispatcher()) {
192+
composeTestRule.setContent {
193+
state = NiaAppState(
194+
navController = NavHostController(LocalContext.current),
195+
coroutineScope = backgroundScope,
196+
windowSizeClass = getCompactWindowClass(),
197+
networkMonitor = networkMonitor,
198+
userNewsResourceRepository = userNewsResourceRepository,
199+
timeZoneMonitor = timeZoneMonitor,
200+
)
201+
}
202+
val changedTz = TimeZone.of("Europe/Prague")
203+
backgroundScope.launch { state.currentTimeZone.collect() }
204+
timeZoneMonitor.setTimeZone(changedTz)
205+
assertEquals(
206+
changedTz,
207+
state.currentTimeZone.value,
208+
)
209+
}
210+
180211
private fun getCompactWindowClass() = WindowSizeClass.calculateFromSize(DpSize(500.dp, 300.dp))
181212
}
182213

app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import androidx.compose.runtime.mutableStateOf
3333
import androidx.compose.runtime.setValue
3434
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
3535
import androidx.lifecycle.Lifecycle
36+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
3637
import androidx.lifecycle.lifecycleScope
3738
import androidx.lifecycle.repeatOnLifecycle
3839
import androidx.metrics.performance.JankStats
@@ -42,10 +43,13 @@ import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper
4243
import com.google.samples.apps.nowinandroid.core.analytics.LocalAnalyticsHelper
4344
import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository
4445
import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor
46+
import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor
4547
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
4648
import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig
4749
import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand
50+
import com.google.samples.apps.nowinandroid.core.ui.LocalTimeZone
4851
import com.google.samples.apps.nowinandroid.ui.NiaApp
52+
import com.google.samples.apps.nowinandroid.ui.rememberNiaAppState
4953
import dagger.hilt.android.AndroidEntryPoint
5054
import kotlinx.coroutines.flow.collect
5155
import kotlinx.coroutines.flow.onEach
@@ -67,6 +71,9 @@ class MainActivity : ComponentActivity() {
6771
@Inject
6872
lateinit var networkMonitor: NetworkMonitor
6973

74+
@Inject
75+
lateinit var timeZoneMonitor: TimeZoneMonitor
76+
7077
@Inject
7178
lateinit var analyticsHelper: AnalyticsHelper
7279

@@ -126,17 +133,25 @@ class MainActivity : ComponentActivity() {
126133
onDispose {}
127134
}
128135

129-
CompositionLocalProvider(LocalAnalyticsHelper provides analyticsHelper) {
136+
val appState = rememberNiaAppState(
137+
windowSizeClass = calculateWindowSizeClass(this),
138+
networkMonitor = networkMonitor,
139+
userNewsResourceRepository = userNewsResourceRepository,
140+
timeZoneMonitor = timeZoneMonitor,
141+
)
142+
143+
val currentTimeZone by appState.currentTimeZone.collectAsStateWithLifecycle()
144+
145+
CompositionLocalProvider(
146+
LocalAnalyticsHelper provides analyticsHelper,
147+
LocalTimeZone provides currentTimeZone,
148+
) {
130149
NiaTheme(
131150
darkTheme = darkTheme,
132151
androidTheme = shouldUseAndroidTheme(uiState),
133152
disableDynamicTheming = shouldDisableDynamicTheming(uiState),
134153
) {
135-
NiaApp(
136-
networkMonitor = networkMonitor,
137-
windowSizeClass = calculateWindowSizeClass(this),
138-
userNewsResourceRepository = userNewsResourceRepository,
139-
)
154+
NiaApp(appState)
140155
}
141156
}
142157
}

0 commit comments

Comments
 (0)