Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,18 @@ jobs:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-cached-${{ matrix.api-level }}-${{ matrix.os }}-${{ matrix.target }}
key: avd-cached-${{ matrix.api-level }}-${{ matrix.os }}-${{ matrix.target }}-${{ hashFiles('**/libs.versions.toml') }}
restore-keys: |
avd-cached-${{ matrix.api-level }}-${{ matrix.os }}-${{ matrix.target }}-
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's this about?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cache fallback. The exact key includes hashFiles('**/libs.versions.toml'), so when deps change there's no exact match. Without restore-keys, that's a total cache miss — the emulator runner has to set up everything from scratch. With restore-keys: avd-cached-{api-level}-{os}-{target}-, GitHub will restore the most recent cached AVD for that API level/target combination (from a previous dep version) as a partial restore. Then force-avd-creation: true wipes that old snapshot and creates a fresh one, which gets saved under the new key.

- name: Create AVD and generate snapshot for caching
if: steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
arch: ${{ matrix.arch }}
force-avd-creation: false
# FORCE true here ensures if 'actions/cache' restored old avd, we wipe and start with a fresh image for the new dependency hash.
force-avd-creation: true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean we create a new AVD on every run? Doesn't that slow down CI?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No — only when libs.versions.toml changes. The step has if: steps.avd-cache.outputs.cache-hit != 'true', so it's skipped entirely on an exact cache hit. The key includes hashFiles('**/libs.versions.toml'), so on runs where deps haven't changed the key matches → cache-hit = 'true' → step is skipped entirely.

force-avd-creation: true only matters when the step does run (cache miss or partial match via restore-keys): it ensures any restored but stale AVD snapshot is wiped and a fresh one is created, rather than reusing a snapshot from a different dep version. The Instrumentation Tests step keeps force-avd-creation: false so it always reuses whatever snapshot was just created (or retrieved from an exact cache hit).

emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -no-snapshot-load
disable-animations: false
script: echo "Generated AVD snapshot for caching."
Expand All @@ -92,14 +95,6 @@ jobs:
arch: ${{ matrix.arch }}
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -no-snapshot-save
script: |
# Uninstall existing packages to avoid INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES
# when a cached AVD snapshot has old APKs signed with different keys.
adb uninstall com.squareup.leakcanary || true
adb uninstall com.squareup.leakcanary.test || true
adb uninstall com.squareup.leakcanary.core || true
adb uninstall com.squareup.leakcanary.core.test || true
adb uninstall com.squareup.leakcanary.instrumentation || true
adb uninstall com.squareup.leakcanary.instrumentation.test || true
touch emulator.log
chmod 777 emulator.log
adb logcat >> emulator.log &
Expand Down
4 changes: 3 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ buildscript {
classpath(libs.gradlePlugin.binaryCompatibility)
classpath(libs.gradlePlugin.keeper)
classpath(libs.gradlePlugin.sqldelight)
classpath("com.google.dagger:hilt-android-gradle-plugin:2.43.2")
classpath(libs.gradlePlugin.hilt)
}
}

Expand Down Expand Up @@ -68,6 +68,8 @@ subprojects {
"-Xlint:all",
"-Xlint:-serial",
"-Xlint:-deprecation",
"-Xlint:-options", // Silences Java 8 obsolete warning
// "-Xlint:-this-escape", // Silences Java 21+ leaking 'this' warning (Java 21+ only) (Currently we build with J17 so not needed)
// espresso-core classes say they're compiled with 51.0 but contain 52.0 attributes.
// warning: [classfile] MethodParameters attribute introduced in version 52.0 class files is ignored in version 51.0 class files
// "-Werror"
Expand Down
25 changes: 15 additions & 10 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,27 @@
compose = "1.4.3"
kotlin = "1.8.21"
coroutines = "1.7.3"
androidXTest = "1.1.0"
androidXJunit = "1.1.3"
androidXTest = "1.5.0"
androidXJunit = "1.1.5"
workManager = "2.7.0"
detekt = "1.23.8"
hilt = "2.53"
androidMinSdk = "14"
androidCompileSdk = "34"
androidCompileSdk = "35"

[libraries]
gradlePlugin-android = { module = "com.android.tools.build:gradle", version = "8.0.0" }
gradlePlugin-android = { module = "com.android.tools.build:gradle", version = "8.2.2" }
gradlePlugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
gradlePlugin-dokka = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version = "1.8.10" }
gradlePlugin-binaryCompatibility = { module = "org.jetbrains.kotlinx:binary-compatibility-validator", version = "0.13.1" }
gradlePlugin-mavenPublish = { module = "com.vanniktech:gradle-maven-publish-plugin", version = "0.25.2" }
gradlePlugin-detekt = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt" }
gradlePlugin-keeper = { module = "com.slack.keeper:keeper", version = "0.7.0" }
gradlePlugin-sqldelight = { module = "app.cash.sqldelight:gradle-plugin", version = "2.0.0-alpha05" }
gradlePlugin-hilt = { module = "com.google.dagger:hilt-android-gradle-plugin", version.ref = "hilt" }

hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }

coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }

Expand All @@ -50,13 +55,13 @@ androidX-fragment = { module = "androidx.fragment:fragment", version = "1.0.0" }
androidX-multidex = { module = "androidx.multidex:multidex", version = "2.0.1" }
# Exposed transitively, avoid increasing
androidX-startup = { module = "androidx.startup:startup-runtime", version = "1.0.0" }
androidX-test-core = { module = "androidx.test:core", version = "1.4.0" }
androidX-test-monitor = { module = "androidx.test:monitor", version = "1.4.0" }
androidX-test-core = { module = "androidx.test:core", version = "1.5.0" }
androidX-test-monitor = { module = "androidx.test:monitor", version = "1.6.1" }
androidX-test-rules = { module = "androidx.test:rules", version.ref = "androidXTest" }
# Exposed transitively, avoid increasing
androidX-test-runner = { module = "androidx.test:runner", version = "1.4.0" }
androidX-test-orchestrator = { module = "androidx.test:orchestrator", version = "1.4.1" }
androidX-test-espresso = { module = "androidx.test.espresso:espresso-core", version = "3.4.0" }
androidX-test-runner = { module = "androidx.test:runner", version = "1.5.2" }
androidX-test-orchestrator = { module = "androidx.test:orchestrator", version = "1.4.2" } # 1.5.0+ requires API 21+, keeping at 1.4.2 for API 16 compatibility
androidX-test-espresso = { module = "androidx.test.espresso:espresso-core", version = "3.5.1" }
androidX-test-junit = { module = "androidx.test.ext:junit", version.ref = "androidXJunit" }
androidX-test-junitKtx = { module = "androidx.test.ext:junit-ktx", version.ref = "androidXJunit" }
androidX-test-uiautomator = { module = "androidx.test.uiautomator:uiautomator", version = "2.2.0" }
Expand All @@ -70,7 +75,7 @@ clikt = { module = "com.github.ajalt:clikt", version = "2.3.0" }
neo4j = { module = "org.neo4j:neo4j", version = "4.4.6" }
curtains = { module = "com.squareup.curtains:curtains", version = "1.2.4" }
jline = { module = "jline:jline", version = "2.14.6" }
junit = { module = "junit:junit", version = "4.12" }
junit = { module = "junit:junit", version = "4.13.2" }
kotlinStatistics = { module = "org.nield:kotlin-statistics", version = "1.2.1" }
mockito = { module = "org.mockito:mockito-core", version = "3.5.10" }
mockitoKotlin = { module = "com.nhaarman.mockitokotlin2:mockito-kotlin", version = "2.2.0" }
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
4 changes: 3 additions & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
44 changes: 31 additions & 13 deletions gradlew

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions leakcanary/leakcanary-android-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ fun gitSha(): String {
android {
resourcePrefix = "leak_canary_"
compileSdk = libs.versions.androidCompileSdk.get().toInt()

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

defaultConfig {
minSdk = libs.versions.androidMinSdk.get().toInt()
// Avoid DeprecatedTargetSdkVersionDialog during UI tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ internal class LeakDirectoryProvider constructor(
}

@TargetApi(M) fun hasStoragePermission(): Boolean {
// Defensive check: @TargetApi doesn't prevent this method from being called on older APIs
@Suppress("ObsoleteSdkInt")
if (SDK_INT < M) {
return true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ internal class RequestPermissionActivity : Activity() {

fun createPendingIntent(context: Context, permission: String): PendingIntent {
val intent = createIntent(context, permission)
// Defensive check: @TargetApi on class doesn't prevent this method from being called on older APIs
@Suppress("ObsoleteSdkInt")
val flags = if (Build.VERSION.SDK_INT >= 23) {
FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE
} else {
Expand Down
6 changes: 6 additions & 0 deletions leakcanary/leakcanary-android-process/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ dependencies {

android {
compileSdk = libs.versions.androidCompileSdk.get().toInt()

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

defaultConfig {
minSdk = libs.versions.androidMinSdk.get().toInt()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ object LeakCanaryProcess {
return false
}

val mainProcess = packageInfo.applicationInfo.processName
val mainProcess = packageInfo.applicationInfo?.processName ?: return false

val component = ComponentName(context, serviceClass)
val serviceInfo: ServiceInfo
Expand Down
6 changes: 6 additions & 0 deletions leakcanary/leakcanary-android-utils/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ dependencies {

android {
compileSdk = libs.versions.androidCompileSdk.get().toInt()

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

defaultConfig {
minSdk = libs.versions.androidMinSdk.get().toInt()
}
Expand Down
6 changes: 6 additions & 0 deletions leakcanary/leakcanary-android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ dependencies {

android {
compileSdk = libs.versions.androidCompileSdk.get().toInt()

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

defaultConfig {
minSdk = libs.versions.androidMinSdk.get().toInt()
// Avoid DeprecatedTargetSdkVersionDialog / INSTALL_FAILED_DEPRECATED_SDK_VERSION on API 28+
Expand Down
7 changes: 5 additions & 2 deletions leakcanary/leakcanary-app-aidl/api/leakcanary-app-aidl.api
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
public abstract interface class org/leakcanary/internal/LeakUiApp : android/os/IInterface {
public static final field DESCRIPTOR Ljava/lang/String;
public abstract fun sendHeapAnalysis (Lorg/leakcanary/internal/ParcelableHeapAnalysis;Landroid/net/Uri;)V
}

Expand All @@ -12,9 +13,11 @@ public abstract class org/leakcanary/internal/LeakUiApp$Stub : android/os/Binder
public fun <init> ()V
public fun asBinder ()Landroid/os/IBinder;
public static fun asInterface (Landroid/os/IBinder;)Lorg/leakcanary/internal/LeakUiApp;
public static fun getDefaultImpl ()Lorg/leakcanary/internal/LeakUiApp;
public fun onTransact (ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
public static fun setDefaultImpl (Lorg/leakcanary/internal/LeakUiApp;)Z
}

public class org/leakcanary/internal/LeakUiApp$_Parcel {
public fun <init> ()V
}

public final class org/leakcanary/internal/ParcelableHeapAnalysis : android/os/Parcelable {
Expand Down
6 changes: 3 additions & 3 deletions leakcanary/leakcanary-app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ android {
kotlinCompilerExtensionVersion = "1.4.7"
}

packagingOptions {
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
Expand Down Expand Up @@ -94,9 +94,9 @@ dependencies {
debugImplementation("androidx.compose.ui:ui-test-manifest:${libs.versions.compose.get()}")
// TODO Split out what's included in debug vs the subset for release
implementation(projects.leakcanary.leakcanaryAndroid)
implementation("com.google.dagger:hilt-android:2.43.2")
implementation(libs.hilt.android)
implementation(libs.okio2)
kapt("com.google.dagger:hilt-compiler:2.43.2")
kapt(libs.hilt.compiler)
}

kapt {
Expand Down
5 changes: 5 additions & 0 deletions object-watcher/object-watcher-android-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ android {
resourcePrefix = "leak_canary_watcher_"
compileSdk = libs.versions.androidCompileSdk.get().toInt()

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

defaultConfig {
minSdk = libs.versions.androidMinSdk.get().toInt()
consumerProguardFiles("consumer-proguard-rules.pro")
Expand Down
5 changes: 5 additions & 0 deletions object-watcher/object-watcher-android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ android {
resourcePrefix = "leak_canary_watcher_"
compileSdk = libs.versions.androidCompileSdk.get().toInt()

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

defaultConfig {
minSdk = libs.versions.androidMinSdk.get().toInt()
consumerProguardFiles("consumer-proguard-rules.pro")
Expand Down
6 changes: 6 additions & 0 deletions plumber/plumber-android-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ dependencies {
android {
resourcePrefix = "leak_canary_plumber"
compileSdk = libs.versions.androidCompileSdk.get().toInt()

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

defaultConfig {
minSdk = libs.versions.androidMinSdk.get().toInt()
consumerProguardFiles("consumer-proguard-rules.pro")
Expand Down
2 changes: 1 addition & 1 deletion samples/leakcanary-android-sample/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ android {
}
}
namespace = "com.example.leakcanary"
testNamespace = "com.squareup.leakcanary.instrumentation.test"
testNamespace = "com.example.leakcanary.test"
lint {
disable += "GoogleAppIndexingWarning"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package leakcanary.tests
package com.example.leakcanary.test

import androidx.test.ext.junit.rules.ActivityScenarioRule
import com.example.leakcanary.MainActivity
Expand Down
Loading