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

chore: gradient backgrounds support #88

Merged
merged 5 commits into from
Jan 24, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Next

- recording: gradient background support ([#88](https://github.com/PostHog/posthog-android/pull/88))

## 3.1.4 - 2024-01-19

- Set `Content-Length` header for gzip bodies because of more strict proxies ([#86](https://github.com/PostHog/posthog-android/pull/86))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.PorterDuff
import android.graphics.Typeface
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
Expand Down Expand Up @@ -248,7 +250,7 @@ public class PostHogReplayIntegration(
val wireframe = view.toWireframe() ?: return

// if the decorView has no backgroundColor, we use the theme color
if (wireframe.style?.backgroundColor == null || wireframe.style?.backgroundColor == "#ffffff") {
if (wireframe.style?.backgroundColor == null) {
context.theme?.toRGBColor()?.let {
wireframe.style?.backgroundColor = it
}
Expand Down Expand Up @@ -341,8 +343,13 @@ public class PostHogReplayIntegration(
if (view is ViewStub) {
return null
}
if (view.id == android.R.id.statusBarBackground || view.id == android.R.id.navigationBarBackground) {
return null

var type: String? = null
if (view.id == android.R.id.statusBarBackground) {
type = "status_bar"
}
if (view.id == android.R.id.navigationBarBackground) {
type = "navigation_bar"
}

val coordinates = IntArray(2)
Expand All @@ -359,14 +366,13 @@ public class PostHogReplayIntegration(
background.toRGBColor()?.let { color ->
style.backgroundColor = color
} ?: run {
style.backgroundColor = "#ffffff"
style.backgroundImage = background.base64(view.width, view.height)
}
}

var checked: Boolean? = null

var text: String? = null
var type: String? = null
var inputType: String? = null
var value: Any? = null
// button inherits from textview
Expand Down Expand Up @@ -514,7 +520,7 @@ public class PostHogReplayIntegration(
type = "image"
if (!view.isNoCapture(config.sessionReplayConfig.maskAllImages)) {
// TODO: we can probably do a LRU caching here for already captured images
base64 = view.drawable?.base64()
base64 = view.drawable?.base64(view.width, view.height)
}
}

Expand Down Expand Up @@ -616,7 +622,9 @@ public class PostHogReplayIntegration(
}
}
color?.let {
return it.defaultColor.toRGBColor()
if (it.defaultColor != -1) {
return it.defaultColor.toRGBColor()
}
}
}
return null
Expand All @@ -628,31 +636,44 @@ public class PostHogReplayIntegration(
this.height > 0
}

private fun Drawable.base64(): String? {
private fun Bitmap.base64(): String? {
if (!isValid()) {
return null
}

ByteArrayOutputStream(allocationByteCount).use {
compress(Bitmap.CompressFormat.PNG, 30, it)
val byteArray = it.toByteArray()
return Base64.encodeToString(byteArray, Base64.DEFAULT)
}
}

private fun Drawable.base64(width: Int, height: Int): String? {
when (this) {
is BitmapDrawable -> {
if (!bitmap.isValid()) {
return null
}

ByteArrayOutputStream(bitmap.allocationByteCount).use {
bitmap.compress(Bitmap.CompressFormat.PNG, 30, it)
val byteArray = it.toByteArray()
return Base64.encodeToString(byteArray, Base64.DEFAULT)
try {
return bitmap.base64()
} catch (_: Throwable) {
// ignore
}
}

is LayerDrawable -> {
return getFirstDrawable()?.base64()
return getFirstDrawable()?.base64(width, height)
}

is InsetDrawable -> {
drawable?.let {
return it.base64()
return it.base64(width, height)
}
}
}
// TODO: vector, gradient drawables

try {
return toBitmap(width, height).base64()
} catch (_: Throwable) {
// ignore
}
return null
}

Expand Down Expand Up @@ -722,6 +743,15 @@ public class PostHogReplayIntegration(
return Triple(addedItems, removedItems, updatedItems)
}

private fun Drawable.toBitmap(width: Int, height: Int): Bitmap {
val bitmap = Bitmap.createBitmap(displayMetrics, width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.MULTIPLY)
setBounds(0, 0, canvas.width, canvas.height)
draw(canvas)
return bitmap
}

private fun MotionEvent.getRawXCompat(index: Int): Float {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
getRawX(index)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class MyApp : Application() {
// remove("\$device_name")
}
}
sessionReplayConfig.maskAllTextInputs = true
sessionReplayConfig.maskAllTextInputs = false
sessionReplayConfig.maskAllImages = false
sessionReplayConfig.captureLogcat = true
}
PostHogAndroid.setup(this, config)
Expand Down
23 changes: 13 additions & 10 deletions posthog/api/posthog.api
Original file line number Diff line number Diff line change
Expand Up @@ -464,26 +464,28 @@ public final class com/posthog/internal/replay/RRRemovedNode {

public final class com/posthog/internal/replay/RRStyle {
public fun <init> ()V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/lang/String;
public final fun component10 ()Ljava/lang/Integer;
public final fun component10 ()Ljava/lang/String;
public final fun component11 ()Ljava/lang/Integer;
public final fun component12 ()Ljava/lang/Integer;
public final fun component13 ()Ljava/lang/Integer;
public final fun component14 ()Ljava/lang/String;
public final fun component14 ()Ljava/lang/Integer;
public final fun component15 ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Ljava/lang/Integer;
public final fun component3 ()Ljava/lang/String;
public final fun component4 ()Ljava/lang/Integer;
public final fun component5 ()Ljava/lang/String;
public final fun component6 ()Ljava/lang/Integer;
public final fun component7 ()Ljava/lang/String;
public final fun component5 ()Ljava/lang/Integer;
public final fun component6 ()Ljava/lang/String;
public final fun component7 ()Ljava/lang/Integer;
public final fun component8 ()Ljava/lang/String;
public final fun component9 ()Ljava/lang/String;
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;)Lcom/posthog/internal/replay/RRStyle;
public static synthetic fun copy$default (Lcom/posthog/internal/replay/RRStyle;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;ILjava/lang/Object;)Lcom/posthog/internal/replay/RRStyle;
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;)Lcom/posthog/internal/replay/RRStyle;
public static synthetic fun copy$default (Lcom/posthog/internal/replay/RRStyle;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;ILjava/lang/Object;)Lcom/posthog/internal/replay/RRStyle;
public fun equals (Ljava/lang/Object;)Z
public final fun getBackgroundColor ()Ljava/lang/String;
public final fun getBackgroundImage ()Ljava/lang/String;
public final fun getBar ()Ljava/lang/String;
public final fun getBorderColor ()Ljava/lang/String;
public final fun getBorderRadius ()Ljava/lang/Integer;
Expand All @@ -499,6 +501,7 @@ public final class com/posthog/internal/replay/RRStyle {
public final fun getVerticalAlign ()Ljava/lang/String;
public fun hashCode ()I
public final fun setBackgroundColor (Ljava/lang/String;)V
public final fun setBackgroundImage (Ljava/lang/String;)V
public final fun setBar (Ljava/lang/String;)V
public final fun setBorderColor (Ljava/lang/String;)V
public final fun setBorderRadius (Ljava/lang/Integer;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.posthog.PostHogInternal
public data class RRStyle(
public var color: String? = null,
public var backgroundColor: String? = null,
public var backgroundImage: String? = null,
public var borderWidth: Int? = null,
public var borderRadius: Int? = null,
public var borderColor: String? = null,
Expand Down
Loading