Dagger Modules

Purpose

Dagger Modules provide scoped and configurable instances of core playback components such as the FSM player, UI and ad controllers, ad and cue point retrievers, monitors, and VPAID client implementations. This subtopic addresses the need for flexible dependency provisioning that supports different runtime environments (e.g., real app with WebView-based VPAID or default/mock setups) while ensuring modularity, testability, and lifecycle management.

By encapsulating the creation logic of these dependencies, Dagger Modules support injection with a consistent lifecycle scope (`@ActicityScope`). This isolates configuration details from consumers and enables smooth swapping or extension of components without affecting the rest of the system.

Functionality

Key Responsibilities of Dagger Modules

Differences Between Modules

Two provided modules illustrate typical variations:

Example Snippet: Providing FSM Player

@ActicityScope
@Provides
FsmPlayer provideFsmPlayer(StateFactory factory) {
    return new FsmPlayerImperial(factory) {
        @Override
        public Class initializeState() {
            return FetchCuePointState.class;
        }
    };
}

This snippet shows how the FSM player is initialized with a factory and the starting state, ensuring consistent FSM setup across injection contexts.

Example Snippet: Ad Interface with Simulated Delay (FSMModuleReal)

@ActicityScope
@Provides
AdInterface provideAdInterfaceNoPreroll() {
    return new AdInterface() {
        @Override
        public void fetchAd(AdRetriever retriever, final RetrieveAdCallback callback) {
            new Thread(() -> {
                try { Thread.sleep(2000); } catch (InterruptedException ignored) {}
                new Handler(Looper.getMainLooper()).post(() -> callback.onReceiveAd(provideAdMediaModel()));
            }).start();
        }

        @Override
        public void fetchQuePoint(CuePointsRetriever retriever, final CuePointCallBack callBack) {
            new Thread(() -> {
                try { Thread.sleep(2000); } catch (InterruptedException ignored) {}
                new Handler(Looper.getMainLooper()).post(() -> callBack.onCuePointReceived(new long[] { 0, 60000, 900000, 1800000, 3600000 }));
            }).start();
        }
    };
}

This implementation simulates network latency for fetching ads and cue points, illustrating how the module abstracts data provision behind asynchronous callbacks.

Relationship to Parent Topic and Other Subtopics

Dagger Modules are foundational to the **Dependency Injection Setup** parent topic, concretely supplying the runtime instances of FSM player, controllers, retrievers, monitors, and VPAID clients. They define *how* these dependencies are constructed and scoped, complementing the components and custom scope annotations that manage *where* and *when* the dependencies live.

By isolating the provisioning logic:

This modular injection approach underpins the entire media playback system's flexibility and maintainability.

Diagram

classDiagram
    class FSMModuleReal {
        +WebView webView
        +View rootView
        +provideStateFactory() StateFactory
        +provideFsmPlayer(StateFactory) FsmPlayer
        +provideController() PlayerUIController
        +provideComponentController() PlayerAdLogicController
        +provideAdRetriever() AdRetriever
        +provideCuePointsRetriever() CuePointsRetriever
        +provideAdPlayingMonitor(FsmPlayer) AdPlayingMonitor
        +provideCuePointMonitor(FsmPlayer) CuePointMonitor
        +provideAdMediaModel() AdMediaModel
        +provideAdInterfaceNoPreroll() AdInterface
        +provideVpaidClient(FsmPlayer) VpaidClient
    }

    class PlayerModuleDefault {
        +provideStateFactory() StateFactory
        +provideFsmPlayer(StateFactory) FsmPlayer
        +provideController() PlayerUIController
        +provideComponentController() PlayerAdLogicController
        +provideAdRetriever() AdRetriever
        +provideCuePointsRetriever() CuePointsRetriever
        +provideAdPlayingMonitor(FsmPlayer) AdPlayingMonitor
        +provideCuePointMonitor(FsmPlayer) CuePointMonitor
        +provideAdMediaModel() AdMediaModel
        +provideAdInterfaceNoPreroll() AdInterface
        +provideVpaidClient() VpaidClient
    }

    FSMModuleReal ..|> PlayerModuleDefault : extends/overrides

    FSMModuleReal --> WebView
    FSMModuleReal --> View
    FSMModuleReal --> FsmPlayer
    FSMModuleReal --> PlayerUIController
    FSMModuleReal --> PlayerAdLogicController
    FSMModuleReal --> AdRetriever
    FSMModuleReal --> CuePointsRetriever
    FSMModuleReal --> AdPlayingMonitor
    FSMModuleReal --> CuePointMonitor
    FSMModuleReal --> AdInterface
    FSMModuleReal --> VpaidClient

    PlayerModuleDefault --> FsmPlayer
    PlayerModuleDefault --> PlayerUIController
    PlayerModuleDefault --> PlayerAdLogicController
    PlayerModuleDefault --> AdRetriever
    PlayerModuleDefault --> CuePointsRetriever
    PlayerModuleDefault --> AdPlayingMonitor
    PlayerModuleDefault --> CuePointMonitor
    PlayerModuleDefault --> AdInterface
    PlayerModuleDefault --> VpaidClient

This class diagram highlights the two main Dagger modules that provide scoped instances of critical playback components, showing their key methods and relationships. `FSMModuleReal` extends or overrides the default provisioning to support real-world playback scenarios involving WebView and asynchronous ad fetching.


By centralizing and scoping the provisioning of playback components, Dagger Modules enable a clean, modular architecture that supports flexible runtime configurations and simplifies testing and maintenance.