697 Commits

Author SHA1 Message Date
tonihei
d9aee0f6a4 Add DataSource contract test for transfer listeners when opening fails.
TransferListener has the contract to have exactly one onTransferEnd per
onTransferStart, so the test can both assert that onTransferInitializing
is called, but not onTransferEnd (even after calling close).

PiperOrigin-RevId: 362262078
2021-03-12 10:42:55 +00:00
tonihei
bc9fb8615e Use correct period-window offset for initial prepare position.
MaskingMediaSource needs to resolve the prepare position set for a MaskingPeriod
while the source was still unprepared to the first actual prepare position.

It currently assumes that the period-window offset and the default position is
zero. This assumption is correct when a PlaceholderTimeline is used, but it
may not be true if the real timeline is already known (e.g. when re-preparing
a live stream after a playback error).

Fix this by using the known timeline at the time of the preparation.
Also:
 - Update a test that should have caught this to use lazy re-preparation.
 - Change the demo app code to use the recommended way to restart playback
   after a BehindLiveWindowException.

Issue: #8675
PiperOrigin-RevId: 361604191
2021-03-12 10:40:15 +00:00
gyumin
ffb7c466ed Implement addMediaItems(List) and clearMediaItems() in BasePlayer
PiperOrigin-RevId: 361487730
2021-03-12 10:39:54 +00:00
kimvde
0dcdbf0adf Add Player onAvailableCommandsChanged callback
PiperOrigin-RevId: 361122259
2021-03-12 10:39:22 +00:00
Denise LaFayette
f7f40bcb25 Address code review comments
- Split text emphasis mark and style into two IntDefs
- Represent textEmphasis="none" with a span rather than null
- Fixed bugs in the style parsing logic
2021-03-05 12:23:34 -08:00
Denise LaFayette
60a3af8d77 Fix broken unit test in TtmlDecoder.textEmphasis()
- Merge RUBY_POSITION with TEXT_EMPHASIS_POSITION in TtmlNode
2021-03-04 16:06:56 -08:00
Denise LaFayette
4ad6454713 Address code review comments
- Refactor TextEmphasis class to support different ordering of styles
- Merge RubySpan.Position and TextEmphasisSpan.Position
- Remove TTML constructs from Spanned classes
2021-03-04 15:49:28 -08:00
olly
560ed115df Add ResolvingDataSourceContractTest
PiperOrigin-RevId: 359783527
2021-03-02 17:03:35 +00:00
olly
759b0431bb DataSource: Tighten contract to throw if opened beyond end-of-input
Includes fixes for the HTTP implementations, which previously
broke this contract specifically in the case when a server
responds to a range request with a HTTP 200 response. To fix
this case, skipping to the requested position is moved from
read() to open(). As a side effect, this nicely simplifies
CronetDataSource!

PiperOrigin-RevId: 359737301
2021-03-02 17:03:14 +00:00
olly
c319220354 Add BandaidHttpDataSourceContractTest
Also fix a bug where BandaidHttpDataSource would pass -1 to
TransferListener.onBytesTransferred!

PiperOrigin-RevId: 359722821
2021-03-02 17:02:45 +00:00
olly
635544efe9 Add DataSourceContractTest for reading from the end with a set length
Given we're proposing to make reading from the end a non-error case,
it's important to check that we return the right thing from open(),
and that we read the right thing (i.e., nothing) once opened.

For now, this test allows quite a bit of permissiveness, in line
with other related tests. This will be tightened up in due course.

PiperOrigin-RevId: 359504075
2021-03-02 17:02:04 +00:00
Denise LaFayette
fcda8d47ff Support tts:textEmphasis in TTML parser and WebView output 2021-03-01 14:21:22 -08:00
olly
716d003c84 Add FakeDataSourceContractTest
PiperOrigin-RevId: 359095093
2021-02-24 15:46:27 +00:00
olly
19adc43bf1 Contract test for start-position-out-of-range case
Currently, this only asserts that *if* an exception is thrown, it
must be a position-out-of-range exception as determined by
DataSourceException.isCausedByPositionOutOfRange.

Issue: #7326
PiperOrigin-RevId: 359092124
2021-02-24 15:46:19 +00:00
olly
d8b5a1d7f4 Contract test for end-position-out-of-range case
Assert that an exception is not thrown from DataSource.open
if the DataSpec's start position is valid but its end position
extends beyond the end of the data.

HTTP based DataSource implementations have no good way of
knowing when this is the case, so it makes sense to make this
the required behaviour, rather than requiring an exception to
be thrown or allowing both.

