Skip to content
This repository has been archived by the owner on Feb 11, 2022. It is now read-only.

ALL-3936/Assert support DRM #54

Merged
merged 7 commits into from
Jun 27, 2017
Merged

Conversation

Mecharyry
Copy link
Contributor

Problem

We were crashing when a device that does not support Media DRM apis was attempting to play content. The error message was not useful to clients as it did not provide information as to why the crash occurred.

Solution

Check the device version when trying to create a Player with a DrmHandler, if it does not meet the required api level then we crash with a meaningful message.

Changed the scope of some associated classes, removing static factory methods where possible.

Test(s) added

Add tests to the DrmSessionCreatorFactory to assert the exceptions and messages.

Screenshots

No UI changes.

Paired with

@ouchadam

@zegnus zegnus self-assigned this Jun 27, 2017
this.androidDeviceVersion = androidDeviceVersion;
this.handler = handler;
}

public DrmSessionCreator createFor(DrmType drmType, DrmHandler drmHandler) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that we can throw unchecked exceptions, we can help the user of this method to manage expectations if we document them ;)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you think we should add a checked exception to the PlayerBuilder.build()?

if so we can propagate those errors up into PlayerCreationExceptions

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we recover from those exceptions or is a fatal crash?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, they'll be thrown if the device or available players can't handle the drm types (content types should eventually be taken into account here as well)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we cannot recover this is a fatal exception, don't check them then

@@ -19,12 +18,7 @@
private final FrameworkMediaDrmCreator frameworkMediaDrmCreator;
private final Handler handler;

static StreamingDrmSessionCreator newInstance(MediaDrmCallback mediaDrmCallback, FrameworkMediaDrmCreator frameworkMediaDrmCreator) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -12,13 +12,7 @@
private final HttpPoster httpPoster;
private final ProvisioningCapabilities capabilities;

public static ProvisionExecutor newInstance() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


public class NoPlayerExoPlayerCreator {

private final InternalCreator internalCreator;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we gain much doing this (apart from creating a whole class). You can just hold a reference to the handler and then use a static method just use a local create method. We then reduce indirection.

Copy link
Contributor

@ouchadam ouchadam Jun 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the internal classes are to enable testing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also if you do this, you can remove the static newInstance and simply use the normal constructor

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked the code, ok.

ExoPlayerTwoImpl and AndroidMediaPlayerImpl class can be package protected ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We did this in the #55 PR 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok 👍


public class NoPlayerMediaPlayerCreator {

private final InternalCreator internalCreator;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as before

return new PlayerFactory(
context,
prioritizedPlayerTypes,
NoPlayerExoPlayerCreator.newInstance(handler),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you remove the internal indirection for the creation then you can just use new NoPlayerE....(handler)

@zegnus
Copy link
Contributor

zegnus commented Jun 27, 2017

Please review public facing methods and document all possible exceptions that those methods can throw, also document those exceptions in internal implementation so that developers can keep track of them :)

@juankysoriano juankysoriano self-assigned this Jun 27, 2017
@ouchadam
Copy link
Contributor

@zegnus We'll add javadoc to the PlayerBuilder in the lastest PR #40

@@ -6,7 +6,7 @@
import java.net.HttpURLConnection;
import java.net.URL;

class HttpPoster {
public class HttpPoster {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thy is this class now public?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather keep this package and in case make a newInstance on the ProvisioningExecutor. I think that's one of the little benefits, on my opinion, of the newInstance and therefore I don't see justification from removing it from ProvisioningExecutor

Copy link
Contributor

@ouchadam ouchadam Jun 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these classes were being used in the client project, we'll replace this class with an interface and make this impl package again

We inlined the logic into the client and instead hide all of this logic


public Player createExoPlayer(Context context, DrmSessionCreator drmSessionCreator, boolean downgradeSecureDecoder) {
ExoPlayerTwoImpl player = internalCreator.create(context, drmSessionCreator, downgradeSecureDecoder);
player.initialise();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -58,10 +67,10 @@ public Player create(DrmType drmType, DrmHandler drmHandler, boolean downgradeSe
private Player createPlayerForType(PlayerType playerType, DrmType drmType, DrmHandler drmHandler, boolean downgradeSecureDecoder) {
switch (playerType) {
case MEDIA_PLAYER:
return mediaPlayerCreator.createMediaPlayer(context);
return noPlayerMediaPlayerCreator.createMediaPlayer(context);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative could have been not having the InternalCreator in the creators (therefore you don't need testing) and doing the test for the player.initialise() here (which I believe is the bit you wanted to test)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this would mean making all the impls public as they live inside their own player specific packages

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, we can still have the InternalCreator it that benefits us for reducing the scope of those classes, but I still believe we can benefit from doing player.initialise() here instead of the two creators.

Not a blocker, just a thought

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mentioned this the no-player room but I can say again 👻

It comes down to which layer should provide a fully instantiated player, should it be the concrete player packages (media/exo) which allows all the classes to remain package local or the noplayer root and then expose implementation details about the separate players

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahhhhhhhhhhhhhhhhh

I undertand now, thanks. Yes let's keep this like it is

import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify;

public class NoPlayerMediaPlayerCreatorTest {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

read my comment on NoPlayerFactory, we could take rid of two test classes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scratch this

@juankysoriano juankysoriano merged commit 5a50fe1 into exo-player-2 Jun 27, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants