diff options
author | Fabian Henneke <FabianHenneke@users.noreply.github.com> | 2020-07-14 11:30:29 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-14 15:00:29 +0530 |
commit | 681c557e9ef174543c290aff4346a52326ba3950 (patch) | |
tree | e893d4403a36686da7ef0b25979edd792ee66cad | |
parent | 2f657108b3cc6a8d41f2a06ad53e9e45f816e1bb (diff) |
Revert "Work around Chrome Autofill issue (#921)" (#933)
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | app/src/main/AndroidManifest.xml | 13 | ||||
-rw-r--r-- | app/src/main/java/com/zeapo/pwdstore/UserPreference.kt | 57 | ||||
-rw-r--r-- | app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ChromeCompatFix.kt | 94 | ||||
-rw-r--r-- | app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt | 1 | ||||
-rw-r--r-- | app/src/main/res/values-v28/bools.xml | 8 | ||||
-rw-r--r-- | app/src/main/res/values/bools.xml | 1 | ||||
-rw-r--r-- | app/src/main/res/values/strings.xml | 11 | ||||
-rw-r--r-- | app/src/main/res/xml/oreo_autofill_chrome_compat_fix.xml | 13 | ||||
-rw-r--r-- | app/src/main/res/xml/preference.xml | 5 |
10 files changed, 9 insertions, 195 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 729e66cd..35f99d5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,6 @@ All notable changes to this project will be documented in this file. - Fix authentication failure with usernames that contain the `@` character - Text input boxes were illegible on dark theme - Top-level password names had inconsistent top margin making them look askew -- Autofill can now be made more reliable in Chrome by enabling an accessibility service that works around known Chrome limitations - Password Store no longer ignores the selected OpenKeychain key - Password export now happens in a separate process, preventing possible freezes diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4e6ea102..5fcbe706 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -99,19 +99,6 @@ android:name="android.accessibilityservice" android:resource="@xml/autofill_config" /> </service> - - <service - android:name=".autofill.oreo.ChromeCompatFix" - android:enabled="@bool/enable_chrome_compat_fix" - android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> - <intent-filter> - <action android:name="android.accessibilityservice.AccessibilityService" /> - </intent-filter> - <meta-data - android:name="android.accessibilityservice" - android:resource="@xml/oreo_autofill_chrome_compat_fix" /> - </service> - <service android:name=".ClipboardService" android:process=":clipboard_service_process" /> diff --git a/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt b/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt index 950b6523..f713ad26 100644 --- a/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt +++ b/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt @@ -41,9 +41,7 @@ import com.github.ajalt.timberkt.w import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import com.zeapo.pwdstore.autofill.AutofillPreferenceActivity -import com.zeapo.pwdstore.autofill.AutofillService import com.zeapo.pwdstore.autofill.oreo.BrowserAutofillSupportLevel -import com.zeapo.pwdstore.autofill.oreo.ChromeCompatFix import com.zeapo.pwdstore.autofill.oreo.getInstalledBrowsersWithAutofillSupportLevel import com.zeapo.pwdstore.crypto.BasePgpActivity import com.zeapo.pwdstore.crypto.GetKeyIdsActivity @@ -72,7 +70,6 @@ class UserPreference : AppCompatActivity() { class PrefsFragment : PreferenceFragmentCompat() { private var autoFillEnablePreference: SwitchPreferenceCompat? = null - private var oreoAutofillChromeCompatFix: SwitchPreferenceCompat? = null private var clearSavedPassPreference: Preference? = null private lateinit var autofillDependencies: List<Preference> private lateinit var oreoAutofillDependencies: List<Preference> @@ -118,7 +115,6 @@ class UserPreference : AppCompatActivity() { // Autofill preferences autoFillEnablePreference = findPreference(PreferenceKeys.AUTOFILL_ENABLE) - oreoAutofillChromeCompatFix = findPreference(PreferenceKeys.OREO_AUTOFILL_CHROME_COMPAT_FIX) val oreoAutofillDirectoryStructurePreference = findPreference<ListPreference>(PreferenceKeys.OREO_AUTOFILL_DIRECTORY_STRUCTURE) val oreoAutofillDefaultUsername = findPreference<EditTextPreference>(PreferenceKeys.OREO_AUTOFILL_DEFAULT_USERNAME) val oreoAutofillCustomPublixSuffixes = findPreference<EditTextPreference>(PreferenceKeys.OREO_AUTOFILL_CUSTOM_PUBLIC_SUFFIXES) @@ -277,16 +273,6 @@ class UserPreference : AppCompatActivity() { true } - oreoAutofillChromeCompatFix?.onPreferenceClickListener = ClickListener { - if (oreoAutofillChromeCompatFix!!.isChecked) { - startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)) - true - } else { - // Service will disable itself on startup if the preference has the value false. - false - } - } - findPreference<Preference>(PreferenceKeys.EXPORT_PASSWORDS)?.apply { isVisible = sharedPreferences.getBoolean(PreferenceKeys.REPOSITORY_INITIALIZED, false) onPreferenceClickListener = Preference.OnPreferenceClickListener { @@ -409,20 +395,16 @@ class UserPreference : AppCompatActivity() { } private fun updateAutofillSettings() { - val isAccessibilityAutofillServiceEnabled = callingActivity.isAccessibilityAutofillServiceEnabled + val isAccessibilityServiceEnabled = callingActivity.isAccessibilityServiceEnabled val isAutofillServiceEnabled = callingActivity.isAutofillServiceEnabled autoFillEnablePreference?.isChecked = - isAccessibilityAutofillServiceEnabled || isAutofillServiceEnabled + isAccessibilityServiceEnabled || isAutofillServiceEnabled autofillDependencies.forEach { - it.isVisible = isAccessibilityAutofillServiceEnabled + it.isVisible = isAccessibilityServiceEnabled } oreoAutofillDependencies.forEach { it.isVisible = isAutofillServiceEnabled } - oreoAutofillChromeCompatFix?.apply { - isChecked = callingActivity.isChromeCompatFixServiceEnabled - isVisible = callingActivity.isChromeCompatFixServiceSupported - } } private fun updateClearSavedPassphrasePrefs() { @@ -443,16 +425,13 @@ class UserPreference : AppCompatActivity() { } private fun onEnableAutofillClick() { - if (callingActivity.isAccessibilityAutofillServiceEnabled) { + if (callingActivity.isAccessibilityServiceEnabled) { startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)) } else if (callingActivity.isAutofillServiceEnabled) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) callingActivity.autofillManager!!.disableAutofillServices() - ChromeCompatFix.setStatusInPreferences(requireContext(), false) - updateAutofillSettings() - } else { + else throw IllegalStateException("isAutofillServiceEnabled == true, but Build.VERSION.SDK_INT < Build.VERSION_CODES.O") - } } else { val enableOreoAutofill = callingActivity.isAutofillServiceSupported MaterialAlertDialogBuilder(callingActivity).run { @@ -744,32 +723,14 @@ class UserPreference : AppCompatActivity() { File("$filesDir/.ssh_key").writeText(lines.joinToString("\n")) } - private val isAccessibilityAutofillServiceEnabled: Boolean + private val isAccessibilityServiceEnabled: Boolean get() { val am = getSystemService<AccessibilityManager>() ?: return false val runningServices = am .getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC) return runningServices - .mapNotNull { it?.resolveInfo?.serviceInfo } - .any { it.packageName == BuildConfig.APPLICATION_ID && it.name == AutofillService::class.java.name } - } - - private val isChromeCompatFixServiceEnabled: Boolean - get() { - val am = getSystemService<AccessibilityManager>() ?: return false - val runningServices = am - .getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC) - return runningServices - .mapNotNull { it?.resolveInfo?.serviceInfo } - .any { it.packageName == BuildConfig.APPLICATION_ID && it.name == ChromeCompatFix::class.java.name } - } - - private val isChromeCompatFixServiceSupported: Boolean - get() { - // Autofill compat mode is only available starting with Android Pie and only makes sense - // when used with Autofill enabled. - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) return false - return isAutofillServiceEnabled + .map { it.id.substringBefore("/") } + .any { it == BuildConfig.APPLICATION_ID } } private val isAutofillServiceSupported: Boolean diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ChromeCompatFix.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ChromeCompatFix.kt deleted file mode 100644 index d1f81c0c..00000000 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ChromeCompatFix.kt +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved. - * SPDX-License-Identifier: GPL-3.0-only - */ -package com.zeapo.pwdstore.autofill.oreo - -import android.accessibilityservice.AccessibilityService -import android.content.Context -import android.content.SharedPreferences -import android.os.Build -import android.os.Handler -import android.os.Looper -import android.view.accessibility.AccessibilityEvent -import androidx.annotation.RequiresApi -import androidx.core.content.edit -import androidx.preference.PreferenceManager -import com.github.ajalt.timberkt.i -import com.github.ajalt.timberkt.v -import com.github.ajalt.timberkt.w -import com.zeapo.pwdstore.utils.PreferenceKeys -import com.zeapo.pwdstore.utils.autofillManager - -@RequiresApi(Build.VERSION_CODES.P) -class ChromeCompatFix : AccessibilityService() { - - companion object { - - fun setStatusInPreferences(context: Context, enabled: Boolean) { - PreferenceManager.getDefaultSharedPreferences(context).edit { - putBoolean(PreferenceKeys.OREO_AUTOFILL_CHROME_COMPAT_FIX, enabled) - } - } - } - - private val isEnabledInPreferences - get() = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(PreferenceKeys.OREO_AUTOFILL_CHROME_COMPAT_FIX, true) - - private val handler = Handler(Looper.getMainLooper()) - private val forceRootNodePopulation = Runnable { - val rootPackageName = rootInActiveWindow?.packageName.toString() - v { "$rootPackageName: forced root node population" } - } - private val disableListener = SharedPreferences.OnSharedPreferenceChangeListener { prefs: SharedPreferences, key: String -> - if (key != PreferenceKeys.OREO_AUTOFILL_CHROME_COMPAT_FIX) - return@OnSharedPreferenceChangeListener - if (!isEnabledInPreferences) { - i { "Disabled in settings, shutting down..." } - disableSelf() - } - } - - override fun onAccessibilityEvent(event: AccessibilityEvent) { - handler.removeCallbacks(forceRootNodePopulation) - when (event.eventType) { - AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, AccessibilityEvent.TYPE_ANNOUNCEMENT -> { - // WINDOW_STATE_CHANGED: Triggered on long press in a text field, replacement for - // the missing Autofill action menu item. - // ANNOUNCEMENT: Triggered when a password field is selected. - // - // These events are triggered only by user actions and thus don't need to be handled - // with debounce. However, they only trigger Autofill popups on the *next* input - // field selected by the user. - forceRootNodePopulation.run() - v { "${event.packageName} (${AccessibilityEvent.eventTypeToString(event.eventType)}): forced root node population" } - } - AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED -> { - // WINDOW_CONTENT_CHANGED: Triggered whenever the page contents change. - // - // This event is triggered many times during page load, which makes a debounce - // necessary to prevent huge performance regressions in Chrome. However, it is the - // only event that reliably runs before the user selects a text field. - handler.postDelayed(forceRootNodePopulation, 300) - v { "${event.packageName} (${AccessibilityEvent.eventTypeToString(event.eventType)}): debounced root node population" } - } - } - } - - override fun onServiceConnected() { - super.onServiceConnected() - // Allow the service to be activated only if the Autofill service is already enabled. - if (autofillManager?.hasEnabledAutofillServices() != true) { - w { "Autofill service not enabled, shutting down..." } - disableSelf() - return - } - // Update preferences if the user manually activated the service. - setStatusInPreferences(this, true) - - PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(disableListener) - } - - override fun onInterrupt() {} -} - diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt b/app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt index 3fb05724..3235c7fc 100644 --- a/app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt +++ b/app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt @@ -40,7 +40,6 @@ object PreferenceKeys { const val OPENPGP_KEY_IDS_SET = "openpgp_key_ids_set" const val OPENPGP_KEY_ID_PREF = "openpgp_key_id_pref" const val OPENPGP_PROVIDER_LIST = "openpgp_provider_list" - const val OREO_AUTOFILL_CHROME_COMPAT_FIX = "oreo_autofill_chrome_compat_fix" const val OREO_AUTOFILL_CUSTOM_PUBLIC_SUFFIXES = "oreo_autofill_custom_public_suffixes" const val OREO_AUTOFILL_DEFAULT_USERNAME = "oreo_autofill_default_username" const val OREO_AUTOFILL_DIRECTORY_STRUCTURE = "oreo_autofill_directory_structure" diff --git a/app/src/main/res/values-v28/bools.xml b/app/src/main/res/values-v28/bools.xml deleted file mode 100644 index 3dc8bf79..00000000 --- a/app/src/main/res/values-v28/bools.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?><!-- - ~ Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved. - ~ SPDX-License-Identifier: GPL-3.0-only - --> - -<resources> - <bool name="enable_chrome_compat_fix">true</bool> -</resources> diff --git a/app/src/main/res/values/bools.xml b/app/src/main/res/values/bools.xml index b19e7848..475702a1 100644 --- a/app/src/main/res/values/bools.xml +++ b/app/src/main/res/values/bools.xml @@ -7,5 +7,4 @@ <bool name="leak_canary_allow_in_non_debuggable_build">true</bool> <bool name="enable_accessibility_autofill">true</bool> <bool name="light_status_bar">true</bool> - <bool name="enable_chrome_compat_fix">false</bool> </resources> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0834b96e..a616896f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -275,16 +275,6 @@ <string name="oreo_autofill_enable_dialog_description">Password Store can offer to fill login forms and even save credentials you enter in apps or on websites.</string> <string name="oreo_autofill_enable_dialog_instructions">To enable this feature, tap OK to go to Autofill settings. There, select Password Store from the list and confirm the confirmation prompt with OK.</string> <string name="oreo_autofill_enable_dialog_installed_browsers">Autofill support with installed browsers:</string> - <string name="oreo_autofill_chrome_compat_fix_summary">Make Autofill more reliable in Chrome</string> - <string name="oreo_autofill_chrome_compat_fix_description">This accessibility service makes - Autofill work more reliably in Chrome. It can only be activated if you are already using - Password Store as your Autofill service.\n\nThis service is only active while you are - using Chrome. It does not access any data or take any actions on your behalf, but forces - Chrome to properly forward user interactions to the Password Store Autofill - service.\n\nChrome\'s performance should not be noticeably affected. If you are experiencing - any problems with this service, please create an issue at - https://msfjarvis.dev/aps. - </string> <!-- Autofill --> <string name="autofill_description">Autofills password fields in apps. Only works for Android versions 4.3 and up. Does not rely on the clipboard for Android versions 5.0 and up.</string> @@ -399,7 +389,6 @@ <string name="otp_import_success">Successfully imported TOTP configuration</string> <string name="otp_import_failure">Failed to import TOTP configuration</string> <string name="oreo_autofill_chrome_compat_fix_preference_title">Improve reliability in Chrome</string> - <string name="oreo_autofill_chrome_compat_fix_preference_summary">Requires activating an accessibility service and may affect overall Chrome performance</string> <string name="exporting_passwords">Exporting passwords…</string> <string name="invalid_filename_text">File name must not contain \'/\', set directory above</string> <string name="directory_hint">Directory</string> diff --git a/app/src/main/res/xml/oreo_autofill_chrome_compat_fix.xml b/app/src/main/res/xml/oreo_autofill_chrome_compat_fix.xml deleted file mode 100644 index 196c93d5..00000000 --- a/app/src/main/res/xml/oreo_autofill_chrome_compat_fix.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?><!-- - ~ Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved. - ~ SPDX-License-Identifier: GPL-3.0-only - --> -<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" - android:accessibilityEventTypes="typeWindowContentChanged|typeAnnouncement|typeWindowStateChanged" - android:accessibilityFeedbackType="feedbackGeneric" - android:accessibilityFlags="flagDefault" - android:canRetrieveWindowContent="true" - android:description="@string/oreo_autofill_chrome_compat_fix_description" - android:notificationTimeout="100" - android:packageNames="com.android.chrome,com.chrome.beta,com.chrome.dev,com.chrome.canary" - android:summary="@string/oreo_autofill_chrome_compat_fix_summary" /> diff --git a/app/src/main/res/xml/preference.xml b/app/src/main/res/xml/preference.xml index d4ec4139..0d71d6cc 100644 --- a/app/src/main/res/xml/preference.xml +++ b/app/src/main/res/xml/preference.xml @@ -10,11 +10,6 @@ app:defaultValue="true" app:key="autofill_enable" app:title="@string/pref_autofill_enable_title" /> - <SwitchPreferenceCompat - app:defaultValue="true" - app:key="oreo_autofill_chrome_compat_fix" - app:summary="@string/oreo_autofill_chrome_compat_fix_preference_summary" - app:title="@string/oreo_autofill_chrome_compat_fix_preference_title" /> <ListPreference app:defaultValue="file" app:entries="@array/oreo_autofill_directory_structure_entries" |