Skip to content

Add AJO Basic push notification template support#85

Open
ritusingh-29 wants to merge 11 commits into
adobe:mainfrom
ritusingh-29:feature/ajo-basic-template
Open

Add AJO Basic push notification template support#85
ritusingh-29 wants to merge 11 commits into
adobe:mainfrom
ritusingh-29:feature/ajo-basic-template

Conversation

@ritusingh-29

@ritusingh-29 ritusingh-29 commented Jun 5, 2026

Copy link
Copy Markdown

Summary

Adds AJO (Adobe Journey Optimizer) push notification template support to the notificationbuilder library, beginning with the ajo_basic template type — the first of three planned AJO template types.

AJO push payloads differ from ACC: template-specific configuration arrives as an escaped JSON blob under adb_template_properties, rather than as flat FCM keys. This PR introduces a standalone AJO class hierarchy (AJOPushTemplate, AJOBasicPushTemplate) and a self-contained builder (AJOBasicNotificationBuilder) that parse this blob and render the notification without touching any existing ACC template code path.

The ajo_basic template is selected via the adb_template_type payload key, for example "ajo_basic", and supports:

  • Two image scale types:

    • center_crop fills width and crops vertically.
    • fit_center keeps the full image visible and preserves aspect ratio.

    The scale type is declared per payload under adb_image.scale_type. Both scale-type ImageViews co-exist in the single expanded layout, each initially gone. At render time, the correct one is set to visible and the other is kept gone. This is a workaround for RemoteViews not supporting a dynamically-set ImageView.scaleType.

  • Large icon with its own scale_type, resolved with the same visibility-toggle pattern in both the collapsed and expanded layouts.

  • Action buttons via the existing flat adb_act key, reusing BasicPushTemplate.ActionButton parsing.

  • Standard notification properties: sound, channel, priority, visibility, badge count, sticky, and ticker.

  • No changes to any existing ACC template behavior.

Background

ACC push templates (BasicPushTemplate, CarouselPushTemplate, etc.) all extend the sealed AEPPushTemplate class. AJO templates cannot reuse this hierarchy because AEPPushTemplate is sealed, so it cannot be subclassed from a different package.

A parallel, standalone AJOPushTemplate sealed base class is introduced instead, keeping AJO and ACC code fully decoupled.

NotificationBuilder already dispatches on PushTemplateType. AJO_BASIC is added as a new enum value following the established extension pattern.

What Changed

File Change
PushTemplateConstants.kt Added new AJO_TEMPLATE_PROPERTIES = "adb_template_properties" payload key. Added new AJOTemplatePropertyKeys object with nested SubKeys (text, url, scale_type) and ScaleType (center_crop, fit_center) constants matching the blob schema.
PushTemplateType.kt Added new AJO_BASIC("ajo_basic") enum value and corresponding fromString() mapping.
NotificationBuilder.kt Added new AJO_BASIC routing branch in createNotificationBuilder() that instantiates AJOBasicPushTemplate and delegates to AJOBasicNotificationBuilder.
AJOPushTemplate.kt New standalone sealed base class that does not extend AEPPushTemplate. Parses the adb_template_properties blob for title, body, image URL, large icon, and payload version, falling back to flat FCM keys when blob values are absent. Reads standard notification properties such as sound, channel, priority, visibility, badge, sticky, small icon, and ticker from flat keys.
AJOBasicPushTemplate.kt New class extending AJOPushTemplate. Reads imgScaleType from adb_image.scale_type, defaulting to center_crop; reads largeIconScaleType from adb_large_icon.scale_type; and reads actionButtonsList from the flat adb_act key.
AJOBasicNotificationBuilder.kt New self-contained builder with no dependency on AEPPushNotificationBuilder. Uses a single collapsed layout (ajo_push_template_collapsed) and a single expanded layout (ajo_basic_push_template_expanded). Resolves scale type at render time by toggling View.VISIBLE / View.GONE between the two pre-defined ImageViews in each layout: expanded_image_fit_center or expanded_image_center_crop for the hero image, and large_icon_fit_center or large_icon_center_crop for the large icon in both layouts. Handles channel creation, title/body, images, action buttons, sound, and priority inline.
ajo_push_template_collapsed.xml New collapsed notification layout. Contains a FrameLayout large icon container with both large_icon_center_crop (centerCrop, fixed size) and large_icon_fit_center (fitCenter, fixed size) ImageViews, both initially gone. The correct one is made visible at render time.
ajo_basic_push_template_expanded.xml New expanded layout for ajo_basic. Contains the same dual large icon container as the collapsed layout, plus two hero-image ImageViews below the body text: expanded_image_center_crop with fixed height and centerCrop, and expanded_image_fit_center with wrap_content height, adjustViewBounds="true", minHeight / maxHeight bounds, and fitCenter. Both hero images start gone; the builder makes the correct one visible.
Template.kt Added AJOBasic("AJO Basic", "ajo_basic") enum entry so the ajo_basic directory appears in the testapp template picker.
UINotificationBuilderActivity.kt Wrapped Template.valueOf() in runCatching { }.getOrDefault(Template.Timer) to prevent crashes when a saved shared preference value no longer matches a valid enum name, for example after adding or removing a template.
ajo_basic_center_crop.json Added sample ajo_basic payload with scale_type: center_crop for manual rendering verification.
ajo_basic_fit_center.json Added sample ajo_basic payload with scale_type: fit_center for manual rendering verification.

