Set up project skeleton (milestone 1)
- Architecture and feature overview in docs/ARCHITECTURE.md - Gradle 9.8 / AGP 9.4 / Kotlin 2.4 with version catalog and convention plugins - Modules :app, :core:*, :device-profiles, :feature:* (placeholder screens) - Flavors core (no INTERNET, enforced by a build check) and full - Material You theme, navigation, expert mode and dry-run settings (DataStore) - Pixel 8-10 device detection, unit tests, GPLv3 license, English README with Obtainium badge Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
plugins {
|
||||
alias(libs.plugins.pixelwall.jvm.library)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":core:model"))
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.pixelwall.deviceprofiles
|
||||
|
||||
import org.pixelwall.core.model.DeviceInfo
|
||||
|
||||
/** Gerätespezifisches Wissen. Settings-Keys und Deep-Links folgen ab Meilenstein 2. */
|
||||
interface DeviceProfile {
|
||||
val id: String
|
||||
fun matches(device: DeviceInfo): Boolean
|
||||
}
|
||||
|
||||
object DeviceProfiles {
|
||||
/** Spezifischste Profile zuerst; [AospFallbackProfile] passt immer. */
|
||||
val all: List<DeviceProfile> = listOf(PixelProfile, AospFallbackProfile)
|
||||
|
||||
fun resolve(device: DeviceInfo): DeviceProfile = all.first { it.matches(device) }
|
||||
}
|
||||
|
||||
object AospFallbackProfile : DeviceProfile {
|
||||
override val id = "aosp"
|
||||
override fun matches(device: DeviceInfo) = true
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.pixelwall.deviceprofiles
|
||||
|
||||
import org.pixelwall.core.model.DeviceInfo
|
||||
|
||||
object PixelProfile : DeviceProfile {
|
||||
override val id = "pixel"
|
||||
|
||||
/** Codenamen der unterstützten Geräte (Pixel 8 bis Pixel 10). */
|
||||
val supportedDevices: Map<String, String> = mapOf(
|
||||
"shiba" to "Pixel 8",
|
||||
"husky" to "Pixel 8 Pro",
|
||||
"akita" to "Pixel 8a",
|
||||
"tokay" to "Pixel 9",
|
||||
"caiman" to "Pixel 9 Pro",
|
||||
"komodo" to "Pixel 9 Pro XL",
|
||||
"comet" to "Pixel 9 Pro Fold",
|
||||
"tegu" to "Pixel 9a",
|
||||
"frankel" to "Pixel 10",
|
||||
"blazer" to "Pixel 10 Pro",
|
||||
"mustang" to "Pixel 10 Pro XL",
|
||||
"rango" to "Pixel 10 Pro Fold",
|
||||
)
|
||||
|
||||
/** Android 15 (API 35) und Android 16 (API 36) sind getestet. */
|
||||
val supportedSdkRange = 35..36
|
||||
|
||||
override fun matches(device: DeviceInfo): Boolean =
|
||||
device.manufacturer.equals("Google", ignoreCase = true) && device.device in supportedDevices
|
||||
|
||||
fun isSdkSupported(device: DeviceInfo) = device.sdkInt in supportedSdkRange
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.pixelwall.deviceprofiles
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
import org.pixelwall.core.model.DeviceInfo
|
||||
|
||||
class DeviceProfilesTest {
|
||||
|
||||
private fun device(manufacturer: String, codename: String, sdk: Int = 36) = DeviceInfo(
|
||||
manufacturer = manufacturer,
|
||||
brand = manufacturer.lowercase(),
|
||||
device = codename,
|
||||
model = codename,
|
||||
sdkInt = sdk,
|
||||
release = "16",
|
||||
securityPatch = "2026-10-05",
|
||||
)
|
||||
|
||||
@Test
|
||||
fun pixel9IsDetected() {
|
||||
assertThat(DeviceProfiles.resolve(device("Google", "tokay"))).isEqualTo(PixelProfile)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun olderPixelFallsBackToAosp() {
|
||||
assertThat(DeviceProfiles.resolve(device("Google", "panther"))).isEqualTo(AospFallbackProfile)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun otherVendorFallsBackToAosp() {
|
||||
assertThat(DeviceProfiles.resolve(device("samsung", "tokay"))).isEqualTo(AospFallbackProfile)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sdkSupportRange() {
|
||||
assertThat(PixelProfile.isSdkSupported(device("Google", "shiba", sdk = 35))).isTrue()
|
||||
assertThat(PixelProfile.isSdkSupported(device("Google", "shiba", sdk = 34))).isFalse()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user