AdPlayingState.java
Overview
`AdPlayingState.java` defines the **AdPlayingState** class, a concrete playback state within a finite state machine (FSM) controlling video playback in the media player system. This state is responsible for managing the playback of video advertisements, including preparing the ad player, pausing main content, handling VPAID ads, updating the UI accordingly, and transitioning to other states based on playback events.
In the overall FSM playback module, `AdPlayingState` handles the scenario when an ad is actively playing, ensuring seamless integration of ads into the user experience by managing player instances, resume positions, and UI visibility.
Class: AdPlayingState
Inheritance
Extends:
BaseState
(which implements basic FSM state behavior and provides default implementations)
Purpose
To encapsulate the behavior and transitions of the media player when an advertisement is actively playing.
To coordinate ad playback with the ExoPlayer instances and the UI controllers.
To handle transitions triggered by ad playback events such as ad completion, ad clicks, or detection of VPAID ads.
Key Methods
1. transformToState(Input input, StateFactory factory) : State
**Description:** Determines the next state of the FSM based on an input event received during ad playback.
**Parameters:**
input(Input): An enum representing an event or trigger (e.g., next ad, ad finished, ad click).factory(StateFactory): Factory responsible for creating instances of FSM states.
**Returns:**
Stateobject representing the next playback state to transition into.Returns
nullif no valid transition exists for the input.
**Behavior:**
On
NEXT_AD: Remains inAdPlayingState(likely to play the next ad in sequence).On
AD_CLICK: Transitions to VastAdInteractionSandBoxState (handles user interaction with the ad).On
AD_FINISH: Transitions toMoviePlayingState(resumes main content playback).On
VPAID_MANIFEST: Transitions toVpaidState(handles playing VPAID interactive ads).
**Example Usage:**
State nextState = adPlayingState.transformToState(Input.AD_FINISH, stateFactory);
// nextState will be an instance of MoviePlayingState
2. performWorkAndUpdatePlayerUI(@NonNull FsmPlayer fsmPlayer) : void
**Description:** Executes the core work associated with this state and updates the player UI accordingly.
**Parameters:**
fsmPlayer(FsmPlayer): The FSM player instance controlling playback.
**Behavior:**
Calls the superclass method to perform any base logic.
If
fsmPlayerisnull, returns immediately to avoid errors.Clears any saved ad resume information in the player UI controller.
Calls internal helper method
playingAdAndPauseMovie()to prepare and start ad playback while pausing the main movie player.
3. playingAdAndPauseMovie(PlayerUIController controller, AdMediaModel adMediaModel, PlayerAdLogicController componentController, FsmPlayer fsmPlayer) : void
**Description:** Internal helper method responsible for setting up the ad player, pausing the main content player, configuring UI components, and starting ad playback.
**Parameters:**
controller(PlayerUIController): Controls the ExoPlayer UI and player instances.adMediaModel(AdMediaModel): Model containing ad media and ad sequence information.componentController(PlayerAdLogicController): Manages ad playback logic and analytics.fsmPlayer(FsmPlayer): The FSM player controlling playback and state transitions.
**Behavior:**
Retrieves both ad and content
SimpleExoPlayerinstances.Gets the next ad media from
adMediaModel.If the ad media is VPAID type, triggers a state transition to
VpaidStateviafsmPlayer.transit(Input.VPAID_MANIFEST).Otherwise:
Ensures the VPAID WebView is hidden and shows the standard video player UI.
Pauses the content player (
moviePlayer.setPlayWhenReady(false)).For devices using a single player instance and if ads are not currently playing, saves the current movie play position for resuming later.
Prepares the ad player with the ad media source, taking into account any saved ad resume position.
Updates the
TubiExoPlayerViewwith the ad player and ad media information.Sets the ad player to start playback immediately and adds analytics and metadata listeners.
Hides subtitles during ad playback to avoid overlay issues.
**Important Details:**
The method handles the case where ad resuming is required by checking if a resume position exists (
controller.getAdResumePosition() != C.TIME_UNSET).Uses ExoPlayer's
prepare()andsetPlayWhenReady(true)to start ad playback.Updates the UI component
TubiExoPlayerViewwith the current ad and playback interface.Hides subtitle view during ad playback for better user experience.
4. hideVpaidNShowPlayer(final PlayerUIController imcontroller) : void
**Description:** Ensures that the standard video player UI is visible and the VPAID WebView is hidden and cleared.
**Parameters:**
imcontroller(PlayerUIController): The UI controller managing player views.
**Behavior:**
Sets the ExoPlayer view to visible.
If the VPAID WebView exists, hides it, clears its history, and loads an empty URL to reset it.
Important Implementation Details
Ad Playback Preparation:
The ad player is prepared with the next ad media's media source. If a resume position exists (e.g., after a pause), the player seeks to that position before starting playback.Single Player vs. Multiple Player Instances:
The code checks if the device uses a single player instance for both content and ads. If so, it saves the current movie playback position before starting ads to enable resuming later.VPAID Ad Handling:
VPAID ads are detected by checkingadMedia.isVpaid(). If true, the FSM transitions immediately toVpaidStatewhich handles interactive ads via a WebView rather than ExoPlayer.Analytics and Metadata:
The ad player registers listeners for analytics and metadata output viacomponentController.getAdPlayingMonitor(), enabling tracking and reporting of ad playback events.UI Updates:
The subtitle view is hidden during ad playback to avoid overlapping subtitles on ads. TheTubiExoPlayerViewis updated to reflect the current ad and the number of ads left to be played.
Interaction with Other System Components
FsmPlayer:
TheFsmPlayerinstance controls the overall FSM, triggers state transitions, and holds references to controller classes and media models.PlayerUIController:
Manages the ExoPlayer instances for content and ads, provides access to player views (TubiExoPlayerView), and maintains playback resume info.PlayerAdLogicController:
Handles ad playback logic, analytics monitoring, and playback interface for UI updates.StateFactory:
Responsible for creating instances of states when transitioning from one state to another.AdMediaModel:
Contains the sequence of ads to be played and provides the next ad media information.TubiExoPlayerView:
The UI component that renders video playback, including ads and content, and handles subtitle visibility.VpaidClient and WebView:
For VPAID ads, the system uses a WebView controlled byVpaidClient.AdPlayingStateensures hiding this WebView when playing standard ads.
Usage Example
This state is typically not instantiated directly by client code but managed internally by the FSM player during playback:
// Sample FSM transition triggering ad playback
fsmPlayer.transit(Input.AD_RECEIVED); // This could cause transition to AdPlayingState
// Inside AdPlayingState.performWorkAndUpdatePlayerUI():
// Sets up the ad player, pauses the movie player, and starts playing the ad
// On ad finish event:
fsmPlayer.transit(Input.AD_FINISH); // Transitions to MoviePlayingState to resume content playback
Mermaid Class Diagram
classDiagram
class AdPlayingState {
+transformToState(input: Input, factory: StateFactory): State
+performWorkAndUpdatePlayerUI(fsmPlayer: FsmPlayer): void
}
AdPlayingState --|> BaseState
class BaseState {
+transformToState(input: Input, factory: StateFactory): State
+performWorkAndUpdatePlayerUI(fsmPlayer: FsmPlayer): void
}
class Input {
<<enumeration>>
+NEXT_AD
+AD_CLICK
+AD_FINISH
+VPAID_MANIFEST
//... other inputs
}
class StateFactory {
+createState(classType: Class): State
}
class FsmPlayer {
+transit(input: Input): void
+getPlayerUIController(): PlayerUIController
+getPlayerAdLogicController(): PlayerAdLogicController
// Other methods
}
AdPlayingState --> Input
AdPlayingState --> StateFactory
AdPlayingState --> FsmPlayer
Summary
AdPlayingState manages the playback of video ads within the FSM playback system.
It prepares the ad player, pauses the main content player, updates UI components, and handles ad playback lifecycle.
It supports transition to other states based on input events such as ad completion, ad clicks, or detection of VPAID ads.
Ensures seamless integration of ads into the media playback experience by managing resume positions and UI visibility.
Interacts closely with player controllers, ad logic controllers, media models, and the FSM player to coordinate playback and UI updates.
This class is a core part of the FSM's ad management capabilities, enabling a modular and maintainable approach to handling advertisement playback in the media player.