Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iterating on alpha2 APIs #2665

Merged
merged 4 commits into from
May 3, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ jobs:
touch emulator.log # create log file
chmod 777 emulator.log # allow writing to log file
adb logcat >> emulator.log & # pipe all logcat messages into log file as a background process
./gradlew leakcanary:leakcanary-android-core:connectedCheck leakcanary:leakcanary-android:connectedCheck leakcanary:leakcanary-android-instrumentation:connectedCheck --no-build-cache --no-daemon --stacktrace
./gradlew leakcanary:leakcanary-android-debug:connectedCheck leakcanary:leakcanary-android:connectedCheck leakcanary:leakcanary-android-instrumentation:connectedCheck --no-build-cache --no-daemon --stacktrace
- name: Upload results
if: ${{ always() }}
uses: actions/upload-artifact@v3
Expand Down
4 changes: 2 additions & 2 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ dependencies {
}
```

Note 1: `leakcanary-android` adds the code for automatic installl to `leakcanary-android-core`. If you're calling `AppWatcher.manualInstall()`, you can depend directly on `leakcanary-android-core` instead of `leakcanary-android`, and you won't need the disable any automatic install.
Note 1: `leakcanary-android` adds the code for automatic install to `leakcanary-android-core`. If you're calling `AppWatcher.manualInstall()`, you can depend directly on `leakcanary-android-core` instead of `leakcanary-android`, and you won't need the disable any automatic install.

Note 2: the same principle applies to `leakcanary-object-watcher-android`: it depends on `leakcanary-object-watcher-android-core` and adds automatic install, while `leakcanary-object-watcher-android-startup` leverages the App Startup library. Same for `plumber-android`, `plumber-android-core` and `plumber-android-startup`.

Expand Down Expand Up @@ -1432,7 +1432,7 @@ For more details, see the [2.0-beta-2 Milestone](https://github.com/square/leakc

* New standalone library! [Shark](shark.md) is the heap analyzer that powers LeakCanary 2, and it can run in any Java VM. It comes with a [CLI](shark.md#shark-cli): you can now run `shark-cli analyze-process com.example.myapp` from your computer.
* New Heap Explorer directly on device! Open a Heap Analysis in LeakCanary, tap the options menu and select "Heap Explorer". This is still experimental and not very user friendly, contributions welcome!
* **Large API rewrite** to improve usability. If you used the alpha with a customized configuration, there are breaking changes. Of note: LeakSentry became [AppWatcher](/leakcanary/api/leakcanary-object-watcher-android/leakcanary/-app-watcher/), RefWatcher became [ObjectWatcher](/leakcanary/api/leakcanary-object-watcher/leakcanary/-object-watcher/), AndroidExcludedRefs became [AndroidReferenceMatchers](/leakcanary/api/shark-android/shark/-android-reference-matchers/), AnalysisResultListener became [OnHeapAnalyzedListener](/leakcanary/api/leakcanary-android-core/leakcanary/-on-heap-analyzed-listener/), AndroidLeakTraceInspectors became [AndroidObjectInspectors](/leakcanary/api/shark-android/shark/-android-object-inspectors/).
* **Large API rewrite** to improve usability. If you used the alpha with a customized configuration, there are breaking changes. Of note: LeakSentry became [AppWatcher](/leakcanary/api/leakcanary-object-watcher-android/leakcanary/-app-watcher/), RefWatcher became [ObjectWatcher](/leakcanary/api/leakcanary-object-watcher/leakcanary/-object-watcher/), AndroidExcludedRefs became [AndroidReferenceMatchers](/leakcanary/api/shark-android/shark/-android-reference-matchers/), AnalysisResultListener became [OnHeapAnalyzedListener](/leakcanary/api/leakcanary-android-debug/leakcanary/-on-heap-analyzed-listener/), AndroidLeakTraceInspectors became [AndroidObjectInspectors](/leakcanary/api/shark-android/shark/-android-object-inspectors/).
* The entire API surface is now documented and the documentation is available on this website: see the **LeakCanary API** tab at the top.
* Removed the **dependency on Android X**. No more configuration issues! [#1462](https://github.com/square/leakcanary/issues/1462)
* Added **Proguard rules** for LeakCanary and ObjectWatcher. [#1500](https://github.com/square/leakcanary/pull/1500)
Expand Down
6 changes: 3 additions & 3 deletions docs/dev-env.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
* We use two spaces code indentation, use `SquareAndroid` code style settings from https://github.com/square/java-code-styles.
* Build with `./gradlew build`.
* Running the failing UI tests to confirm leak detection correctly fails UI tests: `./gradlew leakcanary-android-sample:connectedCheck`.
* Normal UI tests: `./gradlew leakcanary-android-core:connectedCheck`.
* Normal UI tests: `./gradlew leakcanary-android-debug:connectedCheck`.

## Static Code Analysis
## Static Code Analysis
* LeakCanary [uses](https://github.com/square/leakcanary/pull/1535) [Detekt](https://arturbosch.github.io/detekt/) for static Code analysis.
* Analyze the entire project with `./gradlew check` or particular modules with `./gradlew :module-name:check`. Detekt will fail the build if any ruleset violations are found. **You should fix all issues before pushing the branch to remote**.
* There's also a **git pre-push** hook that will run analysis automatically before pushing a branch to the remote. If there are any violations - it will prevent the push. Fix the issues!
* You can bypass the git hook though; Travis CI will still run checks and will fail if any violations are found.
* You can bypass the git hook though; Travis CI will still run checks and will fail if any violations are found.
* Detekt report will be printed in the console and saved to `/moduleDir/build/reports/`.

## Deploying locally
Expand Down
2 changes: 1 addition & 1 deletion docs/upgrading-to-leakcanary-2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class DebugExampleApplication : ExampleApplication() {
}
```

