• Skip to primary navigation
  • Skip to content
  • Skip to primary sidebar
VdoCipher: Secure Video Hosting for BusinessVdoCipher
☰
Sign Up
  • Solutions
    • E-learning
    • Enterprise
    • Developer
    • Healthcare
    • Live Streaming
  • Features
  • Pricing
    • Video Hosting & DRM Solution
    • Live Streaming Solution
  • Live
  • Developer
  • About
    • Testimonials
    • The Company
  • Contact
Login
Sign Up

Media3 ExoPlayer Tutorial: How to Stream Videos Securely on Android?

January 2, 2024 /

exoplayer
Try Custom Video Player

Streaming videos securely on Android can be a bit challenging, but it can be easily done with Exoplayer!

When it comes to streaming videos on Android, Exoplayer can be your go-to media player. It is even used by Google apps such as YouTube and Google TV. Exoplayer allows a lot of customization which enables its adoption for various use cases.  Its support of media formats is also very wide, including adaptive streaming formats such as HLS, Dash, and Smooth Streaming. With its support for widevine, you can ensure that your content remains safe

Table Of Content
  • What is an ExoPlayer?
  • What are the Advantages of Using Exoplayer?
  • How To Implement Exoplayer in Android?
  • How To Customize Exoplayer
  • How To Play DRM Content On Exoplayer?
  • Adaptive Bitrate Streaming in Exoplayer
  • How VdoCipher Streams Video on Android Using ExoPlayer

What is an ExoPlayer?

ExoPlayer is an open-source media player for Android maintained by Google. It is not part of the Android framework and is distributed separately from the Android SDK. With ExoPlayer, you can easily take advantage of new features as they become available by updating your app.

ExoPlayer is the best alternative to android’s built-in MediaPlayer API which is used to control the playback of audio/video files and streams. It supports various features such as Dynamic Adaptive Streaming over HTTP(DASH), HTTP Live Streaming(HLS), Smooth Streaming, and Common Encryption. It can be used to play audio as well as video streaming online directly from the server and/or offline(locally) by downloading. It can be easily customized and extended. We can add features like captions, speed control, forward, rewind, etc. to the player. Exoplayer also provides a feature for encrypting the media playback (both online and offline) for secure streaming. It does not work on the device below API level 16.

Let’s see what Exoplayer has to offer and why or when we should use it over the built-in MediaPlayer API.

What are the Advantages of Using Exoplayer?

ExoPlayer has a number of advantages over Android’s built-in MediaPlayer:

  • There are fewer device-specific issues and less variation in behavior across different Android versions and devices with ExoPlayer.
  • You can update the player along with your application. Since ExoPlayer is a library included in your application, you can choose which version to use and easily update to a newer version. To ensure your application are developed and run smoothly, use the Docker platform.
  • You can customize and extend it to meet your needs. A lot of ExoPlayer components can be replaced with custom implementations since it was designed specifically with this in mind.
  • ExoPlayer has in-built support for playlists.
  • The Exoplayer supports a variety of formats in addition to DASH and SmoothStreaming. Additionally, it supports advanced HLS features such as handling #EXT-X-DISCONTINUITY tags and the ability to seamlessly merge, concatenate, and loop media streams.
  • On Android 4.4 (API level 19) and higher, it supports Widevine common encryption. Although the actual widevine support varies from device and is usually only available starting from Android 5. Sometimes, older devices with Android 5 and 6 can also get revoked due to security updates.
  • It is possible to integrate with a number of additional libraries quickly by using official extensions. For example, by using the Interactive Media Ads SDK, you can easily monetize your content with the IMA extension.

Explore More ✅

Stream Your Content Securely On Android With VdoCipher

VdoCipher helps provide end-to-end solutions for video, right from hosting, encoding, and encryption to the player. On top of it, you get APIs to manage videos, players, and more.

How To Implement Exoplayer in Android with examples?

We will create a simple exoplayer application to play a video using MediaItem.

