Skip to content

Commit 2dacd90

Browse files
authored
Merge pull request #105 from garanj/main
Adds watch face support using Watch Face Push
2 parents e9dce54 + b3f773a commit 2dacd90

File tree

361 files changed

+10234
-13
lines changed

Some content is hidden

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

361 files changed

+10234
-13
lines changed

app/build.gradle.kts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ android {
3737
applicationId = "com.android.developers.androidify"
3838
minSdk = libs.versions.minSdk.get().toInt()
3939
targetSdk = 36
40-
versionCode = 5
41-
versionName = "1.1.3"
40+
versionCode = libs.versions.appVersionCode.get().toInt()
41+
versionName = libs.versions.appVersionName.get()
4242

4343
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
4444
}
@@ -96,6 +96,12 @@ android {
9696
isIncludeAndroidResources = true
9797
}
9898
}
99+
// To avoid packaging conflicts when using bouncycastle
100+
packaging {
101+
resources {
102+
excludes.add("META-INF/versions/9/OSGI-INF/MANIFEST.MF")
103+
}
104+
}
99105
}
100106

101107
baselineProfile() {

app/proguard-rules.pro

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,13 @@
3333
-keepattributes Signature
3434
-keepattributes *Annotation*
3535
-keepattributes InnerClasses
36+
37+
# Ignore missing Java SE image classes from TwelveMonkeys ImageIO
38+
-dontwarn javax.imageio.**
39+
40+
# Ignore missing Java SE XML classes from Xerces and other XML processors
41+
-dontwarn org.apache.xml.resolver.**
42+
-dontwarn org.eclipse.wst.xml.xpath2.processor.**
43+
44+
# Ignore missing Java SE annotation processing classes, often from libraries like AutoValue
45+
-dontwarn javax.lang.model.**

app/src/main/AndroidManifest.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@
7878

7979
<category android:name="android.intent.category.LAUNCHER" />
8080
</intent-filter>
81+
<!-- Required deeplink to make the app launchable from the watch -->
82+
<intent-filter>
83+
<action android:name="android.intent.action.VIEW" />
84+
<category android:name="android.intent.category.DEFAULT" />
85+
<category android:name="android.intent.category.BROWSABLE" />
86+
<data android:scheme="androidify"
87+
android:host="launch" />
88+
</intent-filter>
8189
</activity>
8290
<!-- need to use Theme.AppCompat -->
8391
<activity

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,4 @@ subprojects {
5050
licenseHeaderFile(rootProject.file("spotless/copyright.xml"), "(<[^!?])")
5151
}
5252
}
53-
}
53+
}

core/network/src/main/java/com/android/developers/androidify/RemoteConfigDataSource.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ interface RemoteConfigDataSource {
4343
fun getImageGenerationEditsModelName(): String
4444

4545
fun getBotBackgroundInstructionPrompt(): String
46+
47+
fun watchfaceFeatureEnabled(): Boolean
4648
}
4749

4850
@Singleton
@@ -111,4 +113,8 @@ class RemoteConfigDataSourceImpl @Inject constructor() : RemoteConfigDataSource
111113
override fun getBotBackgroundInstructionPrompt(): String {
112114
return remoteConfig.getString("bot_background_instruction_prompt")
113115
}
116+
117+
override fun watchfaceFeatureEnabled(): Boolean {
118+
return remoteConfig.getBoolean("watchface_feature_enabled")
119+
}
114120
}

core/network/src/main/res/xml/remote_config_defaults.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
limitations under the License.
1616
-->
1717
<defaults>
18+
<entry>
19+
<key>watchface_feature_enabled</key>
20+
<value>false</value>
21+
</entry>
1822
<entry>
1923
<key>background_vibes_feature_enabled</key>
2024
<value>false</value>