There are also use cases where the caller may want to use the
end position as an upper bound, without knowing for sure how
long the content is. An example of this use case is wanting to
pre-cache the first N bytes of a stream. This implies that any
exception should be thrown after reading to the end of the
data, rather than preemptively in open.

Issue: #7326
PiperOrigin-RevId: 359063721
2021-02-24 15:46:02 +00:00
olly
c067ee8853 Fix CacheWriter to handle potential DataSink write failures
- If DataSource.close fails then it's unknown whether the underlying file was
  written to the cache. We should assume that it has not been.
- Always re-query cachedBytes at the start of CacheWriter.cache, since its
  current value may be incorrect if a previous failure was the result of a
  file not being written to the cache.

PiperOrigin-RevId: 359039109
2021-02-23 15:06:38 +00:00
gyumin
520f77bef5 Mark convenience methods as final in BasePlayer
PiperOrigin-RevId: 359021944
2021-02-23 15:06:28 +00:00
olly
b4b22d9808 Simplify Resource.isEndOfInputExpected
- Make it a property of the DataSource, not of the resource.
- Apply it only when a contract test reads using an
  unbounded DataSpec.

PiperOrigin-RevId: 358997735
2021-02-23 12:30:14 +00:00
olly
691ac39fcb Read to end-of-stream for HTTP contract tests
#minor-release

PiperOrigin-RevId: 358847933
2021-02-23 12:30:06 +00:00
olly
7f5b5c9b6d Add static TrackSelection type
This type is different to the selection reason, which is
dynamic (i.e., corresponds to the individual selected track,
which can change during playback). The static type is
exposed via TrackSelection, where-as the selection reason
will be internal to the core (i.e., player) module.

PiperOrigin-RevId: 357578201
2021-02-19 10:56:27 +00:00
christosts
086d8f3a8e Contract test for TransferListener callbacks
PiperOrigin-RevId: 357190780
2021-02-12 16:40:40 +00:00
tonihei
4c9780abd0 Add ABR unit tests
This parameterized test execute a single playback with a variety of
specified network conditions, user country and network types, and then
compares some basic ABR performance data against a dump file to detect
changes.

PiperOrigin-RevId: 356468304
2021-02-09 13:59:49 +00:00
tonihei
91c2f891a0 Ensure BandwidthProfileDataSource loading is fully deterministic
We currently block the loading thread until the calculated load
time has past and then unblock again by a message sent from the
playback thread. However, because the loading thread itself is not
using a Looper and runs freely, we don't control when the short
calculations on the loader thread that determine how long we have
to wait are happening, and we also don't control how long it takes
to start and stop this thread.

To solve these problems and to make the playback deterministic we
can
 1. Send a message on the playback thread to block until the loader
    thread has started.
 2. Block the playback thread whenever a loading thread is doing its
    short calculation of wait times. The playback thread knows when it
    can continue because loading either enter a new waiting state for
    a simulated load time or loading is finished completely.
 3. Also wait on the playback thread until the loader has shut down.
    As this is waiting for a message on the playback thread, we can
    achieve this by sending messages to ourselves at the current time
    until the loader is shut down.
All 3 steps together ensure that the loading thread interaction is
compeltely deterministic when simulating bandwidth profiles with the
BandwidthProfileDataSource. As we need to notify the source before and
after the load started/finished, we also need a small wrapper for the
chunk source when running the playback.

PiperOrigin-RevId: 355810408
2021-02-09 13:58:42 +00:00
tonihei
05fddff84f Modernize bandwidth profile simulator.
Main improvement is to switch away from ExoPlayerTestRunner and to
split out the waiting component so that the same class can be used
from Robolectric tests in the future.

The only functional difference is that that BufferLengthLogAction
is removed completely because the data isn't used downstream and the
method of collecting this data is a bit arbitrary.

PiperOrigin-RevId: 355117850
2021-02-02 13:06:43 +00:00
andrewlewis
afb41123c2 Switch transformer tests to use dump files
Add an interface to muxers to allow tests to pass a dumpable muxer.

#minor-release

PiperOrigin-RevId: 354543388
2021-02-01 18:10:55 +00:00
tonihei
ae51e2e1d1 Also fix thread blocking nullness assertion when called from non-Looper
PiperOrigin-RevId: 354268013
2021-02-01 18:10:24 +00:00
tonihei
a60938db96 Fix triggering messages sent from non-Looper threads.
This can happen for instrumented tests that are run on a non-Looper
thread. If these tests send a message to a Looper thread to start the
test procedure, they should just triger the message directly as before.

