# Project Setup

## Requirements

The PRESTOplay SDK for Android is delivered as a Maven Repository that can be added to your application build. All required dependencies are either:

> - Contained in the bundle repository

> - Available on a public repository like jcenter or Maven Central

> - Part of the Android Support Repository that can be installed with the Android SDK-Manager.

To work with the PRESTOplay SDK for Android you need to use the Gradle build system for your application builds.

## Project Configuration

The PRESTOplay SDK for Android can be added as a remote repository, specifying the content groups when needed:

    repositories{
        maven{
            url 'https://mvn.players.castlabs.com/'
            content{
                includeGroupAndSubgroups 'com.castlabs'
                includeGroup 'com.google.android.exoplayer'

                // Optional
                // includeGroupAndSubgroups 'tv.broadpeak'
                // includeGroupAndSubgroups 'com.nielsen'
            }
        }
    }

Alternatively, the PRESTOplay SDK for Android can be referenced from the stored bundle with `repository` folder. This folder is a local Maven Repository that is used to find and integrate the PRESTOplay SDK for Android as a dependency within your project.

You can enable the repository for your project in your build.gradle script by adding it as a local Maven repository:

    repositories{
        maven{
            url '<path/to/castlabs/repository>'
        }
        jcenter()
    }

The <path/to/castlabs/repository> needs to be replaced with the actual path to the `repository` folder that is bundled with the SDK. The repository does not need to be part of your project structure explicitly and you do not need to add it to your version control system. Instead, you can host the repository outside of your project structure. You can for example use a Gradle property to denote the path to the repository folder.

The repository contains all the required pom.xml files to be uploaded to a hosted Maven or Ivy repository.

With the repository added to your build script, you can reference and load the PRESTOplay SDK for Android and its components using:

    dependencies {
        ...
        compile 'com.castlabs.player:castlabs-sdk:4.4.8'
        ...
    }

This will add the SDK and its dependencies to the classpath of your application and you can start referencing classes within the SDK.

After the SDK is added as a dependency, you need to initialize it before you can use it. This is typically done in your Application class using the `PlayerSDK.init()` method. For example:

    public class DemoApp extends Application{
        @Override
        public void onCreate() {
            super.onCreate();
            ...
            PlayerSDK.init(getApplicationContext());
        }
    }

## License Loading

The PRESTOplay SDK for Android requires a license that needs to be distributed with your application. By default, the SDK expects to find the license in your Application Manifest as the castlabs-license meta-data Attribute. For example:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest>
        ...
        <application>
            ...
            <meta-data android:name="castlabs-license"
                       android:value="<your-license-key>" />
            ...
        </application>
    </manifest>

The license key is bound to your Applications SHA-1 Fingerprint and Package name. You can generate license keys on the Castlabs Download Portal. In the Licenses section, you can create License Keys for your Application.

Depending on how you decide to manage your license file, you might want to load it from a different location or use a different name. For this, you can use an implementation of the `LicenseLoader` interface. The SDK already comes with an implementation to load the licenses from the application’s Manifest with the `ManifestLicenseLoader`. This is the default implementation. If you want to use a different loader, you can pass an instance of the `LicenseLoader` to `PlayerSDK.init()`. For example:

    PlayerSDK.init(getContext(),
                   new MyLicenseLoader());

Note that in case the license key is invalid the SDK will not be initialized and the error will be sent via the `PlayerListener.onError(CastlabsPlayerException)`. The SDK however can still be re-initialized with a valid key if applicable.

### User Id

Your PRESTOplay SDK for Android license might require user tracking for accounting purposes. If this is the case, you must provide a unique user id for each view session.

The value of this parameter must be unique for each end-user. Our backend only needs to identify end users on a cross-session basis, but we don’t use this information to do any correlation.

This means that the provided values should be pseudonymized. One example of this could be hashing a user’s email account.

This value can be informed through the parameter `INTENT_USER_ID` if using an `Intent` or with the `userId` field in `PlayerConfig` upon playback initialization.

Note

In case your PRESTOplay SDK for Android license requires user identification, you must inform this field.

Without specifying user ID parameter if mandatory, the SDK license check will result in a rejected license and failed playback attempt. If the license check fails due to missing USER_ID, a player exception will be raised:

    E/CastlabsPlayerException: [ERROR] [TYPE_USER_ID_NOT_PROVIDED] UserID is required for playback

If you’re using DRMToday, the PRESTOplay SDK for Android will, by default, use the user id informed in the `DrmConfiguration`, so there’s no obligation to fill in the `userId` in such scenario. You can still inform the value in the Bundle or the `PlayerConfig` object and it will take precedence.

As mentioned, there are two ways of providing the end user ID to the SDK: `INTENT_USER_ID` or `PlayerConfig.userId` (which can be specified through the `Builder`). The example for this would be:

    // Specify the UserID as an intent bundle parameter
    bundle.putString(SdkConsts.INTENT_USER_ID, "unique-user-id");

or:

    // Alternatively, set the UserID in PlayerConfig as part of the config
    PlayerConfig playerConfig = new PlayerConfig.Builder("<url_to_stream>")
        .userID("unique-user-id")
        .get();

## Third party re-signing conflicts

Each license for the PRESTOplay SDK for Android is tied to a unique developer certificate. This link is checked through the certificate’s SHA1 fingerprint. For this reason, some third party processes which introduce re-signing operations may interfere with the PRESTOplay SDK for Android licence check if such re-signing is done with a different key.

