Airtel Ads SDK Architecture (Android)

Iqaan
Airtel Digital
Published in
9 min readJan 2, 2024

At Airtel, we have multiple applications built for different platforms ranging from mobile apps, web, and large screen. Our apps include music streaming (Wynk Music), OTT/Live TV (Airtel Xstream), mobile recharge and payments app (Airtel Thanks), as well as apps on TV and our own custom (Android) set-top boxes (DTH).

We monetise all these apps using subscriptions and advertising. In this article, we’ll discuss the role and design of our own ads SDK.

Ads SDK is at the heart of our AdTech pod. Our AdTech system includes custom Ad Server, along with creative optimisation (transcoder), audience management, popularity system, ads config, and much more, all working in sync to power the ads on all these platforms.

To avoid the repetitive work on these apps, we have a common library used by all, “Airtel Ads SDK”. Airtel Ads SDK does much more than just integrating just the response from the ad-server.

Project Structure

The Airtel’s Android Ad SDK is based on clean architecture. As in any other project which follows the same architecture, the ad SDK is divided in three parts (layers). The central layer is the data layer. On top of that we have the domain layer, and then the presentation layer.

Each of these layers contain several modules which serve some particular purpose. Here are the few advantages of using this architecture:

  • Separation of concerns: Each module has a clearly defined purpose. Any module does not perform the work outside its scope, and no other module performs the task that this module was created for.
  • Well-defined public interface: All the public interface resides within the presentation layer. Data and domain layers are kept private to the SDK. This also enables us to write better proguard rules.
  • Modularity: New modules of similar type can be easily added at a later point of time. For example, if a new ad server implementation needs to be done, one would add a new server module.
  • Size reduction: Publishers can choose which modules to include/exclude when they’re integrating the ad SDK to reduce the size. Besides that, a well-defined structure also lets a lot of code sharing.

Modules

  • base: This module exposes the most basic classes/interfaces of the ad SDK. For example, it exposes the classes responsible for initialization of the ad SDK, which becomes the entry point. While as the presentation/base module exposes the ad manager, the domain/base module contains AdManagerLoader which is responsible for performing the business logic around the loading of the ad. Most of the internal business logic is present in this module. This module also contains, AdViewObserver responsible for tracking the visibility of the ad to the user.
  • banner: This module exposes the code related to the rendering of the banner ads. It will expose BannerAdData (sub-type of AdData) which contains information related to any particular banner ad. It also contains all the ad templates related to the banner ads.
  • video: Similar to the banner module, this module exposes the code related to the rendering of the video ads. It will expose VideoAdData (subtype of the AdData) which contains information related to any particular video ad.
  • core: This is the most internal layer of the ad SDK (leaving common modules aside). It contains code which is needed by multiple domain modules (for example, if the dfp and airtel module inside the domain layer want to share the code). It also contains some data structures like custom priority queues, rate-limiter, and commonly used extensions. It also contains some dagger related scopes and qualifiers which are used across domain and presentation layers.
  • network: This module is a common place to get network clients (retrofit / okhttp). SDK also creates a global network component in its DI (Dagger) graph which can be used to make API calls anywhere whenever there’s no need to create an API interface.
  • The common module is a tiny module which creates some shortcuts in the code. It basically contains all those interfaces which are required by the internal layers of the ad SDK as well as needed by the client/publisher. (This is the dirty part of the otherwise clean architecture).

Player Module (Player-independent implementation)

Player module exposes a basic implementation of an out-stream video ad player. A client can choose between each of the player modules, for example, “exo2–18” and “exo2–11” each corresponding to whether the client wants to use ExoPlayer 2.18 or ExoPlayer 2.11. A client may choose to omit the player module at all, and provide their own implementation and write their in-stream (ad insertion) logic as well.

Ad Server Modules

In the above diagram, we see “dfp” and “airtel” modules. Each corresponding to Google’s Ad Server and Airtel’s custom ad server logic. The ads SDK is designed in such a way that it can be extended to work with any number of demand partners while not affecting the other areas of the code. For example, all the Google Ads classes only reside in that particular dfp module and no-where else. As of now, we have more server modules than just two.

High-Level Diagram