core/testing/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ dependencies {
5959
implementation(projects.core.network)
6060
implementation(projects.core.util)
6161
implementation(projects.feature.results)
62+
implementation(projects.watchface)
63+
implementation(projects.wear.common)
6264

6365
ksp(libs.hilt.compiler)
6466

core/testing/src/main/java/com/android/developers/testing/network/TestRemoteConfigDataSource.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,8 @@ class TestRemoteConfigDataSource(private val useGeminiNano: Boolean) : RemoteCon
7979
override fun getBotBackgroundInstructionPrompt(): String {
8080
return "bot_background_instruction_prompt"
8181
}
82+
83+
override fun watchfaceFeatureEnabled(): Boolean {
84+
return true
85+
}
8286
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.android.developers.testing.repository
2+
3+
import android.graphics.Bitmap
4+
import com.android.developers.androidify.watchface.WatchFaceAsset
5+
import com.android.developers.androidify.watchface.transfer.WatchFaceInstallationRepository
6+
import com.android.developers.androidify.wear.common.ConnectedWatch
7+
import com.android.developers.androidify.wear.common.WatchFaceActivationStrategy
8+
import com.android.developers.androidify.wear.common.WatchFaceInstallError
9+
import com.android.developers.androidify.wear.common.WatchFaceInstallationStatus
10+
import kotlinx.coroutines.delay
11+
import kotlinx.coroutines.flow.MutableStateFlow
12+
import kotlinx.coroutines.flow.asStateFlow
13+
import java.util.UUID
14+
15+
class FakeWatchFaceInstallationRepository : WatchFaceInstallationRepository {
16+
private val watch = ConnectedWatch(
17+
nodeId = "1234",
18+
displayName = "Pixel Watch",
19+
hasAndroidify = true,
20+
)
21+
22+
private val watchFaceAsset = WatchFaceAsset(
23+
id = "watch_face_1",
24+
previewPath = com.android.developers.androidify.results.R.drawable.watch_face_preview,
25+
)
26+
27+
private var transferId = generateTransferId()
28+
29+
private val _connectedWatch = MutableStateFlow<ConnectedWatch?>(null)
30+
override val connectedWatch = _connectedWatch.asStateFlow()
31+
32+
private val _watchFaceInstallationStatus =
33+
MutableStateFlow<WatchFaceInstallationStatus>(WatchFaceInstallationStatus.NotStarted)
34+
override val watchFaceInstallationUpdates = _watchFaceInstallationStatus.asStateFlow()
35+
36+
override suspend fun createAndTransferWatchFace(
37+
connectedWatch: ConnectedWatch,
38+
watchFace: WatchFaceAsset,
39+
bitmap: Bitmap,
40+
): WatchFaceInstallError {
41+
transferId = generateTransferId()
42+
delay(5_000)
43+
_watchFaceInstallationStatus.value = WatchFaceInstallationStatus.Complete(
44+
success = true,
45+
otherNodeId = "5678",
46+
transferId = transferId,
47+
activationStrategy = WatchFaceActivationStrategy.NO_ACTION_NEEDED,
48+
validationToken = "1234abcd",
49+
installError = WatchFaceInstallError.NO_ERROR,
50+
)
51+
return WatchFaceInstallError.NO_ERROR
52+
}
53+
54+
override suspend fun getAvailableWatchFaces(): Result<List<WatchFaceAsset>> {
55+
return Result.success(listOf(watchFaceAsset))
56+
}
57+
58+
override suspend fun resetInstallationStatus() {
59+
transferId = generateTransferId()
60+
_watchFaceInstallationStatus.value = WatchFaceInstallationStatus.NotStarted
61+
}
62+
63+
private fun generateTransferId() = UUID.randomUUID().toString().take(8)
64+
65+
public fun setWatchAsConnected() {
66+
_connectedWatch.value = watch
67+
}
68+
}

core/theme/build.gradle.kts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ android {
4848
kotlinOptions {
4949
jvmTarget = libs.versions.jvmTarget.get()
5050
}
51-
51+
// To avoid packaging conflicts when using bouncycastle
52+
packaging {
53+
resources {
54+
excludes.add("META-INF/versions/9/OSGI-INF/MANIFEST.MF")
55+
}
56+
}
5257
}
5358

5459
dependencies {
@@ -57,6 +62,7 @@ dependencies {
5762
implementation(libs.androidx.ui.tooling.preview)
5863
implementation(libs.androidx.material3)
5964
implementation(projects.core.util)
65+
implementation(libs.guava)
6066

6167
implementation(libs.androidx.adaptive)
6268
implementation(libs.androidx.adaptive.layout)

0 commit comments

Comments
 (0)