The steps to implement Exoplayer are as follows:

  1. Add exoplayer dependencies in your app level build.gradle
    implementation 'com.google.android.exoplayer:exoplayer-core:2.18.0'
    implementation 'com.google.android.exoplayer:exoplayer-dash:2.18.0'
    implementation 'com.google.android.exoplayer:exoplayer-hls:2.18.0'
    implementation 'com.google.android.exoplayer:exoplayer-ui:2.18.0'
  1. Add SimpleExoPlayerView in layout file A SimpleExoPlayerView can be included in the layout for an Activity belonging to a video application as follows:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<com.google.android.exoplayer2.ui.SimpleExoPlayerView 
    android:id="@+id/exoPlayerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

</FrameLayout>
  1. Create and load the player In your Activity, create an instance of Exoplayer and add it to the SimpleExoPlayerView
    MediaItem represents a media which can be added to the player at the time of preparation. After the player is prepared you can set set setPlayWhenReady to start the playback when media is ready.
SimpleExoPlayerView playerView = findViewById(R.id.exoPlayerView);
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Bind the player to the view.
playerView.setPlayer(player);
// Create and add media item
MediaItem mediaItem = MediaItem.fromUri(video_url);
player.addMediaItem(mediaItem);
// Prepare exoplayer
player.prepare();
// Play media when it is ready
player.setPlayWhenReady(true);
  1. Handling the player controls Methods on the player can be called to control the player. Below are some of the methods:
  • play and pause: Used to play and pause the video
  • seekTo: Seeks to a position specified in milliseconds in the current MediaItem
  • playWhenReady: Whether playback should proceed when ready
  • hasNextMediaItem, hasPreviousMediaItem, seekToPreviousMediaItem, seekToNextMediaItem: Allows navigating through the playlist
  • setPlaybackParameters: Attempts to set the playback parameters.Playback parameters changes may cause the player to buffer. Player.Listener.onPlaybackParametersChanged(PlaybackParameters) will be called whenever the currently active playback parameters change
  1. Release the player Use ExoPlayer.release method to release the player after when it is no longer required.
if (exoPlayer != null) {
    exoPlayer.release();
}

How to Customize Exoplayer?

ExoPlayer comes with many customizations available such as UI adjusting to match your app, deciding caching mechanism for data loaded from the network, customizing server interaction to intercept HTTP requests and responses, customizing error handling policy, enabling asynchronous buffer queueing, and many more. In this section, we will look at how we can customize UI with ExoPlayer.

Customizing ExoPlayer’s UI components

ExoPlayer V2 includes several out-of-the-box UI components for customization, most notably:

  • SimpleExoPlayerView is a high level view for SimpleExoPlayer media playbacks. It displays video, subtitles and album art during playback, and displays playback controls using a PlaybackControlView.
  • PlaybackControlView is a view for controlling ExoPlayer instances. It displays standard playback controls including a play/pause button, fast-forward and rewind buttons, and a seek bar.

Use of this view is optional. You are free to implement your own UI components by yourself at the cost of some extra work. The SimpleExoPlayerView displays video, subtitles, and album art during playback, and displays playback controls using a PlaybackControlView.

A SimpleExoPlayerView can be customized by setting attributes (or calling corresponding methods), overriding the view’s layout file or by specifying a custom view layout file, as mentioned below.

Setting attributes for SimpleExoPlayerView

A SimpleExoPlayerView can be included in the layout for an Activity belonging to a video application as follows

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<com.google.android.exoplayer2.ui.SimpleExoPlayerView 
    android:id="@+id/player"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

</FrameLayout>

Now you can use following attributes on SimpleExoPlayerView to customize it when used in a layout XML file.

  • use_artwork – Whether artwork is used if available in audio streams.
  • default_artwork – Default artwork to use if no artwork available in audio streams.
  • use_controller – Whether the playback controls can be shown.
  • hide_on_touch – Whether the playback controls are hidden by touch events.
  • auto_show – Whether the playback controls are automatically shown when playback starts, pauses, ends, or fails. If set to false, the playback controls can also be manually operated with showController() and hideController().
  • resize_mode – Controls how video and album art is resized within the view. Valid values are fit, fixed_width, fixed_height and fill.
  • surface_type – The type of surface view used for video playbacks. Valid values are surface_view, texture_view and none. Using none is recommended for audio only applications, since creating the surface can be expensive. Using surface_view is recommended for video applications.
  • shutter_background_color – The background color of the exo_shutter view.
  • player_layout_id – Specifies the id of the layout to be inflated.
  • controller_layout_id – Specifies the id of the layout resource to be inflated by the child PlaybackControlView.

