This page describes how initialize the library in your game code and verify that
it is uploading data to Google Play. To find more information on specific
library functions, see the
[reference documentation](https://developer.android.com/games/sdk/reference/performance-tuner/unity).

## Initialize the library

In an initialization method at the start of your game, initialize the library by
instantiating `AndroidPerformanceTuner` and calling its
[`Start()`](https://developer.android.com/games/sdk/reference/performance-tuner/unity/class/google/android/performance-tuner/android-performance-tuner-t-fidelity-t-annotation-#start)
method:  

    using Google.Android.PerformanceTuner;
    using UnityEngine;

    public class SomeBehaviour : MonoBehaviour
    {
        AndroidPerformanceTuner<FidelityParams, Annotation> tuner =
                new AndroidPerformanceTuner<FidelityParams, Annotation>();

        void Start()
        {
            ErrorCode startErrorCode = tuner.Start();
            Debug.Log("Android Performance Tuner started with code: " + startErrorCode);

            tuner.onReceiveUploadLog += request =>
            {
                Debug.Log("Telemetry uploaded with request name: " + request.name);
            };
        }
    }

This code is enough to get Android Performance Tuner started and your game
instrumented. The log statements indicate when Android Performance Tuner has started
and when telemetry has been uploaded to the Google Play Console APIs. Later,
you will find these statements in the log to verify that the plugin is operating
correctly.

### Late initialization (Vulkan only)

If your game targets Vulkan and uses Android Frame Pacing, Android Performance Tuner
should have a late initialization:  

    IEnumerator Start()
    {
        yield return new WaitForEndOfFrame();
        ErrorCode startErrorCode = tuner.Start();
        Debug.Log("Android Performance Tuner started with code: " + startErrorCode);

        tuner.onReceiveUploadLog += request =>
        {
            Debug.Log("Telemetry uploaded with request name: " + request.name);
        };
    }

## Verify the interval between telemetry uploads

The default interval between telemetry uploads in the plugin settings is 30
seconds. This time is set to a short interval to make it easier to verify the
proper uploading of telemetry. When you release your game to production, set
this to a large interval (for example, every 10 minutes) so that the game is not
making too many requests to the APIs, which is especially important for users
who do not have a mobile data plan that includes unlimited data. A large
interval also avoids overusing the device battery.

To verify that the interval is set to 30 seconds, do the following:

1. Select **Google \> Android Performance Tuner** to access the settings.
2. Select the **Instrumentation Settings** tab and click **Use advanced
   settings**.
3. Verify that the **Intervals (minutes)** field contains **0.5**.

![](https://developer.android.com/static/images/games/performance-tuner/unity-apt-instrumentation-settings.png)
**Instrumentation settings** tab in the plugin
| **Warning:** Remember to set the interval to a higher value (for example, every 10 minutes) before releasing your game.

## Verify proper operation

If you are using IL2CPP or code stripping, see
[Manage code stripping](https://developer.android.com/games/sdk/performance-tuner/unity/initialize-library#manage-code-stripping).

Build your game for Android. While your game is launching on a device, open a
terminal on your computer and launch `adb logcat`:  

    adb logcat

In the output of `adb logcat`, search for "TuningFork" (as Tuning Fork is the
internal name of the library):  

    02-03 16:55:45.103 10511 10536 I TuningFork: Got settings from tuningfork/tuningfork_settings.bin
    02-03 16:55:45.103 10511 10536 I TuningFork: Using local file cache at /data/user/0/com.Unity3d.BoatAttackDay/cache/tuningfork
    02-03 16:55:45.105 10511 10536 I TuningFork: OpenGL version 3.2
    02-03 16:55:45.105 10511 10536 I TuningFork: TuningFork.GoogleEndpoint: OK
    02-03 16:55:45.106 10511 10611 I TuningFork: Creating directory /data/user/0/com.Unity3d.BoatAttackDay/cache/tuningfork
    02-03 16:55:45.106 10511 10536 I TuningFork: TuningFork Settings:

    [...]

    02-03 16:55:45.116 10511 10536 I Unity   : Tuningfork started with code: Ok
    02-03 16:55:45.107 10511 10536 I TuningFork: TuningFork initialized
    02-03 16:55:45.107 10511 10536 I UnityTuningfork: Swappy backend: 1
    02-03 16:55:45.107 10511 10536 I TuningFork: Creating directory /data/user/0/com.Unity3d.BoatAttackDay/cache/tuningfork/V1
    02-03 16:55:45.110 10511 10613 I TuningFork: OpenGL version 3.2
    02-03 16:55:45.110 10511 10613 I TuningFork:Web: Connecting to: https://performanceparameters.googleapis.com/v1/applications/com.Unity3d.BoatAttackDay/apks/1:generateTuningParameters

If you made a mistake while setting up the plugin, like forgetting to set the
API key, you'll see an error in the initialization logs:  

    02-03 16:49:44.970  8815  8831 I TuningFork: Got settings from tuningfork/tuningfork_settings.bin
    02-03 16:49:44.971  8815  8831 I TuningFork: Using local file cache at /data/user/0/com.Unity3d.BoatAttackDay/cache/tuningfork
    02-03 16:49:44.972  8815  8831 I TuningFork: OpenGL version 3.2
    02-03 16:49:44.972  8815  8831 W TuningFork.GE: The API key in Tuning Fork TFSettings is invalid
    02-03 16:49:44.972  8815  8831 E TuningFork: TuningFork.GoogleEndpoint: FAILED
    02-03 16:49:44.973  8815  8831 I Unity   : Tuningfork started with code: BadParameter

Check that Android Performance Tuner is uploading telemetry. If you see `TuningFork
initialized` in the logs, wait a bit more and look for logs indicating that
telemetry is being uploaded.  

    02-03 16:58:00.552 10511 10611 I TuningFork:Web: Connecting to: https://performanceparameters.googleapis.com/v1/applications/com.Unity3d.BoatAttackDay/apks/1:uploadTelemetry
    02-03 16:58:00.898 10511 10611 I TuningFork:Web: Response code: 200
    02-03 16:58:00.898 10511 10611 I TuningFork:Web: Response message: OK
    02-03 16:58:00.899 10511 10611 I TuningFork.GE: UPLOAD request returned 200 {}

You can also search in the logs for "Connecting to:". This message is followed
by the response code a few lines after.

If you don't see telemetry upload logs, verify that you properly set the
interval between each upload in the Android Performance Tuner settings to a small
value, like 30 seconds.

### Manage code stripping

| **Warning:** Code stripping is always enabled for the IL2CPP backend.

`Google.Protobuf.dll` uses reflection. During code stripping, some of the
required code may be removed. To avoid this removal, the plugin contains a
`link.xml` file with information about which symbols should be preserved. If you
need some functionality of protobuf which uses reflection and you have code
stripping enabled, add this information into the `link.xml` file to preserve the
symbols.
| **Warning:** The plugin contains the minimum required symbols in `link.xml`. You don't need to add to this file unless you use protobuf functionally which has not been added to `link.xml` yet.

You can read more about
[managed code strippping](https://docs.unity3d.com/2019.3/Documentation/Manual/ManagedCodeStripping.html)
in the Unity documentation.

If you need to preserve all symbols in protobuf, add a `link.xml` file to your
project that contains the following:  

    <linker>
      <assembly fullname="Google.Protobuf" preserve="all"/>
    </linker>

### Ahead-of-time compile (AOT)

Ahead-of-time compile is required for the IL2CPP backend and Unity versions 2017
and 2018 (but not for later versions of Unity).

The AOT compiler may not generate code for generic methods. You need to force
the compiler to generate the proper code required for protobuf by adding the
following method:  

    using Google.Protobuf.Reflection;
    using UnityEngine.Scripting;

    ...

    // Don't call this method.
    [Preserve]
    void ExampleOfForceReflectionInitializationForProtobuf()
    {
        FileDescriptor.ForceReflectionInitialization<Scene>();
        FileDescriptor.ForceReflectionInitialization<ShadowType>();
        FileDescriptor.ForceReflectionInitialization<LevelType>();
        ...
        // Add FileDescriptor.ForceReflectionInitialization<T> for each generated enum.
        // You can find the list of enums in DevTuningfork.cs -> enum section
        // or in the list of enums in Google -> Android Performance Tuner.
    }

You can read more about
[scripting restrictions](https://docs.unity3d.com/Manual/ScriptingRestrictions.html)
in the Unity documentation.