PlayerUIController.java


Overview

`PlayerUIController` is a Java class designed to manage multiple ExoPlayer instances and related UI components involved in media playback within an Android application. Its primary role is to coordinate playback between content videos and advertisements, including support for VPAID ads via a WebView, and to maintain playback resume state information for both content and ads.

This controller abstracts the complexity of handling separate players for content and ads (or reusing a single player instance depending on device capabilities), tracks playback positions to enable seamless resumption, and maintains user playback history. It acts as a bridge between the underlying media playback engines and the user interface layer, facilitating smooth transitions and consistent UI state during playback sessions.


Detailed Breakdown

Class: PlayerUIController

Purpose


Fields

Field Name

Type

Description

`isPlayingAds`

`boolean`

Indicates whether ads are currently playing.

`contentPlayer`

`SimpleExoPlayer`

The ExoPlayer instance used to play main content videos.

`adPlayer`

`SimpleExoPlayer`

The ExoPlayer instance used to play advertisements (may be null or same as contentPlayer).

`vpaidWebView`

`WebView`

A WebView used to display VPAID ads (video ads rendered via HTML/JS).

`exoPlayerView`

`View`

The UI View associated with the ExoPlayer instances (player UI surface).

`adResumeWindow`

`int`

The resume window index for ad playback; `C.INDEX_UNSET` if unset.

`adResumePosition`

`long`

The resume position (in milliseconds) within the ad window; `C.TIME_UNSET` if unset.

`movieResumeWindow`

`int`

The resume window index for content playback; `C.INDEX_UNSET` if unset.

`movieResumePosition`

`long`

The resume position (in milliseconds) within the movie window; `C.TIME_UNSET` if unset.

`hasHistory`

`boolean`

Flag indicating if there is a playback history to resume from.

`historyPosition`

`long`

The playback position to resume from history; `C.TIME_UNSET` if unset.


Constructors

PlayerUIController()

PlayerUIController(@Nullable SimpleExoPlayer contentPlayer, @Nullable SimpleExoPlayer adPlayer, @Nullable WebView vpaidWebView, @Nullable View exoPlayerView)

**Usage example:**

SimpleExoPlayer contentPlayer = ...; // Initialized elsewhere
SimpleExoPlayer adPlayer = ...;      // Optional; could be null
WebView vpaidWebView = ...;          // Optional
View playerView = ...;               // ExoPlayer UI view

PlayerUIController controller = new PlayerUIController(contentPlayer, adPlayer, vpaidWebView, playerView);

Methods

Player Accessors and Mutators


Playback History Management


Resume Information for Ads and Content


Nested Class: PlayerUIController.Builder

A builder class to facilitate flexible and readable construction of `PlayerUIController` instances.

Builder Methods

**Usage example:**

PlayerUIController controller = new PlayerUIController.Builder()
        .setContentPlayer(contentPlayer)
        .setAdPlayer(adPlayer)
        .setVpaidWebView(vpaidWebView)
        .setExoPlayerView(playerView)
        .build();

Important Implementation Details


Interaction with Other System Components


Example Usage Scenario

  1. The application initializes PlayerUIController via the Builder pattern, providing the content player, the ad player, the VPAID WebView, and the player view.

  2. When an ad is about to play, the system requests the ad player via getAdPlayer(). Depending on the device, this might be the content player or a dedicated ad player.

  3. The system saves the current playback position of the content (movie) before switching to ads by calling setMovieResumeInfo(...).

  4. After ad playback, resume info for ads and movie is used to seamlessly return playback to the correct content position.

  5. If the user had previously watched part of the movie, setPlayFromHistory(pos) is called to resume from that position.


Mermaid Class Diagram

classDiagram
    class PlayerUIController {
        - boolean isPlayingAds
        - SimpleExoPlayer contentPlayer
        - SimpleExoPlayer adPlayer
        - WebView vpaidWebView
        - View exoPlayerView
        - int adResumeWindow
        - long adResumePosition
        - int movieResumeWindow
        - long movieResumePosition
        - boolean hasHistory
        - long historyPosition
        + PlayerUIController()
        + PlayerUIController(contentPlayer, adPlayer, vpaidWebView, exoPlayerView)
        + getContentPlayer()
        + setContentPlayer(contentPlayer)
        + getAdPlayer()
        + setAdPlayer(adPlayer)
        + getVpaidWebView()
        + setVpaidWebView(vpaidWebView)
        + getExoPlayerView()
        + setExoPlayerView(exoPlayerView)
        + setPlayFromHistory(pos)
        + hasHistory()
        + getHistoryPosition()
        + clearHistoryRecord()
        + setAdResumeInfo(window, position)
        + clearAdResumeInfo()
        + setMovieResumeInfo(window, position)
        + clearMovieResumeInfo()
        + getAdResumeWindow()
        + getAdResumePosition()
        + getMovieResumeWindow()
        + getMovieResumePosition()
    }

    class PlayerDeviceUtils {
        + useSinglePlayer()
    }

    PlayerUIController --> PlayerDeviceUtils : uses

    class Builder {
        - SimpleExoPlayer contentPlayer
        - SimpleExoPlayer adPlayer
        - WebView vpaidWebView
        - View exoPlayerView
        + setContentPlayer(contentPlayer)
        + setAdPlayer(adPlayer)
        + setVpaidWebView(vpaidWebView)
        + setExoPlayerView(exoPlayerView)
        + build()
    }

    PlayerUIController ..> Builder : creates

Summary

`PlayerUIController` is a central component managing multiple playback instances and related UI elements for a media playback Android app. It elegantly handles the complexities of ad playback vs. content playback, resume positions, and VPAID ad integration via a WebView, providing a flexible interface for other components to interact with playback sessions. The inclusion of a builder pattern enhances configurability and clarity during instantiation.

This controller is crucial for maintaining a seamless viewing experience where playback can pause, resume, switch between content and ads, and support advanced ad formats without disrupting the user interface or playback flow.