# Custom SDK Dependencies

## Overview

See [Custom SDK Dependencies](/paas/sdk/unified-vpn-sdk/features/custom-sdk-dependencies.md)

## Customize the SDK internal logic

1. Create a Configuration File. Define a raw resource file named `sdk_deps.json` to specify custom dependencies. General structure of dependencies config may look like:

   ```json
   {
       "dependency 1 key": {
           "type": "class 1 name for dependency to use"
       },
       "dependency 2 key": {
           "type": "class 2 name for dependency to use"
       }
   }
   ```
2. Set up metadata in `AndroidManifest.xml`. Add the following code to the `<application>` section of your `AndroidManifest.xml` to link the configuration file:

   ```xml
   <meta-data
           android:name="unified.vpn.sdk.deps"
           android:resource="@raw/sdk_deps"/>
   ```
3. Configure ProGuard. Make sure that your custom dependency classes are not renamed or removed by ProGuard or other code obfuscation tools.

## Possible dependencies overrides

You can override various SDK dependencies by creating custom classes and specifying them in the `sdk_deps.json` file. Below is an example of overriding the SDK's logging functionality.

### Custom logger

1. Define a class that extends `unified.vpn.sdk.UnifiedLogDelegate`. This class will handle logging for the SDK:

   ```kotlin
   package com.example.vpnsdk

   import android.content.Context
   import androidx.annotation.Keep
   import okhttp3.OkHttpClient
   import unified.vpn.sdk.*

   @Keep
   class CustomLogger : UnifiedLogDelegate() {
       override fun log(level: Int, e: Throwable?, tag: String, message: String, vararg args: Any?) {
       }

       override fun setLogLevel(logLevel: Int) {
       }
   }
   ```
2. Configure the SDK to Use the Custom Logger: Add the following entry in your `sdk_deps.json` file to specify the custom logger class:

   ```json
   {
       "logger": {
           "type": "com.sdk.sample.CustomLogger"
       }
   }
   ```

#### Additional configuration of OkHttpClient used in SDK

1. Define class that implements **HttpClientConfigurer**

   ```kotlin
   package com.example.vpnsdk

   import android.content.Context
   import androidx.annotation.Keep
   import okhttp3.OkHttpClient
   import unified.vpn.sdk.*

   @Keep
   class SampleOkHttpConfigurer : HttpClientConfigurer {
       override fun configure(builder: OkHttpClient.Builder) {
           // perform custom configuration of OkHttpClient.Builder
       }
   }
   ```
2. Setup SDK dependency override in **sdk\_deps**

   ```javascript
   {
       "okHttpConfigurer": {
           "type": "com.sdk.sample.SampleOkHttpConfigurer"
       }
   }
   ```

### Custom backend URL rotator

1. Create a Custom URL Rotator: Define a class that implements the UrlRotator interface. This class controls the behavior for rotating backend.

   ```kotlin
   package com.example.vpnsdk

   import android.content.Context
   import androidx.annotation.Keep
   import okhttp3.OkHttpClient
   import unified.vpn.sdk.*

   class SampleUrlRotator : UrlRotator {
       override fun failure(httpUrl: String, error: VpnException) {
           // mark url as failed
       }

       override fun success(httpUrl: String, obj: Any?) {
           // mark url as success
       }

       override fun provide(): String {
           // return url for backend calls
           return ""
       }

       override fun size(): Int {
           // return number of possible urls for rotation
           return 1
       }
   }
   ```
2. Create a URL Rotator Factory: Define a class that implements the `UrlRotatorFactory` interface, which creates instances of your custom `UrlRotator`

   ```kotlin
   @Keep
   class SampleUrlRotatorFactory : UrlRotatorFactory {
       override fun create(context: Context, clientInfo: ClientInfo): UrlRotator {
           return SampleUrlRotator()
       }
   }
   ```
3. Configure the SDK to Use the Custom URL Rotator: Update the `sdk_deps.json` file to specify the custom URL rotator factory.

   ```json
   {
       "urlRotator": {
           "type": "com.sdk.sample.SampleUrlRotatorFactory"
       }
   }
   ```

### Custom notification builder

You can customize how notifications are displayed by defining your own notification builder. Follow these steps to set up a custom notification delegate:

1. Create a Custom Notification Delegate Class: Define a class that implements the `NotificationDelegate` interface. This class controls the appearance and behavior of notifications related to VPN activity.

   ```kotlin
   package com.example.vpnsdk

   import android.content.Context
   import androidx.annotation.Keep
   import okhttp3.OkHttpClient
   import unified.vpn.sdk.*

   @Keep
   class SampleNotificationDelegate : NotificationDelegate {
       override suspend fun create(
           context: Context,
           config: SdkNotificationConfig?,
           state: VpnState,
           trafficRx: Long,
           trafficTx: Long,
           speedRx: Long,
           speedTx: Long,
           fallback: NotificationDelegate?
       ): Notification? {
           return null
       }
   }
   ```
2. Configure the SDK to Use the Custom Notification Delegate: Update the `sdk_deps.json` file to specify your custom notification delegate class.

   ```javascript
   {
       "notificationDelegate": {
           "type": "com.sdk.sample.SampleNotificationDelegate"
       }
   }
   ```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://pango.gitbook.io/paas/sdk/vpn-sdk-for-android/features/custom-sdk-dependencies.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
