aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/Application.kt14
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/git/base/BaseGitActivity.kt19
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitConfigActivity.kt15
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitServerConfigActivity.kt12
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordFragment.kt3
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordStore.kt2
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/proxy/ProxySelectorActivity.kt16
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/settings/RepositorySettings.kt23
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt17
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt17
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/proxy/ProxyUtils.kt21
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt51
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/settings/Migrations.kt21
13 files changed, 140 insertions, 91 deletions
diff --git a/app/src/main/java/dev/msfjarvis/aps/Application.kt b/app/src/main/java/dev/msfjarvis/aps/Application.kt
index d7ca97bc..508bdbf9 100644
--- a/app/src/main/java/dev/msfjarvis/aps/Application.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/Application.kt
@@ -16,18 +16,24 @@ import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
import com.github.ajalt.timberkt.Timber.DebugTree
import com.github.ajalt.timberkt.Timber.plant
import dagger.hilt.android.HiltAndroidApp
+import dev.msfjarvis.aps.injection.context.FilesDirPath
+import dev.msfjarvis.aps.injection.prefs.SettingsPreferences
import dev.msfjarvis.aps.util.extensions.getString
-import dev.msfjarvis.aps.util.extensions.sharedPrefs
import dev.msfjarvis.aps.util.git.sshj.setUpBouncyCastleForSshj
import dev.msfjarvis.aps.util.proxy.ProxyUtils
+import dev.msfjarvis.aps.util.settings.GitSettings
import dev.msfjarvis.aps.util.settings.PreferenceKeys
import dev.msfjarvis.aps.util.settings.runMigrations
+import javax.inject.Inject
@Suppress("Unused")
@HiltAndroidApp
class Application : android.app.Application(), SharedPreferences.OnSharedPreferenceChangeListener {
- private val prefs by lazy { sharedPrefs }
+ @Inject @SettingsPreferences lateinit var prefs: SharedPreferences
+ @Inject @FilesDirPath lateinit var filesDirPath: String
+ @Inject lateinit var proxyUtils: ProxyUtils
+ @Inject lateinit var gitSettings: GitSettings
override fun onCreate() {
super.onCreate()
@@ -42,8 +48,8 @@ class Application : android.app.Application(), SharedPreferences.OnSharedPrefere
prefs.registerOnSharedPreferenceChangeListener(this)
setNightMode()
setUpBouncyCastleForSshj()
- runMigrations(applicationContext)
- ProxyUtils.setDefaultProxy()
+ runMigrations(filesDirPath, prefs, gitSettings)
+ proxyUtils.setDefaultProxy()
}
override fun onTerminate() {
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/git/base/BaseGitActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/git/base/BaseGitActivity.kt
index b9bfd911..1d917a3a 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/git/base/BaseGitActivity.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/git/base/BaseGitActivity.kt
@@ -12,6 +12,7 @@ import com.github.michaelbull.result.Result
import com.github.michaelbull.result.andThen
import com.github.michaelbull.result.mapError
import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import dagger.hilt.android.AndroidEntryPoint
import dev.msfjarvis.aps.R
import dev.msfjarvis.aps.util.extensions.getEncryptedGitPrefs
import dev.msfjarvis.aps.util.extensions.sharedPrefs
@@ -25,6 +26,7 @@ import dev.msfjarvis.aps.util.git.operation.SyncOperation
import dev.msfjarvis.aps.util.git.sshj.ContinuationContainerActivity
import dev.msfjarvis.aps.util.settings.GitSettings
import dev.msfjarvis.aps.util.settings.PreferenceKeys
+import javax.inject.Inject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import net.schmizz.sshj.common.DisconnectReason
@@ -36,6 +38,7 @@ import net.schmizz.sshj.userauth.UserAuthException
* Abstract [AppCompatActivity] that holds some information that is commonly shared across
* git-related tasks and makes sense to be held here.
*/
+@AndroidEntryPoint
abstract class BaseGitActivity : ContinuationContainerActivity() {
/** Enum of possible Git operations than can be run through [launchGitOperation]. */
@@ -48,29 +51,31 @@ abstract class BaseGitActivity : ContinuationContainerActivity() {
SYNC,
}
+ @Inject lateinit var gitSettings: GitSettings
+
/**
* Attempt to launch the requested Git operation.
* @param operation The type of git operation to launch
*/
suspend fun launchGitOperation(operation: GitOp): Result<Unit, Throwable> {
- if (GitSettings.url == null) {
+ if (gitSettings.url == null) {
return Err(IllegalStateException("Git url is not set!"))
}
- if (operation == GitOp.SYNC && !GitSettings.useMultiplexing) {
+ if (operation == GitOp.SYNC && !gitSettings.useMultiplexing) {
// If the server does not support multiple SSH channels per connection, we cannot run
// a sync operation without reconnecting and thus break sync into its two parts.
return launchGitOperation(GitOp.PULL).andThen { launchGitOperation(GitOp.PUSH) }
}
val op =
when (operation) {
- GitOp.CLONE -> CloneOperation(this, GitSettings.url!!)
- GitOp.PULL -> PullOperation(this, GitSettings.rebaseOnPull)
+ GitOp.CLONE -> CloneOperation(this, gitSettings.url!!)
+ GitOp.PULL -> PullOperation(this, gitSettings.rebaseOnPull)
GitOp.PUSH -> PushOperation(this)
- GitOp.SYNC -> SyncOperation(this, GitSettings.rebaseOnPull)
+ GitOp.SYNC -> SyncOperation(this, gitSettings.rebaseOnPull)
GitOp.BREAK_OUT_OF_DETACHED -> BreakOutOfDetached(this)
GitOp.RESET -> ResetToRemoteOperation(this)
}
- return op.executeAfterAuthentication(GitSettings.authMode).mapError(::transformGitError)
+ return op.executeAfterAuthentication(gitSettings.authMode).mapError(::transformGitError)
}
fun finishOnSuccessHandler(@Suppress("UNUSED_PARAMETER") nothing: Unit) {
@@ -105,7 +110,7 @@ abstract class BaseGitActivity : ContinuationContainerActivity() {
val err = rootCauseException(throwable)
return when {
err.message?.contains("cannot open additional channels") == true -> {
- GitSettings.useMultiplexing = false
+ gitSettings.useMultiplexing = false
SSHException(
DisconnectReason.TOO_MANY_CONNECTIONS,
"The server does not support multiple Git operations per SSH session. Please try again, a slower fallback mode will be used."
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitConfigActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitConfigActivity.kt
index faaf426f..8ca719eb 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitConfigActivity.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitConfigActivity.kt
@@ -25,7 +25,6 @@ import dev.msfjarvis.aps.databinding.ActivityGitConfigBinding
import dev.msfjarvis.aps.ui.git.base.BaseGitActivity
import dev.msfjarvis.aps.ui.git.log.GitLogActivity
import dev.msfjarvis.aps.util.extensions.viewBinding
-import dev.msfjarvis.aps.util.settings.GitSettings
import kotlinx.coroutines.launch
import org.eclipse.jgit.lib.Constants
import org.eclipse.jgit.lib.Repository
@@ -40,9 +39,9 @@ class GitConfigActivity : BaseGitActivity() {
setContentView(binding.root)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
- if (GitSettings.authorName.isEmpty()) binding.gitUserName.requestFocus()
- else binding.gitUserName.setText(GitSettings.authorName)
- binding.gitUserEmail.setText(GitSettings.authorEmail)
+ if (gitSettings.authorName.isEmpty()) binding.gitUserName.requestFocus()
+ else binding.gitUserName.setText(gitSettings.authorName)
+ binding.gitUserEmail.setText(gitSettings.authorEmail)
setupTools()
binding.saveButton.setOnClickListener {
val email = binding.gitUserEmail.text.toString().trim()
@@ -53,8 +52,8 @@ class GitConfigActivity : BaseGitActivity() {
.setPositiveButton(getString(R.string.dialog_ok), null)
.show()
} else {
- GitSettings.authorEmail = email
- GitSettings.authorName = name
+ gitSettings.authorEmail = email
+ gitSettings.authorName = name
Snackbar.make(
binding.root,
getString(R.string.git_server_config_save_success),
@@ -102,8 +101,8 @@ class GitConfigActivity : BaseGitActivity() {
setMessage(
resources.getString(
R.string.git_break_out_of_detached_success,
- GitSettings.branch,
- "conflicting-${GitSettings.branch}-...",
+ gitSettings.branch,
+ "conflicting-${gitSettings.branch}-...",
)
)
setOnDismissListener { finish() }
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitServerConfigActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitServerConfigActivity.kt
index cab8d3ae..5265131b 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitServerConfigActivity.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitServerConfigActivity.kt
@@ -54,7 +54,7 @@ class GitServerConfigActivity : BaseGitActivity() {
setContentView(binding.root)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
- newAuthMode = GitSettings.authMode
+ newAuthMode = gitSettings.authMode
binding.authModeGroup.apply {
when (newAuthMode) {
@@ -74,21 +74,21 @@ class GitServerConfigActivity : BaseGitActivity() {
}
binding.serverUrl.setText(
- GitSettings.url.also {
+ gitSettings.url.also {
if (it.isNullOrEmpty()) return@also
setAuthModes(it.startsWith("http://") || it.startsWith("https://"))
}
)
- binding.serverBranch.setText(GitSettings.branch)
+ binding.serverBranch.setText(gitSettings.branch)
binding.serverUrl.doOnTextChanged { text, _, _, _ ->
if (text.isNullOrEmpty()) return@doOnTextChanged
setAuthModes(text.startsWith("http://") || text.startsWith("https://"))
}
- binding.clearHostKeyButton.isVisible = GitSettings.hasSavedHostKey()
+ binding.clearHostKeyButton.isVisible = gitSettings.hasSavedHostKey()
binding.clearHostKeyButton.setOnClickListener {
- GitSettings.clearSavedHostKey()
+ gitSettings.clearSavedHostKey()
Snackbar.make(
binding.root,
getString(R.string.clear_saved_host_key_success),
@@ -135,7 +135,7 @@ class GitServerConfigActivity : BaseGitActivity() {
return@setOnClickListener
}
when (val updateResult =
- GitSettings.updateConnectionSettingsIfValid(
+ gitSettings.updateConnectionSettingsIfValid(
newAuthMode = newAuthMode,
newUrl = binding.serverUrl.text.toString().trim(),
newBranch = binding.serverBranch.text.toString().trim()
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordFragment.kt b/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordFragment.kt
index c0f2616d..063f472c 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordFragment.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordFragment.kt
@@ -53,6 +53,7 @@ import me.zhanghai.android.fastscroll.FastScrollerBuilder
@AndroidEntryPoint
class PasswordFragment : Fragment(R.layout.password_recycler_view) {
+ @Inject lateinit var gitSettings: GitSettings
@Inject lateinit var shortcutHandler: ShortcutHandler
private lateinit var recyclerAdapter: PasswordItemRecyclerAdapter
private lateinit var listener: OnFragmentInteractionListener
@@ -111,7 +112,7 @@ class PasswordFragment : Fragment(R.layout.password_recycler_view) {
// When authentication is set to AuthMode.None then the only git operation we can
// run is a pull, so automatically fallback to that.
val operationId =
- when (GitSettings.authMode) {
+ when (gitSettings.authMode) {
AuthMode.None -> BaseGitActivity.GitOp.PULL
else -> BaseGitActivity.GitOp.SYNC
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordStore.kt b/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordStore.kt
index b2591a92..d2f6ca38 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordStore.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordStore.kt
@@ -243,7 +243,7 @@ class PasswordStore : BaseGitActivity() {
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val menuRes =
when {
- GitSettings.authMode == AuthMode.None -> R.menu.main_menu_no_auth
+ gitSettings.authMode == AuthMode.None -> R.menu.main_menu_no_auth
PasswordRepository.isGitRepo() -> R.menu.main_menu_git
else -> R.menu.main_menu_non_git
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/proxy/ProxySelectorActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/proxy/ProxySelectorActivity.kt
index e3761292..936104e3 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/proxy/ProxySelectorActivity.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/proxy/ProxySelectorActivity.kt
@@ -13,6 +13,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.edit
import androidx.core.os.postDelayed
import androidx.core.widget.doOnTextChanged
+import dagger.hilt.android.AndroidEntryPoint
import dev.msfjarvis.aps.R
import dev.msfjarvis.aps.databinding.ActivityProxySelectorBinding
import dev.msfjarvis.aps.util.extensions.getEncryptedProxyPrefs
@@ -21,12 +22,17 @@ import dev.msfjarvis.aps.util.extensions.viewBinding
import dev.msfjarvis.aps.util.proxy.ProxyUtils
import dev.msfjarvis.aps.util.settings.GitSettings
import dev.msfjarvis.aps.util.settings.PreferenceKeys
+import javax.inject.Inject
private val IP_ADDRESS_REGEX = Patterns.IP_ADDRESS.toRegex()
private val WEB_ADDRESS_REGEX = Patterns.WEB_URL.toRegex()
+@AndroidEntryPoint
class ProxySelectorActivity : AppCompatActivity() {
+ @Inject lateinit var gitSettings: GitSettings
+ @Inject lateinit var proxyUtils: ProxyUtils
+
private val binding by viewBinding(ActivityProxySelectorBinding::inflate)
private val proxyPrefs by lazy(LazyThreadSafetyMode.NONE) {
applicationContext.getEncryptedProxyPrefs()
@@ -59,19 +65,19 @@ class ProxySelectorActivity : AppCompatActivity() {
private fun saveSettings() {
proxyPrefs.edit {
binding.proxyHost.text?.toString()?.takeIf { it.isNotEmpty() }.let {
- GitSettings.proxyHost = it
+ gitSettings.proxyHost = it
}
binding.proxyUser.text?.toString()?.takeIf { it.isNotEmpty() }.let {
- GitSettings.proxyUsername = it
+ gitSettings.proxyUsername = it
}
binding.proxyPort.text?.toString()?.takeIf { it.isNotEmpty() }?.let {
- GitSettings.proxyPort = it.toInt()
+ gitSettings.proxyPort = it.toInt()
}
binding.proxyPassword.text?.toString()?.takeIf { it.isNotEmpty() }.let {
- GitSettings.proxyPassword = it
+ gitSettings.proxyPassword = it
}
}
- ProxyUtils.setDefaultProxy()
+ proxyUtils.setDefaultProxy()
Handler(Looper.getMainLooper()).postDelayed(500) { finish() }
}
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/settings/RepositorySettings.kt b/app/src/main/java/dev/msfjarvis/aps/ui/settings/RepositorySettings.kt
index ba871f91..a9055408 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/settings/RepositorySettings.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/settings/RepositorySettings.kt
@@ -6,6 +6,7 @@
package dev.msfjarvis.aps.ui.settings
import android.content.Intent
+import android.content.SharedPreferences
import android.content.pm.ShortcutManager
import android.os.Build
import androidx.core.content.edit
@@ -14,6 +15,10 @@ import androidx.fragment.app.FragmentActivity
import com.github.michaelbull.result.onFailure
import com.github.michaelbull.result.runCatching
import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import dagger.hilt.EntryPoint
+import dagger.hilt.InstallIn
+import dagger.hilt.android.EntryPointAccessors
+import dagger.hilt.components.SingletonComponent
import de.Maxr1998.modernpreferences.Preference
import de.Maxr1998.modernpreferences.PreferenceScreen
import de.Maxr1998.modernpreferences.helpers.checkBox
@@ -22,13 +27,13 @@ import de.Maxr1998.modernpreferences.helpers.onClick
import de.Maxr1998.modernpreferences.helpers.pref
import dev.msfjarvis.aps.R
import dev.msfjarvis.aps.data.repo.PasswordRepository
+import dev.msfjarvis.aps.injection.prefs.GitPreferences
import dev.msfjarvis.aps.ui.git.config.GitConfigActivity
import dev.msfjarvis.aps.ui.git.config.GitServerConfigActivity
import dev.msfjarvis.aps.ui.proxy.ProxySelectorActivity
import dev.msfjarvis.aps.ui.sshkeygen.ShowSshKeyFragment
import dev.msfjarvis.aps.ui.sshkeygen.SshKeyGenActivity
import dev.msfjarvis.aps.ui.sshkeygen.SshKeyImportActivity
-import dev.msfjarvis.aps.util.extensions.getEncryptedGitPrefs
import dev.msfjarvis.aps.util.extensions.getString
import dev.msfjarvis.aps.util.extensions.sharedPrefs
import dev.msfjarvis.aps.util.extensions.snackbar
@@ -37,9 +42,10 @@ import dev.msfjarvis.aps.util.settings.PreferenceKeys
class RepositorySettings(private val activity: FragmentActivity) : SettingsProvider {
- private val encryptedPreferences by lazy(LazyThreadSafetyMode.NONE) {
- activity.getEncryptedGitPrefs()
- }
+ private val hiltEntryPoint = EntryPointAccessors.fromApplication(activity.applicationContext, RepositorySettingsEntryPoint::class.java)
+ private val encryptedPreferences = hiltEntryPoint.encryptedPreferences()
+ private val gitSettings = hiltEntryPoint.gitSettings()
+
private fun <T : FragmentActivity> launchActivity(clazz: Class<T>) {
activity.startActivity(Intent(activity, clazz))
@@ -74,7 +80,7 @@ class RepositorySettings(private val activity: FragmentActivity) : SettingsProvi
}
pref(PreferenceKeys.PROXY_SETTINGS) {
titleRes = R.string.pref_edit_proxy_settings
- visible = GitSettings.url?.startsWith("https") == true && PasswordRepository.isGitRepo()
+ visible = gitSettings.url?.startsWith("https") == true && PasswordRepository.isGitRepo()
onClick {
launchActivity(ProxySelectorActivity::class.java)
true
@@ -206,4 +212,11 @@ class RepositorySettings(private val activity: FragmentActivity) : SettingsProvi
}
}
}
+
+ @EntryPoint
+ @InstallIn(SingletonComponent::class)
+ interface RepositorySettingsEntryPoint {
+ fun gitSettings(): GitSettings
+ @GitPreferences fun encryptedPreferences(): SharedPreferences
+ }
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt
index 7be06385..5d507dc8 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt
@@ -10,6 +10,10 @@ import androidx.fragment.app.FragmentActivity
import com.github.michaelbull.result.Result
import com.github.michaelbull.result.runCatching
import com.google.android.material.snackbar.Snackbar
+import dagger.hilt.EntryPoint
+import dagger.hilt.InstallIn
+import dagger.hilt.android.EntryPointAccessors
+import dagger.hilt.components.SingletonComponent
import dev.msfjarvis.aps.R
import dev.msfjarvis.aps.util.extensions.snackbar
import dev.msfjarvis.aps.util.git.GitException.PullException
@@ -30,6 +34,9 @@ class GitCommandExecutor(
private val operation: GitOperation,
) {
+ private val hiltEntryPoint = EntryPointAccessors.fromApplication(activity.applicationContext, GitCommandExecutorEntryPoint::class.java)
+ private val gitSettings = hiltEntryPoint.gitSettings()
+
suspend fun execute(): Result<Unit, Throwable> {
val snackbar =
activity.snackbar(
@@ -49,8 +56,8 @@ class GitCommandExecutor(
// the previous status will eventually be used to avoid a commit
if (nbChanges > 0) {
withContext(Dispatchers.IO) {
- val name = GitSettings.authorName.ifEmpty { "root" }
- val email = GitSettings.authorEmail.ifEmpty { "localhost" }
+ val name = gitSettings.authorName.ifEmpty { "root" }
+ val email = gitSettings.authorEmail.ifEmpty { "localhost" }
val identity = PersonIdent(name, email)
command.setAuthor(identity).setCommitter(identity).call()
}
@@ -111,4 +118,10 @@ class GitCommandExecutor(
}
.also { snackbar.dismiss() }
}
+
+ @EntryPoint
+ @InstallIn(SingletonComponent::class)
+ interface GitCommandExecutorEntryPoint {
+ fun gitSettings(): GitSettings
+ }
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt
index dbea37e8..5a9da290 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt
@@ -14,6 +14,11 @@ import com.github.michaelbull.result.Result
import com.github.michaelbull.result.onFailure
import com.github.michaelbull.result.runCatching
import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import dagger.hilt.EntryPoint
+import dagger.hilt.InstallIn
+import dagger.hilt.android.AndroidEntryPoint
+import dagger.hilt.android.EntryPointAccessors
+import dagger.hilt.components.SingletonComponent
import dev.msfjarvis.aps.R
import dev.msfjarvis.aps.data.repo.PasswordRepository
import dev.msfjarvis.aps.ui.sshkeygen.SshKeyGenActivity
@@ -26,6 +31,8 @@ import dev.msfjarvis.aps.util.git.sshj.SshKey
import dev.msfjarvis.aps.util.git.sshj.SshjSessionFactory
import dev.msfjarvis.aps.util.settings.AuthMode
import dev.msfjarvis.aps.util.settings.GitSettings
+import javax.inject.Inject
+import javax.inject.Singleton
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import kotlinx.coroutines.Dispatchers
@@ -53,10 +60,11 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
abstract val commands: Array<GitCommand<out Any>>
private val hostKeyFile = callingActivity.filesDir.resolve(".host_key")
private var sshSessionFactory: SshjSessionFactory? = null
+ private val hiltEntryPoint = EntryPointAccessors.fromApplication(callingActivity.applicationContext, GitOperationEntryPoint::class.java)
protected val repository = PasswordRepository.getRepository(null)!!
protected val git = Git(repository)
- protected val remoteBranch = GitSettings.branch
+ protected val remoteBranch = hiltEntryPoint.gitSettings().branch
private val authActivity
get() = callingActivity as ContinuationContainerActivity
@@ -220,4 +228,11 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
/** Timeout in seconds before [TransportCommand] will abort a stalled IO operation. */
private const val CONNECT_TIMEOUT = 10
}
+
+ // Using @EntryPoint seems to be our best option here, changing this to constructor injection would require a larger refactor.
+ @EntryPoint
+ @InstallIn(SingletonComponent::class)
+ interface GitOperationEntryPoint {
+ fun gitSettings(): GitSettings
+ }
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/proxy/ProxyUtils.kt b/app/src/main/java/dev/msfjarvis/aps/util/proxy/ProxyUtils.kt
index e6eb7e43..d21ee24d 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/proxy/ProxyUtils.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/proxy/ProxyUtils.kt
@@ -14,20 +14,20 @@ import java.net.Proxy
import java.net.ProxySelector
import java.net.SocketAddress
import java.net.URI
+import javax.inject.Inject
+import javax.inject.Singleton
/** Utility class for [Proxy] handling. */
-object ProxyUtils {
-
- private const val HTTP_PROXY_USER_PROPERTY = "http.proxyUser"
- private const val HTTP_PROXY_PASSWORD_PROPERTY = "http.proxyPassword"
+@Singleton
+class ProxyUtils @Inject constructor(private val gitSettings: GitSettings) {
/** Set the default [Proxy] and [Authenticator] for the app based on user provided settings. */
fun setDefaultProxy() {
ProxySelector.setDefault(
object : ProxySelector() {
override fun select(uri: URI?): MutableList<Proxy> {
- val host = GitSettings.proxyHost
- val port = GitSettings.proxyPort
+ val host = gitSettings.proxyHost
+ val port = gitSettings.proxyPort
return if (host == null || port == -1) {
mutableListOf(Proxy.NO_PROXY)
} else {
@@ -42,8 +42,8 @@ object ProxyUtils {
}
}
)
- val user = GitSettings.proxyUsername ?: ""
- val password = GitSettings.proxyPassword ?: ""
+ val user = gitSettings.proxyUsername ?: ""
+ val password = gitSettings.proxyPassword ?: ""
if (user.isEmpty() || password.isEmpty()) {
System.clearProperty(HTTP_PROXY_USER_PROPERTY)
System.clearProperty(HTTP_PROXY_PASSWORD_PROPERTY)
@@ -63,4 +63,9 @@ object ProxyUtils {
}
)
}
+
+ companion object {
+ private const val HTTP_PROXY_USER_PROPERTY = "http.proxyUser"
+ private const val HTTP_PROXY_PASSWORD_PROPERTY = "http.proxyPassword"
+ }
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt b/app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt
index d3c85fa7..0d580142 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt
@@ -4,16 +4,19 @@
*/
package dev.msfjarvis.aps.util.settings
+import android.content.SharedPreferences
import androidx.core.content.edit
import com.github.michaelbull.result.getOrElse
import com.github.michaelbull.result.runCatching
-import dev.msfjarvis.aps.Application
import dev.msfjarvis.aps.data.repo.PasswordRepository
-import dev.msfjarvis.aps.util.extensions.getEncryptedGitPrefs
-import dev.msfjarvis.aps.util.extensions.getEncryptedProxyPrefs
+import dev.msfjarvis.aps.injection.context.FilesDirPath
+import dev.msfjarvis.aps.injection.prefs.GitPreferences
+import dev.msfjarvis.aps.injection.prefs.ProxyPreferences
+import dev.msfjarvis.aps.injection.prefs.SettingsPreferences
import dev.msfjarvis.aps.util.extensions.getString
-import dev.msfjarvis.aps.util.extensions.sharedPrefs
import java.io.File
+import javax.inject.Inject
+import javax.inject.Singleton
import org.eclipse.jgit.transport.URIish
enum class Protocol(val pref: String) {
@@ -48,29 +51,22 @@ enum class AuthMode(val pref: String) {
}
}
-object GitSettings {
+@Singleton
+class GitSettings @Inject constructor(
+ @SettingsPreferences private val settings: SharedPreferences,
+ @GitPreferences private val encryptedSettings: SharedPreferences,
+ @ProxyPreferences private val proxySettings: SharedPreferences,
+ @FilesDirPath private val filesDirPath: String,
+) {
- private const val DEFAULT_BRANCH = "master"
-
- private val settings by lazy(LazyThreadSafetyMode.PUBLICATION) {
- Application.instance.sharedPrefs
- }
- private val encryptedSettings by lazy(LazyThreadSafetyMode.PUBLICATION) {
- Application.instance.getEncryptedGitPrefs()
- }
- private val proxySettings by lazy(LazyThreadSafetyMode.PUBLICATION) {
- Application.instance.getEncryptedProxyPrefs()
- }
private val hostKeyPath by lazy(LazyThreadSafetyMode.NONE) {
- "${Application.instance.filesDir}/.host_key"
+ "$filesDirPath/.host_key"
}
-
var authMode
get() = AuthMode.fromString(settings.getString(PreferenceKeys.GIT_REMOTE_AUTH))
private set(value) {
settings.edit { putString(PreferenceKeys.GIT_REMOTE_AUTH, value.pref) }
}
-
var url
get() = settings.getString(PreferenceKeys.GIT_REMOTE_URL)
private set(value) {
@@ -84,55 +80,46 @@ object GitSettings {
encryptedSettings.edit { remove(PreferenceKeys.HTTPS_PASSWORD) }
clearSavedHostKey()
}
-
var authorName
get() = settings.getString(PreferenceKeys.GIT_CONFIG_AUTHOR_NAME) ?: ""
set(value) {
settings.edit { putString(PreferenceKeys.GIT_CONFIG_AUTHOR_NAME, value) }
}
-
var authorEmail
get() = settings.getString(PreferenceKeys.GIT_CONFIG_AUTHOR_EMAIL) ?: ""
set(value) {
settings.edit { putString(PreferenceKeys.GIT_CONFIG_AUTHOR_EMAIL, value) }
}
-
var branch
get() = settings.getString(PreferenceKeys.GIT_BRANCH_NAME) ?: DEFAULT_BRANCH
private set(value) {
settings.edit { putString(PreferenceKeys.GIT_BRANCH_NAME, value) }
}
-
var useMultiplexing
get() = settings.getBoolean(PreferenceKeys.GIT_REMOTE_USE_MULTIPLEXING, true)
set(value) {
settings.edit { putBoolean(PreferenceKeys.GIT_REMOTE_USE_MULTIPLEXING, value) }
}
-
var proxyHost
get() = proxySettings.getString(PreferenceKeys.PROXY_HOST)
set(value) {
proxySettings.edit { putString(PreferenceKeys.PROXY_HOST, value) }
}
-
var proxyPort
get() = proxySettings.getInt(PreferenceKeys.PROXY_PORT, -1)
set(value) {
proxySettings.edit { putInt(PreferenceKeys.PROXY_PORT, value) }
}
-
var proxyUsername
get() = settings.getString(PreferenceKeys.PROXY_USERNAME)
set(value) {
proxySettings.edit { putString(PreferenceKeys.PROXY_USERNAME, value) }
}
-
var proxyPassword
get() = proxySettings.getString(PreferenceKeys.PROXY_PASSWORD)
set(value) {
proxySettings.edit { putString(PreferenceKeys.PROXY_PASSWORD, value) }
}
-
var rebaseOnPull
get() = settings.getBoolean(PreferenceKeys.REBASE_ON_PULL, true)
set(value) {
@@ -141,8 +128,7 @@ object GitSettings {
sealed class UpdateConnectionSettingsResult {
class MissingUsername(val newProtocol: Protocol) : UpdateConnectionSettingsResult()
- class AuthModeMismatch(val newProtocol: Protocol, val validModes: List<AuthMode>) :
- UpdateConnectionSettingsResult()
+ class AuthModeMismatch(val newProtocol: Protocol, val validModes: List<AuthMode>) : UpdateConnectionSettingsResult()
object Valid : UpdateConnectionSettingsResult()
object FailedToParseUrl : UpdateConnectionSettingsResult()
}
@@ -164,7 +150,6 @@ object GitSettings {
}
if (newAuthMode != AuthMode.None && parsedUrl.user.isNullOrBlank())
return UpdateConnectionSettingsResult.MissingUsername(newProtocol)
-
val validHttpsAuth = listOf(AuthMode.None, AuthMode.Password)
val validSshAuth = listOf(AuthMode.OpenKeychain, AuthMode.Password, AuthMode.SshKey)
when {
@@ -189,4 +174,8 @@ object GitSettings {
/** Returns true if a host key was previously saved */
fun hasSavedHostKey(): Boolean = File(hostKeyPath).exists()
+
+ companion object {
+ private const val DEFAULT_BRANCH = "master"
+ }
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/settings/Migrations.kt b/app/src/main/java/dev/msfjarvis/aps/util/settings/Migrations.kt
index b9333617..b24914d0 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/settings/Migrations.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/settings/Migrations.kt
@@ -6,7 +6,6 @@
package dev.msfjarvis.aps.util.settings
-import android.content.Context
import android.content.SharedPreferences
import androidx.core.content.edit
import com.github.ajalt.timberkt.e
@@ -14,20 +13,18 @@ import com.github.ajalt.timberkt.i
import com.github.michaelbull.result.get
import com.github.michaelbull.result.runCatching
import dev.msfjarvis.aps.util.extensions.getString
-import dev.msfjarvis.aps.util.extensions.sharedPrefs
import dev.msfjarvis.aps.util.git.sshj.SshKey
import java.io.File
import java.net.URI
-fun runMigrations(context: Context) {
- val sharedPrefs = context.sharedPrefs
- migrateToGitUrlBasedConfig(sharedPrefs)
+fun runMigrations(filesDirPath: String, sharedPrefs: SharedPreferences, gitSettings: GitSettings) {
+ migrateToGitUrlBasedConfig(sharedPrefs, gitSettings)
migrateToHideAll(sharedPrefs)
- migrateToSshKey(context, sharedPrefs)
+ migrateToSshKey(filesDirPath, sharedPrefs)
migrateToClipboardHistory(sharedPrefs)
}
-private fun migrateToGitUrlBasedConfig(sharedPrefs: SharedPreferences) {
+private fun migrateToGitUrlBasedConfig(sharedPrefs: SharedPreferences, gitSettings: GitSettings) {
val serverHostname = sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_SERVER) ?: return
i { "Migrating to URL-based Git config" }
val serverPort = sharedPrefs.getString(PreferenceKeys.GIT_REMOTE_PORT) ?: ""
@@ -76,10 +73,10 @@ private fun migrateToGitUrlBasedConfig(sharedPrefs: SharedPreferences) {
remove(PreferenceKeys.GIT_REMOTE_PROTOCOL)
}
if (url == null ||
- GitSettings.updateConnectionSettingsIfValid(
- newAuthMode = GitSettings.authMode,
+ gitSettings.updateConnectionSettingsIfValid(
+ newAuthMode = gitSettings.authMode,
newUrl = url,
- newBranch = GitSettings.branch
+ newBranch = gitSettings.branch
) != GitSettings.UpdateConnectionSettingsResult.Valid
) {
e { "Failed to migrate to URL-based Git config, generated URL is invalid" }
@@ -95,8 +92,8 @@ private fun migrateToHideAll(sharedPrefs: SharedPreferences) {
}
}
-private fun migrateToSshKey(context: Context, sharedPrefs: SharedPreferences) {
- val privateKeyFile = File(context.filesDir, ".ssh_key")
+private fun migrateToSshKey(filesDirPath: String, sharedPrefs: SharedPreferences) {
+ val privateKeyFile = File(filesDirPath, ".ssh_key")
if (sharedPrefs.contains(PreferenceKeys.USE_GENERATED_KEY) &&
!SshKey.exists &&
privateKeyFile.exists()