LeakCanary is in charge of taking heap dumps and analyzing them. Its configuration can be updated at any time by replacing [LeakCanary.config](/leakcanary/api/leakcanary-android-core/leakcanary/-leak-canary/config/):
LeakCanary is in charge of taking heap dumps and analyzing them. Its configuration can be updated at any time by replacing [LeakCanary.config](/leakcanary/api/leakcanary-android-debug/leakcanary/-leak-canary/config/):

```kotlin
disableLeakCanaryButton.setOnClickListener {
Expand Down
163 changes: 4 additions & 159 deletions leakcanary/leakcanary-android-core/api/leakcanary-android-core.api
Original file line number Diff line number Diff line change
@@ -1,169 +1,14 @@
public final class com/squareup/leakcanary/core/BuildConfig {
public static final field BUILD_TYPE Ljava/lang/String;
public static final field DEBUG Z
public static final field GIT_SHA Ljava/lang/String;
public static final field LIBRARY_PACKAGE_NAME Ljava/lang/String;
public static final field LIBRARY_VERSION Ljava/lang/String;
public fun <init> ()V
}

public final class leakcanary/AndroidDebugHeapDumper : leakcanary/HeapDumper {
public static final field INSTANCE Lleakcanary/AndroidDebugHeapDumper;
public fun dumpHeap (Ljava/io/File;)V
}

public final class leakcanary/AndroidDebugHeapDumperKt {
public static final fun androidDumper (Lleakcanary/HeapDumper$Companion;)Lleakcanary/AndroidDebugHeapDumper;
}

public final class leakcanary/BackgroundThreadHeapAnalyzer : leakcanary/EventListener {
public static final field INSTANCE Lleakcanary/BackgroundThreadHeapAnalyzer;
public fun onEvent (Lleakcanary/EventListener$Event;)V
}

public abstract interface class leakcanary/EventListener {
public abstract fun onEvent (Lleakcanary/EventListener$Event;)V
}

public abstract class leakcanary/EventListener$Event : java/io/Serializable {
public synthetic fun <init> (Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getUniqueId ()Ljava/lang/String;
}

public final class leakcanary/EventListener$Event$DumpingHeap : leakcanary/EventListener$Event {
public fun <init> (Ljava/lang/String;)V
}

public abstract class leakcanary/EventListener$Event$HeapAnalysisDone : leakcanary/EventListener$Event {
public synthetic fun <init> (Ljava/lang/String;Lshark/HeapAnalysis;Landroid/content/Intent;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getHeapAnalysis ()Lshark/HeapAnalysis;
public final fun getShowIntent ()Landroid/content/Intent;
}

public final class leakcanary/EventListener$Event$HeapAnalysisDone$HeapAnalysisFailed : leakcanary/EventListener$Event$HeapAnalysisDone {
public fun <init> (Ljava/lang/String;Lshark/HeapAnalysisFailure;Landroid/content/Intent;)V
}

public final class leakcanary/EventListener$Event$HeapAnalysisDone$HeapAnalysisSucceeded : leakcanary/EventListener$Event$HeapAnalysisDone {
public fun <init> (Ljava/lang/String;Lshark/HeapAnalysisSuccess;Ljava/util/Set;Landroid/content/Intent;)V
public final fun getUnreadLeakSignatures ()Ljava/util/Set;
}

public final class leakcanary/EventListener$Event$HeapAnalysisProgress : leakcanary/EventListener$Event {
public fun <init> (Ljava/lang/String;Lshark/OnAnalysisProgressListener$Step;D)V
public final fun getProgressPercent ()D
public final fun getStep ()Lshark/OnAnalysisProgressListener$Step;
}

public final class leakcanary/EventListener$Event$HeapDump : leakcanary/EventListener$Event {
public fun <init> (Ljava/lang/String;Ljava/io/File;JLjava/lang/String;)V
public final fun getDurationMillis ()J
public final fun getFile ()Ljava/io/File;
public final fun getReason ()Ljava/lang/String;
}

public final class leakcanary/EventListener$Event$HeapDumpFailed : leakcanary/EventListener$Event {
public fun <init> (Ljava/lang/String;Ljava/lang/Throwable;Z)V
public final fun getException ()Ljava/lang/Throwable;
public final fun getWillRetryLater ()Z
}

public final class leakcanary/LazyForwardingEventListener : leakcanary/EventListener {
public fun <init> (Lkotlin/jvm/functions/Function0;)V
public fun onEvent (Lleakcanary/EventListener$Event;)V
}

public final class leakcanary/LeakCanary {
public static final field INSTANCE Lleakcanary/LeakCanary;
public final fun dumpHeap ()V
public static final fun getConfig ()Lleakcanary/LeakCanary$Config;
public final fun newLeakDisplayActivityIntent ()Landroid/content/Intent;
public static final fun setConfig (Lleakcanary/LeakCanary$Config;)V
public final fun showLeakDisplayActivityLauncherIcon (Z)V
}

public final class leakcanary/LeakCanary$Config {
public fun <init> ()V
public fun <init> (ZZILjava/util/List;Ljava/util/List;Lshark/MetadataExtractor;ZIZLshark/LeakingObjectFinder;Lleakcanary/HeapDumper;Ljava/util/List;Z)V
public synthetic fun <init> (ZZILjava/util/List;Ljava/util/List;Lshark/MetadataExtractor;ZIZLshark/LeakingObjectFinder;Lleakcanary/HeapDumper;Ljava/util/List;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Z
public final fun component10 ()Lshark/LeakingObjectFinder;
public final fun component11 ()Lleakcanary/HeapDumper;
public final fun component12 ()Ljava/util/List;
public final fun component13 ()Z
public final fun component2 ()Z
public final fun component3 ()I
public final fun component4 ()Ljava/util/List;
public final fun component5 ()Ljava/util/List;
public final fun component6 ()Lshark/MetadataExtractor;
public final fun component7 ()Z
public final fun component8 ()I
public final fun component9 ()Z
public final fun copy (ZZILjava/util/List;Ljava/util/List;Lshark/MetadataExtractor;ZIZLshark/LeakingObjectFinder;Lleakcanary/HeapDumper;Ljava/util/List;Z)Lleakcanary/LeakCanary$Config;
public static synthetic fun copy$default (Lleakcanary/LeakCanary$Config;ZZILjava/util/List;Ljava/util/List;Lshark/MetadataExtractor;ZIZLshark/LeakingObjectFinder;Lleakcanary/HeapDumper;Ljava/util/List;ZILjava/lang/Object;)Lleakcanary/LeakCanary$Config;
public fun equals (Ljava/lang/Object;)Z
public final fun getComputeRetainedHeapSize ()Z
public final fun getDumpHeap ()Z
public final fun getDumpHeapWhenDebugging ()Z
public final fun getEventListeners ()Ljava/util/List;
public final fun getHeapDumper ()Lleakcanary/HeapDumper;
public final fun getLeakingObjectFinder ()Lshark/LeakingObjectFinder;
public final fun getMaxStoredHeapDumps ()I
public final fun getMetadataExtractor ()Lshark/MetadataExtractor;
public final fun getObjectInspectors ()Ljava/util/List;
public final fun getReferenceMatchers ()Ljava/util/List;
public final fun getRequestWriteExternalStoragePermission ()Z
public final fun getRetainedVisibleThreshold ()I
public final fun getShowNotifications ()Z
public fun hashCode ()I
public final fun newBuilder ()Lleakcanary/LeakCanary$Config$Builder;
public fun toString ()Ljava/lang/String;
}

public final class leakcanary/LeakCanary$Config$Builder {
public final fun build ()Lleakcanary/LeakCanary$Config;
public final fun computeRetainedHeapSize (Z)Lleakcanary/LeakCanary$Config$Builder;
public final fun dumpHeap (Z)Lleakcanary/LeakCanary$Config$Builder;
public final fun dumpHeapWhenDebugging (Z)Lleakcanary/LeakCanary$Config$Builder;
public final fun eventListeners (Ljava/util/List;)Lleakcanary/LeakCanary$Config$Builder;
public final fun heapDumper (Lleakcanary/HeapDumper;)Lleakcanary/LeakCanary$Config$Builder;
public final fun leakingObjectFinder (Lshark/LeakingObjectFinder;)Lleakcanary/LeakCanary$Config$Builder;
public final fun maxStoredHeapDumps (I)Lleakcanary/LeakCanary$Config$Builder;
public final fun metadataExtractor (Lshark/MetadataExtractor;)Lleakcanary/LeakCanary$Config$Builder;
public final fun objectInspectors (Ljava/util/List;)Lleakcanary/LeakCanary$Config$Builder;
public final fun referenceMatchers (Ljava/util/List;)Lleakcanary/LeakCanary$Config$Builder;
public final fun requestWriteExternalStoragePermission (Z)Lleakcanary/LeakCanary$Config$Builder;
public final fun retainedVisibleThreshold (I)Lleakcanary/LeakCanary$Config$Builder;
public final fun showNotifications (Z)Lleakcanary/LeakCanary$Config$Builder;
}

public final class leakcanary/LogcatEventListener : leakcanary/EventListener {
public static final field INSTANCE Lleakcanary/LogcatEventListener;
public fun onEvent (Lleakcanary/EventListener$Event;)V
}

public final class leakcanary/NotificationEventListener : leakcanary/EventListener {
public static final field INSTANCE Lleakcanary/NotificationEventListener;
public fun onEvent (Lleakcanary/EventListener$Event;)V
}

public final class leakcanary/RemoteWorkManagerHeapAnalyzer : leakcanary/EventListener {
public static final field INSTANCE Lleakcanary/RemoteWorkManagerHeapAnalyzer;
public fun onEvent (Lleakcanary/EventListener$Event;)V
}

public final class leakcanary/ToastEventListener : leakcanary/EventListener {
public static final field INSTANCE Lleakcanary/ToastEventListener;
public fun onEvent (Lleakcanary/EventListener$Event;)V
}

public final class leakcanary/TvEventListener : leakcanary/EventListener {
public static final field INSTANCE Lleakcanary/TvEventListener;
public fun onEvent (Lleakcanary/EventListener$Event;)V
public static final fun forAndroidInProcess (Lleakcanary/HeapDumper$Companion;)Lleakcanary/AndroidDebugHeapDumper;
}

public final class leakcanary/WorkManagerHeapAnalyzer : leakcanary/EventListener {
public static final field INSTANCE Lleakcanary/WorkManagerHeapAnalyzer;
public fun onEvent (Lleakcanary/EventListener$Event;)V
public final class leakcanary/RepeatingAndroidInProcessScenarioKt {
public static final fun repeatingAndroidInProcessScenario (Lshark/ObjectGrowthDetector;II)Lshark/RepeatingScenarioObjectGrowthDetector;
public static synthetic fun repeatingAndroidInProcessScenario$default (Lshark/ObjectGrowthDetector;IIILjava/lang/Object;)Lshark/RepeatingScenarioObjectGrowthDetector;
}

45 changes: 3 additions & 42 deletions leakcanary/leakcanary-android-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,55 +5,16 @@ plugins {
}

dependencies {
api projects.shark.sharkAndroid
api projects.objectWatcher.objectWatcherAndroidCore
api projects.objectWatcher.objectWatcherAndroidAndroidx
api projects.leakcanary.leakcanaryCore
implementation libs.kotlin.stdlib

// Optional dependency
compileOnly libs.androidX.work.runtime
compileOnly libs.androidX.work.multiprocess

testImplementation libs.assertjCore
testImplementation libs.junit
testImplementation libs.kotlin.reflect
testImplementation libs.mockito
testImplementation libs.mockitoKotlin
androidTestImplementation libs.androidX.test.espresso
androidTestImplementation libs.androidX.test.rules
androidTestImplementation libs.androidX.test.runner
androidTestImplementation libs.assertjCore
androidTestImplementation projects.shark.sharkHprofTest
androidTestUtil libs.androidX.test.orchestrator
}

def gitSha() {
return 'git rev-parse --short HEAD'.execute().text.trim()
api projects.shark.sharkAndroid
}

android {
resourcePrefix 'leak_canary_'
compileSdk versions.compileSdk
defaultConfig {
minSdk versions.minSdk
// Avoid DeprecatedTargetSdkVersionDialog during UI tests
targetSdk versions.compileSdk
buildConfigField "String", "LIBRARY_VERSION", "\"${rootProject.ext.VERSION_NAME}\""
buildConfigField "String", "GIT_SHA", "\"${gitSha()}\""
consumerProguardFiles 'consumer-proguard-rules.pro'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

testInstrumentationRunnerArguments clearPackageData: 'true'
testOptions {
execution 'ANDROIDX_TEST_ORCHESTRATOR'
}
minSdk versions.minSdk
}
buildFeatures.buildConfig = false
namespace 'com.squareup.leakcanary.core'
testNamespace 'com.squareup.leakcanary.core.test'
lint {
checkOnly 'Interoperability'
disable 'GoogleAppIndexingWarning'
error 'ObsoleteSdkInt'
}
}
2 changes: 1 addition & 1 deletion leakcanary/leakcanary-android-core/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
POM_ARTIFACT_ID=leakcanary-android-core
POM_NAME=LeakCanary for Android - Core
POM_NAME=LeakCanary Android - Core
POM_PACKAGING=aar