Skip to content
This repository was archived by the owner on Oct 21, 2023. It is now read-only.

Commit a9c6a9a

Browse files
committed
Closes #432
1 parent f06db17 commit a9c6a9a

File tree

22 files changed

+85
-67
lines changed

22 files changed

+85
-67
lines changed

app/build.gradle

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ android {
1414
applicationId "com.crazylegend.vigilante"
1515
minSdkVersion 24
1616
targetSdkVersion 32
17-
versionCode 17
18-
versionName "1.2.4"
17+
versionCode 18
18+
versionName "1.2.5"
1919
vectorDrawables.useSupportLibrary = true
2020
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
2121

@@ -74,7 +74,7 @@ dependencies {
7474
//core
7575
implementation 'androidx.preference:preference-ktx:1.2.0'
7676
implementation 'androidx.core:core-ktx:1.7.0'
77-
implementation 'androidx.fragment:fragment-ktx:1.4.1'
77+
implementation 'androidx.fragment:fragment-ktx:1.5.0-beta01'
7878
implementation 'androidx.appcompat:appcompat:1.4.1'
7979
implementation "androidx.startup:startup-runtime:1.1.1"
8080

app/src/main/java/com/crazylegend/vigilante/MainActivity.kt

+2-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import android.os.Bundle
66
import androidx.appcompat.app.AppCompatActivity
77
import androidx.core.view.isVisible
88
import androidx.navigation.NavController
9-
import androidx.navigation.findNavController
109
import androidx.navigation.fragment.NavHostFragment
1110
import com.crazylegend.kotlinextensions.misc.requestBatteryOptimizations
1211
import com.crazylegend.kotlinextensions.power.isIgnoringBatteryOptimization
@@ -20,10 +19,7 @@ import dagger.hilt.android.AndroidEntryPoint
2019
@AndroidEntryPoint
2120
class MainActivity : AppCompatActivity() {
2221

23-
override fun attachBaseContext(newBase: Context?) {
24-
super.attachBaseContext(newBase)
25-
applyOverrideConfiguration(Configuration())
26-
}
22+
override fun attachBaseContext(newBase: Context?) { super.attachBaseContext(newBase?.let { LocaleHelper.onAttach(it) })}
2723

2824
override fun applyOverrideConfiguration(overrideConfiguration: Configuration?) {
2925
super.applyOverrideConfiguration(overrideConfiguration?.let {
@@ -35,7 +31,7 @@ class MainActivity : AppCompatActivity() {
3531

3632
private val navController: NavController
3733
get() =
38-
binding.navHostContainer.getFragment<NavHostFragment>().navController
34+
binding.navHostContainer.getFragment<NavHostFragment>().navController
3935

4036
override fun onSupportNavigateUp() = navController.navigateUp()
4137

app/src/main/java/com/crazylegend/vigilante/contracts/service/ServiceLifecycle.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import kotlin.coroutines.CoroutineContext
1616
interface ServiceLifecycle : LifecycleOwner, LifecycleEventObserver {
1717

1818
val coroutineContext: CoroutineContext
19-
get() = Dispatchers.Main
19+
get() = Dispatchers.Main.immediate
2020

2121
val scope: CoroutineScope
2222
get() = CoroutineScope(coroutineContext + SupervisorJob())

app/src/main/java/com/crazylegend/vigilante/crashes/CrashFragment.kt

+3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ class CrashFragment : AbstractFragment<LayoutRecyclerBinding>(R.layout.layout_re
4444
uiAction { shareCrash(item) }
4545
}
4646
}
47+
crashesAdapter.onLongClickListener = {position, _, _ ->
48+
onUnableToCopyCrash(position)
49+
}
4750
}
4851

4952
private fun onUnableToCopyCrash(position: Int) {

app/src/main/java/com/crazylegend/vigilante/di/modules/coroutines/appScope/CoroutinesScopesModule.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.crazylegend.vigilante.di.modules.coroutines.appScope
22

33
import com.crazylegend.vigilante.di.modules.coroutines.dispatchers.DefaultDispatcher
4+
import com.crazylegend.vigilante.di.modules.coroutines.dispatchers.MainImmediateDispatcher
45
import dagger.Module
56
import dagger.Provides
67
import dagger.hilt.InstallIn
@@ -21,7 +22,7 @@ object CoroutinesScopesModule {
2122
@Singleton
2223
@Provides
2324
@ApplicationScope
24-
fun providesCoroutineScope(@DefaultDispatcher defaultDispatcher: CoroutineDispatcher): CoroutineScope =
25+
fun providesCoroutineScope(@MainImmediateDispatcher defaultDispatcher: CoroutineDispatcher): CoroutineScope =
2526
CoroutineScope(SupervisorJob() + defaultDispatcher)
2627

2728
}

app/src/main/java/com/crazylegend/vigilante/di/providers/BroadcastProvider.kt

+17-10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import android.content.Intent
66
import android.content.IntentFilter
77
import androidx.lifecycle.ServiceLifecycleDispatcher
88
import com.crazylegend.common.ifTrue
9+
import com.crazylegend.context.registerReceiverSafe
10+
import com.crazylegend.context.unRegisterReceiverSafe
911
import com.crazylegend.vigilante.contracts.service.ServiceLifecycle
1012
import com.crazylegend.vigilante.di.providers.prefs.logging.LoggingPrefs
1113
import com.crazylegend.vigilante.headset.HeadsetReceiver
@@ -20,11 +22,12 @@ import javax.inject.Inject
2022

2123
@ServiceScoped
2224
class BroadcastProvider @Inject constructor(
23-
private val screenReceiver: ScreenReceiver,
24-
private val headsetPlugReceiver: HeadsetReceiver,
25-
private val powerReceiver: PowerReceiver,
26-
private val service: Service,
27-
private val loggingPrefs: LoggingPrefs) : ServiceLifecycle {
25+
private val screenReceiver: ScreenReceiver,
26+
private val headsetPlugReceiver: HeadsetReceiver,
27+
private val powerReceiver: PowerReceiver,
28+
private val service: Service,
29+
private val loggingPrefs: LoggingPrefs
30+
) : ServiceLifecycle {
2831

2932
override val serviceLifecycleDispatcher = ServiceLifecycleDispatcher(this)
3033

@@ -37,9 +40,9 @@ class BroadcastProvider @Inject constructor(
3740
}
3841

3942
override fun disposeResources() {
40-
loggingPrefs.isHeadsetLoggingEnabled.ifTrue { service.unregisterReceiver(headsetPlugReceiver) }
41-
loggingPrefs.isLockScreenLoggingEnabled.ifTrue { service.unregisterReceiver(screenReceiver) }
42-
loggingPrefs.isPowerLoggingEnabled.ifTrue { service.unregisterReceiver(powerReceiver) }
43+
service.unRegisterReceiverSafe(headsetPlugReceiver)
44+
service.unRegisterReceiverSafe(screenReceiver)
45+
service.unRegisterReceiverSafe(powerReceiver)
4346
}
4447

4548
private fun registerPowerReceiver() {
@@ -58,9 +61,13 @@ class BroadcastProvider @Inject constructor(
5861
}
5962
}
6063

61-
private inline fun registerReceiver(initialAction: String, broadcastReceiver: BroadcastReceiver, filterConfig: IntentFilter.() -> Unit = {}) {
64+
private inline fun registerReceiver(
65+
initialAction: String,
66+
broadcastReceiver: BroadcastReceiver,
67+
filterConfig: IntentFilter.() -> Unit = {}
68+
) {
6269
val filter = IntentFilter(initialAction)
6370
filter.filterConfig()
64-
service.registerReceiver(broadcastReceiver, filter)
71+
service.registerReceiverSafe(broadcastReceiver, filter)
6572
}
6673
}

app/src/main/java/com/crazylegend/vigilante/di/providers/prefs/logging/LoggingPrefs.kt

+7-7
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,33 @@ import javax.inject.Singleton
1414
class LoggingPrefs @Inject constructor(@EncryptedPrefs private val defaultPrefs: SharedPreferences) : LoggingPreferences {
1515

1616
override val isPermissionLoggingEnabled: Boolean
17-
get() = getBooleanState(LOG_PERMISSIONS_KEY)
17+
get() = getBooleanState(LOG_PERMISSIONS_KEY, true)
1818

1919
override fun setPermissionLoggingState(isEnabled: Boolean) = putBooleanState(LOG_NOTIFICATIONS_KEY, isEnabled)
2020

2121
override val isPowerLoggingEnabled: Boolean
22-
get() = getBooleanState(LOG_POWER_KEY)
22+
get() = getBooleanState(LOG_POWER_KEY, true)
2323

2424
override fun setPowerLoggingState(isEnabled: Boolean) = putBooleanState(LOG_POWER_KEY, isEnabled)
2525

2626
override val isHeadsetLoggingEnabled: Boolean
27-
get() = getBooleanState(LOG_HEADSET_KEY)
27+
get() = getBooleanState(LOG_HEADSET_KEY, true)
2828

2929
override fun setHeadsetLoggingState(isEnabled: Boolean) = putBooleanState(LOG_HEADSET_KEY, isEnabled)
3030

3131
override val isNotificationsLoggingEnabled: Boolean
32-
get() = getBooleanState(LOG_NOTIFICATIONS_KEY)
32+
get() = getBooleanState(LOG_NOTIFICATIONS_KEY, true)
3333

3434
override val isEmptyNotificationsLoggingEnabled: Boolean
35-
get() = getBooleanState(LOG_EMPTY_PERMISSIONS_KEY)
35+
get() = getBooleanState(LOG_EMPTY_PERMISSIONS_KEY, true)
3636

3737
override fun setNotificationsLoggingState(isEnabled: Boolean) = putBooleanState(LOG_NOTIFICATIONS_KEY, isEnabled)
3838

3939
override val isLockScreenLoggingEnabled: Boolean
40-
get() = getBooleanState(LOG_LOCKSCREEN_KEY)
40+
get() = getBooleanState(LOG_LOCKSCREEN_KEY, true)
4141

4242
override fun setLockScreenLoggingState(isEnabled: Boolean) = putBooleanState(LOG_LOCKSCREEN_KEY, isEnabled)
4343

4444
private fun putBooleanState(key: String, state: Boolean) = defaultPrefs.putBoolean(key, state)
45-
private fun getBooleanState(key: String) = defaultPrefs.getBoolean(key, false)
45+
private fun getBooleanState(key: String, default: Boolean = false) = defaultPrefs.getBoolean(key, default)
4646
}

app/src/main/java/com/crazylegend/vigilante/location/LocationProcessor.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ class LocationProcessor @Inject constructor(
4545
locationStatusReceiver = initLocationStatusReceiver()
4646

4747
scope.launch {
48-
locationStatus.collectLatest {
49-
if (it) {
48+
locationStatus.collectLatest { isGPSEnabled ->
49+
if (isGPSEnabled) {
5050
setLocationIsUsed()
5151
VigilanteService.serviceLayoutListener?.showLocation()
5252
} else {

app/src/main/java/com/crazylegend/vigilante/notifications/NotificationsProvider.kt

+7-5
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,18 @@ import android.view.accessibility.AccessibilityEvent
77
import androidx.lifecycle.ServiceLifecycleDispatcher
88
import com.crazylegend.common.currentTimeMillis
99
import com.crazylegend.common.tryOrElse
10-
import com.crazylegend.coroutines.ioDispatcher
1110
import com.crazylegend.vigilante.BuildConfig
1211
import com.crazylegend.vigilante.contracts.service.ServiceLifecycle
12+
import com.crazylegend.vigilante.di.modules.coroutines.dispatchers.IoDispatcher
1313
import com.crazylegend.vigilante.di.providers.prefs.defaultPrefs.DefaultPreferencessProvider
1414
import com.crazylegend.vigilante.di.providers.prefs.logging.LoggingPrefs
15+
import com.crazylegend.vigilante.notifications.db.NotificationsDAO
1516
import com.crazylegend.vigilante.notifications.db.NotificationsModel
16-
import com.crazylegend.vigilante.notifications.db.NotificationsRepo
1717
import dagger.hilt.android.scopes.ServiceScoped
18-
import kotlinx.coroutines.launch
19-
import java.util.*
18+
import java.util.Date
2019
import javax.inject.Inject
20+
import kotlinx.coroutines.CoroutineDispatcher
21+
import kotlinx.coroutines.launch
2122

2223
/**
2324
* Created by crazy on 10/20/20 to long live and prosper !
@@ -26,7 +27,8 @@ import javax.inject.Inject
2627
class NotificationsProvider @Inject constructor(
2728
private val prefsProvider: DefaultPreferencessProvider,
2829
private val loggingPrefs: LoggingPrefs,
29-
private val notificationsRepo: NotificationsRepo
30+
private val notificationsRepo: NotificationsDAO,
31+
@IoDispatcher private val ioDispatcher: CoroutineDispatcher
3032
) : ServiceLifecycle {
3133

3234
fun processEvent(event: AccessibilityEvent) {

app/src/main/java/com/crazylegend/vigilante/notifications/details/NotificationDetailsViewModel.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package com.crazylegend.vigilante.notifications.details
33
import androidx.lifecycle.ViewModel
44
import androidx.lifecycle.viewModelScope
55
import com.crazylegend.database.coroutines.dbCallStateFlow
6-
import com.crazylegend.vigilante.notifications.db.NotificationsRepo
6+
import com.crazylegend.vigilante.notifications.db.NotificationsDAO
77
import dagger.assisted.Assisted
88
import dagger.assisted.AssistedFactory
99
import dagger.assisted.AssistedInject
@@ -12,8 +12,8 @@ import dagger.assisted.AssistedInject
1212
* Created by crazy on 11/7/20 to long live and prosper !
1313
*/
1414
class NotificationDetailsViewModel @AssistedInject constructor(
15-
private val notificationsRepo: NotificationsRepo,
16-
@Assisted private val notificationID: Int) : ViewModel() {
15+
private val notificationsRepo: NotificationsDAO,
16+
@Assisted private val notificationID: Int) : ViewModel() {
1717

1818
@AssistedFactory
1919
interface NotificationDetailsVMFactory {

app/src/main/java/com/crazylegend/vigilante/notifications/ui/NotificationsViewModel.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package com.crazylegend.vigilante.notifications.ui
22

33
import androidx.lifecycle.ViewModel
44
import androidx.lifecycle.viewModelScope
5-
import com.crazylegend.vigilante.notifications.db.NotificationsRepo
5+
import com.crazylegend.vigilante.notifications.db.NotificationsDAO
66
import com.crazylegend.vigilante.paging.PagingProvider
77
import dagger.hilt.android.lifecycle.HiltViewModel
88
import javax.inject.Inject
@@ -12,7 +12,7 @@ import javax.inject.Inject
1212
*/
1313
@HiltViewModel
1414
class NotificationsViewModel @Inject constructor(
15-
private val repo: NotificationsRepo,
15+
private val repo: NotificationsDAO,
1616
pagingProvider: PagingProvider
1717
) : ViewModel() {
1818

app/src/main/java/com/crazylegend/vigilante/permissions/PermissionsProcessor.kt

+5-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import androidx.lifecycle.ServiceLifecycleDispatcher
66
import com.crazylegend.coroutines.makeIOCall
77
import com.crazylegend.string.isNotNullOrEmpty
88
import com.crazylegend.vigilante.contracts.service.ServiceLifecycle
9+
import com.crazylegend.vigilante.di.modules.coroutines.dispatchers.IoDispatcher
910
import com.crazylegend.vigilante.permissions.db.PermissionRequestModel
1011
import com.crazylegend.vigilante.permissions.db.PermissionRequestsDAO
1112
import dagger.hilt.android.scopes.ServiceScoped
@@ -14,14 +15,16 @@ import kotlinx.coroutines.flow.collectLatest
1415
import kotlinx.coroutines.launch
1516
import java.util.concurrent.atomic.AtomicReference
1617
import javax.inject.Inject
18+
import kotlinx.coroutines.CoroutineDispatcher
1719

1820
/**
1921
* Created by crazy on 10/21/20 to long live and prosper !
2022
*/
2123
@ServiceScoped
2224
@SuppressLint("DefaultLocale")
2325
class PermissionsProcessor @Inject constructor(
24-
private val permissionRequestsRepository: PermissionRequestsDAO
26+
private val permissionRequestsRepository: PermissionRequestsDAO,
27+
@IoDispatcher private val ioDispatcher: CoroutineDispatcher
2528
) : ServiceLifecycle {
2629

2730
override val serviceLifecycleDispatcher: ServiceLifecycleDispatcher = ServiceLifecycleDispatcher(this)
@@ -44,7 +47,7 @@ class PermissionsProcessor @Inject constructor(
4447
val settingsTitle = settingsPermissionTitle.getAndSet(null)
4548
val permissionRequestModel = PermissionRequestModel(newPermissionMessage, currentPackageRef, settingsAppName = settingsTitle)
4649
settingsPermissionTitle.set(null)
47-
scope.makeIOCall {
50+
scope.launch(ioDispatcher) {
4851
permissionRequestsRepository.insertPermissionRequest(permissionRequestModel)
4952
}
5053
}

app/src/main/java/com/crazylegend/vigilante/screen/ScreenReceiver.kt

+5-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ import com.crazylegend.vigilante.di.modules.coroutines.appScope.ApplicationScope
77
import com.crazylegend.vigilante.screen.db.ScreenModel
88
import com.crazylegend.vigilante.screen.db.ScreenRepository
99
import dagger.hilt.android.scopes.ServiceScoped
10-
import kotlinx.coroutines.*
1110
import javax.inject.Inject
11+
import kotlinx.coroutines.CoroutineScope
12+
import kotlinx.coroutines.NonCancellable
13+
import kotlinx.coroutines.launch
14+
import kotlinx.coroutines.withContext
1215

1316
/**
1417
* Created by crazy on 10/30/20 to long live and prosper !
@@ -28,7 +31,7 @@ class ScreenReceiver @Inject constructor(
2831
else -> null
2932
}
3033
screenModel?.apply {
31-
appScope.launch() {
34+
appScope.launch {
3235
withContext(NonCancellable) {
3336
screenRepository.insertScreenAction(this@apply)
3437
}

app/src/main/java/com/crazylegend/vigilante/utils/Extensions.kt

+14-10
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ import com.crazylegend.intent.newIntent
1919
import com.crazylegend.lifecycle.viewCoroutineScope
2020
import com.crazylegend.receivers.isServiceRunning
2121
import com.crazylegend.receivers.startForegroundService
22+
import com.crazylegend.security.encryptedSharedPreferences
2223
import com.crazylegend.view.dimen
2324
import com.crazylegend.vigilante.R
2425
import com.crazylegend.vigilante.database.migrations.CameraAndMicRemovalMigration
2526
import com.crazylegend.vigilante.service.VigilanteService
27+
import com.crazylegend.vigilante.settings.THEME_PREF_KEY
2628
import net.sqlcipher.database.SQLiteDatabase
2729
import net.sqlcipher.database.SupportFactory
2830

@@ -37,10 +39,10 @@ const val MY_OTHER_APPS_URL = "https://funkymuse.dev/apps/"
3739
const val NEW_ISSUE_URL = "${GITHUB_URL}issues/new"
3840
const val DEFAULT_ANIM_TIME = 1000L
3941
val dismissPackages = setOf(
40-
"com.google.android.permissioncontroller",
41-
"com.android.systemui",
42-
"com.google.android.packageinstaller",
43-
"com.android.packageinstaller",
42+
"com.google.android.permissioncontroller",
43+
"com.android.systemui",
44+
"com.google.android.packageinstaller",
45+
"com.android.packageinstaller",
4446
)
4547

4648
fun Context.startVigilante() {
@@ -58,18 +60,18 @@ inline fun <reified T : RoomDatabase> Context.instantiateDatabase(cameraDbName:
5860
val passphrase = SQLiteDatabase.getBytes(packageName.toCharArray())
5961
val factory = SupportFactory(passphrase)
6062
return Room.databaseBuilder(this, T::class.java, cameraDbName)
61-
.addMigrations(CameraAndMicRemovalMigration())
62-
.openHelperFactory(factory)
63-
.build()
63+
.addMigrations(CameraAndMicRemovalMigration())
64+
.openHelperFactory(factory)
65+
.build()
6466
}
6567

6668
@Suppress("UNCHECKED_CAST")
6769
inline fun <reified T : ViewModel> Fragment.assistedViewModel(
68-
crossinline viewModelProducer: (SavedStateHandle) -> T
70+
crossinline viewModelProducer: (SavedStateHandle) -> T
6971
) = viewModels<T> {
7072
object : AbstractSavedStateViewModelFactory(this, arguments) {
7173
override fun <T : ViewModel> create(key: String, modelClass: Class<T>, handle: SavedStateHandle) =
72-
viewModelProducer(handle) as T
74+
viewModelProducer(handle) as T
7375
}
7476
}
7577

@@ -86,4 +88,6 @@ fun PreferenceFragmentCompat.addSpacingForPreferenceBackButton() {
8688
clipToPadding = false
8789
updatePadding(bottom = dimen(R.dimen.padding_bottom_scroll).toInt())
8890
}
89-
}
91+
}
92+
93+
fun Context.darkMode() = encryptedSharedPreferences().getBoolean(THEME_PREF_KEY, false)

app/src/main/res/layout/dialog_one_time_password.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@
109109
<com.google.android.material.button.MaterialButton
110110
android:id="@+id/generatePassword"
111111
app:backgroundTint="@color/primary"
112-
android:textColor="@android:color/white"
112+
android:textColor="@color/white"
113113
android:layout_width="wrap_content"
114114
android:layout_height="wrap_content"
115115
android:layout_marginTop="16dp"

0 commit comments

Comments
 (0)