-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Permissions API #37
Permissions API #37
Conversation
One question I had was whether tracks should be dropped from the publication when disallowed/unsubscribed? Noticed that we seem not to be doing this at the moment for android/JS. Looks like we properly get the tracks again through WebRTC when the permissions are regranted. |
livekit-android-sdk/src/main/java/io/livekit/android/room/Room.kt
Outdated
Show resolved
Hide resolved
livekit-android-sdk/src/main/java/io/livekit/android/room/participant/LocalParticipant.kt
Outdated
Show resolved
Hide resolved
*/ | ||
fun setSubscribed(subscribed: Boolean) { | ||
if (subscribed && !subscriptionAllowed) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this preventing sending an UpdateSubscriptions
message? Sorry, I maybe mistaking code here. But, sending UpdateSubscriptions
should not be prevented. Server will send the SubscriptionPermissionUpdate
when there are no permissions. Note that permissions can be revoked when a track is actively subscribed. So, the server could send that update mid stream too. So, clients should always send subscription message and listen for the update from the server.
I think this code is not preventing sending that message, but just wanted to elaborate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmm, the case I was trying to cover here was if we had previously received a subscription permission update disallowing a track, and the client decides to attempt to subscribe anyways. Should we still attempt the subscription in that case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. Maybe, the log message can be something like already subscribed, but currently does not have permissions
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should still let the client update the server, because it's indicating a desired state.
It does make the API a bit inconsistent, which I don't love:
- .subscribed indicates if it's desired to be subscribed and successfully subscribed
- .setSubscribed updates the desired state
Any alternatives?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed with @boks1971, the proposal is to turn .subscribed
into an enum describing the current subscription status, with "subscribed, not allowed" and "subscribed" as two distinct states.
Thinking about the setSubscribed
part, I think it might be more descriptive of user intent to have separate subscribe()
and unsubscribe()
functions, which would help clear up the inconsistency you note.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that sounds good. though I'm wary about breaking current users. Especially on JS. we could perhaps deprecate .subscribed, but still provide it as a way of returning subscribeState == Subscribed
?
Yes @davidliu . As permissions can be granted/revoked at any time by the publishing end, server keeps track of state and reconciles the subscriptions with changing permissions and pauses/resumes tracks as necessary. The |
Sorry, to be clear, is that a yes, we should drop/remove the tracks from the client, or yes, we should keep them around? |
val isAutoManaged: Boolean | ||
get() = (track as? RemoteVideoTrack)?.autoManageVideo ?: false | ||
|
||
override val subscribed: Boolean | ||
get() { | ||
if (unsubscribed) { | ||
if (unsubscribed || !subscriptionAllowed) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering if this should return false
. The track is subscribed to, but just that it does not have permissions. Feels like this needs to return an enum which gives a better picture of subscription state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm good question, I think technically it's desired to be subscribed, but tricky because clients use subscribed
to indicate if subscription is successful and ready to be streamed.
returning false probably makes more sense than true in this case.
Sorry David. I meant, yes - keep the publications. But, I am not saying a definitive yes without knowing all the client intricacies. Basically, the idea is that certain tracks exist in the system and a subscriber has subscribed to it. But those tracks could be paused/resumed based on publisher side permissions. So, if the subscriber checks what tracks are available in the session, the state will say tracks are available, but they may not be pulled down due to permissions. But, I think this is something to discuss with @davidzhao and @hiroshihorie also to find the right approach. |
|
||
// Unsubscribe if become disallowed. | ||
if (!pub.subscriptionAllowed && pub.subscribed) { | ||
pub.setSubscribed(false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we have to manually unset? or would server send down an unsubscribed event?
I think setSubscribed should be reserved for user intent, so that if a subscription is revoked, and the intent is still there, server can send down the track again when subscription is restored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, this was a misunderstanding on my part and has been removed.
val isAutoManaged: Boolean | ||
get() = (track as? RemoteVideoTrack)?.autoManageVideo ?: false | ||
|
||
override val subscribed: Boolean | ||
get() { | ||
if (unsubscribed) { | ||
if (unsubscribed || !subscriptionAllowed) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm good question, I think technically it's desired to be subscribed, but tricky because clients use subscribed
to indicate if subscription is successful and ready to be streamed.
returning false probably makes more sense than true in this case.
*/ | ||
fun setSubscribed(subscribed: Boolean) { | ||
if (subscribed && !subscriptionAllowed) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should still let the client update the server, because it's indicating a desired state.
It does make the API a bit inconsistent, which I don't love:
- .subscribed indicates if it's desired to be subscribed and successfully subscribed
- .setSubscribed updates the desired state
Any alternatives?
@@ -22,10 +22,6 @@ open class TrackPublication( | |||
private set | |||
open var muted: Boolean = false | |||
internal set | |||
open val subscribed: Boolean |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is kind of useful when you have a TrackPublication, and don't care if it's remote or local, but just need to quickly check isSubscribed then decide to render.
Android seems to have some crashes after repeated enabling/disabling of permissions, but that might be a sample app issue rather than SDK issue. I'll look into that separately. JS seems to handle it fine.