From 91843837df726c789bd8e0a2cd93f5882bb662c5 Mon Sep 17 00:00:00 2001 From: Aaron Hewitt Date: Thu, 15 Oct 2026 18:36:16 +0100 Subject: [PATCH 1/2] Add a Copy command action to the speaker switch while it needs adb While Backtalk lacks MANAGE_ONGOING_CALLS, the "Speaker when away from your ear" switch has a "Copy command" action that copies the adb command from its summary to the clipboard. The action is removed once the permission is granted. Below Android 13, a "Command copied" toast confirms the copy; from Android 13 the system confirms it. The switch stays disabled until the permission is granted, and Backtalk does not speak the actions hint on disabled items, so the action is found through the Actions reading control. - CommandSwitchPreference: a switch with an optional adb command and the Copy command action, for any setting that needs a permission granted with adb. --- lint-baseline.xml | 20 +++++ .../base/CommandSwitchPreference.kt | 77 +++++++++++++++++++ .../base/SoundAndVibrationFragment.java | 11 ++- talkback/src/main/res/values/strings.xml | 4 + .../sound_and_vibration_preferences.xml | 2 +- .../xml/sound_and_vibration_preferences.xml | 2 +- 6 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 talkback/src/main/java/com/google/android/accessibility/talkback/preference/base/CommandSwitchPreference.kt diff --git a/lint-baseline.xml b/lint-baseline.xml index ad44fd5a..fe2fe536 100644 --- a/lint-baseline.xml +++ b/lint-baseline.xml @@ -10,6 +10,26 @@ line="177" column="13"/> + + + + + + + copy(text) + true + }, + ) + } + + private fun copy(text: String) { + if (!ClipboardUtils.copyToClipboard(context, text)) return + // From Android 13 the system confirms copies itself. + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { + Toast.makeText(context, R.string.command_copied, Toast.LENGTH_SHORT).show() + } + } + + private companion object { + val ACTION_COPY_COMMAND = R.id.accessibility_custom_action_0 + } +} diff --git a/talkback/src/main/java/com/google/android/accessibility/talkback/preference/base/SoundAndVibrationFragment.java b/talkback/src/main/java/com/google/android/accessibility/talkback/preference/base/SoundAndVibrationFragment.java index 184b981a..c5864770 100644 --- a/talkback/src/main/java/com/google/android/accessibility/talkback/preference/base/SoundAndVibrationFragment.java +++ b/talkback/src/main/java/com/google/android/accessibility/talkback/preference/base/SoundAndVibrationFragment.java @@ -93,7 +93,8 @@ public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) { /** * The speakerphone setting needs a permission that the user grants with adb, and Android only has - * it from Android 12. Until it is granted, the setting is off and says how to grant it. + * it from Android 12. Until it is granted, the setting is off, says how to grant it and has an + * action that copies the command. */ private void updateSpeakerphonePreference() { Preference pref = findPreference(getString(R.string.pref_speakerphone_away_from_ear_key)); @@ -106,13 +107,15 @@ private void updateSpeakerphonePreference() { return; } boolean granted = SpeakerphoneSettings.INSTANCE.canControlCalls(getContext()); + String command = SpeakerphoneSettings.INSTANCE.grantCommand(getContext()); pref.setEnabled(granted); pref.setSummary( granted ? getString(R.string.summary_pref_speakerphone_away_from_ear) - : getString( - R.string.summary_pref_speakerphone_needs_permission, - SpeakerphoneSettings.INSTANCE.grantCommand(getContext()))); + : getString(R.string.summary_pref_speakerphone_needs_permission, command)); + if (pref instanceof CommandSwitchPreference) { + ((CommandSwitchPreference) pref).setCommand(granted ? null : command); + } } private void updateAudioOutputPreference() { diff --git a/talkback/src/main/res/values/strings.xml b/talkback/src/main/res/values/strings.xml index 16e72d67..20647b67 100644 --- a/talkback/src/main/res/values/strings.xml +++ b/talkback/src/main/res/values/strings.xml @@ -398,6 +398,10 @@ During a call, switches to the speaker when you take the phone away from your ear, and back to the earpiece when you hold it up again. Needs a permission that Android does not give to screen readers. To grant it, run this command with adb or Shizuku, then come back to this screen: %1$s + + Copy command + + Command copied Let other apps speak diff --git a/talkback/src/main/res/xml-v31/sound_and_vibration_preferences.xml b/talkback/src/main/res/xml-v31/sound_and_vibration_preferences.xml index 2a74b99a..78667c4b 100644 --- a/talkback/src/main/res/xml-v31/sound_and_vibration_preferences.xml +++ b/talkback/src/main/res/xml-v31/sound_and_vibration_preferences.xml @@ -31,7 +31,7 @@ android:defaultValue="@bool/pref_proximity_default" android:key="@string/pref_proximity_key" android:title="@string/title_pref_cover_proximity_sensor" /> - - Date: Thu, 15 Oct 2026 18:44:09 +0100 Subject: [PATCH 2/2] Describe the Copy command action in differences.md --- differences.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/differences.md b/differences.md index 2f78634d..d3afbe9a 100644 --- a/differences.md +++ b/differences.md @@ -400,7 +400,7 @@ Android lets only certain apps, such as smartwatch companions, change where call adb shell appops set fyi.quin.backtalk MANAGE_ONGOING_CALLS allow ``` -Then turn on **Sound and vibration** > **Speaker when away from your ear**. Until you grant the permission, the setting is unavailable and shows the command. This feature requires Android 12 or later. +Then turn on **Sound and vibration** > **Speaker when away from your ear**. Until you grant the permission, the setting is unavailable and shows the command, and its **Copy command** action copies the command to the clipboard. This feature requires Android 12 or later. ## Direct touch