This is a simple TV streaming app for AndroidTV that shows and play movie content from HLS sources.
It is based on a Clean Architecture, Coroutines, MVVM, observable (Flow) and command patterns while following the SOLID principles and best practices.
Each feature is implemented in 5 layers with Dependency Inversion between datasource, data and domain layers (we can add to the presentation/domain layer as well in the future):
datasource
layer provides local (Room
) or remote (stubbed API response inHomeInfoRemoteSourceImpl
for now) data sources. Since the API layer is behind an interface, the real REST service could easily be added later on.data
layer holds the repositories and controls the data source flow. The data is provided from local source and if not found, updated from the remote service withFlow
.domain
layer holds the business logic and entities (UseCases
and Domain models), and is in the center of the architecture, so it does not depend on any other module butarchitecture
. Thedomain
layer also controls the thread switching (main -> async -> main).presentation
layer is based onViewModel
(Android one to be lifecycle aware and easier DI with Hilt).ui
layer is a pureCompose
layer withCompose Navigation
between features.- All layers have their own models and mappers to map them to/from other layers.
- Dependency Injection is provided by
Hilt
. - The lib dependencies are provided by the versions catalog.
- All code should be tested, but for the showcase purpose, only the
GetHomeInfoUseCase
,HomeInfoRepositoryImpl
andMovieDomainToPresentationModelMapper
classes are covered byUnitTests
for now.
The idea is to have each feature as a separate set of modules (grouping feature layers in one module) for easier maintenance and easier integration into the app (or removing a feature completely).
There are 3 features/screens modules:
- Home - Home screen with 6 category rows and 12 movies per category. Each movie has an unique id, but since the content is stubbed (there are 12 stubbed movies in the remote source), for faster implementation, they are shared among all categories (the movie order is randomized for each category).
- Movie Details - Shows the details of a selected movie with poster, title, duration, rating, description, button to initiate the playback, and a button to go to the previous screen.
- Video Player - Plays the video with progress info and standard controls. Additionally, there is a back button to go to the previous screen. It uses an interface for the player so it is easier to replace the implementation with another player in the future.
The shared modules are exposed for all features to use them.
shared
module contains specificsubmodules
to be shared among featuresarchitecture
,navigation
andtheme
modules are at a root level to be shared with all modules in the project
- Fix the bug with the player controls lost focus (the player loses focus on subsequent invocation of the overlay). The hardware back button can be used as a workaround to go back and re-enter the screen.
- Make the navigation and notification code more abstract, simpler and reusable among features
- Cover the rest of the code with Unit and UI tests.
- Add the app title to the launcher icon to make it easier to discover