Skip to content

Commit 2547dff

Browse files
authored
Merge branch 'main' into unused-code-cleanup
2 parents f33efaa + a75378c commit 2547dff

File tree

9 files changed

+186
-9
lines changed

9 files changed

+186
-9
lines changed

kmp/androidApp/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

kmp/androidApp/build.gradle.kts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
plugins {
2+
alias(libs.plugins.android.application)
3+
alias(libs.plugins.kotlin.android)
4+
alias(libs.plugins.compose.compiler)
5+
}
6+
7+
android {
8+
namespace = "com.example.kmp.snippets"
9+
compileSdk = libs.versions.compileSdk.get().toInt()
10+
11+
defaultConfig {
12+
applicationId = "com.example.kmp.snippets"
13+
minSdk = libs.versions.minSdk.get().toInt()
14+
targetSdk = libs.versions.targetSdk.get().toInt()
15+
versionCode = 1
16+
versionName = "1.0"
17+
18+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
19+
}
20+
21+
buildTypes {
22+
release {
23+
isMinifyEnabled = false
24+
proguardFiles(
25+
getDefaultProguardFile("proguard-android-optimize.txt"),
26+
"proguard-rules.pro"
27+
)
28+
}
29+
}
30+
31+
compileOptions {
32+
sourceCompatibility = JavaVersion.VERSION_17
33+
targetCompatibility = JavaVersion.VERSION_17
34+
}
35+
36+
kotlin {
37+
jvmToolchain(17)
38+
}
39+
40+
buildFeatures {
41+
compose = true
42+
}
43+
}
44+
45+
dependencies {
46+
val composeBom = project.dependencies.platform(libs.androidx.compose.bom)
47+
implementation(composeBom)
48+
implementation(project(":kmp:shared"))
49+
50+
implementation(libs.androidx.compose.runtime)
51+
implementation(libs.androidx.compose.ui)
52+
implementation(libs.androidx.compose.foundation)
53+
implementation(libs.androidx.compose.foundation.layout)
54+
implementation(libs.androidx.compose.ui.util)
55+
implementation(libs.androidx.compose.material)
56+
implementation(libs.androidx.lifecycle.runtime)
57+
implementation(libs.androidx.lifecycle.viewModelCompose)
58+
}

kmp/androidApp/proguard-rules.pro

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android" />
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.kmp.snippets
18+
19+
import androidx.compose.runtime.Composable
20+
import androidx.lifecycle.viewmodel.compose.viewModel
21+
22+
// [START android_kmp_viewmodel_screen]
23+
// androidApp/ui/MainScreen.kt
24+
25+
@Composable
26+
fun MainScreen(
27+
viewModel: MainViewModel = viewModel(
28+
factory = mainViewModelFactory,
29+
),
30+
) {
31+
// observe the viewModel state
32+
}
33+
// [END android_kmp_viewmodel_screen]

kmp/shared/build.gradle.kts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ plugins {
55
}
66

77
kotlin {
8-
98
// Target declarations - add or remove as needed below. These define
109
// which platforms this KMP module supports.
1110
// See: https://kotlinlang.org/docs/multiplatform-discover-project.html#targets
1211
androidLibrary {
13-
namespace = "com.example.kmp.snippets"
14-
compileSdk = 36
15-
minSdk = 24
12+
namespace = "com.example.kmp.snippets.shared"
13+
compileSdk = libs.versions.compileSdk.get().toInt()
14+
minSdk = libs.versions.minSdk.get().toInt()
1615

1716
withHostTestBuilder {
1817
}
@@ -24,6 +23,8 @@ kotlin {
2423
}
2524
}
2625

26+
jvmToolchain(17)
27+
2728
// For iOS targets, this is also where you should
2829
// configure native binary output. For more information, see:
2930
// https://kotlinlang.org/docs/multiplatform-build-native-binaries.html#build-xcframeworks
@@ -64,9 +65,7 @@ kotlin {
6465

6566
androidMain {
6667
dependencies {
67-
// Add Android-specific dependencies here. Note that this source set depends on
68-
// commonMain by default and will correctly pull the Android artifacts of any KMP
69-
// dependencies declared in commonMain.
68+
7069
}
7170
}
7271

@@ -88,5 +87,4 @@ kotlin {
8887
}
8988
}
9089
}
91-
9290
}

