Skip to content

Commit

Permalink
fix(android): wait for the permission to be accepted before going to …
Browse files Browse the repository at this point in the history
…next step
  • Loading branch information
ThibaultBee committed Feb 5, 2024
1 parent 5e69d34 commit 42f8a0e
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,80 +45,130 @@ class FlutterLiveStreamView(
val isStreaming: Boolean
get() = _isStreaming

var videoConfig = VideoConfig()
set(value) {
if (isStreaming) {
throw UnsupportedOperationException("You have to stop streaming first")
}

onVideoSizeChanged(value.resolution)
private var _videoConfig: VideoConfig? = null
val videoConfig: VideoConfig
get() = _videoConfig!!

val wasPreviewing = _isPreviewing
if (wasPreviewing) {
stopPreview()
}
streamer.configure(value)
field = value
if (wasPreviewing) {
startPreview()
}
fun setVideoConfig(
videoConfig: VideoConfig,
onSuccess: () -> Unit,
onError: (Exception) -> Unit
) {
if (isStreaming) {
throw UnsupportedOperationException("You have to stop streaming first")
}

var audioConfig = AudioConfig()
set(value) {
if (isStreaming) {
throw UnsupportedOperationException("You have to stop streaming first")
}
permissionsManager.requestPermission(
Manifest.permission.RECORD_AUDIO,
onGranted = {
streamer.configure(value)
},
onShowPermissionRationale = { onRequiredPermissionLastTime ->
/**
* Require an AppCompat theme to use MaterialAlertDialogBuilder
*
context.showDialog(
R.string.permission_required,
R.string.record_audio_permission_required_message,
android.R.string.ok,
onPositiveButtonClick = { onRequiredPermissionLastTime() }
) */
onGenericError(SecurityException("Missing permission Manifest.permission.RECORD_AUDIO"))
},
onDenied = {
onGenericError(SecurityException("Missing permission Manifest.permission.RECORD_AUDIO"))
})
onVideoSizeChanged(videoConfig.resolution)

val wasPreviewing = _isPreviewing
if (wasPreviewing) {
stopPreview()
}
streamer.configure(videoConfig)
_videoConfig = videoConfig
if (wasPreviewing) {
startPreview(onSuccess, onError)
} else {
onSuccess()
}
}

private var _audioConfig: AudioConfig? = null
val audioConfig: AudioConfig
get() = _audioConfig!!

fun setAudioConfig(
audioConfig: AudioConfig,
onSuccess: () -> Unit,
onError: (Exception) -> Unit
) {
if (isStreaming) {
throw UnsupportedOperationException("You have to stop streaming first")
}

permissionsManager.requestPermission(
Manifest.permission.RECORD_AUDIO,
onGranted = {
try {
streamer.configure(audioConfig)
_audioConfig = audioConfig
onSuccess()
} catch (e: Exception) {
onError(e)
}
},
onShowPermissionRationale = { onRequiredPermissionLastTime ->
/**
* Require an AppCompat theme to use MaterialAlertDialogBuilder
*
context.showDialog(
R.string.permission_required,
R.string.record_audio_permission_required_message,
android.R.string.ok,
onPositiveButtonClick = { onRequiredPermissionLastTime() }
) */
onError(SecurityException("Missing permission Manifest.permission.RECORD_AUDIO"))
},
onDenied = {
onError(SecurityException("Missing permission Manifest.permission.RECORD_AUDIO"))
})
}

var isMuted: Boolean
get() = streamer.settings.audio.isMuted
set(value) {
streamer.settings.audio.isMuted = value
}

var camera: String
val camera: String
get() = streamer.camera
set(value) {
streamer.camera = value
}

var cameraPosition: String
fun setCamera(camera: String, onSuccess: () -> Unit, onError: (Exception) -> Unit) {
permissionsManager.requestPermission(
Manifest.permission.CAMERA,
onGranted = {
try {
streamer.camera = camera
onSuccess()
} catch (e: Exception) {
onError(e)
}
},
onShowPermissionRationale = { onRequiredPermissionLastTime ->
/**
* Require an AppCompat theme to use MaterialAlertDialogBuilder
*
* context.showDialog(
R.string.permission_required,
R.string.camera_permission_required_message,
android.R.string.ok,
onPositiveButtonClick = { onRequiredPermissionLastTime() }
)*/
onError(SecurityException("Missing permission Manifest.permission.CAMERA"))
},
onDenied = {
onError(SecurityException("Missing permission Manifest.permission.CAMERA"))
})
}

val cameraPosition: String
get() = when {
context.isFrontCamera(streamer.camera) -> "front"
context.isBackCamera(streamer.camera) -> "back"
context.isExternalCamera(streamer.camera) -> "other"
else -> throw IllegalArgumentException("Invalid camera position for camera ${streamer.camera}")
}
set(value) {
val cameraList = when (value) {
"front" -> context.getFrontCameraList()
"back" -> context.getBackCameraList()
"other" -> context.getExternalCameraList()
else -> throw IllegalArgumentException("Invalid camera position: $value")
}
streamer.camera = cameraList[0]

fun setCameraPosition(position: String, onSuccess: () -> Unit, onError: (Exception) -> Unit) {
val cameraList = when (position) {
"front" -> context.getFrontCameraList()
"back" -> context.getBackCameraList()
"other" -> context.getExternalCameraList()
else -> throw IllegalArgumentException("Invalid camera position: $position")
}
setCamera(cameraList.first(), onSuccess, onError)
}

fun dispose() {
streamer.stopStream()
Expand Down Expand Up @@ -150,27 +200,36 @@ class FlutterLiveStreamView(
_isStreaming = false
}

fun startPreview() {
fun startPreview(onSuccess: () -> Unit, onError: (Exception) -> Unit) {
permissionsManager.requestPermission(
Manifest.permission.CAMERA,
onGranted = {
streamer.startPreview(getSurface(videoConfig.resolution))
_isPreviewing = true
if (_videoConfig == null) {
onError(IllegalStateException("Video has not been configured!"))
} else {
try {
streamer.startPreview(getSurface(videoConfig.resolution))
_isPreviewing = true
onSuccess()
} catch (e: Exception) {
onError(e)
}
}
},
onShowPermissionRationale = { onRequiredPermissionLastTime ->
/**
* Require an AppCompat theme to use MaterialAlertDialogBuilder
*
* context.showDialog(
R.string.permission_required,
R.string.camera_permission_required_message,
android.R.string.ok,
onPositiveButtonClick = { onRequiredPermissionLastTime() }
R.string.permission_required,
R.string.camera_permission_required_message,
android.R.string.ok,
onPositiveButtonClick = { onRequiredPermissionLastTime() }
)*/
onGenericError(SecurityException("Missing permission Manifest.permission.CAMERA"))
onError(SecurityException("Missing permission Manifest.permission.CAMERA"))
},
onDenied = {
onGenericError(SecurityException("Missing permission Manifest.permission.CAMERA"))
onError(SecurityException("Missing permission Manifest.permission.CAMERA"))
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,16 @@ class MethodCallHandlerImpl(
"setVideoConfig" -> {
try {
val videoConfig = (call.arguments as Map<String, Any>).toVideoConfig()
flutterView!!.videoConfig = videoConfig
result.success(null)
flutterView!!.setVideoConfig(
videoConfig,
{ result.success(null) },
{
result.error(
"failed_to_set_video_config",
it.message,
null
)
})
} catch (e: Exception) {
result.error("failed_to_set_video_config", e.message, null)
}
Expand All @@ -80,17 +88,32 @@ class MethodCallHandlerImpl(
"setAudioConfig" -> {
try {
val audioConfig = (call.arguments as Map<String, Any>).toAudioConfig()
flutterView!!.audioConfig = audioConfig
result.success(null)
flutterView!!.setAudioConfig(
audioConfig,
{ result.success(null) },
{
result.error(
"failed_to_set_audio_config",
it.message,
null
)
})
} catch (e: Exception) {
result.error("failed_to_set_audio_config", e.message, null)
}
}

"startPreview" -> {
try {
flutterView!!.startPreview()
result.success(null)
flutterView!!.startPreview(
{ result.success(null) },
{
result.error(
"failed_to_set_audio_config",
it.message,
null
)
})
} catch (e: Exception) {
result.error("failed_to_start_preview", e.message, null)
}
Expand Down Expand Up @@ -153,8 +176,15 @@ class MethodCallHandlerImpl(
return
}
try {
flutterView!!.cameraPosition = cameraPosition
result.success(null)
flutterView!!.setCameraPosition(cameraPosition,
{ result.success(null) },
{
result.error(
"failed_to_set_camera_position",
it.message,
null
)
})
} catch (e: Exception) {
result.error("failed_to_set_camera_position", e.message, null)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,18 @@ class PermissionsManager(
val listener = listeners[requestCode] ?: return false
listeners.remove(requestCode)

if (grantResults.isEmpty()) {
return false
}

grantResults.forEach {
if (it == PackageManager.PERMISSION_GRANTED) {
listener.onGranted(permissions[grantResults.indexOf(it)])
} else {
listener.onDenied(permissions[grantResults.indexOf(it)])
}
}

if (grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
listener.onAllGranted()
} else {
Expand Down

0 comments on commit 42f8a0e

Please sign in to comment.