Payload Schema: ajo_basic

FCM data map shown with adb_template_properties expanded for readability:

{
  "adb_template_type": "ajo_basic",
  "adb_title": "<title fallback>",
  "adb_body": "<body fallback>",
  "adb_image": "<image url fallback>",
  "adb_icon": "ic_launcher_background",
  "adb_sound": "bells",
  "adb_channel_id": "ajo_basic_channel",
  "adb_n_count": "1",
  "adb_n_priority": "PRIORITY_HIGH",
  "adb_n_visibility": "PUBLIC",
  "adb_a_type": "WEBURL",
  "adb_uri": "https://www.adobe.com",
  "adb_act": "[{\"label\":\"Learn More\",\"uri\":\"https://www.adobe.com\",\"type\":\"WEBURL\"},{\"label\":\"Open App\",\"uri\":\"\",\"type\":\"OPENAPP\"}]",
  "_xdm": "<tracking token>",
  "adb_template_properties": {
    "adb_version": "1",
    "adb_title": {
      "text": "<title>"
    },
    "adb_body": {
      "text": "<body>"
    },
    "adb_image": {
      "url": "<image url>",
      "scale_type": "center_crop | fit_center"
    },
    "adb_large_icon": {
      "url": "<icon url>",
      "scale_type": "center_crop | fit_center"
    }
  }
}

Values in adb_template_properties take precedence over flat keys. Flat keys serve as fallback for backward compatibility.

Note: In the actual FCM data payload, adb_template_properties is serialized as an escaped JSON string because FCM data values are Map<String, String>.

How Has This Been Tested?

Tested manually via the notificationbuilder testapp by firing ajo_basic payloads with both center_crop and fit_center scale types across the following aspect ratios:

  • 1:1
  • 3:2
  • 5:4
  • 4:3
  • 2:1
  • 16:9

Devices / API Levels Tested

Device API Result
Pixel 6 API 34 / Android 14 ✅ Both scale types render correctly
Pixel 6 Tablet API 34 / Android 14 ✅ Both scale types render correctly
Pixel 5 API 31 / Android 12 ✅ Both scale types render correctly
Pixel 3a API 26 / Android 8 ✅ Both scale types render correctly
Pixel API 21 / Android 5 ⚠️ Image does not render

Types of Changes

  • Bug fix: non-breaking change which fixes an issue
  • New feature: non-breaking change which adds functionality
  • Breaking change: fix or feature that would cause existing functionality to change

Checklist

  • I have signed the Adobe Open Source CLA.
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.

@codecov

codecov Bot commented Jun 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.00000% with 5 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ternal/ajo/builders/AJOBasicNotificationBuilder.kt 96.15% 0 Missing and 3 partials ⚠️
...builder/internal/templates/AJOBasicPushTemplate.kt 95.00% 0 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

…e type

- Collapse two scale-type expanded XMLs into ajo_basic_push_template_expanded.xml
- Use visibility toggling for centerCrop/fitCenter on both expanded image and large icon
- Update collapsed layout to use large_icon_container FrameLayout pattern
- Delete ajo_push_template_expanded_center_crop.xml and ajo_push_template_expanded_fit_center.xml

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we continue using AEPPushTemplate, we can keep the files in same package.
We might not need to create new AJOPushTemplate class in that case

* [adb_template_properties] JSON blob parsed by [AJOPushTemplate].
* Action buttons are read from the flat [adb_act] key, consistent with ACC/AJO handling.
*/
internal class AJOBasicPushTemplate(data: NotificationData) : AJOPushTemplate(data) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

My recommendation will be to extend from AEPPushTemplate only, and remove AJOPushTemplate class.

@ritusingh-29 ritusingh-29 force-pushed the feature/ajo-basic-template branch from 7a9e45e to cf70e9c Compare June 22, 2026 20:25
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.

2 participants