PiperOrigin-RevId: 354066836
2021-02-01 18:10:05 +00:00
tonihei
9b3014dd79 Remove randomness from adaptive bitrate tests.
- The order of sample stream (and thus the order in which loads are
  triggered) currently depends on a Set and thus on the hash codes
  of the objects that change with every run. Changing to a List solves
  this problem.
- The FakeAdaptiveDataSet directly created a static Random (with random
  seed) to compute the variation of chunk sizes. Changing this to an
  injected Random object that can always be initialized with the same
  seed also removed this randomness from the tests.

PiperOrigin-RevId: 353878661
2021-01-26 17:13:46 +00:00
tonihei
2e52c0b8d8 Make FakeClock fully deterministic.
This is achieved by only triggering one message at a time. After
triggering a message we send another to ourselves to know when the
following message can be triggered.

Other required changes:
 - The messages need to be sorted correctly (by time and creation order)
 - To prevent deadlocks when one thread is waiting for another,
   we need to add new method to Clock to indicate that the current
   thread is about to wait. This then allows us to trigger messages
   from other threads in FakeClock.
 - AnalyticsCollectorTest needed some adjustments:
   - onTimelineChanged now deterministically arrives after the initial
     timline is already known, so some of the period information changes
     from window only to full period info.
   - The playlistOperations test suffers from a bug that the first frame
     is rendered too early and that's why we now get additional events.

PiperOrigin-RevId: 353877832
2021-01-26 17:13:35 +00:00
tonihei
a318e56d15 Fix FakeClock remove messages behaviour.
We currently only remove messages that have already been sent
to the actual Handler, not the pending ones that are only kept
in the FakeClock. Fix this by also removing matching messages
from the FakeClock list.

PiperOrigin-RevId: 353877049
2021-01-26 17:13:25 +00:00
tonihei
89ea38d155 Handle all messages in FakeClock.
Currently only delayed messages are handled. Change this to handling
all messages so that we have more control over their execution order.

This requires adding a new wrapper type for the Message to support
the obtainMessage + sendToTarget use case.

PiperOrigin-RevId: 353876557
2021-01-26 17:13:15 +00:00
tonihei
06fe0900a9 Remove FakeClock.sleep.
This functionality isn't used and there is no point in supporting
it.

PiperOrigin-RevId: 353876038
2021-01-26 17:13:03 +00:00
olly
a1f06987eb Replace non-inclusively named constant
Issue: #7565
PiperOrigin-RevId: 353649187
2021-01-25 17:38:26 +00:00
krocard
ec43735054 Split mutations method out of TrackSelection
`TrackSelection` had mutation methods which were to be called only
internally by ExoPlayer components but were exposed in the
public `Player` interface.

The mutation methods have been moved out of `TrackSelection`
to a new class `ExoTrackSelection`.

Current track related read-only method have also been moved out,
because they are actually something quite unclear.
Even for a single item playlist, it's the track being buffered rather
than the track being played, which is unclear.
But when you have a playlist it starts to get really confusing,
because if the next item is being buffered, then it's actually
the last track to be buffered in the currently playing item.
As a final aside, the implementations don't do proper thread synchronization
to ensure visibility of updated state by the calling thread.

Exposing those mutable methods in the public `Player` interface
was problematic because they leaking internal concepts of `ExoPlayer`.
This is also required to minimize the `Player` interface for long term
stability.

`ExoTrackSelection` is a subclass of `TrackSelection`.
This is not ideal as an `TrackSelection` implementation could
break the current immutability.
This was done in order for this refactor to be simpler.
A future patch will fully split the two classes.

All `MediaPeriod` and `Sources` had to be updated to use the new
`TrackSelection` dynamic aspect class name.
An alternative would have been to break ExoPlayer's public API, keeping
`TrackSelection` as the dynamic aspect name, and calling the public static
aspect class `TrackSelectionState` or similar.
Nevertheless, while it would have impacted less files, it would have
many more small apps and casual users of ExoPlayer.

#player-to-common

PiperOrigin-RevId: 353637924
2021-01-25 15:37:38 +00:00
olly
dc7fde1ff7 Some more language fixes
Issue: #7565
PiperOrigin-RevId: 353613493
2021-01-25 15:36:59 +00:00
christosts
0a3542e50e Add contract test for CronetDataSource
PiperOrigin-RevId: 353290124
2021-01-25 15:35:59 +00:00
tonihei
4cbd4e2e2a Use Clock to create Handler for delivering messages.
This ensures the message devilery is governed by the clock.

