Fix compile warnings on AOSP 11
This commit is contained in:
parent
76be2c1ea0
commit
af4b6807f2
20 changed files with 149 additions and 121 deletions
|
@ -11,6 +11,7 @@ import android.hardware.usb.UsbManager.ACTION_USB_DEVICE_DETACHED
|
|||
import android.hardware.usb.UsbManager.EXTRA_DEVICE
|
||||
import android.net.Uri
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.provider.DocumentsContract
|
||||
import android.util.Log
|
||||
import com.stevesoltys.seedvault.metadata.MetadataManager
|
||||
|
@ -74,7 +75,8 @@ abstract class UsbMonitor : BroadcastReceiver() {
|
|||
|
||||
val rootsUri = DocumentsContract.buildRootsUri(AUTHORITY_STORAGE)
|
||||
val contentResolver = context.contentResolver
|
||||
val observer = object : ContentObserver(Handler()) {
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
val observer = object : ContentObserver(handler) {
|
||||
override fun onChange(selfChange: Boolean, uri: Uri?) {
|
||||
super.onChange(selfChange, uri)
|
||||
onStatusChanged(context, action, device)
|
||||
|
|
|
@ -7,7 +7,6 @@ import android.content.pm.PackageInfo
|
|||
import android.database.ContentObserver
|
||||
import android.database.Cursor
|
||||
import android.net.Uri
|
||||
import android.os.FileUtils.closeQuietly
|
||||
import android.provider.DocumentsContract.Document.COLUMN_DOCUMENT_ID
|
||||
import android.provider.DocumentsContract.EXTRA_LOADING
|
||||
import android.provider.DocumentsContract.buildChildDocumentsUriUsingTree
|
||||
|
@ -294,14 +293,14 @@ internal suspend fun getLoadedCursor(timeout: Long = 15_000, query: () -> Cursor
|
|||
withTimeout(timeout) {
|
||||
suspendCancellableCoroutine<Cursor> { cont ->
|
||||
val cursor = query() ?: throw IOException()
|
||||
cont.invokeOnCancellation { closeQuietly(cursor) }
|
||||
cont.invokeOnCancellation { cursor.close() }
|
||||
val loading = cursor.extras.getBoolean(EXTRA_LOADING, false)
|
||||
if (loading) {
|
||||
Log.d(TAG, "Wait for children to get loaded...")
|
||||
cursor.registerContentObserver(object : ContentObserver(null) {
|
||||
override fun onChange(selfChange: Boolean, uri: Uri?) {
|
||||
Log.d(TAG, "Children loaded. Continue...")
|
||||
closeQuietly(cursor)
|
||||
cursor.close()
|
||||
val newCursor = query()
|
||||
if (newCursor == null) cont.cancel(IOException("query returned no results"))
|
||||
else cont.resume(newCursor)
|
||||
|
|
|
@ -32,8 +32,11 @@ class InstallProgressFragment : Fragment() {
|
|||
private lateinit var appList: RecyclerView
|
||||
private lateinit var button: Button
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val v: View = inflater.inflate(R.layout.fragment_restore_progress, container, false)
|
||||
|
||||
progressBar = v.findViewById(R.id.progressBar)
|
||||
|
@ -55,20 +58,16 @@ class InstallProgressFragment : Fragment() {
|
|||
}
|
||||
button.setText(R.string.restore_next)
|
||||
button.setOnClickListener { viewModel.onNextClicked() }
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
viewModel.chosenRestorableBackup.observe(this, Observer { restorableBackup ->
|
||||
viewModel.chosenRestorableBackup.observe(viewLifecycleOwner, Observer { restorableBackup ->
|
||||
backupNameView.text = restorableBackup.name
|
||||
})
|
||||
|
||||
viewModel.installResult.observe(this, Observer { result ->
|
||||
viewModel.installResult.observe(viewLifecycleOwner, Observer { result ->
|
||||
onInstallResult(result)
|
||||
})
|
||||
|
||||
viewModel.nextButtonEnabled.observe(this, Observer { enabled ->
|
||||
viewModel.nextButtonEnabled.observe(viewLifecycleOwner, Observer { enabled ->
|
||||
button.isEnabled = enabled
|
||||
})
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class RestoreActivity : RequireProvisioningActivity() {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
if (isSetupWizard) hideSystemUI()
|
||||
if (isSetupWizard) hideSystemUiNavigation()
|
||||
|
||||
setContentView(R.layout.activity_fragment_container)
|
||||
|
||||
|
|
|
@ -59,25 +59,21 @@ class RestoreProgressFragment : Fragment() {
|
|||
requireActivity().setResult(RESULT_OK)
|
||||
requireActivity().finishAfterTransition()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
// decryption will fail when the device is locked, so keep the screen on to prevent locking
|
||||
requireActivity().window.addFlags(FLAG_KEEP_SCREEN_ON)
|
||||
|
||||
viewModel.chosenRestorableBackup.observe(this, Observer { restorableBackup ->
|
||||
viewModel.chosenRestorableBackup.observe(viewLifecycleOwner, Observer { restorableBackup ->
|
||||
backupNameView.text = restorableBackup.name
|
||||
progressBar.max = restorableBackup.packageMetadataMap.size
|
||||
})
|
||||
|
||||
viewModel.restoreProgress.observe(this, Observer { list ->
|
||||
viewModel.restoreProgress.observe(viewLifecycleOwner, Observer { list ->
|
||||
stayScrolledAtTop { adapter.update(list) }
|
||||
progressBar.progress = list.size
|
||||
})
|
||||
|
||||
viewModel.restoreBackupResult.observe(this, Observer { finished ->
|
||||
viewModel.restoreBackupResult.observe(viewLifecycleOwner, Observer { finished ->
|
||||
button.isEnabled = true
|
||||
if (finished.hasError()) {
|
||||
backupNameView.text = finished.errorMsg
|
||||
|
|
|
@ -24,8 +24,11 @@ class RestoreSetFragment : Fragment() {
|
|||
private lateinit var errorView: TextView
|
||||
private lateinit var backView: TextView
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val v: View = inflater.inflate(R.layout.fragment_restore_set, container, false)
|
||||
|
||||
listView = v.findViewById(R.id.listView)
|
||||
|
@ -36,13 +39,15 @@ class RestoreSetFragment : Fragment() {
|
|||
return v
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// decryption will fail when the device is locked, so keep the screen on to prevent locking
|
||||
requireActivity().window.addFlags(FLAG_KEEP_SCREEN_ON)
|
||||
|
||||
viewModel.restoreSetResults.observe(this, Observer { result -> onRestoreResultsLoaded(result) })
|
||||
viewModel.restoreSetResults.observe(viewLifecycleOwner, Observer { result ->
|
||||
onRestoreResultsLoaded(result)
|
||||
})
|
||||
|
||||
backView.setOnClickListener { requireActivity().finishAfterTransition() }
|
||||
}
|
||||
|
|
|
@ -43,8 +43,8 @@ class AppStatusFragment : Fragment(), AppStatusToggleListener {
|
|||
return v
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
activity?.setTitle(R.string.settings_backup_status_title)
|
||||
|
||||
|
@ -54,7 +54,7 @@ class AppStatusFragment : Fragment(), AppStatusToggleListener {
|
|||
}
|
||||
|
||||
progressBar.visibility = VISIBLE
|
||||
viewModel.appStatusList.observe(this, Observer { result ->
|
||||
viewModel.appStatusList.observe(viewLifecycleOwner, Observer { result ->
|
||||
adapter.update(result.appStatusList, result.diff)
|
||||
progressBar.visibility = INVISIBLE
|
||||
})
|
||||
|
@ -66,7 +66,7 @@ class AppStatusFragment : Fragment(), AppStatusToggleListener {
|
|||
appEditMenuItem = menu.findItem(R.id.edit_app_blacklist)
|
||||
|
||||
// observe edit mode changes here where we are sure to have the MenuItem
|
||||
viewModel.appEditMode.observe(this, Observer { enabled ->
|
||||
viewModel.appEditMode.observe(viewLifecycleOwner, Observer { enabled ->
|
||||
appEditMenuItem.isChecked = enabled
|
||||
adapter.setEditMode(enabled)
|
||||
})
|
||||
|
|
|
@ -5,10 +5,10 @@ import androidx.annotation.CallSuper
|
|||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceFragmentCompat.OnPreferenceStartFragmentCallback
|
||||
import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager
|
||||
import com.stevesoltys.seedvault.R
|
||||
import com.stevesoltys.seedvault.ui.RequireProvisioningActivity
|
||||
import com.stevesoltys.seedvault.ui.RequireProvisioningViewModel
|
||||
import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
|
||||
|
@ -50,13 +50,16 @@ class SettingsActivity : RequireProvisioningActivity(), OnPreferenceStartFragmen
|
|||
}
|
||||
}
|
||||
|
||||
override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference): Boolean {
|
||||
val fragment = supportFragmentManager.fragmentFactory.instantiate(classLoader, pref.fragment)
|
||||
fragment.setTargetFragment(caller, 0)
|
||||
override fun onPreferenceStartFragment(
|
||||
caller: PreferenceFragmentCompat,
|
||||
pref: Preference
|
||||
): Boolean {
|
||||
val fragment =
|
||||
supportFragmentManager.fragmentFactory.instantiate(classLoader, pref.fragment)
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fragment, fragment)
|
||||
.addToBackStack(null)
|
||||
.commit()
|
||||
.replace(R.id.fragment, fragment)
|
||||
.addToBackStack(null)
|
||||
.commit()
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import android.util.Log
|
|||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.preference.Preference
|
||||
|
@ -117,8 +118,12 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
return@OnPreferenceChangeListener false
|
||||
}
|
||||
backupStatus = findPreference("backup_status")!!
|
||||
}
|
||||
|
||||
viewModel.lastBackupTime.observe(this, Observer { time -> setAppBackupStatusSummary(time) })
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
viewModel.lastBackupTime.observe(viewLifecycleOwner, Observer { time -> setAppBackupStatusSummary(time) })
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
|
@ -162,7 +167,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
true
|
||||
}
|
||||
R.id.action_about -> {
|
||||
AboutDialogFragment().show(fragmentManager!!, AboutDialogFragment.TAG)
|
||||
AboutDialogFragment().show(parentFragmentManager, AboutDialogFragment.TAG)
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
|
|
|
@ -116,7 +116,7 @@ class ApkBackup(
|
|||
return PackageMetadata(
|
||||
state = packageState,
|
||||
version = version,
|
||||
installer = pm.getInstallerPackageName(packageName),
|
||||
installer = pm.getInstallSourceInfo(packageName).installingPackageName,
|
||||
sha256 = sha256,
|
||||
signatures = signatures
|
||||
)
|
||||
|
|
|
@ -25,7 +25,7 @@ abstract class BackupActivity : AppCompatActivity() {
|
|||
fragmentTransaction.commit()
|
||||
}
|
||||
|
||||
protected fun hideSystemUI() {
|
||||
protected fun hideSystemUiNavigation() {
|
||||
window.decorView.systemUiVisibility = SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
}
|
||||
|
||||
|
|
|
@ -3,14 +3,11 @@ package com.stevesoltys.seedvault.ui
|
|||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
|
||||
import androidx.annotation.CallSuper
|
||||
import com.stevesoltys.seedvault.ui.recoverycode.RecoveryCodeActivity
|
||||
import com.stevesoltys.seedvault.ui.storage.StorageActivity
|
||||
|
||||
const val REQUEST_CODE_OPEN_DOCUMENT_TREE = 1
|
||||
const val REQUEST_CODE_BACKUP_LOCATION = 2
|
||||
const val REQUEST_CODE_RECOVERY_CODE = 3
|
||||
|
||||
const val INTENT_EXTRA_IS_RESTORE = "isRestore"
|
||||
const val INTENT_EXTRA_IS_SETUP_WIZARD = "isSetupWizard"
|
||||
|
||||
|
@ -24,6 +21,25 @@ private val TAG = RequireProvisioningActivity::class.java.name
|
|||
*/
|
||||
abstract class RequireProvisioningActivity : BackupActivity() {
|
||||
|
||||
private val recoveryCodeRequest =
|
||||
registerForActivityResult(StartActivityForResult()) { result ->
|
||||
if (result.resultCode != RESULT_OK) {
|
||||
Log.w(TAG, "Error in activity result for requesting recovery code")
|
||||
if (!getViewModel().recoveryCodeIsSet()) {
|
||||
finishAfterTransition()
|
||||
}
|
||||
}
|
||||
}
|
||||
private val requestLocation =
|
||||
registerForActivityResult(StartActivityForResult()) { result ->
|
||||
if (result.resultCode != RESULT_OK) {
|
||||
Log.w(TAG, "Error in activity result for requesting location")
|
||||
if (!getViewModel().validLocationIsSet()) {
|
||||
finishAfterTransition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected val isSetupWizard: Boolean
|
||||
get() = intent?.action == ACTION_SETUP_WIZARD
|
||||
|
||||
|
@ -38,35 +54,18 @@ abstract class RequireProvisioningActivity : BackupActivity() {
|
|||
})
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, result: Intent?) {
|
||||
if (requestCode == REQUEST_CODE_BACKUP_LOCATION && resultCode != RESULT_OK) {
|
||||
Log.w(TAG, "Error in activity result: $requestCode")
|
||||
if (!getViewModel().validLocationIsSet()) {
|
||||
finishAfterTransition()
|
||||
}
|
||||
} else if (requestCode == REQUEST_CODE_RECOVERY_CODE && resultCode != RESULT_OK) {
|
||||
Log.w(TAG, "Error in activity result: $requestCode")
|
||||
if (!getViewModel().recoveryCodeIsSet()) {
|
||||
finishAfterTransition()
|
||||
}
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, result)
|
||||
}
|
||||
}
|
||||
|
||||
protected fun showStorageActivity() {
|
||||
val intent = Intent(this, StorageActivity::class.java)
|
||||
intent.putExtra(INTENT_EXTRA_IS_RESTORE, getViewModel().isRestoreOperation)
|
||||
intent.putExtra(INTENT_EXTRA_IS_SETUP_WIZARD, isSetupWizard)
|
||||
startActivityForResult(intent, REQUEST_CODE_BACKUP_LOCATION)
|
||||
requestLocation.launch(intent)
|
||||
}
|
||||
|
||||
protected fun showRecoveryCodeActivity() {
|
||||
val intent = Intent(this, RecoveryCodeActivity::class.java)
|
||||
intent.putExtra(INTENT_EXTRA_IS_RESTORE, getViewModel().isRestoreOperation)
|
||||
intent.putExtra(INTENT_EXTRA_IS_SETUP_WIZARD, isSetupWizard)
|
||||
startActivityForResult(intent, REQUEST_CODE_RECOVERY_CODE)
|
||||
recoveryCodeRequest.launch(intent)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ class RecoveryCodeActivity : BackupActivity() {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
if (isSetupWizard()) hideSystemUI()
|
||||
if (isSetupWizard()) hideSystemUiNavigation()
|
||||
|
||||
setContentView(R.layout.activity_recovery_code)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import android.widget.Button
|
|||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import android.widget.Toast.LENGTH_LONG
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.stevesoltys.seedvault.R
|
||||
|
@ -43,8 +43,11 @@ class RecoveryCodeInputFragment : Fragment() {
|
|||
private lateinit var wordLayout12: TextInputLayout
|
||||
private lateinit var wordList: ConstraintLayout
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val v: View = inflater.inflate(R.layout.fragment_recovery_code_input, container, false)
|
||||
|
||||
introText = v.findViewById(R.id.introText)
|
||||
|
@ -67,8 +70,8 @@ class RecoveryCodeInputFragment : Fragment() {
|
|||
return v
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
if (viewModel.isRestore) {
|
||||
introText.setText(R.string.recovery_code_input_intro)
|
||||
|
@ -137,6 +140,7 @@ class RecoveryCodeInputFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
private fun getWordLayout(i: Int) = when (i + 1) {
|
||||
1 -> wordLayout1
|
||||
2 -> wordLayout2
|
||||
|
|
|
@ -19,8 +19,11 @@ class RecoveryCodeOutputFragment : Fragment() {
|
|||
private lateinit var wordList: RecyclerView
|
||||
private lateinit var confirmCodeButton: Button
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val v: View = inflater.inflate(R.layout.fragment_recovery_code_output, container, false)
|
||||
|
||||
wordList = v.findViewById(R.id.wordList)
|
||||
|
@ -29,8 +32,8 @@ class RecoveryCodeOutputFragment : Fragment() {
|
|||
return v
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
setGridParameters(wordList)
|
||||
wordList.adapter = RecoveryCodeAdapter(viewModel.wordList)
|
||||
|
@ -38,6 +41,7 @@ class RecoveryCodeOutputFragment : Fragment() {
|
|||
confirmCodeButton.setOnClickListener { viewModel.onConfirmButtonClicked() }
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
private fun setGridParameters(list: RecyclerView) {
|
||||
val layoutManager = list.layoutManager as GridLayoutManager
|
||||
if (resources.configuration.orientation == ORIENTATION_LANDSCAPE) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.stevesoltys.seedvault.ui.storage
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.annotation.CallSuper
|
||||
|
@ -22,7 +21,7 @@ class StorageActivity : BackupActivity() {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
if (isSetupWizard()) hideSystemUI()
|
||||
if (isSetupWizard()) hideSystemUiNavigation()
|
||||
|
||||
setContentView(R.layout.activity_fragment_container)
|
||||
|
||||
|
@ -52,16 +51,6 @@ class StorageActivity : BackupActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, result: Intent?) {
|
||||
if (resultCode != RESULT_OK) {
|
||||
Log.w(TAG, "Error in activity result: $requestCode")
|
||||
onInvalidLocation(getString(R.string.storage_check_fragment_permission_error))
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, result)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (supportFragmentManager.backStackEntryCount > 0) {
|
||||
Log.d(TAG, "Blocking back button.")
|
||||
|
|
|
@ -33,8 +33,11 @@ class StorageCheckFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val v: View = inflater.inflate(R.layout.fragment_storage_check, container, false)
|
||||
|
||||
titleView = v.findViewById(R.id.titleView)
|
||||
|
@ -45,12 +48,12 @@ class StorageCheckFragment : Fragment() {
|
|||
return v
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
titleView.text = arguments!!.getString(TITLE)
|
||||
titleView.text = requireArguments().getString(TITLE)
|
||||
|
||||
val errorMsg = arguments!!.getString(ERROR_MSG)
|
||||
val errorMsg = requireArguments().getString(ERROR_MSG)
|
||||
if (errorMsg != null) {
|
||||
progressBar.visibility = INVISIBLE
|
||||
errorView.text = errorMsg
|
||||
|
|
|
@ -12,6 +12,7 @@ import android.database.Cursor
|
|||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.provider.DocumentsContract
|
||||
import android.provider.DocumentsContract.PROVIDER_INTERFACE
|
||||
import android.provider.DocumentsContract.Root.COLUMN_AVAILABLE_BYTES
|
||||
|
@ -72,7 +73,8 @@ internal class StorageRootFetcher(private val context: Context, private val isRe
|
|||
private val whitelistedAuthorities = context.resources.getStringArray(R.array.storage_authority_whitelist)
|
||||
|
||||
private var listener: RemovableStorageListener? = null
|
||||
private val observer = object : ContentObserver(Handler()) {
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private val observer = object : ContentObserver(handler) {
|
||||
override fun onChange(selfChange: Boolean, uri: Uri?) {
|
||||
super.onChange(selfChange, uri)
|
||||
listener?.onStorageChanged()
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package com.stevesoltys.seedvault.ui.storage
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
|
||||
import android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
import android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
@ -13,13 +16,12 @@ import android.view.ViewGroup
|
|||
import android.widget.ImageView
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity.RESULT_OK
|
||||
import androidx.activity.result.contract.ActivityResultContracts.OpenDocumentTree
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.stevesoltys.seedvault.R
|
||||
import com.stevesoltys.seedvault.ui.INTENT_EXTRA_IS_RESTORE
|
||||
import com.stevesoltys.seedvault.ui.REQUEST_CODE_OPEN_DOCUMENT_TREE
|
||||
import org.koin.androidx.viewmodel.ext.android.getSharedViewModel
|
||||
|
||||
internal class StorageRootsFragment : Fragment(), StorageRootClickedListener {
|
||||
|
@ -45,8 +47,11 @@ internal class StorageRootsFragment : Fragment(), StorageRootClickedListener {
|
|||
|
||||
private val adapter by lazy { StorageRootAdapter(viewModel.isRestoreOperation, this) }
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val v: View = inflater.inflate(R.layout.fragment_storage_root, container, false)
|
||||
|
||||
titleView = v.findViewById(R.id.titleView)
|
||||
|
@ -60,10 +65,10 @@ internal class StorageRootsFragment : Fragment(), StorageRootClickedListener {
|
|||
return v
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
viewModel = if (arguments!!.getBoolean(INTENT_EXTRA_IS_RESTORE)) {
|
||||
viewModel = if (requireArguments().getBoolean(INTENT_EXTRA_IS_RESTORE)) {
|
||||
getSharedViewModel<RestoreStorageViewModel>()
|
||||
} else {
|
||||
getSharedViewModel<BackupStorageViewModel>()
|
||||
|
@ -81,7 +86,9 @@ internal class StorageRootsFragment : Fragment(), StorageRootClickedListener {
|
|||
|
||||
listView.adapter = adapter
|
||||
|
||||
viewModel.storageRoots.observe(this, Observer { roots -> onRootsLoaded(roots) })
|
||||
viewModel.storageRoots.observe(viewLifecycleOwner, Observer { roots ->
|
||||
onRootsLoaded(roots)
|
||||
})
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
|
@ -94,21 +101,13 @@ internal class StorageRootsFragment : Fragment(), StorageRootClickedListener {
|
|||
adapter.setItems(roots)
|
||||
}
|
||||
|
||||
override fun onClick(root: StorageRoot) {
|
||||
viewModel.onStorageRootChosen(root)
|
||||
val intent = Intent(requireContext(), PermissionGrantActivity::class.java)
|
||||
intent.data = root.uri
|
||||
intent.addFlags(FLAG_GRANT_PERSISTABLE_URI_PERMISSION or
|
||||
FLAG_GRANT_READ_URI_PERMISSION or FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||
startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE)
|
||||
private val openDocumentTree = registerForActivityResult(OpenSeedvaultTree()) { uri ->
|
||||
viewModel.onUriPermissionResultReceived(uri)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, result: Intent?) {
|
||||
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE_OPEN_DOCUMENT_TREE) {
|
||||
viewModel.onUriPermissionGranted(result)
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, result)
|
||||
}
|
||||
override fun onClick(root: StorageRoot) {
|
||||
viewModel.onStorageRootChosen(root)
|
||||
openDocumentTree.launch(root.uri)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -116,3 +115,16 @@ internal class StorageRootsFragment : Fragment(), StorageRootClickedListener {
|
|||
internal interface StorageRootClickedListener {
|
||||
fun onClick(root: StorageRoot)
|
||||
}
|
||||
|
||||
private class OpenSeedvaultTree : OpenDocumentTree() {
|
||||
@SuppressLint("MissingSuperCall") // we are intentionally creating our own intent
|
||||
override fun createIntent(context: Context, input: Uri?): Intent {
|
||||
return Intent(context, PermissionGrantActivity::class.java).apply {
|
||||
check(input != null) { "Uri was null, but is needed." }
|
||||
data = input
|
||||
val flags = FLAG_GRANT_PERSISTABLE_URI_PERMISSION or
|
||||
FLAG_GRANT_READ_URI_PERMISSION or FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
addFlags(flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.stevesoltys.seedvault.ui.storage
|
|||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.Context.USB_SERVICE
|
||||
import android.content.Intent
|
||||
import android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
import android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
import android.hardware.usb.UsbManager
|
||||
|
@ -24,8 +23,8 @@ import com.stevesoltys.seedvault.ui.MutableLiveEvent
|
|||
private val TAG = StorageViewModel::class.java.simpleName
|
||||
|
||||
internal abstract class StorageViewModel(
|
||||
private val app: Application,
|
||||
protected val settingsManager: SettingsManager
|
||||
private val app: Application,
|
||||
protected val settingsManager: SettingsManager
|
||||
) : AndroidViewModel(app), RemovableStorageListener {
|
||||
|
||||
private val mStorageRoots = MutableLiveData<List<StorageRoot>>()
|
||||
|
@ -44,7 +43,10 @@ internal abstract class StorageViewModel(
|
|||
abstract val isRestoreOperation: Boolean
|
||||
|
||||
companion object {
|
||||
internal fun validLocationIsSet(context: Context, settingsManager: SettingsManager): Boolean {
|
||||
internal fun validLocationIsSet(
|
||||
context: Context,
|
||||
settingsManager: SettingsManager
|
||||
): Boolean {
|
||||
val storage = settingsManager.getStorage() ?: return false
|
||||
if (storage.isUsb) return true
|
||||
return storage.getDocumentFile(context).isDirectory
|
||||
|
@ -66,14 +68,18 @@ internal abstract class StorageViewModel(
|
|||
storageRoot = root
|
||||
}
|
||||
|
||||
internal fun onUriPermissionGranted(result: Intent?) {
|
||||
val uri = result?.data ?: return
|
||||
internal fun onUriPermissionResultReceived(uri: Uri?) {
|
||||
if (uri == null) {
|
||||
val msg = app.getString(R.string.storage_check_fragment_permission_error)
|
||||
mLocationChecked.setEvent(LocationResult(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// inform UI that a location has been successfully selected
|
||||
mLocationSet.setEvent(true)
|
||||
|
||||
// persist permission to access backup folder across reboots
|
||||
val takeFlags = result.flags and (FLAG_GRANT_READ_URI_PERMISSION or FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||
val takeFlags = FLAG_GRANT_READ_URI_PERMISSION or FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
app.contentResolver.takePersistableUriPermission(uri, takeFlags)
|
||||
|
||||
onLocationSet(uri)
|
||||
|
|
Loading…
Add table
Reference in a new issue