Skip to content

Commit

Permalink
Add new option for starting the recording in the paused state
Browse files Browse the repository at this point in the history
This commit adds a new "initially paused" option to BCR's UI. If it's
disabled, then BCR works as it always has: calls are recorded as soon as
they enter the connected state. If the option is enabled, then the
recording starts in the paused state. The user can choose to resume via
BCR's persistent notification. If the recording is never resumed, then
the empty output file is deleted and no success notification will be
shown.

This new option is disabled by default.

Issue: #198

Signed-off-by: Andrew Gunnerson <[email protected]>
  • Loading branch information
chenxiaolong committed Dec 28, 2022
1 parent d858b28 commit da82c37
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 12 deletions.
8 changes: 8 additions & 0 deletions app/src/main/java/com/chiller3/bcr/Preferences.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import java.io.File
class Preferences(private val context: Context) {
companion object {
const val PREF_CALL_RECORDING = "call_recording"
const val PREF_INITIALLY_PAUSED = "initially_paused"
const val PREF_OUTPUT_DIR = "output_dir"
const val PREF_OUTPUT_FORMAT = "output_format"
const val PREF_INHIBIT_BATT_OPT = "inhibit_batt_opt"
Expand Down Expand Up @@ -147,6 +148,13 @@ class Preferences(private val context: Context) {
get() = prefs.getBoolean(PREF_CALL_RECORDING, false)
set(enabled) = prefs.edit { putBoolean(PREF_CALL_RECORDING, enabled) }

/**
* Whether the recording should initially start in the paused state.
*/
var initiallyPaused: Boolean
get() = prefs.getBoolean(PREF_INITIALLY_PAUSED, false)
set(enabled) = prefs.edit { putBoolean(PREF_INITIALLY_PAUSED, enabled) }

/**
* The saved output format.
*
Expand Down
10 changes: 7 additions & 3 deletions app/src/main/java/com/chiller3/bcr/RecorderInCallService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -295,12 +295,16 @@ class RecorderInCallService : InCallService(), RecorderThread.OnRecordingComplet
updateForegroundState()
}

override fun onRecordingCompleted(thread: RecorderThread, file: OutputFile) {
Log.i(TAG, "Recording completed: ${thread.id}: ${file.redacted}")
override fun onRecordingCompleted(thread: RecorderThread, file: OutputFile?) {
Log.i(TAG, "Recording completed: ${thread.id}: ${file?.redacted}")
handler.post {
onThreadExited()

notifySuccess(file)
// If the recording was initially paused and the user never resumed it, there's no
// output file, so nothing needs to be shown.
if (file != null) {
notifySuccess(file)
}
}
}

Expand Down
32 changes: 23 additions & 9 deletions app/src/main/java/com/chiller3/bcr/RecorderThread.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,16 @@ class RecorderThread(
private var captureFailed = false

// Pause state
@Volatile var isPaused = false
set(result) {
Log.d(tag, "Pause state updated: $isPaused")
field = result
@Volatile var isPaused = prefs.initiallyPaused
set(value) {
field = value
if (!value) {
wasEverResumed = true
}

Log.d(tag, "Pause state updated: $value")
}
private var wasEverResumed = !isPaused

// Timestamp
private lateinit var callTimestamp: ZonedDateTime
Expand All @@ -90,6 +95,7 @@ class RecorderThread(

init {
Log.i(tag, "Created thread for call: $call")
Log.i(tag, "Initially paused: $isPaused")

onCallDetailsChanged(call.details)

Expand Down Expand Up @@ -258,8 +264,14 @@ class RecorderThread(
}
}

tryMoveToUserDir(outputFile)?.let {
resultUri = it.uri
if (wasEverResumed) {
tryMoveToUserDir(outputFile)?.let {
resultUri = it.uri
}
} else {
Log.i(tag, "Deleting because recording was never resumed: ${redact(finalFilename)}")
outputFile.delete()
resultUri = null
}

processRetention()
Expand Down Expand Up @@ -292,7 +304,7 @@ class RecorderThread(
val outputFile = resultUri?.let { OutputFile(it, redact(it), format.mimeTypeContainer) }

if (success) {
listener.onRecordingCompleted(this, outputFile!!)
listener.onRecordingCompleted(this, outputFile)
} else {
listener.onRecordingFailed(this, errorMsg, outputFile)
}
Expand Down Expand Up @@ -711,9 +723,11 @@ class RecorderThread(

interface OnRecordingCompletedListener {
/**
* Called when the recording completes successfully. [file] is the output file.
* Called when the recording completes successfully. [file] is the output file. If [file] is
* null, then the recording was started in the paused state and the output file was deleted
* because the user never resumed it.
*/
fun onRecordingCompleted(thread: RecorderThread, file: OutputFile)
fun onRecordingCompleted(thread: RecorderThread, file: OutputFile?)

/**
* Called when an error occurs during recording. If [file] is not null, it points to the
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
<string name="pref_call_recording_name">Call recording</string>
<string name="pref_call_recording_desc">Record incoming and outgoing phone calls. Microphone and notification permissions are required for recording in the background.</string>

<string name="pref_initially_paused_name">Initially paused</string>
<string name="pref_initially_paused_desc_on">Start recording in the paused state. If the recording is never resumed, then the empty output file won\'t be saved.</string>
<string name="pref_initially_paused_desc_off">Start recording immediately when a call connects. To pause or resume, tap on the button in the notification during a call.</string>

<string name="pref_output_dir_name">Output directory</string>
<string name="pref_output_dir_desc">Pick a directory to store recordings.</string>

Expand Down
7 changes: 7 additions & 0 deletions app/src/main/res/xml/root_preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
app:summary="@string/pref_call_recording_desc"
app:iconSpaceReserved="false" />

<SwitchPreferenceCompat
app:key="initially_paused"
app:title="@string/pref_initially_paused_name"
app:summaryOff="@string/pref_initially_paused_desc_off"
app:summaryOn="@string/pref_initially_paused_desc_on"
app:iconSpaceReserved="false" />

<Preference
app:key="output_dir"
app:persistent="false"
Expand Down

0 comments on commit da82c37

Please sign in to comment.