mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-20 03:59:35 +01:00
Respect can publish audio & video permission
With this implementation the can publish audio & video permission are set during the creation of the 'CallActivity'. This permissions are fixed for the complete call. If the permissions are changed by a moderator the call must be left and joined again. Resolves: #1783 Signed-off-by: Tim Krüger <t@timkrueger.me>
This commit is contained in:
parent
dda5a9e3da
commit
c554535bae
@ -170,6 +170,8 @@ import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_NAME;
|
|||||||
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_PASSWORD;
|
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_PASSWORD;
|
||||||
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FROM_NOTIFICATION_START_CALL;
|
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FROM_NOTIFICATION_START_CALL;
|
||||||
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_MODIFIED_BASE_URL;
|
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_MODIFIED_BASE_URL;
|
||||||
|
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_AUDIO;
|
||||||
|
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_VIDEO;
|
||||||
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID;
|
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID;
|
||||||
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN;
|
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN;
|
||||||
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY;
|
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY;
|
||||||
@ -293,6 +295,9 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
private boolean canPublishAudioStream;
|
||||||
|
private boolean canPublishVideoStream;
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
@ -314,6 +319,8 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
conversationName = extras.getString(KEY_CONVERSATION_NAME, "");
|
conversationName = extras.getString(KEY_CONVERSATION_NAME, "");
|
||||||
isVoiceOnlyCall = extras.getBoolean(KEY_CALL_VOICE_ONLY, false);
|
isVoiceOnlyCall = extras.getBoolean(KEY_CALL_VOICE_ONLY, false);
|
||||||
isCallWithoutNotification = extras.getBoolean(KEY_CALL_WITHOUT_NOTIFICATION, false);
|
isCallWithoutNotification = extras.getBoolean(KEY_CALL_WITHOUT_NOTIFICATION, false);
|
||||||
|
canPublishAudioStream = extras.getBoolean(KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_AUDIO);
|
||||||
|
canPublishVideoStream = extras.getBoolean(KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_VIDEO);
|
||||||
|
|
||||||
if (extras.containsKey(KEY_FROM_NOTIFICATION_START_CALL)) {
|
if (extras.containsKey(KEY_FROM_NOTIFICATION_START_CALL)) {
|
||||||
isIncomingCallFromNotification = extras.getBoolean(KEY_FROM_NOTIFICATION_START_CALL);
|
isIncomingCallFromNotification = extras.getBoolean(KEY_FROM_NOTIFICATION_START_CALL);
|
||||||
@ -387,23 +394,41 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
audioOutputDialog.show();
|
audioOutputDialog.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
binding.microphoneButton.setOnClickListener(l -> onMicrophoneClick());
|
if (canPublishAudioStream) {
|
||||||
binding.microphoneButton.setOnLongClickListener(l -> {
|
binding.microphoneButton.setOnClickListener(l -> onMicrophoneClick());
|
||||||
if (!microphoneOn) {
|
binding.microphoneButton.setOnLongClickListener(l -> {
|
||||||
callControlHandler.removeCallbacksAndMessages(null);
|
if (!microphoneOn) {
|
||||||
callInfosHandler.removeCallbacksAndMessages(null);
|
callControlHandler.removeCallbacksAndMessages(null);
|
||||||
cameraSwitchHandler.removeCallbacksAndMessages(null);
|
callInfosHandler.removeCallbacksAndMessages(null);
|
||||||
isPTTActive = true;
|
cameraSwitchHandler.removeCallbacksAndMessages(null);
|
||||||
binding.callControls.setVisibility(View.VISIBLE);
|
isPTTActive = true;
|
||||||
if (!isVoiceOnlyCall) {
|
binding.callControls.setVisibility(View.VISIBLE);
|
||||||
binding.switchSelfVideoButton.setVisibility(View.VISIBLE);
|
if (!isVoiceOnlyCall) {
|
||||||
|
binding.switchSelfVideoButton.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
onMicrophoneClick();
|
||||||
onMicrophoneClick();
|
return true;
|
||||||
return true;
|
});
|
||||||
});
|
} else {
|
||||||
|
binding.microphoneButton.setOnClickListener(
|
||||||
|
l -> Toast.makeText(context,
|
||||||
|
R.string.nc_not_allowed_to_activate_audio,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
binding.cameraButton.setOnClickListener(l -> onCameraClick());
|
if (canPublishVideoStream) {
|
||||||
|
binding.cameraButton.setOnClickListener(l -> onCameraClick());
|
||||||
|
} else {
|
||||||
|
binding.cameraButton.setOnClickListener(
|
||||||
|
l -> Toast.makeText(context,
|
||||||
|
R.string.nc_not_allowed_to_activate_video,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
binding.hangupButton.setOnClickListener(l -> {
|
binding.hangupButton.setOnClickListener(l -> {
|
||||||
hangup(true);
|
hangup(true);
|
||||||
@ -558,7 +583,7 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkPermissions();
|
checkDevicePermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -705,7 +730,7 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void checkPermissions() {
|
private void checkDevicePermissions() {
|
||||||
if (isVoiceOnlyCall) {
|
if (isVoiceOnlyCall) {
|
||||||
onMicrophoneClick();
|
onMicrophoneClick();
|
||||||
} else {
|
} else {
|
||||||
@ -764,7 +789,7 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
binding.switchSelfVideoButton.setVisibility(View.VISIBLE);
|
binding.switchSelfVideoButton.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_CAMERA)) {
|
if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_CAMERA) && canPublishVideoStream) {
|
||||||
if (!videoOn) {
|
if (!videoOn) {
|
||||||
onCameraClick();
|
onCameraClick();
|
||||||
}
|
}
|
||||||
@ -775,7 +800,7 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_MICROPHONE)) {
|
if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_MICROPHONE) && canPublishAudioStream) {
|
||||||
if (!microphoneOn) {
|
if (!microphoneOn) {
|
||||||
onMicrophoneClick();
|
onMicrophoneClick();
|
||||||
}
|
}
|
||||||
@ -888,6 +913,18 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onMicrophoneClick() {
|
public void onMicrophoneClick() {
|
||||||
|
|
||||||
|
if (isVoiceOnlyCall && !isConnectionEstablished()) {
|
||||||
|
fetchSignalingSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!canPublishAudioStream) {
|
||||||
|
microphoneOn = false;
|
||||||
|
binding.microphoneButton.getHierarchy().setPlaceholderImage(R.drawable.ic_mic_off_white_24px);
|
||||||
|
// In the case no audio stream will be published it's not needed to check microphone permissions
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_MICROPHONE)) {
|
if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_MICROPHONE)) {
|
||||||
|
|
||||||
if (!appPreferences.getPushToTalkIntroShown()) {
|
if (!appPreferences.getPushToTalkIntroShown()) {
|
||||||
@ -936,11 +973,6 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
pulseAnimation.start();
|
pulseAnimation.start();
|
||||||
toggleMedia(true, false);
|
toggleMedia(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isVoiceOnlyCall && !isConnectionEstablished()) {
|
|
||||||
fetchSignalingSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (EffortlessPermissions.somePermissionPermanentlyDenied(this, PERMISSIONS_MICROPHONE)) {
|
} else if (EffortlessPermissions.somePermissionPermanentlyDenied(this, PERMISSIONS_MICROPHONE)) {
|
||||||
// Microphone permission is permanently denied so we cannot request it normally.
|
// Microphone permission is permanently denied so we cannot request it normally.
|
||||||
|
|
||||||
@ -957,6 +989,14 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onCameraClick() {
|
public void onCameraClick() {
|
||||||
|
|
||||||
|
if (!canPublishVideoStream) {
|
||||||
|
videoOn = false;
|
||||||
|
binding.cameraButton.getHierarchy().setPlaceholderImage(R.drawable.ic_videocam_off_white_24px);
|
||||||
|
binding.switchSelfVideoButton.setVisibility(View.GONE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_CAMERA)) {
|
if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_CAMERA)) {
|
||||||
videoOn = !videoOn;
|
videoOn = !videoOn;
|
||||||
|
|
||||||
@ -1384,12 +1424,14 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performCall() {
|
private void performCall() {
|
||||||
int inCallFlag;
|
int inCallFlag = Participant.InCallFlags.IN_CALL;
|
||||||
if (isVoiceOnlyCall) {
|
|
||||||
inCallFlag = Participant.InCallFlags.IN_CALL + Participant.InCallFlags.WITH_AUDIO;
|
if (canPublishAudioStream) {
|
||||||
} else {
|
inCallFlag += Participant.InCallFlags.WITH_AUDIO;
|
||||||
inCallFlag =
|
}
|
||||||
Participant.InCallFlags.IN_CALL + Participant.InCallFlags.WITH_AUDIO + Participant.InCallFlags.WITH_VIDEO;
|
|
||||||
|
if (!isVoiceOnlyCall && canPublishVideoStream) {
|
||||||
|
inCallFlag += Participant.InCallFlags.WITH_VIDEO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int apiVersion = ApiUtils.getCallApiVersion(conversationUser, new int[]{ApiUtils.APIv4, 1});
|
int apiVersion = ApiUtils.getCallApiVersion(conversationUser, new int[]{ApiUtils.APIv4, 1});
|
||||||
@ -1495,7 +1537,7 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
|
|
||||||
private void initiateCall() {
|
private void initiateCall() {
|
||||||
if (!TextUtils.isEmpty(roomToken)) {
|
if (!TextUtils.isEmpty(roomToken)) {
|
||||||
checkPermissions();
|
checkDevicePermissions();
|
||||||
} else {
|
} else {
|
||||||
handleFromNotification();
|
handleFromNotification();
|
||||||
}
|
}
|
||||||
@ -2302,7 +2344,7 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
if (peerConnectionWrapper != null) {
|
if (peerConnectionWrapper != null) {
|
||||||
PeerConnection.IceConnectionState iceConnectionState = peerConnectionWrapper.getPeerConnection().iceConnectionState();
|
PeerConnection.IceConnectionState iceConnectionState = peerConnectionWrapper.getPeerConnection().iceConnectionState();
|
||||||
connected = iceConnectionState == PeerConnection.IceConnectionState.CONNECTED ||
|
connected = iceConnectionState == PeerConnection.IceConnectionState.CONNECTED ||
|
||||||
iceConnectionState == PeerConnection.IceConnectionState.COMPLETED;
|
iceConnectionState == PeerConnection.IceConnectionState.COMPLETED;
|
||||||
}
|
}
|
||||||
|
|
||||||
String nick;
|
String nick;
|
||||||
|
@ -2747,6 +2747,14 @@ class ChatController(args: Bundle) :
|
|||||||
bundle.putString(BundleKeys.KEY_CONVERSATION_PASSWORD, roomPassword)
|
bundle.putString(BundleKeys.KEY_CONVERSATION_PASSWORD, roomPassword)
|
||||||
bundle.putString(BundleKeys.KEY_MODIFIED_BASE_URL, conversationUser?.baseUrl)
|
bundle.putString(BundleKeys.KEY_MODIFIED_BASE_URL, conversationUser?.baseUrl)
|
||||||
bundle.putString(KEY_CONVERSATION_NAME, it.displayName)
|
bundle.putString(KEY_CONVERSATION_NAME, it.displayName)
|
||||||
|
bundle.putBoolean(
|
||||||
|
BundleKeys.KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_AUDIO,
|
||||||
|
participantPermissions.canPublishAudio()
|
||||||
|
)
|
||||||
|
bundle.putBoolean(
|
||||||
|
BundleKeys.KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_VIDEO,
|
||||||
|
participantPermissions.canPublishVideo()
|
||||||
|
)
|
||||||
|
|
||||||
if (isVoiceOnlyCall) {
|
if (isVoiceOnlyCall) {
|
||||||
bundle.putBoolean(BundleKeys.KEY_CALL_VOICE_ONLY, true)
|
bundle.putBoolean(BundleKeys.KEY_CALL_VOICE_ONLY, true)
|
||||||
|
@ -39,8 +39,8 @@ class ParticipantPermissions(
|
|||||||
private val canStartCall = (conversation.permissions and START_CALL) == START_CALL
|
private val canStartCall = (conversation.permissions and START_CALL) == START_CALL
|
||||||
val canJoinCall = (conversation.permissions and JOIN_CALL) == JOIN_CALL
|
val canJoinCall = (conversation.permissions and JOIN_CALL) == JOIN_CALL
|
||||||
private val canIgnoreLobby = (conversation.permissions and CAN_IGNORE_LOBBY) == CAN_IGNORE_LOBBY
|
private val canIgnoreLobby = (conversation.permissions and CAN_IGNORE_LOBBY) == CAN_IGNORE_LOBBY
|
||||||
val canPublishAudio = (conversation.permissions and PUBLISH_AUDIO) == PUBLISH_AUDIO
|
private val canPublishAudio = (conversation.permissions and PUBLISH_AUDIO) == PUBLISH_AUDIO
|
||||||
val canPublishVideo = (conversation.permissions and PUBLISH_VIDEO) == PUBLISH_VIDEO
|
private val canPublishVideo = (conversation.permissions and PUBLISH_VIDEO) == PUBLISH_VIDEO
|
||||||
val canPublishScreen = (conversation.permissions and PUBLISH_SCREEN) == PUBLISH_SCREEN
|
val canPublishScreen = (conversation.permissions and PUBLISH_SCREEN) == PUBLISH_SCREEN
|
||||||
private val hasChatPermission = (conversation.permissions and CHAT) == CHAT
|
private val hasChatPermission = (conversation.permissions and CHAT) == CHAT
|
||||||
|
|
||||||
@ -67,6 +67,22 @@ class ParticipantPermissions(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun canPublishAudio(): Boolean {
|
||||||
|
return if (hasConversationPermissions()) {
|
||||||
|
canPublishAudio
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun canPublishVideo(): Boolean {
|
||||||
|
return if (hasConversationPermissions()) {
|
||||||
|
canPublishVideo
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun hasChatPermission(): Boolean {
|
fun hasChatPermission(): Boolean {
|
||||||
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "chat-permission")) {
|
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "chat-permission")) {
|
||||||
return hasChatPermission
|
return hasChatPermission
|
||||||
|
@ -75,4 +75,6 @@ object BundleKeys {
|
|||||||
const val KEY_SYSTEM_NOTIFICATION_ID = "KEY_SYSTEM_NOTIFICATION_ID"
|
const val KEY_SYSTEM_NOTIFICATION_ID = "KEY_SYSTEM_NOTIFICATION_ID"
|
||||||
const val KEY_MESSAGE_ID = "KEY_MESSAGE_ID"
|
const val KEY_MESSAGE_ID = "KEY_MESSAGE_ID"
|
||||||
const val KEY_MIME_TYPE_FILTER = "KEY_MIME_TYPE_FILTER"
|
const val KEY_MIME_TYPE_FILTER = "KEY_MIME_TYPE_FILTER"
|
||||||
|
const val KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_AUDIO = "KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_AUDIO"
|
||||||
|
const val KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_VIDEO = "KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_VIDEO"
|
||||||
}
|
}
|
||||||
|
@ -602,4 +602,7 @@
|
|||||||
<string name="nc_expire_message_one_hour">1 hour</string>
|
<string name="nc_expire_message_one_hour">1 hour</string>
|
||||||
<string name="nc_expire_messages_explanation">Chat messages can be expired after a certain time. Note: Files shared in chat will not be deleted for the owner, but will no longer be shared in the conversation.</string>
|
<string name="nc_expire_messages_explanation">Chat messages can be expired after a certain time. Note: Files shared in chat will not be deleted for the owner, but will no longer be shared in the conversation.</string>
|
||||||
|
|
||||||
|
<string name="nc_not_allowed_to_activate_audio">You\'re not allowed to activate audio!</string>
|
||||||
|
<string name="nc_not_allowed_to_activate_video">You\'re not allowed to activate video!</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -50,8 +50,8 @@ class ParticipantPermissionsTest : TestCase() {
|
|||||||
|
|
||||||
assertFalse(attendeePermissions.isCustom)
|
assertFalse(attendeePermissions.isCustom)
|
||||||
assertFalse(attendeePermissions.canStartCall())
|
assertFalse(attendeePermissions.canStartCall())
|
||||||
assertFalse(attendeePermissions.canIgnoreLobby)
|
assertFalse(attendeePermissions.canIgnoreLobby())
|
||||||
assertFalse(attendeePermissions.canPublishAudio)
|
assertTrue(attendeePermissions.canPublishAudio())
|
||||||
assertFalse(attendeePermissions.canPublishVideo)
|
assertTrue(attendeePermissions.canPublishVideo())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user