The above diagram contains the list of (almost) all the components of the Airtel Ads SDK.

  • Ads Configuration: The Airtel’s Ad SDK loads/shows the ads based on a key called “slot id”. Corresponding to a slot id, the ads configuration provides information related to that slot id. There is an AdConfig portal with which publishers can set up their ad slots. Its access is given during on-boarding.
  • Analytics Manager: it is an object which exposes certain methods that can be called from anywhere in the ad SDK. These methods receive analytics events. Then the analytics manager will broadcast the events to all the analytics transmitters.
  • Ad Loaders: are the classes which make the actual ad request to the server. Its examples are AirtelAdServerLoader, DfpAdLoader, and ImaAdLoader. Each of these ad loaders is responsible for server-specific parsing. That means, AirtelAdServerLoader will parse the JSON response returning from the Airtel ad server, but it won’t parse the internal ad string in one of IAB Standard formats. It delegates the ad parsing to the Ad Parsers.
  • Ad Parsers: Ad Parsers receive a string input data and output a designated ad in the form of InternalAdData. Its examples are VASTParser, VMAPParser, IABNativeBannerParser etc.
  • Post-processor: Once an ad data is loaded, the next step is to load the creatives/assets of the ad. For simple banner ads, it could be an image. For video ads, it could be some part of the video (say a video is of 10MB, we will load the first 1MB, then as the video plays and progresses the rest of the part will be downloaded).
  • Controller: In video ads, VideoAdController is a class which controls the playback of the ad. It identifies when an ad needs to be played in an In-stream video ad format using the help of PlayerProgressMonitor.
  • AdTemplate: is an interface whose main function is the render method. The purpose of the render method is to return a View object, which is treated as the rendered view of the ad. A client/publisher can provide their ad templates as well. In most cases, the client/publisher can re-use all the functionality of the SDK owned ad templates and design their own custom UI without needing to handle UI logic making it robust for the client to implement complex custom designs without having to code much.
  • AdManager: At the heart of the ad SDK is the Ad Manager. It is a class which is responsible for receiving ad requests from clients, delegating the work to the ad loaders, combining the response, and converting the internal ad data to the publicly exposed ad data.

AdViewObserver

It is a class which observes the state of the ad view. It tracks if the ad view is visible to the user, whether the user has moved the app to the background and exposes these events which can be observed from anywhere and certain logic like impression tracking can make use of that. It uses Android’s LifecycleObserver pattern making the ads lifecycle-aware components.

AdViewObserver also includes our own custom implementation of viewability measurement (or what we usually call overlay detection algorithm), which detects if any other view from the client is on top of the ad and thus records these activities for ad validation purposes.

Loading Strategy

Corresponding to one slot id, there can be multiple Slot Items. Each slot item defines which ad server to load the ad from and its required parameters. A loading strategy defines how to deal with these multiple slot items.

One important thing to mention here is that each corresponding to each slot item, there could be multiple ads returned. For example, Airtel Ad Server accepts multiple ad-spots in a single API call, and returns multiple ads in a single response.

Waterfall

In this loading strategy each slot item is processed one-by-one until one of them gives a successful response. So, if the first slot item gives an ad, this loading strategy would NOT attempt to load the next slot item.

This algorithm carries out a depth-first traversal of the ads (as there are some responses which redirect to some other ad source, example VAST Wrappers). The DFS algorithm is carried out asynchronously and is defined in such a way that it can work anywhere with any ad server module.

Parallel

In this loading strategy every slot item will be loaded in parallel, and when the response from all the slot items is received, the process ends. It accumulates the data from all the slot items and then passes that to the publisher. Publishers can choose how to present these multiple ads (either in one-by-one by manner, or in a carousel form, etc.)

Header-Bidding

It is another popular ad requesting strategy, where the client/publisher makes bid requests (parallelly) to multiple ad servers each of which return either a bid response or a bid failure. For all the successful bid responses, the Airtel Ads SDK then sends the bidding data to the target ad server which is responsible for performing the auctioning of the bid data, and returns the creative tag from the ad server which is giving the highest bid and therefore maximising the eCPM.

Ad Player Design

Video ads play a crucial role in Airtel Ads SDK’s overall design. As an SDK, we want to give a native feel to the video ads. While banner ads required assets loading and presenting them on the screen, the video ads are much more complicated than that.

Here are some key concepts which needs to be covered while designing video ads player:

  • Native look and feel and custom UI
  • Progress tracking: Need to track quartiles for a video ad which is used for VTR metric calculation.
  • Video pods: In a single ad slot, multiple video ads may be presented one after the other. These are called podded video ads.
  • Response independent: It shouldn’t matter in which form the response is (VAST/VMAP) or some custom JSON format.
  • In-stream experience: should provide extensibility so that the client/publisher can extend their own content video player. The ad player should also utilise the publisher player’s playback controls. The ad player should also be able to play pre-roll, mid-roll, and post-roll ads. This gives the pure in-stream experience.
  • Supports Auto-Video controls mode, which means the publisher doesn’t have to manually (programatically) play/pause the ad when the ad is in or out of viewport.

Conclusion

To summarise, we have created a modular ads SDK which:

  • Not only interacts (gets ads) from Airtel’s ecosystem, but is extensible to power ads from any source in a unified way.
  • Has a public interface which makes it easy for the developers to integrate with limited knowledge of the Ads ecosystem .
  • Supports rich formats, like banner and native display ads, interstitial ads, audio/video ads, out-stream and in-stream playback.
  • Adheres to IAB standards, owns an Open Measurement certificate for all the ad formats, including companion banners, and has custom MRAID (3.0) implementation.
  • Supports personalised banner ads (where we can show user attributes, name, etc.) on top of the ad creatives.
  • Has thorough analytics and tracking implementations including overlay detection.
  • Is modular in nature, which means developers can decide which modules to exclude.

Acknowledgement

I’m on LinkedIn: linkedin.com/in/iqaan

Contributions to this project made by:
Iqaan Azad, Sanket Arora, Pankaj Kumar, Manas Kashyap, Shikha Singh, Harpreet Kaur

--

--