5
5
package ltd.evilcorp.atox.ui.call
6
6
7
7
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
8
15
import android.os.Bundle
9
16
import android.view.View
10
17
import android.widget.Toast
11
18
import androidx.activity.result.contract.ActivityResultContracts
19
+ import androidx.annotation.RequiresApi
20
+ import androidx.core.content.ContextCompat.getSystemService
12
21
import androidx.core.view.ViewCompat
13
22
import androidx.core.view.WindowInsetsCompat
14
23
import androidx.core.view.updatePadding
@@ -25,9 +34,23 @@ import ltd.evilcorp.atox.vmFactory
25
34
import ltd.evilcorp.domain.feature.CallState
26
35
import ltd.evilcorp.domain.tox.PublicKey
27
36
37
+
28
38
private const val PERMISSION = Manifest .permission.RECORD_AUDIO
29
39
30
40
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
+
31
54
private val vm: CallViewModel by viewModels { vmFactory }
32
55
33
56
private val requestPermissionLauncher = registerForActivityResult(
@@ -40,6 +63,7 @@ class CallFragment : BaseFragment<FragmentCallBinding>(FragmentCallBinding::infl
40
63
}
41
64
}
42
65
66
+ @RequiresApi(Build .VERSION_CODES .S )
43
67
override fun onViewCreated (view : View , savedInstanceState : Bundle ? ) = binding.run {
44
68
ViewCompat .setOnApplyWindowInsetsListener(view) { _, compat ->
45
69
val insets = compat.getInsets(WindowInsetsCompat .Type .systemBars())
@@ -77,6 +101,7 @@ class CallFragment : BaseFragment<FragmentCallBinding>(FragmentCallBinding::infl
77
101
}
78
102
}
79
103
104
+ updateSpeakerphoneOnDetectHeadphones()
80
105
updateSpeakerphoneIcon()
81
106
speakerphone.setOnClickListener {
82
107
vm.toggleSpeakerphone()
@@ -108,12 +133,28 @@ class CallFragment : BaseFragment<FragmentCallBinding>(FragmentCallBinding::infl
108
133
binding.speakerphone.setImageResource(icon)
109
134
}
110
135
136
+
137
+ @RequiresApi(Build .VERSION_CODES .S )
138
+ private fun updateSpeakerphoneOnDetectHeadphones () {
139
+ vm.disableSpeakerphone()
140
+ }
141
+
111
142
private fun startCall () {
112
143
vm.startCall()
113
144
vm.inCall.asLiveData().observe(viewLifecycleOwner) { inCall ->
114
145
if (inCall == CallState .NotInCall ) {
115
146
findNavController().popBackStack()
147
+ hasCalled = false
116
148
}
117
149
}
118
150
}
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
+ }
119
160
}
0 commit comments