Merge branch 'android:main' into main

pull/2092/head
Pichai Takengrach 6 months ago committed by GitHub
commit d691c81c15
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -10,7 +10,7 @@ Thanks for submitting a pull request. To accept your pull request we need you do
**Ensure tests pass and code is formatted correctly** **Ensure tests pass and code is formatted correctly**
- Run local tests on the `DemoDebug` variant by running `./gradlew testDemoDebug` - Run local tests on the `DemoDebug` variant by running `./gradlew testDemoDebug`
- Fix code formatting: `./gradlew --init-script gradle/init.gradle.kts spotlessApply` - Fix code formatting: `./gradlew spotlessApply`
**Add a description** **Add a description**

@ -48,7 +48,7 @@ jobs:
run: ./gradlew :build-logic:convention:check run: ./gradlew :build-logic:convention:check
- name: Check spotless - name: Check spotless
run: ./gradlew spotlessCheck --init-script gradle/init.gradle.kts --no-configuration-cache run: ./gradlew spotlessCheck
- name: Check Dependency Guard - name: Check Dependency Guard
id: dependencyguard_verify id: dependencyguard_verify

@ -4,7 +4,6 @@
<option name="executionName" /> <option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" /> <option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="--init-script=gradle/init.gradle.kts" />
<option name="taskDescriptions"> <option name="taskDescriptions">
<list /> <list />
</option> </option>