Overriding the view’s layout file

To customize the layout of SimpleExoPlayerView throughout your app, or just for certain configurations, you can define exo_simple_player_view.xml layout files in your application res/layout* directories. These layouts will override the one provided by the ExoPlayer library, and will be inflated for use by SimpleExoPlayerView. The view identifies and binds its children by looking for the following ids:

  • exo_content_frame – A frame whose aspect ratio is resized based on the video or album art of the media being played, and the configured resize_mode. The video surface view is inflated into this frame as its first child. Type AspectRatioFrameLayout
  • exo_shutter – A view that’s made visible when video should be hidden. This view is typically an opaque view that covers the video surface view, thereby obscuring it when visible. Type: View
  • exo_subtitles – Displays subtitles. Type: SubtitleView
  • exo_artwork – Displays album art. Type: ImageView
  • exo_controller_placeholder – A placeholder that’s replaced with the inflated PlaybackControlView. Ignored if an exo_controller view exists. Type: View
  • exo_controller – An already inflated PlaybackControlView. Allows use of a custom extension of PlaybackControlView. Note that attributes such as rewind_increment will not be automatically propagated through to this instance. If a view exists with this id, any exo_controller_placeholder view will be ignored. Type: PlaybackControlView
  • exo_overlay – A FrameLayout positioned on top of the player which the app can access via getOverlayFrameLayout(), provided for convenience. Type: FrameLayout

Any child views are optional, but where defined they must be of the expected type.

Specifying a custom layout file

Defining your own exo_simple_player_view.xml is useful to customize the layout of SimpleExoPlayerView throughout your application. It’s also possible to customize the layout for a single instance in a layout file. This can be achieved by setting the player_layout_id attribute on a SimpleExoPlayerView. This make specified layout inflated instead of exo_simple_player_view.xml for only the instance on which the attribute is set.

For more customization option check official document on customizing ExoPlayer.

Changing Video Quality in ExoPlayer on Android

To change the video quality in ExoPlayer, developers can utilize TrackSelector and DefaultTrackSelector. They can create a DefaultTrackSelector, configure it with desired parameters like bitrate, and then pass it to the ExoPlayer instance during initialization​.

Changing ExoPlayer Aspect Ratio

Developers can set the aspect ratio of the ExoPlayer by creating a custom AspectRatioFrameLayout and wrapping it around the PlayerView. They can then use the setAspectRatio method on the AspectRatioFrameLayout to change the aspect ratio.

Implementing ExoPlayer Cache

Caching can be implemented in ExoPlayer by using the CacheDataSourceFactory which wraps around another DataSource.Factory instance. A SimpleCache instance can be used to manage the cache, and the LeastRecentlyUsedCacheEvictor can be used to evict old data from the cache to ensure it doesn’t grow too large​.

ExoPlayer Play Audio from URL

To play audio from a URL, developers can initialize a DefaultDataSourceFactory and a ProgressiveMediaSource (or other appropriate MediaSource depending on the audio format), and prepare the ExoPlayer instance with the MediaSource. The uri of the audio file needs to be passed to the MediaSource to start streaming and playing the audio.

ExoPlayer Play Local File

Playing a local file can be achieved by creating a MediaItem or a RawResourceDataSource with the URI of the local file, and then preparing the ExoPlayer instance with a MediaSource created with that URI. Developers can use the res/raw folder to store and access local files, or use the assets directory if the file is stored there. They can use methods like RawResourceDataSource.buildRawResourceUri or MediaItem.fromUri to create a URI from the local file path

How To Play DRM Content On Exoplayer