settings.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,6 @@ include(
3939
":identity:credentialmanager",
4040
":xr",
4141
":watchfacepush:validator",
42-
":kmp:shared",
42+
":kmp:androidApp",
43+
":kmp:shared"
4344
)

wear/src/main/AndroidManifest.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,21 @@
181181
android:resource="@drawable/tile_preview" />
182182
</service>
183183

184+
<service
185+
android:name=".snippets.tile.FeatureFallback"
186+
android:label="@string/tile_label"
187+
android:description="@string/tile_description"
188+
android:icon="@mipmap/ic_launcher"
189+
android:exported="true"
190+
android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER">
191+
<intent-filter>
192+
<action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" />
193+
</intent-filter>
194+
195+
<meta-data android:name="androidx.wear.tiles.PREVIEW"
196+
android:resource="@drawable/tile_preview" />
197+
</service>
198+
184199
<activity
185200
android:name=".snippets.alwayson.AlwaysOnActivity"
186201
android:label="0 Stopwatch"

wear/src/main/java/com/example/wear/snippets/tile/Tile.kt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@ import android.content.Context
2121
import androidx.annotation.RequiresPermission
2222
import androidx.wear.protolayout.ColorBuilders.argb
2323
import androidx.wear.protolayout.DimensionBuilders
24+
import androidx.wear.protolayout.DimensionBuilders.degrees
25+
import androidx.wear.protolayout.DimensionBuilders.dp
2426
import androidx.wear.protolayout.LayoutElementBuilders
27+
import androidx.wear.protolayout.LayoutElementBuilders.Arc
28+
import androidx.wear.protolayout.LayoutElementBuilders.ArcLine
29+
import androidx.wear.protolayout.LayoutElementBuilders.DashedArcLine
2530
import androidx.wear.protolayout.ResourceBuilders.Resources
2631
import androidx.wear.protolayout.TimelineBuilders
2732
import androidx.wear.protolayout.TimelineBuilders.Timeline
@@ -30,6 +35,8 @@ import androidx.wear.protolayout.expression.DynamicBuilders
3035
import androidx.wear.protolayout.expression.PlatformHealthSources
3136
import androidx.wear.protolayout.material.Text
3237
import androidx.wear.protolayout.material.Typography
38+
import androidx.wear.protolayout.material3.materialScope
39+
import androidx.wear.protolayout.material3.primaryLayout
3340
import androidx.wear.tiles.RequestBuilders
3441
import androidx.wear.tiles.RequestBuilders.ResourcesRequest
3542
import androidx.wear.tiles.TileBuilders.Tile
@@ -200,3 +207,44 @@ class DynamicHeartRate : TileService() {
200207
)
201208
// [END android_wear_tile_dynamic_heart_rate]
202209
}
210+
211+
class FeatureFallback : TileService() {
212+
override fun onTileRequest(requestParams: RequestBuilders.TileRequest): ListenableFuture<Tile> {
213+
214+
// [START android_wear_tile_version_fallback]
215+
val rendererVersion = requestParams.deviceConfiguration.rendererSchemaVersion
216+
217+
val arcElement =
218+
// DashedArcLine has the annotation @RequiresSchemaVersion(major = 1, minor = 500)
219+
// and so is supported by renderer versions 1.500 and greater
220+
if (
221+
rendererVersion.major > 1 ||
222+
(rendererVersion.major == 1 && rendererVersion.minor >= 500)
223+
) {
224+
// Use DashedArcLine if the renderer supports it …
225+
DashedArcLine.Builder()
226+
.setLength(degrees(270f))
227+
.setThickness(8f)
228+
.setLinePattern(
229+
LayoutElementBuilders.DashedLinePattern.Builder()
230+
.setGapSize(8f)
231+
.setGapInterval(10f)
232+
.build()
233+
)
234+
.build()
235+
} else {
236+
// … otherwise use ArcLine.
237+
ArcLine.Builder().setLength(degrees(270f)).setThickness(dp(8f)).build()
238+
}
239+
// [END android_wear_tile_version_fallback]
240+
241+
val layout =
242+
materialScope(this, requestParams.deviceConfiguration) {
243+
primaryLayout(mainSlot = { Arc.Builder().addContent(arcElement).build() })
244+
}
245+
246+
return Futures.immediateFuture(
247+
Tile.Builder().setTileTimeline(Timeline.fromLayoutElement(layout)).build()
248+
)
249+
}
250+
}

0 commit comments

Comments
 (0)