@ -26,7 +26,7 @@ The main Android app lives in the `app/` folder. Feature modules live in `featur
The app and Android libraries have two product flavors: `demo` and `prod`, and two build types: `debug` and `release`. The app and Android libraries have two product flavors: `demo` and `prod`, and two build types: `debug` and `release`.
- Build: `./gradlew assemble{Variant}`. Typically `assembleDemoDebug`. - Build: `./gradlew assemble{Variant}`. Typically `assembleDemoDebug`.
- Fix linting/formatting: `./gradlew --init-script gradle/init.gradle.kts spotlessApply` - Fix linting/formatting: `./gradlew spotlessApply`
- Run local tests: `./gradlew {variant}Test` - Run local tests: `./gradlew {variant}Test`
- Run single test: `./gradlew {variant}Test --tests "com.example.myapp.MyTestClass"` - Run single test: `./gradlew {variant}Test --tests "com.example.myapp.MyTestClass"`
- Run local screenshot tests: `./gradlew verifyRoborazziDemoDebug` - Run local screenshot tests: `./gradlew verifyRoborazziDemoDebug`

@ -36,4 +36,4 @@
</activity> </activity>
</application> </application>
</manifest> </manifest>

@ -18,4 +18,4 @@
<background android:drawable="@drawable/ic_launcher_background"/> <background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground" /> <monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>

@ -18,4 +18,4 @@
<background android:drawable="@drawable/ic_launcher_background"/> <background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground" /> <monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>

@ -16,4 +16,4 @@
--> -->
<resources> <resources>
<string name="app_name">NiA Catalog</string> <string name="app_name">NiA Catalog</string>
</resources> </resources>

@ -16,4 +16,4 @@
--> -->
<resources> <resources>
<style name="Theme.NiaCatalog" parent="android:Theme.Material.Light.NoActionBar" /> <style name="Theme.NiaCatalog" parent="android:Theme.Material.Light.NoActionBar" />
</resources> </resources>

@ -54,7 +54,7 @@ graph TB
:core:data[data]:::android-library :core:data[data]:::android-library
:core:database[database]:::android-library :core:database[database]:::android-library
:core:datastore[datastore]:::android-library :core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library :core:datastore-proto[datastore-proto]:::jvm-library
:core:designsystem[designsystem]:::android-library :core:designsystem[designsystem]:::android-library
:core:domain[domain]:::android-library :core:domain[domain]:::android-library
:core:model[model]:::jvm-library :core:model[model]:::jvm-library

@ -18,7 +18,7 @@ package com.google.samples.apps.nowinandroid.util
import android.util.Log import android.util.Log
import androidx.profileinstaller.ProfileVerifier import androidx.profileinstaller.ProfileVerifier
import com.google.samples.apps.nowinandroid.core.network.di.ApplicationScope import com.google.samples.apps.nowinandroid.core.common.network.di.ApplicationScope
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.guava.await import kotlinx.coroutines.guava.await
import kotlinx.coroutines.launch import kotlinx.coroutines.launch

@ -18,4 +18,4 @@
<background android:drawable="@drawable/ic_launcher_background"/> <background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground" /> <monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>

@ -18,4 +18,4 @@
<background android:drawable="@drawable/ic_launcher_background"/> <background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground" /> <monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>

@ -23,4 +23,4 @@
android:name="firebase_analytics_collection_deactivated" android:name="firebase_analytics_collection_deactivated"
android:value="false" /> android:value="false" />
</application> </application>
</manifest> </manifest>

@ -54,7 +54,7 @@ graph TB
:core:data[data]:::android-library :core:data[data]:::android-library
:core:database[database]:::android-library :core:database[database]:::android-library
:core:datastore[datastore]:::android-library :core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library :core:datastore-proto[datastore-proto]:::jvm-library
:core:designsystem[designsystem]:::android-library :core:designsystem[designsystem]:::android-library
:core:domain[domain]:::android-library :core:domain[domain]:::android-library
:core:model[model]:::jvm-library :core:model[model]:::jvm-library

@ -45,6 +45,7 @@ dependencies {
compileOnly(libs.kotlin.gradlePlugin) compileOnly(libs.kotlin.gradlePlugin)
compileOnly(libs.ksp.gradlePlugin) compileOnly(libs.ksp.gradlePlugin)
compileOnly(libs.room.gradlePlugin) compileOnly(libs.room.gradlePlugin)
compileOnly(libs.spotless.gradlePlugin)
implementation(libs.truth) implementation(libs.truth)
lintChecks(libs.androidx.lint.gradle) lintChecks(libs.androidx.lint.gradle)
} }

@ -1,17 +1,17 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import com.android.build.api.dsl.ApplicationExtension import com.android.build.api.dsl.ApplicationExtension

@ -1,17 +1,17 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import com.android.build.api.dsl.ApplicationExtension import com.android.build.api.dsl.ApplicationExtension
@ -20,12 +20,13 @@ import com.google.samples.apps.nowinandroid.configureBadgingTasks
import com.google.samples.apps.nowinandroid.configureGradleManagedDevices import com.google.samples.apps.nowinandroid.configureGradleManagedDevices
import com.google.samples.apps.nowinandroid.configureKotlinAndroid import com.google.samples.apps.nowinandroid.configureKotlinAndroid
import com.google.samples.apps.nowinandroid.configurePrintApksTask import com.google.samples.apps.nowinandroid.configurePrintApksTask
import com.google.samples.apps.nowinandroid.configureSpotlessForAndroid
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.configure
class AndroidApplicationConventionPlugin : Plugin<Project> { abstract class AndroidApplicationConventionPlugin : Plugin<Project> {
override fun apply(target: Project) { override fun apply(target: Project) {
with(target) { with(target) {
apply(plugin = "com.android.application") apply(plugin = "com.android.application")
@ -42,6 +43,7 @@ class AndroidApplicationConventionPlugin : Plugin<Project> {
configurePrintApksTask(this) configurePrintApksTask(this)
configureBadgingTasks(this) configureBadgingTasks(this)
} }
configureSpotlessForAndroid()
} }
} }
} }

@ -1,17 +1,17 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import com.android.build.api.dsl.ApplicationExtension import com.android.build.api.dsl.ApplicationExtension
@ -41,7 +41,7 @@ class AndroidApplicationFirebaseConventionPlugin : Plugin<Project> {
datastore-proto brings in protobuf dependencies. These are the source of truth datastore-proto brings in protobuf dependencies. These are the source of truth
for Now in Android. for Now in Android.
That's why the duplicate classes from below dependencies are excluded. That's why the duplicate classes from below dependencies are excluded.
*/ */
exclude(group = "com.google.protobuf", module = "protobuf-javalite") exclude(group = "com.google.protobuf", module = "protobuf-javalite")
exclude(group = "com.google.firebase", module = "protolite-well-known-types") exclude(group = "com.google.firebase", module = "protolite-well-known-types")
} }

@ -1,17 +1,17 @@
/* /*
* Copyright 2023 The Android Open Source Project * Copyright 2023 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import com.android.build.api.dsl.ApplicationExtension import com.android.build.api.dsl.ApplicationExtension
@ -28,4 +28,4 @@ class AndroidApplicationFlavorsConventionPlugin : Plugin<Project> {
} }
} }
} }
} }

@ -1,17 +1,17 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import com.android.build.api.dsl.ApplicationExtension import com.android.build.api.dsl.ApplicationExtension

@ -1,20 +1,19 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import com.google.samples.apps.nowinandroid.libs
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.apply

@ -1,17 +1,17 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import com.android.build.api.dsl.LibraryExtension import com.android.build.api.dsl.LibraryExtension

@ -1,17 +1,17 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import com.android.build.api.dsl.LibraryExtension import com.android.build.api.dsl.LibraryExtension

@ -1,17 +1,17 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import com.android.build.api.dsl.LibraryExtension import com.android.build.api.dsl.LibraryExtension
@ -20,6 +20,7 @@ import com.google.samples.apps.nowinandroid.configureFlavors
import com.google.samples.apps.nowinandroid.configureGradleManagedDevices import com.google.samples.apps.nowinandroid.configureGradleManagedDevices
import com.google.samples.apps.nowinandroid.configureKotlinAndroid import com.google.samples.apps.nowinandroid.configureKotlinAndroid
import com.google.samples.apps.nowinandroid.configurePrintApksTask import com.google.samples.apps.nowinandroid.configurePrintApksTask
import com.google.samples.apps.nowinandroid.configureSpotlessForAndroid
import com.google.samples.apps.nowinandroid.disableUnnecessaryAndroidTests import com.google.samples.apps.nowinandroid.disableUnnecessaryAndroidTests
import com.google.samples.apps.nowinandroid.libs import com.google.samples.apps.nowinandroid.libs
import org.gradle.api.Plugin import org.gradle.api.Plugin
@ -28,7 +29,7 @@ import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.dependencies
class AndroidLibraryConventionPlugin : Plugin<Project> { abstract class AndroidLibraryConventionPlugin : Plugin<Project> {
override fun apply(target: Project) { override fun apply(target: Project) {
with(target) { with(target) {
apply(plugin = "com.android.library") apply(plugin = "com.android.library")
@ -52,6 +53,7 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
configurePrintApksTask(this) configurePrintApksTask(this)
disableUnnecessaryAndroidTests(target) disableUnnecessaryAndroidTests(target)
} }
configureSpotlessForAndroid()
dependencies { dependencies {
"androidTestImplementation"(libs.findLibrary("kotlin.test").get()) "androidTestImplementation"(libs.findLibrary("kotlin.test").get())
"testImplementation"(libs.findLibrary("kotlin.test").get()) "testImplementation"(libs.findLibrary("kotlin.test").get())

@ -1,17 +1,17 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import com.android.build.api.dsl.LibraryExtension import com.android.build.api.dsl.LibraryExtension

@ -1,17 +1,17 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import com.android.build.api.dsl.ApplicationExtension import com.android.build.api.dsl.ApplicationExtension

@ -1,17 +1,17 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import androidx.room.gradle.RoomExtension import androidx.room.gradle.RoomExtension

@ -1,17 +1,17 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import com.android.build.api.dsl.TestExtension import com.android.build.api.dsl.TestExtension

@ -1,17 +1,17 @@
/* /*
* Copyright 2023 The Android Open Source Project * Copyright 2023 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import com.android.build.gradle.api.AndroidBasePlugin import com.android.build.gradle.api.AndroidBasePlugin

@ -1,33 +1,35 @@
/* /*
* Copyright 2023 The Android Open Source Project * Copyright 2023 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import com.google.samples.apps.nowinandroid.configureKotlinJvm import com.google.samples.apps.nowinandroid.configureKotlinJvm
import com.google.samples.apps.nowinandroid.configureSpotlessForJvm
import com.google.samples.apps.nowinandroid.libs import com.google.samples.apps.nowinandroid.libs
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.dependencies
class JvmLibraryConventionPlugin : Plugin<Project> { abstract class JvmLibraryConventionPlugin : Plugin<Project> {
override fun apply(target: Project) { override fun apply(target: Project) {
with(target) { with(target) {
apply(plugin = "org.jetbrains.kotlin.jvm") apply(plugin = "org.jetbrains.kotlin.jvm")
apply(plugin = "nowinandroid.android.lint") apply(plugin = "nowinandroid.android.lint")
configureKotlinJvm() configureKotlinJvm()
configureSpotlessForJvm()
dependencies { dependencies {
"testImplementation"(libs.findLibrary("kotlin.test").get()) "testImplementation"(libs.findLibrary("kotlin.test").get())
} }

@ -15,12 +15,24 @@
*/ */
import com.google.samples.apps.nowinandroid.configureGraphTasks import com.google.samples.apps.nowinandroid.configureGraphTasks
import com.google.samples.apps.nowinandroid.configureSpotlessForRootProject
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.configuration.BuildFeatures
import javax.inject.Inject
abstract class RootPlugin : Plugin<Project> {
@get:Inject abstract val buildFeatures: BuildFeatures
class RootPlugin : Plugin<Project> {
override fun apply(target: Project) { override fun apply(target: Project) {
require(target.path == ":") require(target.path == ":")
target.subprojects { configureGraphTasks() } if (!buildFeatures.isIsolatedProjectsEnabled()) {
target.subprojects { configureGraphTasks() }
}
target.configureSpotlessForRootProject()
} }
} }
private fun BuildFeatures.isIsolatedProjectsEnabled(): Boolean {
return isolatedProjects.active.getOrElse(false)
}

@ -1,17 +1,17 @@
/* /*
* Copyright 2023 The Android Open Source Project * Copyright 2023 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.samples.apps.nowinandroid package com.google.samples.apps.nowinandroid
@ -30,6 +30,6 @@ import org.gradle.api.Project
internal fun LibraryAndroidComponentsExtension.disableUnnecessaryAndroidTests( internal fun LibraryAndroidComponentsExtension.disableUnnecessaryAndroidTests(
project: Project, project: Project,
) = beforeVariants { ) = beforeVariants {
it.androidTest.enable = it.androidTest.enable it.androidTest.enable = it.androidTest.enable &&
&& project.projectDir.resolve("src/androidTest").exists() project.projectDir.resolve("src/androidTest").exists()
} }

@ -1,17 +1,17 @@
/* /*
* Copyright 2023 The Android Open Source Project * Copyright 2023 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.samples.apps.nowinandroid package com.google.samples.apps.nowinandroid
@ -123,7 +123,6 @@ fun Project.configureBadgingTasks(
badging = project.layout.buildDirectory.file( badging = project.layout.buildDirectory.file(
"outputs/apk_from_bundle/${variant.name}/${variant.name}-badging.txt", "outputs/apk_from_bundle/${variant.name}/${variant.name}-badging.txt",
) )
} }
val updateBadgingTaskName = "update${capitalizedVariantName}Badging" val updateBadgingTaskName = "update${capitalizedVariantName}Badging"
@ -141,7 +140,6 @@ fun Project.configureBadgingTasks(
this.updateBadgingTaskName = updateBadgingTaskName this.updateBadgingTaskName = updateBadgingTaskName
output = project.layout.buildDirectory.dir("intermediates/$checkBadgingTaskName") output = project.layout.buildDirectory.dir("intermediates/$checkBadgingTaskName")
} }
} }
} }

@ -1,17 +1,17 @@
/* /*
* Copyright 2023 The Android Open Source Project * Copyright 2023 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.samples.apps.nowinandroid package com.google.samples.apps.nowinandroid
@ -34,7 +34,6 @@ internal fun configureGradleManagedDevices(
val allDevices = listOf(pixel4, pixel6, pixelC) val allDevices = listOf(pixel4, pixel6, pixelC)
val ciDevices = listOf(pixel4, pixelC) val ciDevices = listOf(pixel4, pixelC)
commonExtension.testOptions.apply { commonExtension.testOptions.apply {
@Suppress("UnstableApiUsage") @Suppress("UnstableApiUsage")
managedDevices { managedDevices {

@ -17,12 +17,10 @@
package com.google.samples.apps.nowinandroid package com.google.samples.apps.nowinandroid
import com.android.build.api.artifact.ScopedArtifact import com.android.build.api.artifact.ScopedArtifact
import com.android.build.api.dsl.BuildType
import com.android.build.api.dsl.CommonExtension import com.android.build.api.dsl.CommonExtension
import com.android.build.api.variant.AndroidComponentsExtension import com.android.build.api.variant.AndroidComponentsExtension
import com.android.build.api.variant.ScopedArtifacts import com.android.build.api.variant.ScopedArtifacts
import com.android.build.api.variant.SourceDirectories import com.android.build.api.variant.SourceDirectories
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.Directory import org.gradle.api.file.Directory
import org.gradle.api.file.RegularFile import org.gradle.api.file.RegularFile
@ -86,7 +84,6 @@ internal fun Project.configureJacoco(
"create${variant.name.capitalize()}CombinedCoverageReport", "create${variant.name.capitalize()}CombinedCoverageReport",
JacocoReport::class, JacocoReport::class,
) { ) {
classDirectories.setFrom( classDirectories.setFrom(
allJars, allJars,
allDirectories.map { dirs -> allDirectories.map { dirs ->
@ -107,7 +104,7 @@ internal fun Project.configureJacoco(
sourceDirectories.setFrom( sourceDirectories.setFrom(
files( files(
variant.sources.java.toFilePaths(), variant.sources.java.toFilePaths(),
variant.sources.kotlin.toFilePaths() variant.sources.kotlin.toFilePaths(),
), ),
) )
@ -120,7 +117,6 @@ internal fun Project.configureJacoco(
) )
} }
variant.artifacts.forScope(ScopedArtifacts.Scope.PROJECT) variant.artifacts.forScope(ScopedArtifacts.Scope.PROJECT)
.use(reportTask) .use(reportTask)
.toGet( .toGet(

@ -103,7 +103,7 @@ private inline fun <reified T : KotlinBaseExtension> Project.configureKotlin() =
* The binary signature changes. The error on the declaration is no longer reported. * The binary signature changes. The error on the declaration is no longer reported.
* '-Xconsistent-data-class-copy-visibility' compiler flag and ConsistentCopyVisibility annotation are now unnecessary. * '-Xconsistent-data-class-copy-visibility' compiler flag and ConsistentCopyVisibility annotation are now unnecessary.
*/ */
"-Xconsistent-data-class-copy-visibility" "-Xconsistent-data-class-copy-visibility",
) )
} }
} }

@ -1,17 +1,17 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.samples.apps.nowinandroid package com.google.samples.apps.nowinandroid

@ -1,3 +1,19 @@
/*
* Copyright 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid package com.google.samples.apps.nowinandroid
import com.android.build.api.dsl.ApplicationExtension import com.android.build.api.dsl.ApplicationExtension
@ -8,7 +24,7 @@ import org.gradle.kotlin.dsl.invoke
@Suppress("EnumEntryName") @Suppress("EnumEntryName")
enum class FlavorDimension { enum class FlavorDimension {
contentType contentType,
} }
// The content for the app can either come from local static data which is useful for demo // The content for the app can either come from local static data which is useful for demo

@ -1,17 +1,17 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.samples.apps.nowinandroid package com.google.samples.apps.nowinandroid
@ -49,7 +49,9 @@ internal fun Project.configurePrintApksTask(extension: AndroidComponentsExtensio
javaSources.zip(kotlinSources) { javaDirs, kotlinDirs -> javaSources.zip(kotlinSources) { javaDirs, kotlinDirs ->
javaDirs + kotlinDirs javaDirs + kotlinDirs
} }
} else javaSources ?: kotlinSources } else {
javaSources ?: kotlinSources
}
if (artifact != null && testSources != null) { if (artifact != null && testSources != null) {
tasks.register( tasks.register(
@ -96,8 +98,9 @@ internal abstract class PrintApkLocationTask : DefaultTask() {
val builtArtifacts = builtArtifactsLoader.get().load(apkFolder.get()) val builtArtifacts = builtArtifactsLoader.get().load(apkFolder.get())
?: throw RuntimeException("Cannot load APKs") ?: throw RuntimeException("Cannot load APKs")
if (builtArtifacts.elements.size != 1) if (builtArtifacts.elements.size != 1) {
throw RuntimeException("Expected one APK !") throw RuntimeException("Expected one APK !")
}
val apk = File(builtArtifacts.elements.single().outputFile).toPath() val apk = File(builtArtifacts.elements.single().outputFile).toPath()
println(apk) println(apk)
} }

@ -1,17 +1,17 @@
/* /*
* Copyright 2023 The Android Open Source Project * Copyright 2023 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.samples.apps.nowinandroid package com.google.samples.apps.nowinandroid

@ -0,0 +1,80 @@
/*
* Copyright 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid
import com.diffplug.gradle.spotless.SpotlessExtension
import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure
internal fun Project.configureSpotlessForAndroid() {
configureSpotlessCommon()
extensions.configure<SpotlessExtension> {
format("xml") {
target("src/**/*.xml")
// Look for the first XML tag that isn't a comment (<!--) or the xml declaration (<?xml)
licenseHeaderFile(rootDir.resolve("spotless/copyright.xml"), "(<[^!?])")
endWithNewline()
}
}
}
internal fun Project.configureSpotlessForJvm() {
configureSpotlessCommon()
}
internal fun Project.configureSpotlessForRootProject() {
apply(plugin = "com.diffplug.spotless")
extensions.configure<SpotlessExtension> {
kotlin {
target("build-logic/convention/src/**/*.kt")
ktlint(libs.findVersion("ktlint").get().requiredVersion).editorConfigOverride(
mapOf("android" to "true"),
)
licenseHeaderFile(rootDir.resolve("spotless/copyright.kt"))
endWithNewline()
}
format("kts") {
target("*.kts")
target("build-logic/*.kts")
target("build-logic/convention/*.kts")
// Look for the first line that doesn't have a block comment (assumed to be the license)
licenseHeaderFile(rootDir.resolve("spotless/copyright.kts"), "(^(?![\\/ ]\\*).*$)")
endWithNewline()
}
}
}
private fun Project.configureSpotlessCommon() {
apply(plugin = "com.diffplug.spotless")
extensions.configure<SpotlessExtension> {
kotlin {
target("src/**/*.kt")
ktlint(libs.findVersion("ktlint").get().requiredVersion).editorConfigOverride(
mapOf("android" to "true"),
)
licenseHeaderFile(rootDir.resolve("spotless/copyright.kt"))
endWithNewline()
}
format("kts") {
target("*.kts")
// Look for the first line that doesn't have a block comment (assumed to be the license)
licenseHeaderFile(rootDir.resolve("spotless/copyright.kts"), "(^(?![\\/ ]\\*).*$)")
endWithNewline()
}
}
}

@ -38,5 +38,6 @@ plugins {
alias(libs.plugins.roborazzi) apply false alias(libs.plugins.roborazzi) apply false
alias(libs.plugins.google.osslicenses) apply false alias(libs.plugins.google.osslicenses) apply false
alias(libs.plugins.room) apply false alias(libs.plugins.room) apply false
alias(libs.plugins.spotless) apply false
alias(libs.plugins.nowinandroid.root) alias(libs.plugins.nowinandroid.root)
} }

@ -14,4 +14,4 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<manifest /> <manifest />

@ -22,4 +22,4 @@ dependencies {
implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.coroutines.core)
testImplementation(libs.kotlinx.coroutines.test) testImplementation(libs.kotlinx.coroutines.test)
testImplementation(libs.turbine) testImplementation(libs.turbine)
} }

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.google.samples.apps.nowinandroid.core.network package com.google.samples.apps.nowinandroid.core.common.network
import javax.inject.Qualifier import javax.inject.Qualifier
import kotlin.annotation.AnnotationRetention.RUNTIME import kotlin.annotation.AnnotationRetention.RUNTIME

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 The Android Open Source Project * Copyright 2026 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -14,10 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
package com.google.samples.apps.nowinandroid.core.network.di package com.google.samples.apps.nowinandroid.core.common.network.di
import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.common.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.Default import com.google.samples.apps.nowinandroid.core.common.network.NiaDispatchers.Default
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn

@ -1,5 +1,5 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2026 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -14,11 +14,11 @@
* limitations under the License. * limitations under the License.
*/ */
package com.google.samples.apps.nowinandroid.core.network.di package com.google.samples.apps.nowinandroid.core.common.network.di
import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.common.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.Default import com.google.samples.apps.nowinandroid.core.common.network.NiaDispatchers.Default
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.common.network.NiaDispatchers.IO
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.google.samples.apps.nowinandroid.core.result package com.google.samples.apps.nowinandroid.core.common.result
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.catch

@ -1,5 +1,5 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2026 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.google.samples.apps.nowinandroid.core.result package com.google.samples.apps.nowinandroid.core.common.result
import app.cash.turbine.test import app.cash.turbine.test
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
@ -40,6 +40,7 @@ class ResultKtTest {
"Test Done", "Test Done",
errorResult.exception.message, errorResult.exception.message,
) )
Result.Loading, Result.Loading,
is Result.Success, is Result.Success,
-> throw IllegalStateException( -> throw IllegalStateException(

@ -19,7 +19,7 @@ graph TB
:core:data-test[data-test]:::android-library :core:data-test[data-test]:::android-library
:core:database[database]:::android-library :core:database[database]:::android-library
:core:datastore[datastore]:::android-library :core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library :core:datastore-proto[datastore-proto]:::jvm-library
:core:model[model]:::jvm-library :core:model[model]:::jvm-library
:core:network[network]:::android-library :core:network[network]:::android-library
:core:notifications[notifications]:::android-library :core:notifications[notifications]:::android-library

@ -16,13 +16,13 @@
package com.google.samples.apps.nowinandroid.core.data.test.repository package com.google.samples.apps.nowinandroid.core.data.test.repository
import com.google.samples.apps.nowinandroid.core.common.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.common.network.NiaDispatchers.IO
import com.google.samples.apps.nowinandroid.core.data.Synchronizer import com.google.samples.apps.nowinandroid.core.data.Synchronizer
import com.google.samples.apps.nowinandroid.core.data.model.asExternalModel import com.google.samples.apps.nowinandroid.core.data.model.asExternalModel
import com.google.samples.apps.nowinandroid.core.data.repository.NewsRepository import com.google.samples.apps.nowinandroid.core.data.repository.NewsRepository
import com.google.samples.apps.nowinandroid.core.data.repository.NewsResourceQuery import com.google.samples.apps.nowinandroid.core.data.repository.NewsResourceQuery
import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource
import com.google.samples.apps.nowinandroid.core.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO
import com.google.samples.apps.nowinandroid.core.network.demo.DemoNiaNetworkDataSource import com.google.samples.apps.nowinandroid.core.network.demo.DemoNiaNetworkDataSource
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow

@ -16,11 +16,11 @@
package com.google.samples.apps.nowinandroid.core.data.test.repository package com.google.samples.apps.nowinandroid.core.data.test.repository
import com.google.samples.apps.nowinandroid.core.common.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.common.network.NiaDispatchers.IO
import com.google.samples.apps.nowinandroid.core.data.Synchronizer import com.google.samples.apps.nowinandroid.core.data.Synchronizer
import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository
import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.model.data.Topic
import com.google.samples.apps.nowinandroid.core.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO
import com.google.samples.apps.nowinandroid.core.network.demo.DemoNiaNetworkDataSource import com.google.samples.apps.nowinandroid.core.network.demo.DemoNiaNetworkDataSource
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow

@ -18,7 +18,7 @@ graph TB
:core:data[data]:::android-library :core:data[data]:::android-library
:core:database[database]:::android-library :core:database[database]:::android-library
:core:datastore[datastore]:::android-library :core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library :core:datastore-proto[datastore-proto]:::jvm-library
:core:model[model]:::jvm-library :core:model[model]:::jvm-library
:core:network[network]:::android-library :core:network[network]:::android-library
:core:notifications[notifications]:::android-library :core:notifications[notifications]:::android-library

@ -16,4 +16,4 @@
--> -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest> </manifest>

@ -16,6 +16,8 @@
package com.google.samples.apps.nowinandroid.core.data.repository package com.google.samples.apps.nowinandroid.core.data.repository
import com.google.samples.apps.nowinandroid.core.common.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.common.network.NiaDispatchers.IO
import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceDao import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceDao
import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceFtsDao import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceFtsDao
import com.google.samples.apps.nowinandroid.core.database.dao.TopicDao import com.google.samples.apps.nowinandroid.core.database.dao.TopicDao
@ -24,8 +26,6 @@ import com.google.samples.apps.nowinandroid.core.database.model.PopulatedNewsRes
import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel
import com.google.samples.apps.nowinandroid.core.database.model.asFtsEntity import com.google.samples.apps.nowinandroid.core.database.model.asFtsEntity
import com.google.samples.apps.nowinandroid.core.model.data.SearchResult import com.google.samples.apps.nowinandroid.core.model.data.SearchResult
import com.google.samples.apps.nowinandroid.core.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine

@ -25,8 +25,8 @@ import android.net.NetworkRequest
import android.net.NetworkRequest.Builder import android.net.NetworkRequest.Builder
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.tracing.trace import androidx.tracing.trace
import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.common.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.common.network.NiaDispatchers.IO
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.awaitClose

@ -23,9 +23,9 @@ import android.content.IntentFilter
import android.os.Build.VERSION import android.os.Build.VERSION
import android.os.Build.VERSION_CODES import android.os.Build.VERSION_CODES
import androidx.tracing.trace import androidx.tracing.trace
import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.common.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.common.network.NiaDispatchers.IO
import com.google.samples.apps.nowinandroid.core.network.di.ApplicationScope import com.google.samples.apps.nowinandroid.core.common.network.di.ApplicationScope
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope

@ -14,4 +14,4 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<manifest /> <manifest />

@ -13,7 +13,7 @@ config:
graph TB graph TB
subgraph :core subgraph :core
direction TB direction TB
:core:datastore-proto[datastore-proto]:::android-library :core:datastore-proto[datastore-proto]:::jvm-library
end end
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000; classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;

@ -15,23 +15,19 @@
*/ */
plugins { plugins {
alias(libs.plugins.nowinandroid.android.library) alias(libs.plugins.nowinandroid.jvm.library)
alias(libs.plugins.protobuf) alias(libs.plugins.protobuf)
} }
android {
namespace = "com.google.samples.apps.nowinandroid.core.datastore.proto"
}
// Setup protobuf configuration, generating lite Java and Kotlin classes // Setup protobuf configuration, generating lite Java and Kotlin classes
protobuf { protobuf {
protoc { protoc {
artifact = libs.protobuf.protoc.get().toString() artifact = libs.protobuf.protoc.get().toString()
} }
generateProtoTasks { generateProtoTasks {
all().forEach { task -> all().configureEach {
task.builtins { builtins {
register("java") { named("java") {
option("lite") option("lite")
} }
register("kotlin") { register("kotlin") {
@ -42,14 +38,6 @@ protobuf {
} }
} }
androidComponents.beforeVariants {
android.sourceSets.register(it.name) {
val buildDir = layout.buildDirectory.get().asFile
java.srcDir(buildDir.resolve("generated/source/proto/${it.name}/java"))
kotlin.srcDir(buildDir.resolve("generated/source/proto/${it.name}/kotlin"))
}
}
dependencies { dependencies {
api(libs.protobuf.kotlin.lite) api(libs.protobuf.kotlin.lite)
} }

@ -15,7 +15,7 @@ graph TB
direction TB direction TB
:core:common[common]:::jvm-library :core:common[common]:::jvm-library
:core:datastore[datastore]:::android-library :core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library :core:datastore-proto[datastore-proto]:::jvm-library
:core:datastore-test[datastore-test]:::android-library :core:datastore-test[datastore-test]:::android-library
:core:model[model]:::jvm-library :core:model[model]:::jvm-library
end end

@ -14,4 +14,4 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<manifest /> <manifest />

@ -15,7 +15,7 @@ graph TB
direction TB direction TB
:core:common[common]:::jvm-library :core:common[common]:::jvm-library
:core:datastore[datastore]:::android-library :core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library :core:datastore-proto[datastore-proto]:::jvm-library
:core:model[model]:::jvm-library :core:model[model]:::jvm-library
end end

@ -14,4 +14,4 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<manifest /> <manifest />

@ -20,12 +20,12 @@ import android.content.Context
import androidx.datastore.core.DataStore import androidx.datastore.core.DataStore
import androidx.datastore.core.DataStoreFactory import androidx.datastore.core.DataStoreFactory
import androidx.datastore.dataStoreFile import androidx.datastore.dataStoreFile
import com.google.samples.apps.nowinandroid.core.common.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.common.network.NiaDispatchers.IO
import com.google.samples.apps.nowinandroid.core.common.network.di.ApplicationScope
import com.google.samples.apps.nowinandroid.core.datastore.IntToStringIdsMigration import com.google.samples.apps.nowinandroid.core.datastore.IntToStringIdsMigration
import com.google.samples.apps.nowinandroid.core.datastore.UserPreferences import com.google.samples.apps.nowinandroid.core.datastore.UserPreferences
import com.google.samples.apps.nowinandroid.core.datastore.UserPreferencesSerializer import com.google.samples.apps.nowinandroid.core.datastore.UserPreferencesSerializer
import com.google.samples.apps.nowinandroid.core.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO
import com.google.samples.apps.nowinandroid.core.network.di.ApplicationScope
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn

@ -14,4 +14,4 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<manifest /> <manifest />

@ -18,7 +18,7 @@ graph TB
:core:data[data]:::android-library :core:data[data]:::android-library
:core:database[database]:::android-library :core:database[database]:::android-library
:core:datastore[datastore]:::android-library :core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library :core:datastore-proto[datastore-proto]:::jvm-library
:core:domain[domain]:::android-library :core:domain[domain]:::android-library
:core:model[model]:::jvm-library :core:model[model]:::jvm-library
:core:network[network]:::android-library :core:network[network]:::android-library

@ -30,4 +30,4 @@ dependencies {
implementation(libs.javax.inject) implementation(libs.javax.inject)
testImplementation(projects.core.testing) testImplementation(projects.core.testing)
} }

@ -14,4 +14,4 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<manifest /> <manifest />

@ -1,3 +1,48 @@
# :core:navigation module # `:core:navigation`
## Dependency graph
![Dependency graph](../../docs/images/graphs/dep_graph_core_navigation.svg) ## Module dependency graph
<!--region graph-->
```mermaid
---
config:
layout: elk
elk:
nodePlacementStrategy: SIMPLE
---
graph TB
subgraph :core
direction TB
:core:navigation[navigation]:::android-library
end
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;
```
<details><summary>📋 Graph legend</summary>
```mermaid
graph TB
application[application]:::android-application
feature[feature]:::android-feature
library[library]:::android-library
jvm[jvm]:::jvm-library
application -.-> feature
library --> jvm
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;
```
</details>
<!--endregion-->

@ -17,4 +17,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
</manifest> </manifest>

@ -19,8 +19,8 @@ package com.google.samples.apps.nowinandroid.core.network.demo
import JvmUnitTestDemoAssetManager import JvmUnitTestDemoAssetManager
import android.os.Build.VERSION.SDK_INT import android.os.Build.VERSION.SDK_INT
import android.os.Build.VERSION_CODES.M import android.os.Build.VERSION_CODES.M
import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.common.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.common.network.NiaDispatchers.IO
import com.google.samples.apps.nowinandroid.core.network.NiaNetworkDataSource import com.google.samples.apps.nowinandroid.core.network.NiaNetworkDataSource
import com.google.samples.apps.nowinandroid.core.network.model.NetworkChangeList import com.google.samples.apps.nowinandroid.core.network.model.NetworkChangeList
import com.google.samples.apps.nowinandroid.core.network.model.NetworkNewsResource import com.google.samples.apps.nowinandroid.core.network.model.NetworkNewsResource

@ -28,4 +28,4 @@
android:pathData="M17.6,11.48 L19.44,8.3a0.63,0.63 0,0 0,-1.09 -0.63l-1.88,3.24a11.43,11.43 0,0 0,-8.94 0L5.65,7.67a0.63,0.63 0,0 0,-1.09 0.63L6.4,11.48A10.81,10.81 0,0 0,1 20L23,20A10.81,10.81 0,0 0,17.6 11.48ZM7,17.25A1.25,1.25 0,1 1,8.25 16,1.25 1.25,0 0,1 7,17.25ZM17,17.25A1.25,1.25 0,1 1,18.25 16,1.25 1.25,0 0,1 17,17.25Z" android:pathData="M17.6,11.48 L19.44,8.3a0.63,0.63 0,0 0,-1.09 -0.63l-1.88,3.24a11.43,11.43 0,0 0,-8.94 0L5.65,7.67a0.63,0.63 0,0 0,-1.09 0.63L6.4,11.48A10.81,10.81 0,0 0,1 20L23,20A10.81,10.81 0,0 0,17.6 11.48ZM7,17.25A1.25,1.25 0,1 1,8.25 16,1.25 1.25,0 0,1 7,17.25ZM17,17.25A1.25,1.25 0,1 1,18.25 16,1.25 1.25,0 0,1 17,17.25Z"
android:fillColor="#FF000000"/> android:fillColor="#FF000000"/>
</group> </group>
</vector> </vector>

@ -21,4 +21,4 @@
Theme_Material_Light_NoActionBar is the base theme used by the production app. Theme_Material_Light_NoActionBar is the base theme used by the production app.
--> -->
<application android:theme="@android:style/Theme.Material.NoActionBar" /> <application android:theme="@android:style/Theme.Material.NoActionBar" />
</manifest> </manifest>

@ -18,7 +18,7 @@ graph TB
:core:data[data]:::android-library :core:data[data]:::android-library
:core:database[database]:::android-library :core:database[database]:::android-library
:core:datastore[datastore]:::android-library :core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library :core:datastore-proto[datastore-proto]:::jvm-library
:core:model[model]:::jvm-library :core:model[model]:::jvm-library
:core:network[network]:::android-library :core:network[network]:::android-library
:core:notifications[notifications]:::android-library :core:notifications[notifications]:::android-library

@ -14,4 +14,4 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<manifest /> <manifest />

@ -16,10 +16,10 @@
package com.google.samples.apps.nowinandroid.core.testing.di package com.google.samples.apps.nowinandroid.core.testing.di
import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.common.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.Default import com.google.samples.apps.nowinandroid.core.common.network.NiaDispatchers.Default
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.common.network.NiaDispatchers.IO
import com.google.samples.apps.nowinandroid.core.network.di.DispatchersModule import com.google.samples.apps.nowinandroid.core.common.network.di.DispatchersModule
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent

@ -14,4 +14,4 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<manifest /> <manifest />

@ -16,14 +16,16 @@
package com.google.samples.apps.nowinandroid.core.ui package com.google.samples.apps.nowinandroid.core.ui
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
/** /**
* Multipreview annotation that represents various device sizes. Add this annotation to a composable * Multipreview annotation that represents various device sizes. Add this annotation to a composable
* to render various devices. * to render various devices.
*/ */
@Preview(name = "phone", device = "spec:shape=Normal,width=360,height=640,unit=dp,dpi=480") @Preview(name = "phone", device = Devices.PHONE, showBackground = true)
@Preview(name = "landscape", device = "spec:shape=Normal,width=640,height=360,unit=dp,dpi=480") @Preview(name = "phone_in_landscape", widthDp = 891, heightDp = 411, showBackground = true)
@Preview(name = "foldable", device = "spec:shape=Normal,width=673,height=841,unit=dp,dpi=480") @Preview(name = "foldable", device = Devices.FOLDABLE, showBackground = true)
@Preview(name = "tablet", device = "spec:shape=Normal,width=1280,height=800,unit=dp,dpi=480") @Preview(name = "tablet", device = Devices.TABLET, showBackground = true)
@Preview(name = "desktop", device = Devices.DESKTOP, showBackground = true)
annotation class DevicePreviews annotation class DevicePreviews

@ -20,4 +20,4 @@ plugins {
android { android {
namespace = "com.google.samples.apps.nowinandroid.feature.bookmarks.api" namespace = "com.google.samples.apps.nowinandroid.feature.bookmarks.api"
} }

@ -30,7 +30,7 @@ graph TB
:core:data[data]:::android-library :core:data[data]:::android-library
:core:database[database]:::android-library :core:database[database]:::android-library
:core:datastore[datastore]:::android-library :core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library :core:datastore-proto[datastore-proto]:::jvm-library
:core:designsystem[designsystem]:::android-library :core:designsystem[designsystem]:::android-library
:core:model[model]:::jvm-library :core:model[model]:::jvm-library
:core:navigation[navigation]:::android-library :core:navigation[navigation]:::android-library

@ -14,4 +14,4 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<manifest /> <manifest />

@ -155,7 +155,7 @@ private fun LoadingState(modifier: Modifier = Modifier) {
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.wrapContentSize() .wrapContentSize()
.testTag("forYou:loading"), .testTag("bookmarks:loading"),
contentDesc = stringResource(id = R.string.feature_bookmarks_api_loading), contentDesc = stringResource(id = R.string.feature_bookmarks_api_loading),
) )
} }

@ -14,4 +14,4 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<manifest /> <manifest />

@ -21,4 +21,4 @@
<string name="feature_foryou_api_navigate_up">Navigate up</string> <string name="feature_foryou_api_navigate_up">Navigate up</string>
<string name="feature_foryou_api_onboarding_guidance_title">What are you interested in?</string> <string name="feature_foryou_api_onboarding_guidance_title">What are you interested in?</string>
<string name="feature_foryou_api_onboarding_guidance_subtitle">Updates from topics you follow will appear here. Follow some things to get started.</string> <string name="feature_foryou_api_onboarding_guidance_subtitle">Updates from topics you follow will appear here. Follow some things to get started.</string>
</resources> </resources>

@ -30,7 +30,7 @@ graph TB
:core:data[data]:::android-library :core:data[data]:::android-library
:core:database[database]:::android-library :core:database[database]:::android-library
:core:datastore[datastore]:::android-library :core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library :core:datastore-proto[datastore-proto]:::jvm-library
:core:designsystem[designsystem]:::android-library :core:designsystem[designsystem]:::android-library
:core:domain[domain]:::android-library :core:domain[domain]:::android-library
:core:model[model]:::jvm-library :core:model[model]:::jvm-library

@ -40,4 +40,4 @@ dependencies {
androidTestImplementation(libs.bundles.androidx.compose.ui.test) androidTestImplementation(libs.bundles.androidx.compose.ui.test)
androidTestImplementation(projects.core.testing) androidTestImplementation(projects.core.testing)
} }

@ -20,4 +20,4 @@ plugins {
android { android {
namespace = "com.google.samples.apps.nowinandroid.feature.interests.api" namespace = "com.google.samples.apps.nowinandroid.feature.interests.api"
} }

@ -14,4 +14,4 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<manifest /> <manifest />

@ -52,4 +52,4 @@
android:strokeColor="#8C4190" android:strokeColor="#8C4190"
android:strokeLineCap="round" android:strokeLineCap="round"
android:strokeWidth="2" /> android:strokeWidth="2" />
</vector> </vector>

@ -1,3 +1,101 @@
# :feature:interests:impl module # `:feature:interests:impl`
## Dependency graph
![Dependency graph](../../../docs/images/graphs/dep_graph_feature_interests_impl.svg) ## Module dependency graph
<!--region graph-->
```mermaid
---
config:
layout: elk
elk:
nodePlacementStrategy: SIMPLE
---
graph TB
subgraph :feature
direction TB
subgraph :feature:interests
direction TB
:feature:interests:api[api]:::android-library
:feature:interests:impl[impl]:::android-library
end
subgraph :feature:topic
direction TB
:feature:topic:api[api]:::android-library
end
end
subgraph :core
direction TB
:core:analytics[analytics]:::android-library
:core:common[common]:::jvm-library
:core:data[data]:::android-library
:core:database[database]:::android-library
:core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library
:core:designsystem[designsystem]:::android-library
:core:domain[domain]:::android-library
:core:model[model]:::jvm-library
:core:navigation[navigation]:::android-library
:core:network[network]:::android-library
:core:notifications[notifications]:::android-library
:core:ui[ui]:::android-library
end
:core:data -.-> :core:analytics
:core:data --> :core:common
:core:data --> :core:database
:core:data --> :core:datastore
:core:data --> :core:network
:core:data -.-> :core:notifications
:core:database --> :core:model
:core:datastore -.-> :core:common
:core:datastore --> :core:datastore-proto
:core:datastore --> :core:model
:core:domain --> :core:data
:core:domain --> :core:model
:core:network --> :core:common
:core:network --> :core:model
:core:notifications -.-> :core:common
:core:notifications --> :core:model
:core:ui --> :core:analytics
:core:ui --> :core:designsystem
:core:ui --> :core:model
:feature:interests:api --> :core:navigation
:feature:interests:impl -.-> :core:designsystem
:feature:interests:impl -.-> :core:domain
:feature:interests:impl -.-> :core:ui
:feature:interests:impl -.-> :feature:interests:api
:feature:interests:impl -.-> :feature:topic:api
:feature:topic:api -.-> :core:designsystem
:feature:topic:api --> :core:navigation
:feature:topic:api -.-> :core:ui
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;
```
<details><summary>📋 Graph legend</summary>
```mermaid
graph TB
application[application]:::android-application
feature[feature]:::android-feature
library[library]:::android-library
jvm[jvm]:::jvm-library
application -.-> feature
library --> jvm
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;
```
</details>
<!--endregion-->

@ -25,7 +25,7 @@ graph TB
:core:data[data]:::android-library :core:data[data]:::android-library
:core:database[database]:::android-library :core:database[database]:::android-library
:core:datastore[datastore]:::android-library :core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library :core:datastore-proto[datastore-proto]:::jvm-library
:core:domain[domain]:::android-library :core:domain[domain]:::android-library
:core:model[model]:::jvm-library :core:model[model]:::jvm-library
:core:navigation[navigation]:::android-library :core:navigation[navigation]:::android-library

@ -25,4 +25,3 @@ android {
dependencies { dependencies {
implementation(projects.core.domain) implementation(projects.core.domain)
} }

@ -34,7 +34,7 @@ graph TB
:core:data[data]:::android-library :core:data[data]:::android-library
:core:database[database]:::android-library :core:database[database]:::android-library
:core:datastore[datastore]:::android-library :core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library :core:datastore-proto[datastore-proto]:::jvm-library
:core:designsystem[designsystem]:::android-library :core:designsystem[designsystem]:::android-library
:core:domain[domain]:::android-library :core:domain[domain]:::android-library
:core:model[model]:::jvm-library :core:model[model]:::jvm-library

@ -34,4 +34,4 @@ dependencies {
androidTestImplementation(libs.bundles.androidx.compose.ui.test) androidTestImplementation(libs.bundles.androidx.compose.ui.test)
androidTestImplementation(projects.core.testing) androidTestImplementation(projects.core.testing)
} }

@ -25,7 +25,7 @@ graph TB
:core:data[data]:::android-library :core:data[data]:::android-library
:core:database[database]:::android-library :core:database[database]:::android-library
:core:datastore[datastore]:::android-library :core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library :core:datastore-proto[datastore-proto]:::jvm-library
:core:designsystem[designsystem]:::android-library :core:designsystem[designsystem]:::android-library
:core:model[model]:::jvm-library :core:model[model]:::jvm-library
:core:network[network]:::android-library :core:network[network]:::android-library

@ -1,3 +1,66 @@
# :feature:topic:api module # `:feature:topic:api`
## Dependency graph
![Dependency graph](../../../docs/images/graphs/dep_graph_feature_topic_api.svg) ## Module dependency graph
<!--region graph-->
```mermaid
---
config:
layout: elk
elk:
nodePlacementStrategy: SIMPLE
---
graph TB
subgraph :feature
direction TB
subgraph :feature:topic
direction TB
:feature:topic:api[api]:::android-library
end
end
subgraph :core
direction TB
:core:analytics[analytics]:::android-library
:core:designsystem[designsystem]:::android-library
:core:model[model]:::jvm-library
:core:navigation[navigation]:::android-library
:core:ui[ui]:::android-library
end
:core:ui --> :core:analytics
:core:ui --> :core:designsystem
:core:ui --> :core:model
:feature:topic:api -.-> :core:designsystem
:feature:topic:api --> :core:navigation
:feature:topic:api -.-> :core:ui
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;
```
<details><summary>📋 Graph legend</summary>
```mermaid
graph TB
application[application]:::android-application
feature[feature]:::android-feature
library[library]:::android-library
jvm[jvm]:::jvm-library
application -.-> feature
library --> jvm
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;
```
</details>
<!--endregion-->

@ -22,4 +22,4 @@ plugins {
android { android {
namespace = "com.google.samples.apps.nowinandroid.feature.topic.api" namespace = "com.google.samples.apps.nowinandroid.feature.topic.api"
} }

@ -1,3 +1,92 @@
# :feature:topic:impl module # `:feature:topic:impl`
## Dependency graph
![Dependency graph](../../../docs/images/graphs/dep_graph_feature_topic_impl.svg) ## Module dependency graph
<!--region graph-->
```mermaid
---
config:
layout: elk
elk:
nodePlacementStrategy: SIMPLE
---
graph TB
subgraph :feature
direction TB
subgraph :feature:topic
direction TB
:feature:topic:api[api]:::android-library
:feature:topic:impl[impl]:::android-library
end
end
subgraph :core
direction TB
:core:analytics[analytics]:::android-library
:core:common[common]:::jvm-library
:core:data[data]:::android-library
:core:database[database]:::android-library
:core:datastore[datastore]:::android-library
:core:datastore-proto[datastore-proto]:::android-library
:core:designsystem[designsystem]:::android-library
:core:model[model]:::jvm-library
:core:navigation[navigation]:::android-library
:core:network[network]:::android-library
:core:notifications[notifications]:::android-library
:core:ui[ui]:::android-library
end
:core:data -.-> :core:analytics
:core:data --> :core:common
:core:data --> :core:database
:core:data --> :core:datastore
:core:data --> :core:network
:core:data -.-> :core:notifications
:core:database --> :core:model
:core:datastore -.-> :core:common
:core:datastore --> :core:datastore-proto
:core:datastore --> :core:model
:core:network --> :core:common
:core:network --> :core:model
:core:notifications -.-> :core:common
:core:notifications --> :core:model
:core:ui --> :core:analytics
:core:ui --> :core:designsystem
:core:ui --> :core:model
:feature:topic:api -.-> :core:designsystem
:feature:topic:api --> :core:navigation
:feature:topic:api -.-> :core:ui
:feature:topic:impl -.-> :core:data
:feature:topic:impl -.-> :core:designsystem
:feature:topic:impl -.-> :core:ui
:feature:topic:impl -.-> :feature:topic:api
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;
```
<details><summary>📋 Graph legend</summary>
```mermaid
graph TB
application[application]:::android-application
feature[feature]:::android-feature
library[library]:::android-library
jvm[jvm]:::jvm-library
application -.-> feature
library --> jvm
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;
```
</details>
<!--endregion-->

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save