-
Notifications
You must be signed in to change notification settings - Fork 5
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
Interface for DRM Visibility #39
Conversation
kabliz
commented
Aug 21, 2024
- Adds DrmState to ArmadilloState, giving full visibility into DRM status to the client, including the expiration date for content.
- Splits SocketTimeout from HttpResponseCodeException, into ConnectivityException to better differentiate connectivity difficulties from developer error.
- Ensures that ArmadilloState is updated from the main thread consistently.
- Adds DrmState to ArmadilloState, giving full visibility into DRM status to the client, including the expiration date for content. - Splits SocketTimeout from HttpResponseCodeException, into ConnectivityException to better differentiate connectivity difficulties from developer error. - Ensures that ArmadilloState is updated from the main thread consistently.
@@ -25,7 +27,7 @@ internal interface StateStore { | |||
} | |||
} | |||
|
|||
internal class ArmadilloStateStore(private val reducer: Reducer) : | |||
internal class ArmadilloStateStore(private val reducer: Reducer, private val appContext: Context) : |
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 worry about this leaking the context now that it's holding a reference to it?
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.
Would it help if we held a reference to the looper instead? ArmadilloStateStore(..., appContext: Context) ... private val looper = appContext.mainLooper
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 the app context rather than the activity context, so it shouldn't be a danger for leaks the way Activity
is
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.
Resolved by passing in Handler
@@ -33,7 +33,7 @@ internal class AppModule(private val context: Context) { | |||
@Singleton | |||
@PrivateModule | |||
@Provides | |||
fun stateStore(reducer: Reducer): ArmadilloStateStore = ArmadilloStateStore(reducer) | |||
fun stateStore(reducer: Reducer): ArmadilloStateStore = ArmadilloStateStore(reducer, context) |
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.
Actually, you could even pass the looper from here, since that's what you actually need the context for
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 reads better yea
val dataSourceFactory = this.drmHttpDataSourceFactory | ||
?: DefaultHttpDataSource.Factory().setUserAgent(this.userAgent) | ||
val httpDrmCallback = HttpMediaDrmCallback(if (drmConfiguration.licenseUri == null) null else drmConfiguration.licenseUri.toString(), drmConfiguration.forceDefaultLicenseUri, (dataSourceFactory)!!) | ||
val var4: UnmodifiableIterator<*> = drmConfiguration.licenseRequestHeaders.entries.iterator() |
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 seems like it got eaten a little bit by the class converter. Can you clean this up so it's a little more readable?
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.
Original java code
for (Map.Entry<String, String> entry : drmConfiguration.licenseRequestHeaders.entrySet()) {
httpDrmCallback.setKeyRequestProperty(entry.getKey(), entry.getValue());
}
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.
thank you that helps to see the intended behavior
} | ||
|
||
/** New original provider for this class */ | ||
class ArmadilloDrmProvider(private val stateStore: StateStore.Modifier) : ExoMediaDrm.Provider { |
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.
Probably makes more sense for this to be a separate class in its own file than an inner class
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 felt that the large amount of single use classes in separate files made everything very hard to follow. It was very hard to figure out how to build this feature.
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 felt that the large amount of single use classes in separate files made everything very hard to follow. It was very hard to figure out how to build this feature.
This x1000. This is what I meant by my audio player being a more simplified interpretation of armadillo and could be a good reference of what exactly is being done
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.
Yeah if i were to refactor this project, i would use some Facades, layers or something to help indicate hierarchy and order. Though I love, love the Reducer, as it helps so much to wrangle the spaghetti coming from Exoplayer.
return drmSessionManager | ||
} | ||
|
||
/** New original provider for this class */ |
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.
The only thing this does differently is emit events to the dispatcher, right? Can you make that explicit in the docstring
} | ||
} | ||
val download = downloadTracker.getDownload(request.url.toUri()) | ||
val isDownloaded = download != null && download.state != Download.STATE_FAILED |
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'm worried about isDownloaded
here because it's also possible for it to be in progress, which would be misleading. But I don't have a better suggestion. It could be either in progress or finished. Maybe forDownload
?
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.
ah nice catch, this line was there before but i didn't think much of it. Im changing it to check for Completion, because in progress might not contain the audio that is resuming.
Armadillo/src/main/java/com/scribd/armadillo/playback/mediasource/DashMediaSourceGenerator.kt
Show resolved
Hide resolved
val dataSourceFactory = this.drmHttpDataSourceFactory | ||
?: DefaultHttpDataSource.Factory().setUserAgent(this.userAgent) | ||
val httpDrmCallback = HttpMediaDrmCallback(if (drmConfiguration.licenseUri == null) null else drmConfiguration.licenseUri.toString(), drmConfiguration.forceDefaultLicenseUri, (dataSourceFactory)!!) | ||
val var4: UnmodifiableIterator<*> = drmConfiguration.licenseRequestHeaders.entries.iterator() |
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.
Maybe clean up the DefaultDrmSessionManagerProvider
code a bit, or leave it to better convey what it's copied from? idk
|
||
//ExoMediaDrm.OnEventListener doesn't do anything at all, so its not used | ||
if (Util.SDK_INT >= 23) { | ||
instance.setOnKeyStatusChangeListener { exoMediaDrm, sessionId, keyStatuses, b -> |
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.
If we're gonna keep all the params names (are we using them later?), the last boolean param is actually hasNewUsableKey
😁
val dataSourceFactory = this.drmHttpDataSourceFactory | ||
?: DefaultHttpDataSource.Factory().setUserAgent(this.userAgent) | ||
val httpDrmCallback = HttpMediaDrmCallback(if (drmConfiguration.licenseUri == null) null else drmConfiguration.licenseUri.toString(), drmConfiguration.forceDefaultLicenseUri, (dataSourceFactory)!!) | ||
val var4: UnmodifiableIterator<*> = drmConfiguration.licenseRequestHeaders.entries.iterator() |
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.
Original java code
for (Map.Entry<String, String> entry : drmConfiguration.licenseRequestHeaders.entrySet()) {
httpDrmCallback.setKeyRequestProperty(entry.getKey(), entry.getValue());
}
- Adds DrmState to ArmadilloState, giving full visibility into DRM status to the client, including the expiration date for content. - Splits SocketTimeout from HttpResponseCodeException, into ConnectivityException to better differentiate connectivity difficulties from developer error. - Ensures that ArmadilloState is updated from the main thread consistently.
@@ -73,11 +71,10 @@ internal class ArmadilloDrmSessionManagerProvider @Inject constructor(private va | |||
private fun createManager(drmConfiguration: DrmConfiguration): DrmSessionManager { | |||
val dataSourceFactory = this.drmHttpDataSourceFactory | |||
?: DefaultHttpDataSource.Factory().setUserAgent(this.userAgent) | |||
val httpDrmCallback = HttpMediaDrmCallback(if (drmConfiguration.licenseUri == null) null else drmConfiguration.licenseUri.toString(), drmConfiguration.forceDefaultLicenseUri, (dataSourceFactory)!!) | |||
val var4: UnmodifiableIterator<*> = drmConfiguration.licenseRequestHeaders.entries.iterator() | |||
val license = if (drmConfiguration.licenseUri == null) null else drmConfiguration.licenseUri.toString() |
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.
Any reason not to just use drmConfiguration.licenseUri?.toString()
?