main

square/leakcanary

Last updated at: 29/12/2023 09:37

RemoteHeapAnalyzerWorker.kt

TLDR

This file contains the implementation of the RemoteHeapAnalyzerWorker class, which extends the RemoteListenableWorker class from the Android WorkManager library. It provides methods for starting remote work and obtaining foreground information for heap analysis.

Classes

RemoteHeapAnalyzerWorker

This class is responsible for performing heap analysis on a remote device using the WorkManager library. It extends the RemoteListenableWorker class and provides implementation for the startRemoteWork and getForegroundInfoAsync methods.

The startRemoteWork method retrieves a heap dump from the input data, runs the analysis in a background thread, and sends progress events if the analysis is not canceled. If the analysis is canceled, a debug message is logged. Finally, the method sets the result to success or cancellation accordingly.

The getForegroundInfoAsync method retrieves the foreground information for heap analysis from the application context.

package leakcanary.internal

import android.content.Context
import androidx.work.ForegroundInfo
import androidx.work.WorkerParameters
import androidx.work.impl.utils.futures.SettableFuture
import androidx.work.multiprocess.RemoteListenableWorker
import com.google.common.util.concurrent.ListenableFuture
import leakcanary.BackgroundThreadHeapAnalyzer.heapAnalyzerThreadHandler
import leakcanary.EventListener.Event.HeapDump
import leakcanary.internal.HeapAnalyzerWorker.Companion.asEvent
import leakcanary.internal.HeapAnalyzerWorker.Companion.heapAnalysisForegroundInfoAsync
import shark.SharkLog

internal class RemoteHeapAnalyzerWorker(appContext: Context, workerParams: WorkerParameters) :
  RemoteListenableWorker(appContext, workerParams) {

  override fun startRemoteWork(): ListenableFuture<Result> {
    val heapDump = inputData.asEvent<HeapDump>()
    val result = SettableFuture.create<Result>()
    heapAnalyzerThreadHandler.post {
      val doneEvent = AndroidDebugHeapAnalyzer.runAnalysisBlocking(heapDump, isCanceled = {
        result.isCancelled
      }) { progressEvent ->
        if (!result.isCancelled) {
          InternalLeakCanary.sendEvent(progressEvent)
        }
      }
      if (result.isCancelled) {
        SharkLog.d { "Remote heap analysis for ${heapDump.file} was canceled" }
      } else {
        InternalLeakCanary.sendEvent(doneEvent)
        result.set(Result.success())
      }
    }
    return result
  }

  override fun getForegroundInfoAsync(): ListenableFuture<ForegroundInfo> {
    return applicationContext.heapAnalysisForegroundInfoAsync()
  }
}