aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/dev/msfjarvis/aps/ui/settings/AutofillSettings.kt
blob: 74b407fdd9dd8ecce94330ee57fda5ce8d74c152 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
 * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
 * SPDX-License-Identifier: GPL-3.0-only
 */

package dev.msfjarvis.aps.ui.settings

import de.Maxr1998.modernpreferences.PreferenceScreen
import de.Maxr1998.modernpreferences.helpers.editText
import de.Maxr1998.modernpreferences.helpers.onClick
import de.Maxr1998.modernpreferences.helpers.singleChoice
import de.Maxr1998.modernpreferences.helpers.switch
import de.Maxr1998.modernpreferences.preferences.SwitchPreference
import de.Maxr1998.modernpreferences.preferences.choice.SelectionItem
import dev.msfjarvis.aps.BuildConfig
import dev.msfjarvis.aps.R
import dev.msfjarvis.aps.util.autofill.DirectoryStructure
import dev.msfjarvis.aps.util.extensions.autofillManager
import dev.msfjarvis.aps.util.settings.PreferenceKeys
import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import androidx.annotation.RequiresApi
import androidx.appcompat.widget.AppCompatTextView
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import com.github.androidpasswordstore.autofillparser.BrowserAutofillSupportLevel
import com.github.androidpasswordstore.autofillparser.getInstalledBrowsersWithAutofillSupportLevel
import com.google.android.material.dialog.MaterialAlertDialogBuilder

class AutofillSettings(private val activity: FragmentActivity) : SettingsProvider {

    private val isAutofillServiceEnabled: Boolean
        get() {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return false
            return activity.autofillManager?.hasEnabledAutofillServices() == true
        }

    @RequiresApi(Build.VERSION_CODES.O)
    private fun showAutofillDialog(pref: SwitchPreference) {
        val observer = LifecycleEventObserver { _, event ->
            when (event) {
                Lifecycle.Event.ON_RESUME -> {
                    pref.checked = isAutofillServiceEnabled
                }
                else -> {
                }
            }
        }
        MaterialAlertDialogBuilder(activity).run {
            setTitle(R.string.pref_autofill_enable_title)
            @SuppressLint("InflateParams")
            val layout =
                activity.layoutInflater.inflate(R.layout.oreo_autofill_instructions, null)
            val supportedBrowsersTextView =
                layout.findViewById<AppCompatTextView>(R.id.supportedBrowsers)
            supportedBrowsersTextView.text =
                getInstalledBrowsersWithAutofillSupportLevel(context).joinToString(
                    separator = "\n"
                ) {
                    val appLabel = it.first
                    val supportDescription = when (it.second) {
                        BrowserAutofillSupportLevel.None -> activity.getString(R.string.oreo_autofill_no_support)
                        BrowserAutofillSupportLevel.FlakyFill -> activity.getString(R.string.oreo_autofill_flaky_fill_support)
                        BrowserAutofillSupportLevel.PasswordFill -> activity.getString(R.string.oreo_autofill_password_fill_support)
                        BrowserAutofillSupportLevel.PasswordFillAndSaveIfNoAccessibility -> activity.getString(R.string.oreo_autofill_password_fill_and_conditional_save_support)
                        BrowserAutofillSupportLevel.GeneralFill -> activity.getString(R.string.oreo_autofill_general_fill_support)
                        BrowserAutofillSupportLevel.GeneralFillAndSave -> activity.getString(R.string.oreo_autofill_general_fill_and_save_support)
                    }
                    "$appLabel: $supportDescription"
                }
            setView(layout)
            setPositiveButton(R.string.dialog_ok) { _, _ ->
                val intent = Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE).apply {
                    data = Uri.parse("package:${BuildConfig.APPLICATION_ID}")
                }
                activity.startActivity(intent)
            }
            setNegativeButton(R.string.dialog_cancel, null)
            setOnDismissListener { pref.checked = isAutofillServiceEnabled }
            activity.lifecycle.addObserver(observer)
            show()
        }
    }

    override fun provideSettings(builder: PreferenceScreen.Builder) {
        builder.apply {
            switch(PreferenceKeys.AUTOFILL_ENABLE) {
                titleRes = R.string.pref_autofill_enable_title
                visible = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
                defaultValue = isAutofillServiceEnabled
                onClick {
                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return@onClick true
                    if (isAutofillServiceEnabled) {
                        activity.autofillManager?.disableAutofillServices()
                    } else {
                        showAutofillDialog(this)
                    }
                    false
                }
            }
            val values = activity.resources.getStringArray(R.array.oreo_autofill_directory_structure_values)
            val titles = activity.resources.getStringArray(R.array.oreo_autofill_directory_structure_entries)
            val items = values.zip(titles).map { SelectionItem(it.first, it.second, null) }
            singleChoice(PreferenceKeys.OREO_AUTOFILL_DIRECTORY_STRUCTURE, items) {
                initialSelection = DirectoryStructure.DEFAULT.value
                dependency = PreferenceKeys.AUTOFILL_ENABLE
                titleRes = R.string.oreo_autofill_preference_directory_structure
            }
            editText(PreferenceKeys.OREO_AUTOFILL_DEFAULT_USERNAME) {
                dependency = PreferenceKeys.AUTOFILL_ENABLE
                titleRes = R.string.preference_default_username_title
                summaryProvider = { activity.getString(R.string.preference_default_username_summary) }
            }
            editText(PreferenceKeys.OREO_AUTOFILL_CUSTOM_PUBLIC_SUFFIXES) {
                dependency = PreferenceKeys.AUTOFILL_ENABLE
                titleRes = R.string.preference_custom_public_suffixes_title
                summaryProvider = { activity.getString(R.string.preference_custom_public_suffixes_summary) }
                textInputHintRes = R.string.preference_custom_public_suffixes_hint
            }
        }
    }
}