Skip to content
This repository has been archived by the owner on Aug 7, 2024. It is now read-only.

Commit

Permalink
feat: support for recording internal audio in rooted devices (#284)
Browse files Browse the repository at this point in the history
* feat: support for recording internal audio in rooted devices

* fixup! feat: support for recording internal audio in rooted devices
  • Loading branch information
SuhasDissa authored Apr 11, 2024
1 parent 3850194 commit 6663a6e
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 4 deletions.
4 changes: 4 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission
android:name="android.permission.CAPTURE_AUDIO_OUTPUT"
tools:ignore="ProtectedPermissions" />


<!-- Opt out for network permissions that are optional for the ExoPlayer -->
<uses-permission
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ enum class AudioDeviceSource(val value: Int) {
DEFAULT(MediaRecorder.AudioSource.DEFAULT),
MIC(MediaRecorder.AudioSource.MIC),
CAMCORDER(MediaRecorder.AudioSource.CAMCORDER),
UNPROCESSED(MediaRecorder.AudioSource.UNPROCESSED);
UNPROCESSED(MediaRecorder.AudioSource.UNPROCESSED),
REMOTE_SUBMIX(MediaRecorder.AudioSource.REMOTE_SUBMIX);

companion object {
fun fromInt(value: Int) = AudioDeviceSource.values().first { it.value == value }
Expand Down
36 changes: 34 additions & 2 deletions app/src/main/java/com/bnyro/recorder/ui/models/RecorderModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.os.Build
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.annotation.RequiresApi
import androidx.compose.runtime.getValue
Expand All @@ -18,7 +19,9 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModel
import com.bnyro.recorder.R
import com.bnyro.recorder.canvas_overlay.CanvasOverlay
import com.bnyro.recorder.enums.AudioDeviceSource
import com.bnyro.recorder.enums.AudioSource
import com.bnyro.recorder.enums.RecorderState
import com.bnyro.recorder.services.AudioRecorderService
Expand Down Expand Up @@ -75,8 +78,22 @@ class RecorderModel : ViewModel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
audioPermission.add(Manifest.permission.POST_NOTIFICATIONS)
}
val internalAudio = Preferences.prefs.getInt(
Preferences.audioDeviceSourceKey,
0
) == AudioDeviceSource.REMOTE_SUBMIX.value
if (internalAudio) {
audioPermission.add(Manifest.permission.CAPTURE_AUDIO_OUTPUT)
}

if (!PermissionHelper.checkPermissions(context, audioPermission.toTypedArray())) return
if (!PermissionHelper.checkPermissions(context, audioPermission.toTypedArray())) {
Toast.makeText(
context,
context.getString(R.string.no_sufficient_permissions), Toast.LENGTH_SHORT
)
.show()
return
}

val serviceIntent =
if (Preferences.prefs.getBoolean(Preferences.losslessRecorderKey, false)) {
Expand Down Expand Up @@ -161,12 +178,27 @@ class RecorderModel : ViewModel() {
Preferences.prefs.getInt(Preferences.audioSourceKey, 0) == AudioSource.MICROPHONE.value

if (recordAudio) requiredPermissions.add(Manifest.permission.RECORD_AUDIO)

val internalAudio = Preferences.prefs.getInt(
Preferences.audioDeviceSourceKey,
0
) == AudioDeviceSource.REMOTE_SUBMIX.value
if (internalAudio) requiredPermissions.add(Manifest.permission.CAPTURE_AUDIO_OUTPUT)

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requiredPermissions.add(Manifest.permission.POST_NOTIFICATIONS)
}

if (requiredPermissions.isEmpty()) return true

return PermissionHelper.checkPermissions(context, requiredPermissions.toTypedArray())
val granted = PermissionHelper.checkPermissions(context, requiredPermissions.toTypedArray())
if (!granted) {
Toast.makeText(
context,
context.getString(R.string.no_sufficient_permissions), Toast.LENGTH_SHORT
)
.show()
}
return granted
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,8 @@ fun SettingsScreen() {
R.string.default_audio,
R.string.microphone,
R.string.camcorder,
R.string.unprocessed
R.string.unprocessed,
R.string.internal_audio
).map {
stringResource(it)
},
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,6 @@
<string name="cant_access_selected_folder">Can\'t access selected folder!</string>
<string name="draw_mode">Draw Mode</string>
<string name="erase_mode">Erase Mode</string>
<string name="internal_audio">Internal Audio (Root)</string>
<string name="no_sufficient_permissions">No sufficient permissions to start recording</string>
</resources>

0 comments on commit 6663a6e

Please sign in to comment.