Skip to content

Instantly share code, notes, and snippets.

View esafirm's full-sized avatar
🏠
Working from home

Esa Firman esafirm

🏠
Working from home
View GitHub Profile
@esafirm
esafirm / LazyPlayerHandle.kt
Last active October 1, 2026 04:18
Truly lazy ExoPlayer via ForwardingSimpleBasePlayer - sanity check
import android.os.Looper
import androidx.annotation.OptIn
import androidx.media3.common.ForwardingSimpleBasePlayer
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.common.SimpleBasePlayer
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.ExoPlayer
import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture
@esafirm
esafirm / save-state-pager-collision-lesson.md
Created August 15, 2026 06:12
BLAN-30244 lesson: SaveStateHelper 'already registered' crash in pager tests — the page-instance identity trap

BLAN-30244 — The "Save bundle: save state provider is already registered" crash in pager tests: the page-instance identity trap

Background

While adding a UI regression test for the pager-in-NavPageDisplay save-state bug (distro dashboard ReleasesPageViewModel — stale filter restored across page instances, fixed in 3c48c7748fb "Different instance of SaveStateHelper for each Page instance"), we hit a crash:

TaggedException: [CRITICAL] Save bundle: save state provider is already registered
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.BlurMaskFilter
import android.graphics.Matrix
import android.view.ViewGroup
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
import androidx.camera.core.ImageProxy
@esafirm
esafirm / FirstFailureMediaFactory.kt
Last active February 3, 2026 08:28
Easy way to simulate a player exception in ExoPlayer
package com.bandlab.media.player
import androidx.media3.common.MediaItem
import androidx.media3.datasource.TransferListener
import androidx.media3.exoplayer.analytics.PlayerId
import androidx.media3.exoplayer.source.MediaSource
import java.util.Random
class FirstFailureMediaSourceFactory(
private val delegate: MediaSource.Factory,
/**
* Parse the result from [apkanalyzer dex packages <apk>] and give us summary about the data
*
* Author @esafirm
*/
// (type/state/defined methods/referenced methods /byte size/name)
// P, C, M, and F indicate packages, classes, methods, and fields, respectively. And x, k, r, and d indicate removed, kept, referenced and defined nodes, respectively.
enum Type {

Multi Flavor App

Using BuildConfig

if (BuildConfig.Theme == "red") {
	RedTheme { ... }
}else {
	GreenTheme { ... }
}
@esafirm
esafirm / jetify.sh
Last active September 23, 2020 03:11
Download AAR and jetify it. Unix only!
#!/usr/bin/env bash
TARGET=temp_target
AAR_URL=$1
TARGET_NAME=$2
ZIP_NAME=jetifier.zip
# Download Jetifier
curl "https://dl.google.com/dl/android/studio/jetifier-zips/1.0.0-beta09/jetifier-standalone.zip" -o $ZIP_NAME
@esafirm
esafirm / drafter.rb
Created May 18, 2020 03:26
Drafter Forumula
require 'formula'
class Drafter < Formula
homepage 'http://apiblueprint.org'
head 'https://github.com/apiaryio/drafter.git', :tag => 'v4.1.0'
def install
system "./configure", "--shared"
system "make", "drafter"
bin.install Dir["bin/drafter"]
class MemoryProfilerRule : TestRule {
override fun apply(base: Statement?, description: Description?): Statement {
return MemoryProfilerWatcher().apply(base, description)
}
private inner class MemoryProfilerWatcher : TestWatcher() {
private val runtime = Runtime.getRuntime()
private var before: Long = 0
@esafirm
esafirm / test_checker.rb
Created February 19, 2020 03:08
Script to test check
#!/usr/bin/env ruby
# frozen_string_literal: true
TARGET_DIR = ARGV[0]
@failing_module = []
@no_test_module = []
def fail_number(file_path)
file = IO.read(file_path)