Skip to content

Commit 52b6ec8

Browse files
authored
Merge pull request #225 from KieronQuinn/release/2.3.2
2.3.2
2 parents 7275371 + ab1df75 commit 52b6ec8

35 files changed

+281
-173
lines changed

app/build.gradle

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@ plugins {
77
id 'dagger.hilt.android.plugin'
88
id 'com.google.protobuf'
99
id 'dev.rikka.tools.refine'
10+
id 'com.google.devtools.ksp'
1011
}
1112

1213
apply plugin: 'com.google.android.gms.oss-licenses-plugin'
1314

14-
String DEFAULT_MANIFEST = "248:https://storage.googleapis.com/music-iq-db/updatable_ytm_db/20230507-030029/manifest.json"
15-
String DEFAULT_MANIFEST_V3 = "3050:https://storage.googleapis.com/music-iq-db/updatable_db_v3/20230507-030029/manifest.json"
15+
String DEFAULT_MANIFEST = "266:https://storage.googleapis.com/music-iq-db/updatable_ytm_db/20240128-030108/manifest.json"
16+
String DEFAULT_MANIFEST_V3 = "3073:https://storage.googleapis.com/music-iq-db/updatable_db_v3/20240128-030108/manifest.json"
1617

17-
def tagName = '2.3.1'
18-
def version = 231
18+
def tagName = '2.3.2'
19+
def version = 232
1920

