Baseline Profileの生成をBaseline Profile Gradleプラグインに置き換える

androidx.benchmark 1.2 以降で登場した Baseline Profile Gradleプラグインを使うことで Baseline Profile の生成がこれまでの実装より簡略できるので、置き換え手順を書いていきます。


これまで Baseline Profile の生成をしていなかったプロジェクトでは、Android Studio Iguana 以降で追加予定の Baseline Profile module のテンプレートで簡単にセットアップできるようになります。

https://developer.android.com/topic/performance/baselineprofiles/create-baselineprofile#create-new-profile


## 移行手順
### Gradle プラグインの追加

Baseline Profile Gradleプラグインの依存を追加してプロジェクトで使えるように設定します。  

```libs.versions.toml
[plugins]
...
baselineProfilePlugin = { id = "androidx.baselineprofile", version.ref = "baselineProfile" }
```

```build.gradle.kts
plugins {
    ...
   alias(libs.plugins.baselineProfilePlugin) apply false
}
```

### app モジュールの移行

app モジュールでは Plugin や依存の追加と Plugin への置き換えで不要になる `buildTypes` を削除します。 

```app/build.gradle.kts
plugins {
    ...
    // Pluginの依存を追加
    alias(libs.plugins.baselineProfilePlugin)
}

android {
    ...
    buildTypes {
        release {
            isShrinkResources = true
            isMinifyEnabled = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
        // 以下は削除
//        create("benchmark") {
//            signingConfig = signingConfigs.getByName("debug")
//            matchingFallbacks.add("release")
//            isDebuggable = false
//        }
    }
    ...
}

dependencies {
    ...
    // BaselineProfileのモジュールの依存を baselineProfile で追加
    "baselineProfile"(projects.benchmark)
}
```

### benchmark のモジュールの移行

app モジュールと同様に Plugin や依存の追加と Plugin への置き換えで不要になる `buildTypes` を削除します。 
Plugin の追加によって `BaselineProfileProducerExtension` が使えるようになるので、`managedDevices` の設定などを行います。

```benchmark/build.gradle.kt
plugins {
    ...
    // Pluginの依存を追加
    alias(libs.plugins.baselineProfilePlugin)
}

android {
    ...
    // 以下は削除
//    buildTypes {
//        create("benchmark") {
//            isDebuggable = true
//            signingConfig = getByName("debug").signingConfig
//            matchingFallbacks.add("release")
//        }
//    }

    targetProjectPath = ":app"
    testOptions.managedDevices.devices {
        create<ManagedVirtualDevice>("pixel6Api34") {
            device = "Pixel 6"
            apiLevel = 34
            systemImageSource = "google"
        }
    }
}

baselineProfile {
    /**
     * Gradle Managed Deviceを使っているならば、
     * こちらにもtestOptionsのcreate<ManagedVirtualDevice>で設定したデバイス名を渡す
     */
    managedDevices += "pixel6Api34"
    useConnectedDevices = false
}

dependencies {
    ...
}

// 以下はbuildTypesを削除したことで不要になるので削除
//androidComponents {
//    beforeVariants {
//        it.enable = it.buildType == "benchmark"
//    }
//}
```

### 生成の実行
gradle から以下のコマンドを呼ぶことで、`app/src/release/generated/baselineProfiles` に Baseline Profiles が生成されます。

```
gradle :app:generateBaselineProfile
```

or
```
gradle :app:generate{Variant}BaselineProfile
```

## Baseline Profile Gradleプラグインの便利な設定

Baseline Profile Gradleプラグインで追加された便利な設定をいくつか紹介します。

### `automaticGenerationDuringBuild`

`automaticGenerationDuringBuild` を app モジュールで有効にすると、`assembleRelease` のリリースビルド時に Baseline Profiles の生成をした後でリリースビルドがされるようになります。　　
これまでは Baseline Profiles の生成タスクをした後でリリースビルドのタスクを実行するといった流れだったものが一つのタスクで完了できるようになります。
常にリリースビルドで有効にしているとビルド時間が増加することになるため、ビルドバリアントごとにこの動作を設定することもできます。  

```app/build.gradle.kts
baselineProfile {
    automaticGenerationDuringBuild = true
}
```

https://developer.android.com/topic/performance/baselineprofiles/configure-baselineprofiles#auto-generate-for-releases

### `filter`

`filter` を app モジュールで設定すると、特定のクラスのみ Baseline Profiles に含めることができます。
ライブラリ開発者はサンプルアプリのコードを除外するなどといった使い道があります。  
こちらの設定もビルドバリアントごとのフィルタリングを指定することもできます。  

```app/build.gradle.kts
baselineProfile {
    filter {
        include("com.somelibrary.widget.grid.**")
        exclude("com.somelibrary.widget.grid.debug.**")
        exclude("com.somelibrary.**")
        exclude("com.somelibrary.*")
        exclude("com.somelibrary.MyClass")
    }
}
```

https://developer.android.com/topic/performance/baselineprofiles/configure-baselineprofiles#filter-profile-rules



* * *

これまでは benchmark モジュールで実行して生成されたファイルを移動していたのが Plugin に移行することで不要になったので、これまで以上に簡単にリリースフローに組み込みやすくなりました。  
また、`buildType` も不要になったのでプロジェクトのコードに集中できるのも地味にいい改善ポイントですね。