Also replace setting a Handler with a Looper to facilititate this
change.

PiperOrigin-RevId: 353019729
2021-01-22 16:21:44 +00:00
tonihei
d1faf713af Use Clock to create Handler in ListenerSet.
This ensures the Handler is governed by this clock.

PiperOrigin-RevId: 353011555
2021-01-22 16:21:27 +00:00
ibaker
3069251bd0 Add gzip support to WebServerDispatcher
Add a test to DataSourceContractTest that asserts the gzip flag is
either ignored or handled correctly.

Add a test resource to DefaultHttpDataSourceContracTest that enables
gzip compression on the 'server' and checks it's handled correctly by
the client.

PiperOrigin-RevId: 352574359
2021-01-19 19:23:57 +00:00
christosts
21f3fa9f7c Add contract test for DataSchemeDataSource
PiperOrigin-RevId: 352558063
2021-01-19 19:23:40 +00:00
christosts
c808751009 Add contract tests for OkHttpDataSource
PiperOrigin-RevId: 352554949
2021-01-19 19:23:31 +00:00
olly
adb9dcb43f Add KeyRequest.getRequestType
Issue: #7847
PiperOrigin-RevId: 351661084
2021-01-15 10:55:36 +00:00
olly
a95b2ebb1d Fix audio session ID generation
- SimpleExoPlayer now always generates a session ID at
  construction time. This ID is used indefinitely, including
  for tunneling, unless a call to setAudioSessionId is made
  to change it.
- DefaultTrackSelector support for enabling tunneling has
  been changed to a boolean, since tunneling now uses the
  same session ID as non-tunneled mode.
- Since the session ID is now always set at the top level,
  internal propagation of generated session IDs is no longer
  necessary, and so is removed.

PiperOrigin-RevId: 351349687
2021-01-13 00:03:16 +00:00
ibaker
01ae2b047f Remove expectedResolvedLength from DataSourceContractTest
Whether a resource resolves to a known length or not is more than just
a property of the resource & data source - for example if
`DataSpec.flags` contains `ALLOW_GZIP` then the length might be
unresolved. More generally, a `DataSource` could randomly return
`C.UNKNOWN_LENGTH` from `open()` 50% of the time and still fulfil the
`DataSource` interface. This makes it ~impossible to write a meaningful
assertion aroun this.

So this change relaxes the assertion slightly to more closely match the
definition of the `DataSource` interface.

We leave the `resolveToUnknownLength` toggle in
`WebServerDispatcher.Resource` because this is still useful for
simulating the case of a server that is serving a file it doesn't
know the length of.

PiperOrigin-RevId: 351124246
2021-01-11 18:05:24 +00:00
ibaker
653d180d4c Add 302 redirect test to DefaultHttpDataSourceContractTest
PiperOrigin-RevId: 348760170
2020-12-23 22:53:15 +00:00
ibaker
f44e5bd292 Add a DefaultHttpDataSource contract test
Also add a MockWebServer Dispatcher that can be customised with
different resources and behaviours for different paths.

PiperOrigin-RevId: 348759662
2020-12-23 22:53:06 +00:00
ibaker
e154cb1787 Fix calls to readExactly in DataSourceContractTest
The length needs to change depending on the positition/length parameters
passed to DataSpec, so it doesn't really make sense to keep this private
method - it's clearer to in-line the calls in each test.

PiperOrigin-RevId: 348749254
2020-12-23 22:52:57 +00:00
ibaker
df0b74e4c4 DataSourceContractTest: Add tests for reading subranges
PiperOrigin-RevId: 348443305
2020-12-23 22:51:29 +00:00
bachinger
04824dfd25 Make DefaultHttpDataSourceFactory an inner class of the built class
#exofixit

PiperOrigin-RevId: 348441436
2020-12-23 22:51:20 +00:00
tonihei
30ee29df1a Use real SampleQueue in FakeSampleStream.
This replaces all the duplicated logic previously implemented in
FakeSampleStream and more closely follows the pattern of how
SampleStreams are used from real MediaPeriods.

Some tests needed adjustments because using real the SampleQueue
improved behaviour:
 - Waiting for isLoading is only needed once even across period
   boundaries because the real SampleQueue doesn't have the on/off
   pattern.
 - AnalyticsCollectorTest.playlistOperations() was wrongly asserting
   that some pre-buffering events. The new version is more intuitively
   correct we pre-buffer the second item during the initial loading
   phase (thus period1seq1) and keep the buffer in the queue after
   the removal operation.

PiperOrigin-RevId: 348440255
2020-12-23 22:51:00 +00:00