So far we have gone through the advantages of using ExoPlayer and how to customize it to suit our needs, in this section, we will see how to use ExoPlayer to play DRM-protected content which is also mentioned as its advantage over the in-built MediaPlayer API.

Before we start lets understand what is Digital rights management (DRM). Digital rights management (DRM) is way to protect copyrights for digital media. It has been developed to protect all kinds of digital materials prepared for computers and other technological devices, including movies, tv series, games, music and software. Putting these restrictions on DRM-protected content is creating security issues that prevent copying and distribution over the internet.

ExoPlayer uses Android’s Media Drm API to support DRM protected playbacks.

The minimum Android versions required for different supported DRM schemes, along with the streaming formats for which they’re supported are the following. In addition to the below table, playback is limited on older devices due to security updates. Android version 7 and above are more reliable to widevine playback.

While building a media source for ExoPlayer, you should specify the UUID of the DRM system and the license server URI. Using these properties we will build an instance of DefaultDrmSessionManager needed for handling DRM related key and provisioning request to enable media playback.

Frist we need to create a instance of DrmSessionManager

private DefaultDrmSessionManager buildDrmSessionManager(UUID uuid, String licenseUrl, String userAgent) {  
    HttpDataSource.Factory licenseDataSourceFactory = new DefaultHttpDataSource.Factory().setUserAgent(userAgent);  
    HttpMediaDrmCallback drmCallback = new HttpMediaDrmCallback(licenseUrl, true,  
            licenseDataSourceFactory);  
    return new DefaultDrmSessionManager.Builder()  
            .setUuidAndExoMediaDrmProvider(uuid, FrameworkMediaDrm.DEFAULT_PROVIDER)  
            .build(drmCallback);  
}

Now we have to build a media source with license url

DRM License Url : https://proxy.uat.widevine.com/proxy?provider=widevine_test

private DashMediaSource buildDashMediaSource(Uri uri) {  
    String drmLicenseUrl = "https://proxy.uat.widevine.com/proxy?provider=widevine_test";  
    String userAgent = Util.getUserAgent(context, context.getApplicationContext().getPackageName());  
    UUID drmSchemeUuid = Util.getDrmUuid(C.WIDEVINE_UUID.toString());  

    DrmSessionManager drmSessionManager = buildDrmSessionManager(drmSchemeUuid, drmLicenseUrl, userAgent);  

    DataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(context, new DefaultHttpDataSource.Factory().setUserAgent(userAgent));  
    return new DashMediaSource.Factory(dataSourceFactory)  
            .setDrmSessionManagerProvider(unusedMediaItem -> drmSessionManager)  
            .createMediaSource(  
                    new MediaItem.Builder()  
                            .setUri(uri)  
                            .setMimeType(MimeTypes.APPLICATION_MPD)  
                            .build()  
            );  
}

Now add url and its ready to be played.

DRM Url: https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd

private void initializePlayer() {  
    String url = "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd";  

    MediaSource mediaSource = buildDashMediaSource(Uri.parse(url));  

    ExoTrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory();  
    TrackSelector trackSelector = new DefaultTrackSelector(context, videoTrackSelectionFactory);  
    trackSelector.setParameters(trackSelector.getParameters().buildUpon()  
            .setPreferredTextLanguage("en")  
            .build());  

    DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(context)  
            .forceEnableMediaCodecAsynchronousQueueing()  
            .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF);  

    int maxBufferMs = DefaultLoadControl.DEFAULT_MAX_BUFFER_MS;  

    DefaultLoadControl loadControl = new DefaultLoadControl.Builder()  
            .setBufferDurationsMs(DefaultLoadControl.DEFAULT_MIN_BUFFER_MS,  
                    maxBufferMs,  
                    DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,  
                    DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS)  
            .build();  

    ExoPlayer exoPlayer = new ExoPlayer.Builder(context, renderersFactory)  
            .setTrackSelector(trackSelector)  
            .setLoadControl(loadControl)  
            .build();  

    exoPlayer.setMediaSource(mediaSource);  
    exoPlayer.prepare();  
}

In next section we will see how we at VdoCipher use ExoPlayer to stream DRM protected videos.

