Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e67dfb3

Browse files
committedNov 18, 2022
Disable speakerphone when headphones are plugged
1 parent 25dd10d commit e67dfb3

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed
 

‎atox/src/main/kotlin/ui/call/CallFragment.kt

+41
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,19 @@
55
package ltd.evilcorp.atox.ui.call
66

77
import android.Manifest
8+
import android.media.AudioDeviceInfo.TYPE_BLE_HEADSET
9+
import android.media.AudioDeviceInfo.TYPE_BLE_SPEAKER
10+
import android.media.AudioDeviceInfo.TYPE_BLUETOOTH_SCO
11+
import android.media.AudioDeviceInfo.TYPE_WIRED_HEADPHONES
12+
import android.media.AudioDeviceInfo.TYPE_WIRED_HEADSET
13+
import android.media.AudioManager
14+
import android.os.Build
815
import android.os.Bundle
916
import android.view.View
1017
import android.widget.Toast
1118
import androidx.activity.result.contract.ActivityResultContracts
19+
import androidx.annotation.RequiresApi
20+
import androidx.core.content.ContextCompat.getSystemService
1221
import androidx.core.view.ViewCompat
1322
import androidx.core.view.WindowInsetsCompat
1423
import androidx.core.view.updatePadding
@@ -25,9 +34,23 @@ import ltd.evilcorp.atox.vmFactory
2534
import ltd.evilcorp.domain.feature.CallState
2635
import ltd.evilcorp.domain.tox.PublicKey
2736

37+
2838
private const val PERMISSION = Manifest.permission.RECORD_AUDIO
2939

3040
class CallFragment : BaseFragment<FragmentCallBinding>(FragmentCallBinding::inflate) {
41+
42+
companion object {
43+
private var hasCalled = false
44+
@RequiresApi(Build.VERSION_CODES.S)
45+
private val audioOutputDevices = arrayOf(
46+
TYPE_WIRED_HEADPHONES,
47+
TYPE_WIRED_HEADSET,
48+
TYPE_BLE_HEADSET,
49+
TYPE_BLE_SPEAKER,
50+
TYPE_BLUETOOTH_SCO
51+
)
52+
}
53+
3154
private val vm: CallViewModel by viewModels { vmFactory }
3255

3356
private val requestPermissionLauncher = registerForActivityResult(
@@ -40,6 +63,7 @@ class CallFragment : BaseFragment<FragmentCallBinding>(FragmentCallBinding::infl
4063
}
4164
}
4265

66+
@RequiresApi(Build.VERSION_CODES.S)
4367
override fun onViewCreated(view: View, savedInstanceState: Bundle?) = binding.run {
4468
ViewCompat.setOnApplyWindowInsetsListener(view) { _, compat ->
4569
val insets = compat.getInsets(WindowInsetsCompat.Type.systemBars())
@@ -77,6 +101,7 @@ class CallFragment : BaseFragment<FragmentCallBinding>(FragmentCallBinding::infl
77101
}
78102
}
79103

104+
updateSpeakerphoneOnDetectHeadphones()
80105
updateSpeakerphoneIcon()
81106
speakerphone.setOnClickListener {
82107
vm.toggleSpeakerphone()
@@ -108,12 +133,28 @@ class CallFragment : BaseFragment<FragmentCallBinding>(FragmentCallBinding::infl
108133
binding.speakerphone.setImageResource(icon)
109134
}
110135

136+
137+
@RequiresApi(Build.VERSION_CODES.S)
138+
private fun updateSpeakerphoneOnDetectHeadphones() {
139+
vm.disableSpeakerphone()
140+
}
141+
111142
private fun startCall() {
112143
vm.startCall()
113144
vm.inCall.asLiveData().observe(viewLifecycleOwner) { inCall ->
114145
if (inCall == CallState.NotInCall) {
115146
findNavController().popBackStack()
147+
hasCalled = false
116148
}
117149
}
118150
}
151+
152+
@RequiresApi(Build.VERSION_CODES.S)
153+
private fun headphonesArePlugged(): Boolean {
154+
val ctx = context ?: return false
155+
val audioManager = getSystemService(ctx, AudioManager::class.java) ?: return false
156+
return audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS).any { info ->
157+
audioOutputDevices.contains(info.type)
158+
}
159+
}
119160
}

‎atox/src/main/kotlin/ui/call/CallViewModel.kt

+11-2
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ class CallViewModel @Inject constructor(
4949
fun startSendingAudio() = callManager.startSendingAudio()
5050
fun stopSendingAudio() = callManager.stopSendingAudio()
5151

52-
fun toggleSpeakerphone() {
53-
speakerphoneOn = !speakerphoneOn
52+
fun applyProximityScreenSetting() {
5453
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
5554
if (speakerphoneOn) {
5655
proximityScreenOff.release()
@@ -60,6 +59,16 @@ class CallViewModel @Inject constructor(
6059
}
6160
}
6261

62+
fun disableSpeakerphone() {
63+
speakerphoneOn = false
64+
applyProximityScreenSetting()
65+
}
66+
67+
fun toggleSpeakerphone() {
68+
speakerphoneOn = !speakerphoneOn
69+
applyProximityScreenSetting()
70+
}
71+
6372
val inCall = callManager.inCall
6473
val sendingAudio = callManager.sendingAudio
6574

0 commit comments

Comments
 (0)
Please sign in to comment.