Skip to content

Release PT 2.4.0#989

Merged
Anush-Shand merged 25 commits intomasterfrom
develop
Apr 13, 2026
Merged

Release PT 2.4.0#989
Anush-Shand merged 25 commits intomasterfrom
develop

Conversation

@Anush-Shand
Copy link
Copy Markdown
Contributor

@Anush-Shand Anush-Shand commented Apr 13, 2026

Summary by CodeRabbit

  • New Features

    • Introduced vertical image push notification template supporting multiple images, action buttons, gradient backgrounds, rounded corners, and configurable button border styling.
    • Enhanced timer template with customizable chronometer styling including border color, radius, width, gradient backgrounds, and style options.
  • Bug Fixes

    • Improved exception logging and error handling across geofence and notification components for better diagnostics.

deeksha-rgb and others added 25 commits February 11, 2026 14:31
…trace-hms

fix(SDK-5461): Remove printStackTrace from HMS module
…trace-geofence

bug(SDK-5461): Remove printStackTrace usage from Geofence module
* task(SDK-5545) - Vertical Template Implementation

* task(SDK-5618) - Fixes button layout_width

* task(SDK-5545) - Improves layout

* task(SDK-5545) - Default Alt Text Fix

* task(SDK-5545) - Adds tests for Vertical Template

* task(SDK-5545) - Adds default colours

* task(SDK-5545) - Rounded corners by default

* task(SDK-5545) - Adds pt_ prefix

* task(SDK-5545) - Code reuse

* task(SDK-5545) - Improves signature of VerticalImageButtonData

* task(SDK-5545) - Adds log for early return

* task(SDK-5545) - Accepts gradient direction in degrees for linear gradient

* task(SDK-5545) - Allows null deeplink to navigate to app by default

(cherry picked from commit e730050)
   feat(SDK-5618): Timer Template chronometer enhancements
  - Added configurable border radius for chronometer box (pt_chrono_border_radius)
  - Added configurable border width for chronometer box (pt_chrono_border_width)
  - Added gradient support for chronometer background (pt_chrono_style, pt_chrono_grad_clr1, pt_chrono_grad_clr2, pt_chrono_grad_dir)
  - Added solid border color support (pt_chrono_border_clr)
  - Fixed border overlap bug for solid and gradient styles
  - Improved null safety (replaced !! with elvis operator for timer_end)
  - Removed unnecessary timer_container wrapper layout
  - Segmented HRS/MIN/SEC design deferred to future release (preserved on task/SDK-5618/segmented-timer-design)

(cherry picked from commit 5307b0e)
(cherry picked from commit 58b02b1)
* chore/pt - Removes api-23-checks

* task(SDK-5658) - Vertical Template Button Click

* task(SDK-5658) - Vertical Template Button Click fix for notification clicked event

