FsmPlayerImperial.java
Overview
`FsmPlayerImperial.java` is an abstract class extending the core finite state machine (FSM) player `FsmPlayer`. It implements the `CuePointCallBack` interface to handle cue point events specifically related to ad insertion points during media playback. This class adds logic to detect preroll ads (cue points at time zero) and update the cue point monitor accordingly. It also manages state transitions triggered by the presence or absence of preroll ads and handles cue point fetch errors by transitioning to error states.
In essence, `FsmPlayerImperial` bridges the asynchronous cue point retrieval process with the FSM's playback state transitions, ensuring preroll ads are properly recognized and managed within the FSM playback lifecycle.
Detailed Explanation
Class: FsmPlayerImperial
public abstract class FsmPlayerImperial extends FsmPlayer implements CuePointCallBack
Description
Extends
FsmPlayer, inheriting the FSM playback logic and state management.Implements
CuePointCallBackto receive asynchronous notifications when cue points are fetched or fail to fetch.Contains logic to:
Detect preroll ads from cue points (cue point at 0).
Update the internal
CuePointMonitorby removing preroll cue points when necessary.Trigger FSM state transitions based on cue point analysis.
Forward cue point data to the playback interface for UI/activity updates.
Constructor
public FsmPlayerImperial(StateFactory factory)
Parameter:
StateFactory factory: Factory instance to create and manage FSM states.
Behavior:
Calls superclass constructor with thefactoryto initialize state management.
Methods
onCuePointReceived(long[] cuePoints)
@Override
public void onCuePointReceived(long[] cuePoints)
Purpose: Callback invoked when cue points are successfully fetched.
Parameters:
long[] cuePoints: Array of cue points indicating ad insertion times in milliseconds.
Behavior:
Logs cue point receipt.
Checks if preroll ad exists by examining if the first cue point is at 0.
If preroll ad exists:
Calls
updateCuePointsWithRemoveFirstCue(cuePoints, true)to remove preroll cue point.Triggers FSM transition with input
Input.HAS_PREROLL_AD.
If no preroll ad:
Calls
updateCuePointsWithRemoveFirstCue(cuePoints, false)to update cue points as-is.Triggers FSM transition with input
Input.NO_PREROLL_AD.
Forwards cue points to
playerComponentController.getTubiPlaybackInterface()to notify the UI layer (DoubleViewTubiPlayerActivity).
Usage Example:
// Assuming cue points fetched as [0, 30000, 60000]
long[] cuePoints = {0L, 30000L, 60000L};
fsmPlayerImperialInstance.onCuePointReceived(cuePoints);
// FSM transitions to handle preroll ad and updates cue point monitor accordingly.
onCuePointError()
@Override
public void onCuePointError()
Purpose: Callback invoked when cue points fail to fetch.
Behavior:
Logs an error indicating cue point fetch failure.
Triggers FSM transition with input
Input.ERRORto handle this error scenario.
Implementation Detail: A TODO comment indicates that more robust error handling is planned.
updateCuePointsWithRemoveFirstCue(long[] array, boolean yes)
private void updateCuePointsWithRemoveFirstCue(long[] array, boolean yes)
Purpose: Updates the cue point monitor with the cue points, optionally removing the first cue (preroll).
Parameters:
long[] array: Original cue points array.boolean yes: Flag indicating whether to remove the first cue point.
Behavior:
Checks if
playerComponentControllerand itsCuePointMonitorare available; logs error and returns if not.If
yesistrue:Calls
removePreroll(array)to return a new array excluding the first cue point.Updates
CuePointMonitorwith this modified array.
If
no:Updates
CuePointMonitorwith the original cue points array.
Usage: Internal helper method used by
onCuePointReceived.
hasPrerollAd(long[] cuePoints)
private boolean hasPrerollAd(long[] cuePoints)
Purpose: Detects if the cue points array contains a preroll ad cue point.
Parameters:
long[] cuePoints: Array of cue points.
Returns:
trueif the first cue point equals 0, indicating a preroll ad; otherwise,false.Implementation Detail:
The method considers the first cue point at time 0 as a preroll ad signal.
removePreroll(long[] array)
private long[] removePreroll(long[] array)
Purpose: Returns a new cue points array with the first cue point removed.
Parameters:
long[] array: Original cue points array.
Returns: New array excluding the first element if length > 1; otherwise, returns the original array.
Usage: Helps to exclude preroll cue points from the cue point monitor list.
Important Implementation Details
Preroll Ad Handling:
The preroll ad is uniquely identified by a cue point at timestamp 0. The class explicitly removes this cue point from the monitored cue points list to prevent double handling by the cue point monitor, which monitors midroll and postroll ads.State Transitions:
The class triggers FSM transitions based on cue point presence:Input.HAS_PREROLL_ADif preroll is detected.Input.NO_PREROLL_ADif no preroll is present.Input.ERRORon cue point fetch failure.
These inputs drive the FSM to enter states for preroll ad preparation or directly to content playback.
Integration with Player Controllers:
Updates to cue points are propagated to theCuePointMonitorviaplayerComponentController, ensuring consistency between the FSM state and the UI/playback layer.Logging:
UsesExoPlayerLoggerto record significant events, facilitating debugging and monitoring.
Interaction with Other System Components
Superclass
FsmPlayer:
Inherits core FSM functionality such as state management, playback control, and transition handling.CuePointCallBackInterface:
Implements callbacks invoked by the cue point retriever components responsible for fetching ad insertion points.playerComponentController:
Used to access theCuePointMonitor(for updating cue points) and the playback interface (to notify UI about cue point reception).FSM State Factory and States:
Transitions triggered here cause the FSM to switch between states like fetching ads for preroll, playing preroll ads, or starting content playback.Activity Layer (
DoubleViewTubiPlayerActivity):
Receives updates through the playback interface about cue points, enabling UI updates or analytics.
Usage Example
StateFactory factory = new StateFactory();
FsmPlayerImperial player = new FsmPlayerImperial(factory) {
// Implement abstract methods if any
};
// Cue points fetched asynchronously:
long[] cuePoints = {0L, 45000L, 90000L};
player.onCuePointReceived(cuePoints);
// The FSM will detect preroll, remove the 0 cue point from monitor,
// transition to the preroll ad handling state,
// and notify the UI component.
Mermaid Class Diagram
classDiagram
class FsmPlayerImperial {
-static final String TAG
+FsmPlayerImperial(StateFactory factory)
+void onCuePointReceived(long[] cuePoints)
+void onCuePointError()
-void updateCuePointsWithRemoveFirstCue(long[] array, boolean yes)
-boolean hasPrerollAd(long[] cuePoints)
-long[] removePreroll(long[] array)
}
FsmPlayerImperial --|> FsmPlayer
FsmPlayerImperial ..|> CuePointCallBack
Summary
`FsmPlayerImperial.java` is a specialized extension of the FSM player that handles cue point callbacks in the media playback FSM. It detects preroll ads (cue point at 0), updates the cue point list to exclude preroll from midroll monitoring, and triggers state transitions accordingly. It also handles cue point fetch errors by transitioning to an error state. This class plays a critical role in integrating asynchronous cue point retrieval with the FSM playback logic, enabling correct ad playback scheduling and UI updates within the Tubitv media player system.