### Protection tools

Some Android app protection and obfuscation software needs to re-sign the app bundle or apk after the protection and obfuscation actions have taken place. In order for the PRESTOplay SDK for Android license check to succeed, it is necessary that the fingerprint of the key that is used to sign the application is the one indicated upon the PRESTOplay SDK for Android key generation.

If you are experiencing issues with license validation after running protection software, please make sure the third party protection tool is using the same key to re-sign the binary.

#### DexProtector

If using Licel's DexProtector, you should pay close attention to the `signMode` element in the configuration. Such should be set to `release`, alongside the path and information about the keystore to use for signing.

This is the same keystore from which the SHA1 fingerprint should have been extracted in order to generate the license for the PRESTOplay SDK for Android.

### Amazon App Store

Please note that the Amazon App store re-signs submitted APKs and hence changes the signature of the Application and the signing key. Since the Castlabs License is bound to the signing key, you need to create a dedicated license using the SHA1 that is exposed on the Amazon Developer console.

Amazon App Store SHA1

## Variant Builds

You can leverage the support of the Android build plugin for “build variants” to create different versions of your application from a single project. This is particularly useful when you want to provide optimized experiences for different Android API levels or device capabilities.

For instance, you might want to create a build that targets newer Android versions with features that rely on more recent APIs, and another build for older devices that uses fallback mechanisms or has a slightly reduced feature set.

A detailed discussion of build variants is out of scope for this documentation, but a simple example looks like this:

    ...
    android {
        ...
        defaultConfig {
            minSdkVersion 21
            // Common configurations for all variants
            applicationId "com.example.myapp"
            // Set a base versionCode. Flavors will need specific ones.
            versionCode 1
            // Other common configurations
        }
        signingConfigs { ... }
        buildTypes { ... }
        productFlavors {
            // Flavor for newer devices, targeting API 23 (Marshmallow) and above
            modern {
                minSdkVersion 23
                // For multiple APKs in Play Store, the one with higher API support
                // often needs a higher version code.
                versionCode 200 // Example: 200 (prefix) + defaultConfig.versionCode
                versionNameSuffix "-modern"
            }
            // Flavor for older devices, supporting from API 21 (Lollipop) up to API 22
            legacy {
                minSdkVersion 21
                // This variant targets older APIs, so it should have a lower version code
                // to ensure users on newer OS versions get the 'modern' APK.
                versionCode 100 // Example: 100 (prefix) + defaultConfig.versionCode
                versionNameSuffix "-legacy"
                // Important: If you want this APK to only be for devices up to API 22
                // you would define maxSdkVersion here.
                // maxSdkVersion 22
            }
        }

        // Optional: If you're using App Bundles (recommended), Google Play handles
        // delivering the correct APK based on device API level.
        // If you are manually uploading multiple APKs, ensure your versionCode logic
        // is correct. See: https://developer.android.com/google/play/publishing/multiple-apks.html
    }
    ...
    dependencies {
        ...

        // Common dependencies for all variants
        implementation 'com.castlabs.player:castlabs-sdk:4.4.8' // Or your current SDK version

        // You could have dependencies specific to a flavor based on API level needs:
        // modernImplementation 'androidx.appcompat:appcompat:1.6.1' // Example with a newer library version
        // legacyImplementation 'androidx.appcompat:appcompat:1.3.1' // Example with an older compatible version
        ...
    }
    ...

In this example, we create two product flavors: “modern” and “legacy”.

- modern Flavor:

  - Targets minSdkVersion 23 (Android Marshmallow).

  - It’s assigned a higher versionCode (e.g., 200). This is important if you’re publishing multiple APKs to the Google Play Store, as it ensures devices capable of running this version receive it.

- legacy Flavor:

  - Targets an older minSdkVersion 21 (Android Lollipop).

  - It has a lower versionCode (e.g., 100).

  - The commented-out maxSdkVersion 22 shows how you could restrict this APK to only be installable on devices up to API level 22. If you set maxSdkVersion for the legacy flavor and a minSdkVersion for the modern flavor that is higher than the legacy flavor’s maxSdkVersion, you ensure that there is no overlap in API level targeting.

## Split APK Builds

The SDK includes native components for ARM and x86 architectures bundled in their AAR files. Similar to the variant builds (see Variant Builds), you can use the split APK feature of the Android Gradle plugin to generate APK versions specific to ARM and x86 architectures and further reduce the APK size of the final application for a single variant. You can find more information about ABI splits and variant builds in the Android Tools wiki.

## Proguard Configuration

The PRESTOplay SDK for Android and all the plugins embed a Proguard configuration in their `aar` files and there is no need to specify anything specific to the Castlabs SDK in your Proguard configuration file.

## Protocol buffer dependencies

The PRESTOplay SDK for Android uses Google’s protobuf library some of its components. More precisely, the `protobuf-javalite` artifact is being used. If you’re using in your project another version of such library, you’ll need to exclude it from the conflicting packages so the build goes through without finding duplicate classes.

Note that this also applies to transitive dependencies. One common example is Google’s `play-services-cast-framework` used for the Google Cast sender:

    // Don't include the transitive protobuf dependency
    implementation ('com.google.android.gms:play-services-cast-framework:X.Y.Z') {
        exclude group: 'com.google.protobuf'
    }