(cherry picked from commit b95190c)
(cherry picked from commit 9be3a54)
(cherry picked from commit cc4310f)
…ements (#984)

* add unit tests for timer template chronometer enhancements

* add unit tests for NotificationBitmapUtils

* recycle bitmaps in teardown to prevent memory leaks

(cherry picked from commit 114ed7c)
(cherry picked from commit b7169b5)
…emplates SDK version 2.3.0 → 2.4. - Add v2.4.0 entry to PT changelog (Image with CTA template, Timer enhancements)

 - Update integration doc with new PT version
 - Add release date entry to root CHANGELOG.md
* task(SDK-5545) - Vertical Template Implementation (#965)

* task(SDK-5545) - Vertical Template Implementation

* task(SDK-5618) - Fixes button layout_width

* task(SDK-5545) - Improves layout

* task(SDK-5545) - Default Alt Text Fix

* task(SDK-5545) - Adds tests for Vertical Template

* task(SDK-5545) - Adds default colours

* task(SDK-5545) - Rounded corners by default

* task(SDK-5545) - Adds pt_ prefix

* task(SDK-5545) - Code reuse

* task(SDK-5545) - Improves signature of VerticalImageButtonData

* task(SDK-5545) - Adds log for early return

* task(SDK-5545) - Accepts gradient direction in degrees for linear gradient

* task(SDK-5545) - Allows null deeplink to navigate to app by default

(cherry picked from commit e730050)

* Merge pull request #967 from CleverTap/task/SDK-5618/timer-template-d

   feat(SDK-5618): Timer Template chronometer enhancements
  - Added configurable border radius for chronometer box (pt_chrono_border_radius)
  - Added configurable border width for chronometer box (pt_chrono_border_width)
  - Added gradient support for chronometer background (pt_chrono_style, pt_chrono_grad_clr1, pt_chrono_grad_clr2, pt_chrono_grad_dir)
  - Added solid border color support (pt_chrono_border_clr)
  - Fixed border overlap bug for solid and gradient styles
  - Improved null safety (replaced !! with elvis operator for timer_end)
  - Removed unnecessary timer_container wrapper layout
  - Segmented HRS/MIN/SEC design deferred to future release (preserved on task/SDK-5618/segmented-timer-design)

(cherry picked from commit 5307b0e)

* fixed test issues

(cherry picked from commit 58b02b1)

* chore/pt - Removes api-23-checks (#975)

* chore/pt - Removes api-23-checks

* task(SDK-5658) - Vertical Template Button Click

* task(SDK-5658) - Vertical Template Button Click fix for notification clicked event

(cherry picked from commit b95190c)

* task(SDK-5544) - Adds tracking of wzrk_c2a for vertical template

(cherry picked from commit 3b597b8)

* task(SDK-5544) - PR comments

(cherry picked from commit 9be3a54)

* task(SDK-5544) - Fixes a test

(cherry picked from commit cc4310f)

* test(SDK-5618): add unit tests for timer template chronometer enhancements (#984)

* add unit tests for timer template chronometer enhancements

* add unit tests for NotificationBitmapUtils

* recycle bitmaps in teardown to prevent memory leaks

(cherry picked from commit 114ed7c)

* task(CMS-1607) - Makes border radius and border width configurable

(cherry picked from commit c834cbd)

* task(CMS-1607) - Adds tests

(cherry picked from commit b7169b5)

* chore(pt): bump version to 2.4.0 and update changelogs                                       - Bump push templates SDK version 2.3.0 → 2.4. - Add v2.4.0 entry to PT changelog (Image with CTA template, Timer enhancements)
 - Update integration doc with new PT version
 - Add release date entry to root CHANGELOG.md

---------

Co-authored-by: Anush-Shand <127097095+Anush-Shand@users.noreply.github.com>
Co-authored-by: deeksha-rgb <deeksha@clevertap.com>
Co-authored-by: anush <anush@clevertap.com>
@francispereira
Copy link
Copy Markdown

francispereira commented Apr 13, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 13, 2026

Walkthrough

CleverTap Push Templates SDK v2.4.0 introduces a new vertical image template type with configurable media, text, and styled buttons. Enhancements include timer chronometer styling with border and gradient controls. Stack-trace printing replaced with structured logger calls across modules. Notification click handling explicitly invoked in service. API-level guards simplified.

Changes

Cohort / File(s) Summary
Documentation & Changelog
CHANGELOG.md, docs/CTPUSHTEMPLATES.md, docs/CTPUSHTEMPLATESCHANGELOG.md, templates/CTPUSHTEMPLATESCHANGELOG.md, gradle/libs.versions.toml
Updated version references to 2.4.0 and added changelog entries documenting new vertical image template and enhanced timer styling features.
Logging Refactoring (Geofence Module)
clevertap-geofence/src/main/java/com/clevertap/android/geofence/BackgroundLocationWork.java, CTGeofenceAPI.java, CTGeofenceBootReceiver.java, CTGeofenceReceiver.java, CTLocationUpdateReceiver.java, GeofenceUpdateTask.java, GoogleGeofenceAdapter.java, GoogleLocationAdapter.java, PushGeofenceEventTask.java, PushLocationEventTask.java, Utils.java, model/CTGeofence.java
Systematically replaced e.printStackTrace() calls with structured logger.debug(..., e) calls; removed direct stack-trace printing while preserving exception information in logs.
Logging Refactoring (Core & HMS)
clevertap-core/src/main/java/com/clevertap/android/sdk/pushnotification/CTNotificationIntentService.java, clevertap-hms/src/main/java/com/clevertap/android/hms/CTHmsMessageHandler.java, HmsNotificationParser.java
Removed direct e.printStackTrace() calls; added explicit CleverTapAPI.handleNotificationClicked() call in notification intent handling.
Constants & Type Definitions
clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/PTConstants.java, TemplateType.kt
Added new constants for Vertical Image Template (VT_C2A keys, text fields, button styling) and Timer chronometer styling (border, gradient, color keys); added VERTICAL_IMAGE enum constant and mapping.
Template Data Models
clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/TemplateData.kt
Extended TimerTemplateData with chronometer styling properties (background/border colors, gradient, border radius/width); added ButtonStyle enum; introduced VerticalImageButtonData and VerticalImageTemplateData models.
Template Factory & Routing
clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/TemplateDataFactory.kt, PushTemplateReceiver.java
Added factory methods for vertical image template creation and button data parsing; extended PushTemplateReceiver to handle VERTICAL_IMAGE template type with new handleVerticalImageButtonClick method; removed SDK-version guards and Logger imports; removed fallback NotificationHandler invocations.
Template Rendering & Styling
clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/TemplateRenderer.kt, styles/VerticalImageStyle.kt
Added VerticalImageStyle rendering path; simplified PendingIntent flag construction by removing API-level conditionals; added explicit style imports; created new VerticalImageStyle class that builds small/big RemoteViews, configures pending intents, and disables dismissal.
Bitmap & Visual Utilities
clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/content/NotificationBitmapUtils.kt
New utility object providing solid, linear-gradient, and radial-gradient bitmap generation with support for rounded corners and borders; centralizes bitmap rendering logic for template visuals.
Vertical Image Content Views
clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/content/VerticalImageContentView.kt, VerticalImageBigContentView.kt, VerticalImageSmallContentView.kt
New abstract base class for vertical image templates with button setup logic; concrete implementations for big (full-screen) and small (collapsed) vertical image notifications with media, text, and button configuration.
Timer Content View Updates
clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/content/TimerSmallContentView.kt
Replaced direct chronometer background setting with new setupChronometerBackground routine using bitmap generation based on ButtonStyle (solid, linear-gradient, radial-gradient); enhanced chronometer styling with color and border support.
Pending Intent Factory
clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/content/PendingIntentFactory.kt
Added vertical image pending-intent identifiers (CONTENT and BUTTON); simplified flag construction by unconditionally applying immutable flags; removed SDK-version gates for immutable flag application.
Layout Resources (Timer)
clevertap-pushtemplates/src/main/res/layout.../timer.xml, timer_collapsed.xml
Refactored chronometer layout to use new wrapper container with background ImageView layer; added frame structure for chronometer background bitmap; maintained padding and gravity settings.
Layout Resources (Vertical Image)
clevertap-pushtemplates/src/main/res/layout.../vertical_image_big.xml, vertical_image_small.xml
New layout files for vertical image template: big layout with two-column design (image + text/button), small layout with horizontal layout (text + image + button); support for optional text fields and button configuration.
Color & Drawable Resources
clevertap-pushtemplates/src/main/res/values/colors.xml, values-night/colors.xml, drawable/pt_vertical_img_btn_default_bg.xml
Added button text/background colors for light and dark modes; added drawable resource for default button background with rounded corners.
Template Validators
clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/validators/ValidatorFactory.kt, VerticalImageTemplateValidator.kt
Added vertical image template validation factory method and validator class; validates required base content text and display image URL.
Unit Tests
clevertap-pushtemplates/src/test/java/com/clevertap/android/pushtemplates/TemplateDataFactoryTest.kt, TemplateRendererTest.kt, VerticalImageTemplateValidatorTest.kt, content/NotificationBitmapUtilsTest.kt, UtilsTest.kt
Added comprehensive test coverage for vertical image template creation, rendering, validation, and bitmap utilities; removed legacy API 21 compatibility test; extended timer tests to cover new chronometer styling properties.
Sample App
sample/src/main/java/com/clevertap/demo/ui/main/HomeScreenFragment.kt
Updated clickCommand handler mappings to shift geofence-related command keys and Compose Inbox key (no functional changes).

Sequence Diagram(s)

sequenceDiagram
    participant Receiver as PushTemplateReceiver
    participant Renderer as TemplateRenderer
    participant Factory as TemplateDataFactory
    participant Validator as ValidatorFactory
    participant Style as VerticalImageStyle
    participant BitmapUtil as NotificationBitmapUtils
    participant Intent as PendingIntentFactory
    participant Manager as NotificationManager

    Receiver->>Renderer: renderNotification(templateType, extras)
    Renderer->>Factory: createTemplateData(VERTICAL_IMAGE, extras)
    Factory->>Factory: createVerticalImageTemplateData(...)<br/>with buttonData, text, media
    Factory-->>Renderer: VerticalImageTemplateData
    Renderer->>Validator: getValidator(VerticalImageTemplateData)
    Validator-->>Renderer: VerticalImageTemplateValidator
    Renderer->>Renderer: validate()
    alt Validation Success
        Renderer->>Style: VerticalImageStyle(...).builderFromStyle(...)
        Style->>Style: makeSmallContentRemoteView()
        Style->>BitmapUtil: createSolidBitmap/LinearGradientBitmap(...)
        BitmapUtil-->>Style: Bitmap (button/background)
        Style->>Style: makeBigContentRemoteView()
        Style->>Intent: getPendingIntent(VERTICAL_IMAGE_CONTENT)
        Intent-->>Style: PendingIntent
        Style->>Manager: notify(notificationId, notification)
    else Validation Failure
        Renderer-->>Receiver: null
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

PushTemplates, feature, refactoring

Suggested reviewers

  • piyush-kukadiya
  • CTLalit
  • deeksha-rgb
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.06% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Release PT 2.4.0' clearly and concisely summarizes the main purpose of the pull request: releasing version 2.4.0 of the Push Templates SDK with its new features.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
clevertap-geofence/src/main/java/com/clevertap/android/geofence/CTLocationUpdateReceiver.java (1)

64-69: ⚠️ Potential issue | 🟡 Minor

Align timeout log text with actual limit and log the exception.

Line 66 still says 10 secs, but the timeout constant is 8000 ms (Line 29). Also, the TimeoutException should be logged with e for consistency with the other updated catch blocks.

Suggested patch
-                        } catch (TimeoutException e) {
-                            CTGeofenceAPI.getLogger().debug(CTGeofenceAPI.GEOFENCE_LOG_TAG,
-                                    "Timeout location receiver execution limit of 10 secs");
+                        } catch (TimeoutException e) {
+                            CTGeofenceAPI.getLogger().debug(CTGeofenceAPI.GEOFENCE_LOG_TAG,
+                                    "Timeout location receiver execution limit of 8 secs", e);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@clevertap-geofence/src/main/java/com/clevertap/android/geofence/CTLocationUpdateReceiver.java`
around lines 64 - 69, Update the TimeoutException catch in
CTLocationUpdateReceiver to log the actual timeout value and include the
exception object: change the message that currently says "Timeout location
receiver execution limit of 10 secs" to reflect the timeout constant
(LOCATION_RECEIVER_EXECUTION_TIMEOUT_MS / 1000 or "8 secs") and pass the
exception 'e' into CTGeofenceAPI.getLogger().debug(...) so it matches the other
catch blocks and surfaces the stack trace.
🧹 Nitpick comments (5)
sample/src/main/java/com/clevertap/demo/ui/main/HomeScreenFragment.kt (1)

86-108: Consider de-risking positional command strings.

Routing by hardcoded "sectionIndex-itemIndex" strings is brittle; any list reorder can silently break actions again. Recommend centralizing these IDs as named constants (or moving to typed commands) to reduce drift risk.

♻️ Minimal refactor in this file (named constants)
+private const val CMD_WEBVIEW = "7-0"
+private const val CMD_GEOFENCE_INIT = "8-0"
+private const val CMD_GEOFENCE_TRIGGER = "8-1"
+private const val CMD_GEOFENCE_DEACTIVATE = "8-2"
+private const val CMD_INBOX_COMPOSE = "3-16"

...
-                "7-0" -> startActivity(Intent(activity, WebViewActivity::class.java))
-                "8-0" -> { // init Geofence API
+                CMD_WEBVIEW -> startActivity(Intent(activity, WebViewActivity::class.java))
+                CMD_GEOFENCE_INIT -> { // init Geofence API
...
-                "8-1" -> { // trigger location
+                CMD_GEOFENCE_TRIGGER -> { // trigger location
...
-                "8-2" -> CTGeofenceAPI.getInstance(context).deactivate() // deactivate geofence
-                "3-16" -> startActivity(Intent(activity, CustomInboxComposeActivity::class.java)) // Launch Compose Inbox
+                CMD_GEOFENCE_DEACTIVATE -> CTGeofenceAPI.getInstance(context).deactivate() // deactivate geofence
+                CMD_INBOX_COMPOSE -> startActivity(Intent(activity, CustomInboxComposeActivity::class.java)) // Launch Compose Inbox
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sample/src/main/java/com/clevertap/demo/ui/main/HomeScreenFragment.kt` around
lines 86 - 108, The fragment routes actions by brittle string literals like
"7-0", "8-0", "8-1", "8-2", and "3-16"; replace these inline positional keys
with named constants or a typed command enum/sealed class (e.g.,
COMMAND_WEBVIEW, COMMAND_INIT_GEOFENCE, COMMAND_TRIGGER_LOCATION,
COMMAND_DEACTIVATE_GEOFENCE, COMMAND_COMPOSE_INBOX) and update the when branch
to match against those symbols; locate the routing switch in HomeScreenFragment
(the block referencing cleverTapInstance, checkPermissions(),
requestPermissions(), initCTGeofenceApi(),
CTGeofenceAPI.getInstance(context).triggerLocation(), deactivate(),
startActivity(...)) and change the case labels to use the new constants/enum
values to make the mapping explicit and safer against list reordering.
clevertap-pushtemplates/src/test/java/com/clevertap/android/pushtemplates/TemplateRendererTest.kt (1)

2179-2220: Assert that failed validation never reaches VerticalImageStyle.

These two tests only check that renderNotification() returns null. They would still pass if the renderer instantiated VerticalImageStyle and called builderFromStyle(...) before returning null, so it is worth verifying zero style invocations here.

Test hardening
     every { mockContentValidator.validate() } returns false
+    mockkConstructor(VerticalImageStyle::class)

     val result = templateRendererLocal.renderNotification(
         verticalBundle, context, mockNotificationBuilder, mockConfig, 123
     )

     assertNull(result)
+    verify(exactly = 0) {
+        anyConstructed<VerticalImageStyle>().builderFromStyle(any(), any(), any(), any())
+    }

Apply the same zero-invocation check in the null-validator test.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@clevertap-pushtemplates/src/test/java/com/clevertap/android/pushtemplates/TemplateRendererTest.kt`
around lines 2179 - 2220, Update both tests
(test_renderNotification_vertical_image_template_invalid and
test_renderNotification_vertical_image_template_null_validator) to assert that
no VerticalImageStyle usage occurs: after invoking
TemplateRenderer.renderNotification(...) add a verification that
VerticalImageStyle.builderFromStyle(...) was never called (or that
VerticalImageStyle was not instantiated/used) using the mocking framework; keep
the existing assertions that result is null and reference
TemplateDataFactory.createTemplateData, ValidatorFactory.getValidator and
mockContentValidator.validate to locate the setup to append the zero-invocation
check.
clevertap-pushtemplates/src/test/java/com/clevertap/android/pushtemplates/content/NotificationBitmapUtilsTest.kt (1)

36-270: Assert rendered output, not just bitmap dimensions.

Right now these tests would still pass if each factory returned a same-sized blank bitmap. Sampling a few interior/edge pixels would make the suite catch regressions in solid fill, border rendering, and gradient direction.

Examples
assertEquals(bgColor, bitmap.getPixel(width / 2, height / 2))
assertNotEquals(
    bitmap.getPixel(0, height / 2),
    bitmap.getPixel(width - 1, height / 2)
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@clevertap-pushtemplates/src/test/java/com/clevertap/android/pushtemplates/content/NotificationBitmapUtilsTest.kt`
around lines 36 - 270, Update the tests for
NotificationBitmapUtils.createSolidBitmap, createLinearGradientBitmap, and
createRadialBitmap to assert rendered content not just dimensions: sample
interior pixels (e.g. center) to assert expected fill color (use assertEquals
with bgColor or expected color), sample edge/side pixels to verify border
presence/width (compare edge vs inset pixels or assert border color at 0,x or
x,0), and for gradients sample two distinct points (e.g. left vs right or
diagonal points) and assert they differ with assertNotEquals to validate
direction; modify each relevant test to include one or two pixel-sampling
assertions (using bitmap.getPixel) in addition to the existing size assertions.
clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/content/TimerSmallContentView.kt (1)

66-119: Make the chronometer bitmap size density-aware.

CHRONO_BITMAP_WIDTH and CHRONO_BITMAP_HEIGHT are raw pixels. On higher-density devices this bitmap will be stretched to fit the chronometer bounds, which makes the pill background, border width, and corner radius look inconsistent. Please derive these dimensions from dp/resources before creating the bitmap.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/content/TimerSmallContentView.kt`
around lines 66 - 119, CHRONO_BITMAP_WIDTH and CHRONO_BITMAP_HEIGHT are raw
pixels causing scaling issues; update setupChronometerBackground to compute
density-aware pixel sizes (e.g., convert a DP constant to pixels via
context.resources.displayMetrics.density or a shared Utils.dpToPx method) and
pass those computed px values into
NotificationBitmapUtils.createLinearGradientBitmap / createRadialBitmap /
createSolidBitmap instead of the raw constants; retain the companion dp
constants (or replace them with dp values) and perform the dp->px conversion
inside setupChronometerBackground before creating the bitmap (reference
setupChronometerBackground, CHRONO_BITMAP_WIDTH, CHRONO_BITMAP_HEIGHT, and the
NotificationBitmapUtils.create* methods).
clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/PTConstants.java (1)

129-136: Extract the chronometer radius default here.

6f is now duplicated in TemplateDataFactory.kt Line 294 and TemplateData.kt Line 122. Defining a PT_CHRONO_BORDER_RADIUS_DEFAULT alongside the other template defaults will keep the parser and model from drifting.

♻️ Small follow-up
+    public static final float PT_CHRONO_BORDER_RADIUS_DEFAULT = 6f;

Then reference it from the timer parser/model instead of hardcoding 6f.

Also applies to: 225-227

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/PTConstants.java`
around lines 129 - 136, Add a new default constant in PTConstants (e.g.,
PT_CHRONO_BORDER_RADIUS_DEFAULT) next to the other PT_* defaults and set it to
the shared default value (6f); then update TemplateDataFactory.kt and
TemplateData.kt to reference PTConstants.PT_CHRONO_BORDER_RADIUS_DEFAULT instead
of hardcoding 6f in the chronometer/parser/model, and similarly replace any
other hardcoded template defaults mentioned around PT constants (lines
referenced in the comment) to use corresponding PT_*_DEFAULT constants to avoid
duplication and drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/PushTemplateReceiver.java`:
- Around line 622-649: The code incorrectly treats any non-empty
pt_product_display_linear as "linear" and unguardedly indexes priceList; change
the isLinear computation to parse the boolean value (e.g.,
Boolean.parseBoolean(pt_product_display_linear)) instead of checking emptiness
(use the same pt_product_display_linear variable referenced in the diff), and
before calling contentViewBig.setTextViewText(R.id.product_price,
priceList.get(currentPosition)) validate that priceList != null &&
priceList.size() > currentPosition (or use a safe fallback like empty string or
hide the price view) to avoid IndexOutOfBoundsExceptions; apply these checks
alongside the existing layout switching logic around
setCustomContentViewBasicKeys, contentViewBig, and contentViewSmall.

In `@clevertap-pushtemplates/src/main/res/layout/timer.xml`:
- Around line 62-72: The ImageView with id chronometer_bg is decorative but
lacks an explicit null content description; update the <ImageView
android:id="@+id/chronometer_bg"> element(s) (including the collapsed timer
variants) to add android:contentDescription="@null" so TalkBack treats it as
decorative and does not announce it; keep the existing tools:ignore attributes
intact.

In `@docs/CTPUSHTEMPLATESCHANGELOG.md`:
- Line 5: The documented template id `pt_vertical_image` doesn't match the
runtime parser: update either the docs or the parser so they agree; specifically
either change the changelog entry to `pt_vertical_img` or modify
TemplateType.fromString() to accept `pt_vertical_image` (e.g., add an
alias/branch for that string) so the vertical-image renderer is reachable;
locate TemplateType.fromString() and the changelog mention of
`pt_vertical_image` and make them consistent.

In `@templates/CTPUSHTEMPLATESCHANGELOG.md`:
- Line 5: The changelog entry references the wrong template id; update the
documented template id `pt_vertical_image` to match the actual enum/parser value
`pt_vertical_img` (or alternatively modify the enum/parser to accept
`pt_vertical_image`) so integrators see a working payload; locate references to
`pt_vertical_image` in the changelog and replace them with `pt_vertical_img`, or
update the enum/parser handling where `pt_vertical_img` is defined to also
accept `pt_vertical_image` (ensure both the changelog text and the runtime
enum/parser are consistent).

---

Outside diff comments:
In
`@clevertap-geofence/src/main/java/com/clevertap/android/geofence/CTLocationUpdateReceiver.java`:
- Around line 64-69: Update the TimeoutException catch in
CTLocationUpdateReceiver to log the actual timeout value and include the
exception object: change the message that currently says "Timeout location
receiver execution limit of 10 secs" to reflect the timeout constant
(LOCATION_RECEIVER_EXECUTION_TIMEOUT_MS / 1000 or "8 secs") and pass the
exception 'e' into CTGeofenceAPI.getLogger().debug(...) so it matches the other
catch blocks and surfaces the stack trace.

---

Nitpick comments:
In
`@clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/content/TimerSmallContentView.kt`:
- Around line 66-119: CHRONO_BITMAP_WIDTH and CHRONO_BITMAP_HEIGHT are raw
pixels causing scaling issues; update setupChronometerBackground to compute
density-aware pixel sizes (e.g., convert a DP constant to pixels via
context.resources.displayMetrics.density or a shared Utils.dpToPx method) and
pass those computed px values into
NotificationBitmapUtils.createLinearGradientBitmap / createRadialBitmap /
createSolidBitmap instead of the raw constants; retain the companion dp
constants (or replace them with dp values) and perform the dp->px conversion
inside setupChronometerBackground before creating the bitmap (reference
setupChronometerBackground, CHRONO_BITMAP_WIDTH, CHRONO_BITMAP_HEIGHT, and the
NotificationBitmapUtils.create* methods).

In
`@clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/PTConstants.java`:
- Around line 129-136: Add a new default constant in PTConstants (e.g.,
PT_CHRONO_BORDER_RADIUS_DEFAULT) next to the other PT_* defaults and set it to
the shared default value (6f); then update TemplateDataFactory.kt and
TemplateData.kt to reference PTConstants.PT_CHRONO_BORDER_RADIUS_DEFAULT instead
of hardcoding 6f in the chronometer/parser/model, and similarly replace any
other hardcoded template defaults mentioned around PT constants (lines
referenced in the comment) to use corresponding PT_*_DEFAULT constants to avoid
duplication and drift.

In
`@clevertap-pushtemplates/src/test/java/com/clevertap/android/pushtemplates/content/NotificationBitmapUtilsTest.kt`:
- Around line 36-270: Update the tests for
NotificationBitmapUtils.createSolidBitmap, createLinearGradientBitmap, and
createRadialBitmap to assert rendered content not just dimensions: sample
interior pixels (e.g. center) to assert expected fill color (use assertEquals
with bgColor or expected color), sample edge/side pixels to verify border
presence/width (compare edge vs inset pixels or assert border color at 0,x or
x,0), and for gradients sample two distinct points (e.g. left vs right or
diagonal points) and assert they differ with assertNotEquals to validate
direction; modify each relevant test to include one or two pixel-sampling
assertions (using bitmap.getPixel) in addition to the existing size assertions.

In
`@clevertap-pushtemplates/src/test/java/com/clevertap/android/pushtemplates/TemplateRendererTest.kt`:
- Around line 2179-2220: Update both tests
(test_renderNotification_vertical_image_template_invalid and
test_renderNotification_vertical_image_template_null_validator) to assert that
no VerticalImageStyle usage occurs: after invoking
TemplateRenderer.renderNotification(...) add a verification that
VerticalImageStyle.builderFromStyle(...) was never called (or that
VerticalImageStyle was not instantiated/used) using the mocking framework; keep
the existing assertions that result is null and reference
TemplateDataFactory.createTemplateData, ValidatorFactory.getValidator and
mockContentValidator.validate to locate the setup to append the zero-invocation
check.

In `@sample/src/main/java/com/clevertap/demo/ui/main/HomeScreenFragment.kt`:
- Around line 86-108: The fragment routes actions by brittle string literals
like "7-0", "8-0", "8-1", "8-2", and "3-16"; replace these inline positional
keys with named constants or a typed command enum/sealed class (e.g.,
COMMAND_WEBVIEW, COMMAND_INIT_GEOFENCE, COMMAND_TRIGGER_LOCATION,
COMMAND_DEACTIVATE_GEOFENCE, COMMAND_COMPOSE_INBOX) and update the when branch
to match against those symbols; locate the routing switch in HomeScreenFragment
(the block referencing cleverTapInstance, checkPermissions(),
requestPermissions(), initCTGeofenceApi(),
CTGeofenceAPI.getInstance(context).triggerLocation(), deactivate(),
startActivity(...)) and change the case labels to use the new constants/enum
values to make the mapping explicit and safer against list reordering.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6e53b4bf-95ed-437d-9227-7a892ef3cf55

📥 Commits

Reviewing files that changed from the base of the PR and between 147c433 and dfbeefe.

📒 Files selected for processing (52)
  • CHANGELOG.md
  • clevertap-core/src/main/java/com/clevertap/android/sdk/pushnotification/CTNotificationIntentService.java
  • clevertap-geofence/src/main/java/com/clevertap/android/geofence/BackgroundLocationWork.java
  • clevertap-geofence/src/main/java/com/clevertap/android/geofence/CTGeofenceAPI.java
  • clevertap-geofence/src/main/java/com/clevertap/android/geofence/CTGeofenceBootReceiver.java
  • clevertap-geofence/src/main/java/com/clevertap/android/geofence/CTGeofenceReceiver.java
  • clevertap-geofence/src/main/java/com/clevertap/android/geofence/CTLocationUpdateReceiver.java
  • clevertap-geofence/src/main/java/com/clevertap/android/geofence/GeofenceUpdateTask.java
  • clevertap-geofence/src/main/java/com/clevertap/android/geofence/GoogleGeofenceAdapter.java
  • clevertap-geofence/src/main/java/com/clevertap/android/geofence/GoogleLocationAdapter.java
  • clevertap-geofence/src/main/java/com/clevertap/android/geofence/PushGeofenceEventTask.java
  • clevertap-geofence/src/main/java/com/clevertap/android/geofence/PushLocationEventTask.java
  • clevertap-geofence/src/main/java/com/clevertap/android/geofence/Utils.java
  • clevertap-geofence/src/main/java/com/clevertap/android/geofence/model/CTGeofence.java
  • clevertap-hms/src/main/java/com/clevertap/android/hms/CTHmsMessageHandler.java
  • clevertap-hms/src/main/java/com/clevertap/android/hms/HmsNotificationParser.java
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/PTConstants.java
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/PushTemplateReceiver.java
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/TemplateData.kt
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/TemplateDataFactory.kt
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/TemplateRenderer.kt
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/TemplateType.kt
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/content/NotificationBitmapUtils.kt
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/content/PendingIntentFactory.kt
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/content/TimerSmallContentView.kt
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/content/VerticalImageBigContentView.kt
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/content/VerticalImageContentView.kt
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/content/VerticalImageSmallContentView.kt
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/styles/VerticalImageStyle.kt
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/validators/ValidatorFactory.kt
  • clevertap-pushtemplates/src/main/java/com/clevertap/android/pushtemplates/validators/VerticalImageTemplateValidator.kt
  • clevertap-pushtemplates/src/main/res/drawable/pt_vertical_img_btn_default_bg.xml
  • clevertap-pushtemplates/src/main/res/layout-v31/timer.xml
  • clevertap-pushtemplates/src/main/res/layout-v31/timer_collapsed.xml
  • clevertap-pushtemplates/src/main/res/layout-v31/vertical_image_big.xml
  • clevertap-pushtemplates/src/main/res/layout-v31/vertical_image_small.xml
  • clevertap-pushtemplates/src/main/res/layout/timer.xml
  • clevertap-pushtemplates/src/main/res/layout/timer_collapsed.xml
  • clevertap-pushtemplates/src/main/res/layout/vertical_image_big.xml
  • clevertap-pushtemplates/src/main/res/layout/vertical_image_small.xml
  • clevertap-pushtemplates/src/main/res/values-night/colors.xml
  • clevertap-pushtemplates/src/main/res/values/colors.xml
  • clevertap-pushtemplates/src/test/java/com/clevertap/android/pushtemplates/TemplateDataFactoryTest.kt
  • clevertap-pushtemplates/src/test/java/com/clevertap/android/pushtemplates/TemplateRendererTest.kt
  • clevertap-pushtemplates/src/test/java/com/clevertap/android/pushtemplates/UtilsTest.kt
  • clevertap-pushtemplates/src/test/java/com/clevertap/android/pushtemplates/VerticalImageTemplateValidatorTest.kt
  • clevertap-pushtemplates/src/test/java/com/clevertap/android/pushtemplates/content/NotificationBitmapUtilsTest.kt
  • docs/CTPUSHTEMPLATES.md
  • docs/CTPUSHTEMPLATESCHANGELOG.md
  • gradle/libs.versions.toml
  • sample/src/main/java/com/clevertap/demo/ui/main/HomeScreenFragment.kt
  • templates/CTPUSHTEMPLATESCHANGELOG.md
💤 Files with no reviewable changes (3)
  • clevertap-hms/src/main/java/com/clevertap/android/hms/HmsNotificationParser.java
  • clevertap-hms/src/main/java/com/clevertap/android/hms/CTHmsMessageHandler.java
  • clevertap-pushtemplates/src/test/java/com/clevertap/android/pushtemplates/UtilsTest.kt

Comment thread clevertap-pushtemplates/src/main/res/layout/timer.xml
Comment thread docs/CTPUSHTEMPLATESCHANGELOG.md
Comment thread templates/CTPUSHTEMPLATESCHANGELOG.md
@github-actions
Copy link
Copy Markdown

Code Coverage Debug

Overall Project 67.82% -0.76%
Files changed 48.9%

Module Coverage
clevertap-hms 87.66%
clevertap-geofence 81.05% -0.34%
clevertap-core 67.9%
clevertap-pushtemplates 61.63% -7.86%
Files
Module File Coverage
clevertap-hms CTHmsMessageHandler.java 68.18%
HmsNotificationParser.java 63.16%
clevertap-geofence PushGeofenceEventTask.java 96.1% -0.98%
CTGeofence.java 93.55%
PushLocationEventTask.java 92.41%
Utils.java 89.36% -1.18%
GoogleGeofenceAdapter.java 88.36%
GeofenceUpdateTask.java 87.6%
CTLocationUpdateReceiver.java 81.58%
CTGeofenceAPI.java 81.28% -0.82%
CTGeofenceBootReceiver.java 78.61%
GoogleLocationAdapter.java 75.07%
CTGeofenceReceiver.java 73.79%
BackgroundLocationWork.java 55.7%
clevertap-core CTNotificationIntentService.java 0% -1.81%
clevertap-pushtemplates VerticalImageTemplateValidator.kt 100%
TemplateDataFactory.kt 99.72% -0.28%
PTConstants.java 97.06%
TemplateType.kt 94.52%
TemplateData.kt 87.04% -5.02%
TemplateRenderer.kt 81.85%
ValidatorFactory.kt 27.98%
PushTemplateReceiver.java 2.48% -39.61%

@Anush-Shand Anush-Shand merged commit edf4414 into master Apr 13, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants