Skip to content

Commit

Permalink
1.1
Browse files Browse the repository at this point in the history
- Added a new compatibility checker that checks if getModelState() is supported. This isn't 100% perfect so a bypass is also available
- Tweaked sound trigger injection to include an XML line that's required for some devices
- Fixed track list not loading for some people
- Hopefully fixed log dump zips
- Newly built modules will now also keep a copy of your original sound trigger XML. This change allows for comparison in the log dumps, and may help updates in the future.
- Removed a load of unused logging
  • Loading branch information
KieronQuinn committed Apr 17, 2021
1 parent b49095b commit 09fdf12
Show file tree
Hide file tree
Showing 50 changed files with 802 additions and 115 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Built application files
*.apk
app/*/*.apk
*.ap_
*.aab

Expand Down
41 changes: 33 additions & 8 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,20 @@ plugins {
id 'com.google.android.gms.oss-licenses-plugin'
}

def tagName = '1.0'
def tagName = '1.1'
def moduleVersionName = "1.1"
def moduleVersionCode = 11

def getLocalProperty(String propName) {
def propsFile = rootProject.file('local.properties')
if (propsFile.exists()) {
def props = new Properties()
props.load(new FileInputStream(propsFile))
return props[propName]
} else {
return ""
}
}

android {
compileSdkVersion 'android-S'
Expand All @@ -17,21 +30,25 @@ android {
applicationId "com.kieronquinn.app.ambientmusicmod"
minSdkVersion 26
targetSdkVersion 'S'
versionCode 1
versionName "1.0"
versionCode 11
versionName "1.1"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

buildConfigField("String", "BUILD_MODULE_VERSION", "\"1.0\"")
buildConfigField("int", "BUILD_MODULE_VERSION_CODE", "1")
buildConfigField("String", "BUILD_MODULE_VERSION", "\"${moduleVersionName}\"")
buildConfigField("int", "BUILD_MODULE_VERSION_CODE", "${moduleVersionCode}")
buildConfigField("String", "TAG_NAME", "\"${tagName}\"")

}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
buildConfigField("String", "TEST_OUTPUT_CSV_DIR", "\"" + getLocalProperty("test.output.csv_dir").replace("\\", "\\\\") + "\"")
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
Expand All @@ -45,6 +62,10 @@ android {
viewBinding true
}

testOptions {
unitTests.returnDefaultValues = true
}

/**
* Hack that re-replaces the minSdk and targetSdk back to levels that allow installing on lower than Android S Developer Preview
* TODO remove this when S becomes stable
Expand All @@ -58,6 +79,7 @@ android {
manifestContent = manifestContent
.replaceAll('android:minSdkVersion="S"', 'android:minSdkVersion="26"')
.replaceAll('android:targetSdkVersion="S"', 'android:targetSdkVersion="30"')
.replaceAll('android:testOnly="true"', 'android:testOnly="false"')
def fos = new FileOutputStream(manifestFile.getPath())
fos.write(manifestContent.getBytes())
fos.flush()
Expand Down Expand Up @@ -120,7 +142,9 @@ dependencies {
implementation 'com.squareup.picasso:picasso:2.71828'

//libsu for root
implementation "com.github.topjohnwu.libsu:core:3.1.1"
def libsuVersion = '3.1.2'
implementation "com.github.topjohnwu.libsu:core:${libsuVersion}"
implementation "com.github.topjohnwu.libsu:service:${libsuVersion}"

//Insetter for compat status/nav bar insets
implementation 'dev.chrisbanes.insetter:insetter:0.5.0'
Expand All @@ -139,8 +163,9 @@ dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'


testImplementation 'junit:junit:4.+'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.json:json:20201115'
testImplementation 'com.github.doyaaaaaken:kotlin-csv-jvm:0.15.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
Expand Down
4 changes: 2 additions & 2 deletions app/release/output-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
{
"type": "SINGLE",
"filters": [],
"versionCode": 1,
"versionName": "1.0",
"versionCode": 11,
"versionName": "1.1",
"outputFile": "app-release.apk"
}
]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// IRootService.aidl
package com.kieronquinn.app.ambientmusicmod;

import android.os.ParcelUuid;

interface IRootService {

int getModelState(in ParcelUuid uuid);

}
8 changes: 4 additions & 4 deletions app/src/main/assets/magisk/Ambient/module.prop
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
id=AmbientMusicTest
id=AmbientMusicMod
name=Ambient Music Mod
version=1.0
versionCode=1
version=%MODULEVERSION%
versionCode=%MODULEVERSIONCODE%
author=Kieron Quinn / Quinny899
description=Port of Pixel Ambient Music to other devices. You MUST use the Xposed module AS WELL as this module for it to work.
description=Port of Pixel Ambient Music to other, compatible devices. You MUST enable the Xposed module AS WELL as this module for it to work.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import com.kieronquinn.app.ambientmusicmod.app.ui.installer.InstallerViewModel
import com.kieronquinn.app.ambientmusicmod.app.ui.installer.InstallerViewModelImpl
import com.kieronquinn.app.ambientmusicmod.app.ui.installer.build.InstallerBuildViewModel
import com.kieronquinn.app.ambientmusicmod.app.ui.installer.build.InstallerBuildViewModelImpl
import com.kieronquinn.app.ambientmusicmod.app.ui.installer.modelstate.InstallerModelStateCheckBottomSheetViewModel
import com.kieronquinn.app.ambientmusicmod.app.ui.installer.modelstate.InstallerModelStateCheckBottomSheetViewModelImpl
import com.kieronquinn.app.ambientmusicmod.app.ui.installer.outputpicker.InstallerOutputPickerViewModel
import com.kieronquinn.app.ambientmusicmod.app.ui.installer.outputpicker.InstallerOutputPickerViewModelImpl
import com.kieronquinn.app.ambientmusicmod.app.ui.installer.xposed.InstallerXposedWarningBottomSheetViewModel
Expand Down Expand Up @@ -130,13 +132,14 @@ class AmbientApplication: Application() {
viewModel<InstallerXposedWarningBottomSheetViewModel> { InstallerXposedWarningBottomSheetViewModelImpl() }
viewModel<InstallerOutputPickerViewModel> { InstallerOutputPickerViewModelImpl() }
viewModel<InstallerBuildViewModel> { InstallerBuildViewModelImpl(get()) }
viewModel<InstallerModelStateCheckBottomSheetViewModel> { InstallerModelStateCheckBottomSheetViewModelImpl(get()) }

//Database viewer
viewModel<DatabaseSharedViewModel> { DatabaseSharedViewModelImpl(get()) }
viewModel<DatabaseCopyWarningViewModel> { DatabaseCopyWarningViewModelImpl() }
viewModel<DatabaseCopyViewModel> { DatabaseCopyViewModelImpl(get()) }
viewModel<DatabaseViewerViewModel> { DatabaseViewerViewModelImpl(get()) }
viewModel<DatabaseViewerSharedViewModel> { DatabaseViewerSharedViewModelImpl(get()) }
viewModel<DatabaseViewerSharedViewModel> { DatabaseViewerSharedViewModelImpl() }
viewModel<DatabaseViewerTracksViewModel> { DatabaseViewerTracksViewModelImpl() }
viewModel<DatabaseViewerArtistsViewModel> { DatabaseViewerArtistsViewModelImpl() }
viewModel<DatabaseViewerArtistTracksViewModel> { DatabaseViewerArtistTracksViewModelImpl() }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.kieronquinn.app.ambientmusicmod.app.service

import android.annotation.SuppressLint
import android.content.Intent
import android.os.IBinder
import android.os.ParcelUuid
import com.kieronquinn.app.ambientmusicmod.IRootService
import com.kieronquinn.app.ambientmusicmod.xposed.wrappers.SoundTriggerManager
import com.topjohnwu.superuser.ipc.RootService

/**
* Root Service (using libsu RootService) that calls getModelState() on Sound Trigger with the Ambient model UUID
* The UUID actually doesn't matter here, what we're interested in is the response from the system.
* 0 -> OK, model is loaded
* -38 -> "Crash", getModelState is not natively supported (probably Sound Trigger 2.1), but will start working with the Xposed module
* Any other unknown states (See SoundTriggerManager.isResponseOk()) are also OK, anything else that is known is a fail.
* The most common fail response is -MAX_INT, which indicates the method call failed gracefully and getModelState is NOT supported.
*/
class AmbientRootService: RootService() {

private val rootBinder = object: IRootService.Stub() {

@SuppressLint("WrongConstant")
override fun getModelState(uuid: ParcelUuid): Int {
val soundTrigger = SoundTriggerManager(getSystemService("soundtrigger"), classLoader)
return soundTrigger.getModelState(uuid.uuid)
}

}

override fun onBind(intent: Intent): IBinder {
return rootBinder
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ class GetModelStateForegroundService: LifecycleService(), SharedPreferences.OnSh
super.onCreate()
createNotificationChannel()
startForeground(NOTIFICATION_ID_FOREGROUND, createNotification())
Log.d("GetModelState", "jobTime $jobTime")
if(jobTime == 0){
stopSelf()
return
Expand Down Expand Up @@ -128,7 +127,6 @@ class GetModelStateForegroundService: LifecycleService(), SharedPreferences.OnSh
if(!minuteTicker.isScheduled && jobTime != 0){
val timeToAdd: Long = if(jobTime == -1){
//Automatic mode selected
Log.d("GetModelState", "Using automatic time of $automaticTime")
automaticTime ?: DEFAULT_AUTOMATIC_TIME
}else{
//Job time (in minutes) * 60 seconds - 10 seconds
Expand Down Expand Up @@ -157,7 +155,6 @@ class GetModelStateForegroundService: LifecycleService(), SharedPreferences.OnSh
}

override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
Log.d("GetModelState", "onSharedPreferenceChanged")
if(key == AmbientSharedPreferences.KEY_JOB_TIME){
// Time changed, we'll need to re-schedule the alarm
jobTime = settings.jobTime
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,21 @@ class AmbientContainerFragment: BaseFragment<FragmentContainerBinding>(FragmentC
binding.mainAppLink.root.setOnClickListener {
viewModel.onMainAppLinkClicked()
}
binding.mainAppLink.root.slideIn {
sharedViewModel.setAppLinkHeight(binding.mainAppLink.root.height.toFloat())
binding.mainAppLink.root.run {
slideIn {
sharedViewModel.setAppLinkHeight(binding.mainAppLink.root.height.toFloat())
isClickable = true
isFocusable = true
}
}
} else {
binding.mainAppLink.root.setOnClickListener(null)
binding.mainAppLink.root.slideOut {
sharedViewModel.setAppLinkHeight(0f)
binding.mainAppLink.root.run {
slideOut {
sharedViewModel.setAppLinkHeight(0f)
isClickable = false
isFocusable = false
}
}
}
}
Expand Down Expand Up @@ -220,7 +228,7 @@ class AmbientContainerFragment: BaseFragment<FragmentContainerBinding>(FragmentC
setIconResource(R.drawable.ic_build)
backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.accent))
}
AmbientContainerSharedViewModel.CompatibilityState.NOT_COMPATIBLE -> {
AmbientContainerSharedViewModel.CompatibilityState.NOT_COMPATIBLE, AmbientContainerSharedViewModel.CompatibilityState.NEED_MODULE_CHECK -> {
//Yellow
setIconResource(R.drawable.ic_warning)
backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.fab_color_warning))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@ abstract class AmbientContainerSharedViewModel: ViewModel() {
abstract val mainAppLinkHeight: Flow<Float>
abstract val fabClick: Flow<InstallerViewModel.CompatibilityStatus>
abstract val shouldShowFab: Flow<FabVisibility>
abstract val forceRefreshBus: Flow<Unit>

abstract fun setAppLinkHeight(height: Float)
abstract fun setCompatibilityState(compatibilityState: InstallerViewModel.CompatibilityStatus)
abstract fun setPage(@IdRes pageId: Int)
abstract fun onFabClicked()
abstract fun forceRefresh()

enum class CompatibilityState {
COMPATIBLE,
NO_XPOSED,
NOT_COMPATIBLE
NOT_COMPATIBLE,
NEED_MODULE_CHECK
}

sealed class FabVisibility {
Expand All @@ -41,8 +45,10 @@ class AmbientContainerSharedViewModelImpl: AmbientContainerSharedViewModel() {
private val _fabClick = MutableSharedFlow<InstallerViewModel.CompatibilityStatus>()
override val fabClick = _fabClick.asSharedFlow()

private val _forceRefreshBus = MutableSharedFlow<Unit>()
override val forceRefreshBus = _forceRefreshBus.asSharedFlow()

override fun setAppLinkHeight(height: Float) {
Log.d("AC", "setAppLinkHeight $height")
viewModelScope.launch {
_mainAppLinkHeight.emit(height)
}
Expand All @@ -64,7 +70,6 @@ class AmbientContainerSharedViewModelImpl: AmbientContainerSharedViewModel() {

override fun onFabClicked() {
viewModelScope.launch {
Log.d("FabClick", "VM ${compatibilityState.value}")
_fabClick.emit(compatibilityState.value ?: return@launch)
}
}
Expand All @@ -75,4 +80,10 @@ class AmbientContainerSharedViewModelImpl: AmbientContainerSharedViewModel() {
}
}

override fun forceRefresh() {
viewModelScope.launch {
_forceRefreshBus.emit(Unit)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ class AmbientContainerViewModelImpl(private val navigation: NavigationComponent,
override val currentPage: Flow<Page?> = _currentPage.asStateFlow()

private val _shouldShowMainAppLink = combine(mainAppInstalled, _currentPage){ appInstalled: Boolean, page: Page? ->
Log.d("AC", "shouldShowMainAppLink ${appInstalled && page?.id == R.id.settingsFragment}")
appInstalled && page?.id == R.id.settingsFragment
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ class DatabaseSharedViewModelImpl(private val context: Context): DatabaseSharedV
}

private fun loadTracks() = viewModelScope.launch(Dispatchers.IO) {
Log.d("LoadBus", "loadTracks")
val tracks = ArrayList<Track>()
val startTime = System.currentTimeMillis()
val success = Superpacks.forEachSuperpack(context, getCoreMatcherFile()){ file, index, count ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,10 @@ class DatabaseCopyBottomSheetFragment: BaseBottomSheetDialogFragment() {


private val startReceiver = SecureBroadcastReceiver { _, _ ->
Log.d("DatabaseCopy", "start received")
viewModel.copyStarted()
}

private val resultReceiver = SecureBroadcastReceiver { _, _ ->
Log.d("DatabaseCopy", "finish received")
viewModel.copyFinished()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ class DatabaseViewerFragment: BaseFragment<FragmentDatabaseViewerBinding>(Fragme
}
}

private var isLoading = false

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
lifecycleScope.launchWhenResumed {
launch {
innerSharedViewModel.loadBus.collect {
Log.d("LoadBus", "ping")
sharedViewModel.reload()
}
}
Expand All @@ -86,14 +87,14 @@ class DatabaseViewerFragment: BaseFragment<FragmentDatabaseViewerBinding>(Fragme
}
launch {
viewModel.shouldShowControls.collect {
binding.bottomNavigation.isVisible = it
binding.searchContainer.isVisible = it
if(!isLoading) {
binding.bottomNavigation.isVisible = it
binding.searchContainer.isVisible = it
}
}
}
launch {
Log.d("XASuperpacks", "start collect")
viewModel.shouldShowUpdateBanner.collect {
Log.d("XASuperpacks", "update available $it")
binding.databaseViewerUpdate.root.isVisible = it
}
}
Expand Down Expand Up @@ -134,6 +135,7 @@ class DatabaseViewerFragment: BaseFragment<FragmentDatabaseViewerBinding>(Fragme

private fun handleState(state: DatabaseSharedViewModel.State) = when(state) {
is DatabaseSharedViewModel.State.Loading -> {
isLoading = true
binding.navHostFragmentDatabaseViewer.isVisible = false
binding.databaseViewerLoading.isVisible = true
binding.databaseViewerLoadingProgressIndeterminate.isVisible = false
Expand All @@ -142,13 +144,15 @@ class DatabaseViewerFragment: BaseFragment<FragmentDatabaseViewerBinding>(Fragme
binding.bottomNavigation.isVisible = false
}
is DatabaseSharedViewModel.State.Loaded -> {
isLoading = false
binding.navHostFragmentDatabaseViewer.isVisible = true
binding.databaseViewerLoading.isVisible = false
binding.searchContainer.isVisible = true
binding.bottomNavigation.isVisible = true
viewModel.onLoaded()
}
is DatabaseSharedViewModel.State.Sorting, DatabaseSharedViewModel.State.Idle, DatabaseSharedViewModel.State.StartLoading -> {
is DatabaseSharedViewModel.State.Sorting, is DatabaseSharedViewModel.State.Idle, is DatabaseSharedViewModel.State.StartLoading -> {
isLoading = true
binding.databaseViewerLoading.isVisible = true
binding.databaseViewerLoadingProgress.visibility = View.INVISIBLE
binding.databaseViewerLoadingProgressIndeterminate.isVisible = true
Expand Down
Loading

0 comments on commit 09fdf12

Please sign in to comment.