2021
def getKeystoreProperties() {
2122
def properties = new Properties()
@@ -41,7 +42,7 @@ android {
4142
defaultConfig {
4243
applicationId "com.kieronquinn.app.ambientmusicmod"
4344
minSdk 28
44-
targetSdk 33
45+
targetSdk 34
4546
versionCode version
4647
versionName tagName
4748

@@ -86,7 +87,9 @@ android {
8687
}
8788
buildFeatures {
8889
viewBinding true
90+
aidl true
8991
}
92+
namespace 'com.kieronquinn.app.ambientmusicmod'
9093
}
9194

9295
protobuf {
@@ -111,31 +114,31 @@ protobuf {
111114

112115
dependencies {
113116
//AndroidX
114-
implementation 'androidx.core:core-ktx:1.10.1'
117+
implementation 'androidx.core:core-ktx:1.12.0'
115118
implementation 'androidx.appcompat:appcompat:1.6.1'
116119
implementation 'androidx.core:core-splashscreen:1.0.1'
117120
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
118121
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
119122
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
120-
implementation "androidx.work:work-runtime-ktx:2.8.1"
123+
implementation "androidx.work:work-runtime-ktx:2.9.0"
121124
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
122-
implementation "androidx.lifecycle:lifecycle-service:2.6.1"
123-
implementation "androidx.security:security-crypto:1.0.0"
125+
implementation "androidx.lifecycle:lifecycle-service:2.7.0"
126+
implementation "androidx.security:security-crypto:1.1.0-alpha06"
124127

125128
//Material UI
126-
implementation 'com.google.android.material:material:1.9.0'
129+
implementation 'com.google.android.material:material:1.11.0'
127130

128131
//MonetCompat for colours on < S
129132
implementation 'com.github.KieronQuinn:MonetCompat:0.4.1'
130133

131134
//Dependency Injection
132-
implementation "io.insert-koin:koin-android:3.4.0"
135+
implementation "io.insert-koin:koin-android:3.5.0"
133136

134137
//Protobuf is used in reading data from ASI
135-
implementation "com.google.protobuf:protobuf-javalite:3.21.9"
138+
implementation "com.google.protobuf:protobuf-javalite:3.25.2"
136139

137140
//Lottie for animations
138-
implementation 'com.airbnb.android:lottie:5.2.0'
141+
implementation 'com.airbnb.android:lottie:6.3.0'
139142

140143
//Used for chip layouts
141144
implementation 'com.google.android.flexbox:flexbox:3.0.0'
@@ -144,7 +147,7 @@ dependencies {
144147
implementation 'com.github.alxrm:audiowave-progressbar:0.9.2'
145148

146149
implementation 'com.google.guava:guava:31.1-android'
147-
implementation 'com.google.code.gson:gson:2.9.1'
150+
implementation 'com.google.code.gson:gson:2.10.1'
148151

149152
//Update & APK downloading
150153
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
@@ -174,10 +177,10 @@ dependencies {
174177
implementation "dev.rikka.tools.refine:runtime:$refine_version"
175178

176179
//Dagger + Hilt for injection in Astrea
177-
implementation "com.google.dagger:hilt-android:2.38.1"
178-
implementation 'com.google.dagger:dagger:2.41'
179-
kapt 'com.google.dagger:dagger-compiler:2.41'
180-
kapt "com.google.dagger:hilt-compiler:2.41"
180+
implementation "com.google.dagger:hilt-android:2.50"
181+
implementation 'com.google.dagger:dagger:2.50'
182+
kapt 'com.google.dagger:dagger-compiler:2.50'
183+
kapt "com.google.dagger:hilt-compiler:2.50"
181184

182185
//OSS libraries activity
183186
implementation 'com.google.android.gms:play-services-oss-licenses:17.0.1'
@@ -192,9 +195,9 @@ dependencies {
192195
implementation 'com.github.duanhong169:colorpicker:1.1.6'
193196

194197
//Room for local song list cache
195-
def room_version = "2.5.1"
198+
def room_version = "2.6.1"
196199
implementation "androidx.room:room-runtime:$room_version"
197-
kapt "androidx.room:room-compiler:$room_version"
200+
ksp "androidx.room:room-compiler:$room_version"
198201

199202
testImplementation 'junit:junit:4.13.2'
200203
androidTestImplementation 'androidx.test.ext:junit:1.1.5'

app/release/output-metadata.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
"type": "SINGLE",
1212
"filters": [],
1313
"attributes": [],
14-
"versionCode": 230,
15-
"versionName": "2.3",
14+
"versionCode": 232,
15+
"versionName": "2.3.2",
1616
"outputFile": "app-release.apk"
1717
}
1818
],

app/src/main/AndroidManifest.xml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
xmlns:tools="http://schemas.android.com/tools"
4-
package="com.kieronquinn.app.ambientmusicmod">
3+
xmlns:tools="http://schemas.android.com/tools">
54

65
<permission
76
android:name="com.kieronquinn.app.ambientmusicmod.ACCESS_SERVICE"
@@ -12,6 +11,7 @@
1211
<uses-permission android:name="android.permission.INTERNET" />
1312
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
1413
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
14+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
1515
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
1616
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
1717
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
@@ -79,7 +79,8 @@
7979

8080
<receiver
8181
android:name=".receivers.ExternalAccessReceiver"
82-
android:exported="true">
82+
android:exported="true"
83+
tools:ignore="ExportedReceiver">
8384
<intent-filter>
8485
<action android:name="${applicationId}.action.ENABLE" />
8586
<action android:name="${applicationId}.action.DISABLE" />
@@ -89,7 +90,8 @@
8990
</intent-filter>
9091
</receiver>
9192

92-
<service android:name=".service.AmbientMusicModForegroundService" />
93+
<service android:name=".service.AmbientMusicModForegroundService"
94+
android:foregroundServiceType="specialUse" />
9395

9496
<service
9597
android:name=".service.QuickSettingTileService"
@@ -159,6 +161,9 @@
159161
<meta-data
160162
android:name="android.appwidget.provider"
161163
android:resource="@xml/appwidgetprovider_dynamic" />
164+
<meta-data
165+
android:name="com.samsung.android.appwidget.provider"
166+
android:resource="@xml/samsung_widget" />
162167
</receiver>
163168

164169
<!-- 4x1 widget (< Android 12) -->

app/src/main/java/com/kieronquinn/app/ambientmusicmod/repositories/EncryptedSettingsRepository.kt

Lines changed: 5 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,17 @@
11
package com.kieronquinn.app.ambientmusicmod.repositories
22

33
import android.content.Context
4-
import android.content.SharedPreferences
5-
import androidx.security.crypto.EncryptedSharedPreferences
6-
import androidx.security.crypto.MasterKeys
74
import com.kieronquinn.app.ambientmusicmod.BuildConfig
85
import com.kieronquinn.app.ambientmusicmod.repositories.BaseSettingsRepository.AmbientMusicModSetting
6+
import com.kieronquinn.app.ambientmusicmod.utils.extensions.createEncryptedSharedPrefDestructively
97
import com.kieronquinn.app.ambientmusicmod.utils.extensions.randomSecureString
10-
import java.security.KeyStore
118

129
interface EncryptedSettingsRepository {
13-
14-
val encryptionAvailable: Boolean
15-
1610
val externalAccessEnabled: AmbientMusicModSetting<Boolean>
1711
val externalAccessRequireToken: AmbientMusicModSetting<Boolean>
1812
val externalAccessToken: AmbientMusicModSetting<String>
1913
val externalAccessToggleEnabled: AmbientMusicModSetting<Boolean>
2014
val externalAccessRecognitionEnabled: AmbientMusicModSetting<Boolean>
21-
2215
}
2316

2417
class EncryptedSettingsRepositoryImpl(
@@ -42,56 +35,14 @@ class EncryptedSettingsRepositoryImpl(
4235

4336
private const val EXTERNAL_ACCESS_RECOGNITION_ENABLED = "external_access_recognition_enabled"
4437
private const val DEFAULT_ACCESS_EXTERNAL_RECOGNITION_ENABLED = true
45-
46-
private fun tryLoadSharedPreferences(context: Context): SharedPreferences? {
47-
//Regular load, should work 99% of the time
48-
getSharedPreferences(context)?.let {
49-
return it
50-
}
51-
//If failed, delete the key and start again
52-
deleteMasterKeyEntry()
53-
//If it still fails, nothing we can do
54-
return getSharedPreferences(context)
55-
}
56-
57-
private fun getSharedPreferences(context: Context): SharedPreferences? {
58-
return try {
59-
val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
60-
val mainKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)
61-
EncryptedSharedPreferences.create(
62-
"${BuildConfig.APPLICATION_ID}_encrypted_prefs",
63-
mainKeyAlias,
64-
context,
65-
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
66-
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
67-
)
68-
}catch (e: Exception) {
69-
//Failed to load shared prefs
70-
null
71-
}
72-
}
73-
74-
private fun deleteMasterKeyEntry() {
75-
try {
76-
KeyStore.getInstance("AndroidKeyStore").apply {
77-
load(null)
78-
deleteEntry("_androidx_security_master_key_")
79-
}
80-
}catch (e: Exception){
81-
//Failed to delete key
82-
}
83-
}
8438
}
8539

86-
private val encryptedSharedPreferences by lazy {
87-
tryLoadSharedPreferences(context)
40+
override val sharedPreferences by lazy {
41+
context.createEncryptedSharedPrefDestructively(
42+
"${BuildConfig.APPLICATION_ID}_encrypted_prefs"
43+
)
8844
}
8945

90-
override val sharedPreferences
91-
get() = encryptedSharedPreferences ?: throw RuntimeException("Encrypted prefs failed to load")
92-
93-
override val encryptionAvailable = encryptedSharedPreferences != null
94-
9546
override val externalAccessEnabled =
9647
boolean(EXTERNAL_ACCESS_ENABLED, DEFAULT_EXTERNAL_ACCESS_ENABLED)
9748

app/src/main/java/com/kieronquinn/app/ambientmusicmod/repositories/ExternalAccessRepository.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package com.kieronquinn.app.ambientmusicmod.repositories
22

33
import android.content.Intent
4+
import com.kieronquinn.app.ambientmusicmod.repositories.RecognitionRepository.RecognitionState
45
import com.kieronquinn.app.ambientmusicmod.repositories.RemoteSettingsRepository.SettingsState
6+
import com.kieronquinn.app.ambientmusicmod.service.AmbientMusicModForegroundService
57
import com.kieronquinn.app.ambientmusicmod.utils.extensions.firstNotNull
68
import com.kieronquinn.app.pixelambientmusic.model.SettingsStateChange
79
import kotlinx.coroutines.MainScope
8-
import kotlinx.coroutines.flow.launchIn
910
import kotlinx.coroutines.launch
1011
import kotlinx.coroutines.withTimeout
1112

@@ -64,7 +65,11 @@ class ExternalAccessRepositoryImpl(
6465
recognitionRepository.requestOnDemandRecognition()
6566
}else{
6667
recognitionRepository.requestRecognition()
67-
}.launchIn(scope)
68+
}.collect {
69+
if(it is RecognitionState.Recognised){
70+
AmbientMusicModForegroundService.sendManualRecognition(it)
71+
}
72+
}
6873
}
6974
}
7075

@@ -85,21 +90,18 @@ class ExternalAccessRepositoryImpl(
8590
}
8691

8792
private suspend fun verifyTokenIfRequired(intent: Intent): Boolean {
88-
if(!encryptedSettings.encryptionAvailable) return false
8993
if(!encryptedSettings.externalAccessRequireToken.get()) return true
9094
val token = intent.getStringExtra(EXTRA_TOKEN) ?: return false
9195
return encryptedSettings.externalAccessToken.get() == token
9296
}
9397

9498
private suspend fun toggleEnabled(): Boolean {
95-
return encryptedSettings.encryptionAvailable
96-
&& encryptedSettings.externalAccessEnabled.get()
99+
return encryptedSettings.externalAccessEnabled.get()
97100
&& encryptedSettings.externalAccessToggleEnabled.get()
98101
}
99102

100103
private suspend fun recognitionEnabled(): Boolean {
101-
return encryptedSettings.encryptionAvailable
102-
&& encryptedSettings.externalAccessEnabled.get()
104+
return encryptedSettings.externalAccessEnabled.get()
103105
&& encryptedSettings.externalAccessRecognitionEnabled.get()
104106
}
105107

app/src/main/java/com/kieronquinn/app/ambientmusicmod/repositories/RemoteSettingsRepository.kt

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,33 @@ import com.kieronquinn.app.ambientmusicmod.PACKAGE_NAME_PAM
2020
import com.kieronquinn.app.ambientmusicmod.model.settings.BannerMessage
2121
import com.kieronquinn.app.ambientmusicmod.model.settings.toLocalBannerMessage
2222
import com.kieronquinn.app.ambientmusicmod.repositories.RemoteSettingsRepository.*
23-
import com.kieronquinn.app.ambientmusicmod.utils.extensions.*
23+
import com.kieronquinn.app.ambientmusicmod.utils.extensions.contentResolverAsTFlow
24+
import com.kieronquinn.app.ambientmusicmod.utils.extensions.getNetworkCapabilities
25+
import com.kieronquinn.app.ambientmusicmod.utils.extensions.getSplits
26+
import com.kieronquinn.app.ambientmusicmod.utils.extensions.isArmv7
27+
import com.kieronquinn.app.ambientmusicmod.utils.extensions.isOnDemandConfigValueSet
28+
import com.kieronquinn.app.ambientmusicmod.utils.extensions.isPermissionGranted
29+
import com.kieronquinn.app.ambientmusicmod.utils.extensions.isX86_64
30+
import com.kieronquinn.app.ambientmusicmod.utils.extensions.map
31+
import com.kieronquinn.app.ambientmusicmod.utils.extensions.onPackageChanged
32+
import com.kieronquinn.app.ambientmusicmod.utils.extensions.registerReceiverCompat
33+
import com.kieronquinn.app.ambientmusicmod.utils.extensions.safeQuery
2434
import com.kieronquinn.app.pixelambientmusic.model.LastRecognisedSong
2535
import com.kieronquinn.app.pixelambientmusic.model.SettingsStateChange
2636
import kotlinx.coroutines.CoroutineScope
2737
import kotlinx.coroutines.Dispatchers
2838
import kotlinx.coroutines.channels.awaitClose
29-
import kotlinx.coroutines.flow.*
39+
import kotlinx.coroutines.flow.Flow
40+
import kotlinx.coroutines.flow.MutableStateFlow
41+
import kotlinx.coroutines.flow.SharingStarted
42+
import kotlinx.coroutines.flow.StateFlow
43+
import kotlinx.coroutines.flow.callbackFlow
44+
import kotlinx.coroutines.flow.combine
45+
import kotlinx.coroutines.flow.flatMapLatest
46+
import kotlinx.coroutines.flow.flow
47+
import kotlinx.coroutines.flow.flowOn
48+
import kotlinx.coroutines.flow.map
49+
import kotlinx.coroutines.flow.stateIn
3050
import kotlinx.coroutines.withContext
3151
import com.kieronquinn.app.pixelambientmusic.model.SettingsState as RemoteSettingsState
3252

@@ -162,7 +182,7 @@ class RemoteSettingsRepositoryImpl(
162182
}
163183
}
164184
trySend(isEnabled())
165-
context.registerReceiver(
185+
context.registerReceiverCompat(
166186
receiver, IntentFilter(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED)
167187
)
168188
awaitClose {

0 commit comments

Comments
 (0)