Adaptive Bitrate Streaming in Exoplayer

Exoplayer can also be used for adaptive bitrate streaming to set video quality automatically based on available network bandwidth. Adaptive bitrate streaming (also known as adaptive streaming) is a technology designed to deliver video in the most efficient way possible and in the highest usable quality for each specific user and device.

For slow connections, the video will be played in low quality, and for fast connections, the video will be played in the best quality with less buffer time. These qualities(bit rates and resolutions) are known as tracks. The same media content is split into multiple tracks, each for a given quality based on bit rate and resolution. Each track is split into chunks of a given duration, typically between 2 and 10 seconds. This makes it easier to switch between tracks with changing network speeds and signals.

Implementing Adaptive Track Selection

To implement Adaptive streaming, add TrackSelector while initializing the player. The TrackSelector is used to switch between multiple tracks.

ExoTrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory();

TrackSelector trackSelector = new DefaultTrackSelector(context, videoTrackSelectionFactory);  
trackSelector.setParameters(trackSelector.getParameters().buildUpon()
        .setMaxVideoSizeSd()  
        .setPreferredTextLanguage("en")  
        .build());  

ExoPlayer exoPlayer = new ExoPlayer.Builder(context)  
        .setTrackSelector(trackSelector)  
        .build();  

Create an adaptive track selection factory with default parameters and pass it to DefaultTrackSelector which is responsible for choosing tracks in the media item.
Then pass the trackSelector to ExoPlayer builder.

Build an Adaptive Media Source

DASH, HLS, and SmoothStreaming are all media formats ExoPlayer supports that are capable of adaptive streaming, but we’ll focus on DASH for now and use the DashMediaSource. To stream DASH content, you need to create a MediaItem.

Uri manifestUri = Uri.parse(dashUrl); 
DataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(context, new DefaultHttpDataSource.Factory().setUserAgent(userAgent));
mediaSource = new DashMediaSource.Factory(dataSourceFactory)
                    .createMediaSource(
                            new MediaItem.Builder()
                                .setUri(manifestUri)
                                .setMimeType(MimeTypes.APPLICATION_MPD)
                                .build()
                    );

How VdoCipher Streams Video on Android Using ExoPlayer

The components of our video streaming can be broken down into four main parts:

  1. Client attempting to play content
  2. VdoCipher license server that generates decryption keys based on client requests
  3. Provisioning server if unique credentials are required for devices
  4. Content server that serves encrypted content

At client side we try to play protected content from the content server via a DashMediaSource with a provided DrmSessionManager, this DRMSessionManager contains the implementation of MediaDRMCallback wrapping a HttpMediaDrmCallback that extends its functionality by wrapping/unwrapping license request/response and throwing custom exceptions to help identify the cause. In the meantime, if the device needs provisioning, a request to the provisioning server is done via callback. After the MediaDRM client receives the license, and it is passed to ExoPlayer via the media source and media playback will begin. This procedure is repeated with every media playback request for non-persistent licenses. Our application saves persistent licenses and reuses them until they expire. In addition, persistent license requests are fetched before the secure video playback starts with OfflineLicenseHelper, allowing for video initialization to happen regardless of whether or not the license fetch operation succeeded. Now lets see how these classes are utilized.

How Exoplayer can play video from URL in Android video player?

After creating the instance of Exoplayer you can pass the video_url as, MediaItem mediaItem = MediaItem.fromUri(video_url);

You can also stop playback on cloned apps, emulators and rooted devices in Android with our Play Integrity integration in Android SDK. Check out our play integrity api documentation to know more. Learn more about android video SDK to stream your videos on Android with VdoCipher.

Stream Your Videos Securely on Android With VdoCipher

VdoCipher helps ver 2000+ customers over 40+ countries to host their videos securely, helping them to boost their video revenues. We provide end-to-end solutions for video, right from hosting, encoding, and encryption to the player. On top of it, you get Apis to manage videos, players, and more.

Sign Up Now!
Decorative Circle
Mansi & Nafis
Mansi & Nafis

Mansi and Nafis both are Android Developers at VdoCipher. This article was jointly written by both of them

Filed Under: Android Technology

Reader Interactions

Primary Sidebar

Secure Your Videos

Blog Categories

  • DRM 
  • APIs and Sample Codes
  • WordPress
  • E-learning
  • Media
  • Video Tech

Popular Posts

  • Google Widevine DRM
  • WordPress video plugin
  • Video Quality
  • Dynamic Watermarking
  • Encrypted Video Streaming
  • Video Hosting For Online Courses
  • Online Video Player
  • Apple Fairplay DRM
  • SVOD VS TVOD VS AVOD
  • Exoplayer
  • DRM

Top Recent Posts

  • Enterprise Video Platform
  • Cloud Video Platform
  • Video Player for Android
  • DRM Solution
  • Video Bitrate
  • React Native Video
  • Video Piracy
  • Learning Management System
  • AVPlayer
  • Live Streaming Websites
  • DRM Providers
  • DRM Security
  • Private Video Hosting
  • HTML5 Video Player

Schedule Demo Link
Popular Blogs
  • How many use easy video download piracy tools ?
  • Apple FairPlay DRM : Video Protection on iOS & Safari
  • 12 Video Piracy Statistics, 6 Prevention Methods
  • Elearning Video Protection from Piracy
  • Content Creator Economy Growth and other Statistics Report
  • Top 21 Education Apps In India For Online Learning
  • How To Embed Videos in WordPress A Comprehensive Guide
  • Live Streaming Platform For E-learning Media & Broadcast
  • Explained in Simple Language, 32 Key DRM Encryption Terminologies
  • Best Video Player for Android Comparison 2024
Recent Blogs
  • How to Build a Flutter Live Streaming Application?
  • How To Prevent Video Download From Your Website?
  • DRM Server Solutions with Widevine License and Apple FairPlay
  • Top 12 Live Streaming Platforms: All You Need To Know in 2025
  • Best DRM Tools to protect your Videos & other Digital Assets
  • Best Video Frame Rate or FPS for Cinematic Movies, 4K, YouTube & Instagram
  • Top DRM Products Overview as Software Service and Hardware
  • 15+ Best Study Apps For Students In 2025
Featured Blogs
  • Online Video Player
  • Video Encryption
  • Video Protection
  • Video Hosting
  • Widevine DRM
  • Fairplay DRM
  • Video Quality
  • Online Video Platform
  • Video hosting for business
Comparison
  • VdoCipher vs Vimeo
  • VdoCipher vs Dacast
  • VdoCipher vs YouTube
  • VdoCipher vs Zoom
  • VdoCipher vs JW Player
  • VdoCipher vs Dacast Live
    Contact Us
  • Phone : +91 7619171878
  • Whatsapp : +91 7042238654
  • E-mail : support@vdocipher.com
Company
  • Home
  • Glossary
  • Features
  • About Us
  • Pricing
  • FAQs
  • Contact
Services
  • Enterprise
  • E-Learning
  • Developer
  • Healthcare
  • Live Streaming Platform
  • Video Analytics
  • Media and Entertainment
  • DRM and Antipiracy
  • APIs for Developers
  • Video Hosting
  • Video API
  • Video DRM
  • Google DRM
  • DRM License Server
  • Custom Video Player
  • Play Integrity
Countries Served
  • Secure Video Hosting in USA
  • Secure Video Hosting in India
  • Secure Video Player in Brazil
  • Secure Video Streaming in UK
  • Secure Video Streaming in Saudi Arabia
  • Video Encryption in Spain
  • Video Encryption in Italy
  • Protected Video Streaming in Indonesia
  • Encrypted Video Player in Canada
  • Protected Video Streaming in Australia
  • Encrypted Video Player in Germany
  • Video DRM for Sri Lanka
  • Video DRM for Middle East
  • DRM Encryption for Europe
  • DRM Encryption for Asia
  • DRM Solutions for Japan
  • DRM Solutions for UAE
  • DRM Software for Chile
  • DRM Software for Russia

Copyright © 2025 VdoCipher. All rights reserved.

  • Terms
  • Privacy Policy