Skip to content

Add push V3 client framework and migration guide#5440

Open
shai-almog wants to merge 11 commits into
masterfrom
push-v3-client-framework
Open

Add push V3 client framework and migration guide#5440
shai-almog wants to merge 11 commits into
masterfrom
push-v3-client-framework

Conversation

@shai-almog

@shai-almog shai-almog commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add the builder-based Push V3 client API, typed messages, registration sink, listeners, errors, subscriptions, and pluggable low-level PushTransport
  • connect native delivery seams on Android, iOS, and JavaScript
  • integrate push dispatch with Surfaces and Live Activities/widgets
  • preserve the classic API while directing new classic sends to BuildCloud's compatibility endpoint
  • replace the active developer guide chapter with a V3-only guide and move the former material to a deprecated chapter
  • add deterministic low-stack push tests and run the real JavaScript service worker contract in PR CI

Why

The existing callback-only API cannot express modern push lifecycle, typed schema-3 payloads, custom native push transports, registration state, or system surfaces cleanly. The new API provides those bindings while retaining compatibility for existing applications during the server cutover.

Testing strategy

CI does not pretend to provide physical-device end-to-end delivery:

  • Java tests drive the actual PushClient.dispatch() native seam and cover registration, unregistration, foreground/background delivery, cold-start replay, custom transports, and Surfaces
  • the JavaScript contract loads the real service-worker source with mocked browser clients and notification APIs
  • optional staging/device scripts remain diagnostics, not CI or nightly gates
  • backend provider and durable-queue tests live independently in the private BuildCloud repository

Companion services

This PR is designed to ship with BuildCloud PR #115 and BuildDaemon PR #156. BuildCloud preserves /push/push compatibility so the standalone PushServer can be retired; BuildDaemon detects Push V3 usage and generates the corresponding native FCM, APNs, Huawei, and callback bindings.

BuildCloud includes WNS provider delivery for explicit Windows targets. This client PR intentionally does not modify or revive the unsupported UWP port.

Validation

  • PushTest: 12 tests
  • PushMessageTest: 5 tests
  • PushClientTransportTest: 4 tests
  • real service-worker contract: pass
  • 623 include-backed developer-guide snippets validated
  • full AsciiDoctor developer-guide render
  • Vale: zero errors
  • changed-file copyright headers
  • focused PMD, Checkstyle, and SpotBugs reports
  • git diff --check

Copilot AI review requested due to automatic review settings July 23, 2026 04:34

Copilot AI left a comment

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.

Pull request overview

This PR introduces a new Push V3 client framework to Codename One, adding a typed push envelope model and an explicit client binding (PushClient) while preserving the legacy push API via a compatibility endpoint and a deprecated documentation chapter.

Changes:

  • Added the Push V3 client API (typed PushMessage, PushSubscription, PushTransport, listeners/sinks, and dispatch wiring).
  • Updated native seams across Android/iOS/JavaScript/UWP to route typed envelopes and to support managed vs. legacy behavior.
  • Added deterministic push contract tests (including a real JavaScript service-worker contract) and updated the developer guide to V3-first with a deprecated legacy chapter.

Reviewed changes

Copilot reviewed 33 out of 34 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/push-e2e/service-worker-contract.mjs Executes the real JS service worker in a mocked environment to validate v3 push delivery behavior.
tests/push-e2e/scenarios.json Defines end-to-end diagnostic scenarios for optional/staging push verification.
tests/push-e2e/README.md Documents the push testing strategy and boundaries (CI vs. optional diagnostics).
scripts/run-push-e2e.sh Operator-run script to exercise BuildCloud push admission + receipt polling against real devices/providers.
Ports/UWP/VSProjectTemplate/UWPApp/src/com/codename1/impl/SilverlightImplementation.cs Routes WNS registration/delivery through PushClient when active; falls back to legacy behavior otherwise.
Ports/JavaScriptPort/src/main/webapp/sw.js Adds v3 push detection, delivery semantics, and deep-link handling in notification clicks.
Ports/JavaScriptPort/src/main/webapp/js/push.js Extends web push registration to optionally emit a typed subscription envelope for v3.
Ports/JavaScriptPort/src/main/java/com/codename1/impl/html5/HTML5Push.java Bridges HTML5 push registration and message delivery into PushClient when active.
Ports/JavaScriptPort/src/main/java/com/codename1/impl/html5/HTML5Implementation.java Ensures explicit push callback binding is respected before registering push on HTML5.
Ports/iOSPort/src/com/codename1/impl/ios/IOSImplementation.java Avoids legacy server registration when PushClient owns registration; forwards APNs token to active callback.
Ports/iOSPort/nativeSources/CodenameOne_GLAppDelegate.m Routes managed typed envelope (cn1 dictionary) intact to Java push dispatch before legacy decoding.
Ports/Android/src/com/codename1/impl/android/StubUtil.java Exposes stub helpers publicly for generated services to query app state/stub class.
Ports/Android/src/com/codename1/impl/android/AndroidImplementation.java Adds Android v3 push handling path, plus Huawei transport accommodations for register/deregister.
maven/core-unittests/src/test/java/com/codename1/push/PushTest.java Updates legacy push URL to the BuildCloud compatibility endpoint.
maven/core-unittests/src/test/java/com/codename1/push/PushMessageTest.java Adds unit tests for typed envelope JSON roundtrip, schema validation, and immutability.
maven/core-unittests/src/test/java/com/codename1/push/PushClientTransportTest.java Adds tests for transport seam behavior, registration sinks, dispatch, and surface replay.
maven/codenameone-maven-plugin/src/main/resources/com/codename1/builders/CN1FirebaseMessagingService7.javas Generated FCM service routes typed envelope payloads into Android v3 handler when present.
maven/codenameone-maven-plugin/src/main/resources/com/codename1/builders/CN1FirebaseMessagingService.javas Same as above for the non-“7” template.
maven/codenameone-maven-plugin/src/main/java/com/codename1/builders/AndroidGradleBuilder.java Adds Huawei Push Kit support and updates generated push callback routing to use explicit callback getter.
docs/developer-guide/Push-Notifications.asciidoc Replaces push chapter with V3-first guidance (typed envelopes, client binding, managed/custom transports).
docs/developer-guide/developer-guide.asciidoc Includes the new deprecated push chapter under historical reference.
docs/developer-guide/Deprecated-Push-Notifications.asciidoc Restores legacy push docs as an explicitly deprecated chapter for migration reference.
CodenameOne/src/com/codename1/surfaces/Surfaces.java Adds push-facing entry point to publish remote widget timelines.
CodenameOne/src/com/codename1/surfaces/LiveActivity.java Adds push-facing entry points to update/end live activities by id.
CodenameOne/src/com/codename1/push/PushTransport.java Introduces pluggable low-level native transport interface for custom push stacks.
CodenameOne/src/com/codename1/push/PushSubscription.java Adds immutable model for transport-produced registration material and capabilities.
CodenameOne/src/com/codename1/push/PushRegistrationSink.java Adds application-owned server sink interface for storing/removing subscriptions.
CodenameOne/src/com/codename1/push/PushMessage.java Adds immutable typed v3 push envelope model + builder + JSON parse/serialize helpers.
CodenameOne/src/com/codename1/push/PushListener.java Adds listener interface for registration/message/error callbacks on EDT.
CodenameOne/src/com/codename1/push/PushError.java Adds structured error model for transport/registration/delivery failures.
CodenameOne/src/com/codename1/push/PushClient.java Adds the core v3 client binding, managed registration/unregistration, and native dispatch entry points.
CodenameOne/src/com/codename1/push/Push.java Points legacy server sends at BuildCloud compatibility endpoint.
CodenameOne/src/com/codename1/impl/CodenameOneImplementation.java Adds getPushCallback() accessor for ports/generated code to retrieve explicit callback binding.
.github/workflows/pr.yml Runs the JS service-worker contract test in PR CI (Node) after core unit tests on Java 8.
Files not reviewed (1)
  • Ports/JavaScriptPort/src/main/webapp/sw.js: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread CodenameOne/src/com/codename1/push/PushClient.java
Comment thread CodenameOne/src/com/codename1/push/PushMessage.java
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

✅ ByteCodeTranslator Quality Report

Test & Coverage

  • Tests: 407 total, 0 failed, 14 skipped

Benchmark Results

  • Execution Time: 22865 ms

  • Hotspots (Top 20 sampled methods):

    • 18.69% java.util.ArrayList.indexOf (342 samples)
    • 4.70% com.codename1.tools.translator.BytecodeMethod.addToConstantPool (86 samples)
    • 4.26% java.lang.StringBuilder.append (78 samples)
    • 4.21% com.codename1.tools.translator.ByteCodeClass.markDependent (77 samples)
    • 3.55% com.codename1.tools.translator.Parser.cn1EnsureSubclassIndex (65 samples)
    • 3.44% com.codename1.tools.translator.BytecodeMethod.equals (63 samples)
    • 2.90% com.codename1.tools.translator.ByteCodeClass.hasDeclaredMethod (53 samples)
    • 2.35% org.objectweb.asm.tree.analysis.Analyzer.analyze (43 samples)
    • 2.08% java.util.HashMap.hash (38 samples)
    • 2.02% com.codename1.tools.translator.bytecodes.Invoke.resolveDirectTarget (37 samples)
    • 1.91% com.codename1.tools.translator.Parser.generateClassAndMethodIndexHeader (35 samples)
    • 1.75% org.objectweb.asm.tree.analysis.Analyzer.findSubroutine (32 samples)
    • 1.48% com.codename1.tools.translator.BytecodeMethod.optimize (27 samples)
    • 1.31% com.codename1.tools.translator.Parser.classIndex (24 samples)
    • 1.20% java.lang.String.equals (22 samples)
    • 1.15% java.lang.System.identityHashCode (21 samples)
    • 1.15% com.codename1.tools.translator.Parser.resolveDupForms (21 samples)
    • 1.09% java.util.TreeMap.getEntry (20 samples)
    • 0.93% com.codename1.tools.translator.BytecodeMethod.appendCMethodPrefix (17 samples)
    • 0.87% com.codename1.tools.translator.BytecodeMethod.updateInlinableFieldDependencies (16 samples)
  • ⚠️ Coverage report not generated.

Static Analysis

  • ✅ SpotBugs: no findings (report was not generated by the build).
  • ⚠️ PMD report not generated.
  • ⚠️ Checkstyle report not generated.

Generated automatically by the PR CI workflow.

@github-actions

Copy link
Copy Markdown
Contributor

Cloudflare Preview

@shai-almog

shai-almog commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 151 screenshots: 151 matched.

Native Android coverage

  • 📊 Line coverage: 8.37% (7322/87435 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 8.26% (38206/462263), branch 3.02% (1311/43428), complexity 3.29% (1572/47783), method 4.94% (1275/25820), class 10.04% (349/3475)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6367 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.ClassReader – 0.00% (0/1524 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1187 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.MethodWriter – 0.00% (0/922 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/736 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/625 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.Frame – 0.00% (0/570 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/551 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 8.37% (7322/87435 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 8.26% (38206/462263), branch 3.02% (1311/43428), complexity 3.29% (1572/47783), method 4.94% (1275/25820), class 10.04% (349/3475)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6367 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.ClassReader – 0.00% (0/1524 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1187 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.MethodWriter – 0.00% (0/922 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/736 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/625 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.Frame – 0.00% (0/570 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/551 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend scalar fallback (no native SIMD)
SIMD int-add (64K x300) java 180ms / native 127ms = 1.4x speedup
SIMD float-mul (64K x300) java 204ms / native 116ms = 1.7x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 52.000 ms
Base64 CN1 decode 64.000 ms
Base64 native encode 354.000 ms
Base64 encode ratio (CN1/native) 0.147x (85.3% faster)
Base64 native decode 297.000 ms
Base64 decode ratio (CN1/native) 0.215x (78.5% faster)
Image encode benchmark status skipped (SIMD unsupported)

@shai-almog

shai-almog commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 181 screenshots: 181 matched.
✅ JavaScript-port screenshot tests passed.

Copilot AI review requested due to automatic review settings July 23, 2026 05:39

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 37 out of 38 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • Ports/JavaScriptPort/src/main/webapp/sw.js: Generated file
Comments suppressed due to low confidence (2)

tests/push-e2e/service-worker-contract.mjs:1

  • This test can produce misleading results if the service worker fails to register a push event handler or doesn’t call event.waitUntil(): handlers.push may be undefined (throwing), or completion may remain undefined and await completion will resolve immediately without validating any async work. Add an assertion that handlers.push is a function and that waitUntil() was called with a thenable/Promise before awaiting, so failures reliably indicate a broken service-worker contract.
    scripts/run-push-e2e.sh:1
  • If the targets file is missing a provider key, jq -r will yield null and the script will attempt to send a request with "token":"null", which can mask configuration mistakes and create hard-to-triage failures. Add an explicit check that target is non-empty and not "null" before constructing/sending the request, and fail the scenario/provider with a clear error message.

Comment thread CodenameOne/src/com/codename1/push/PushMessage.java
Comment thread docs/demos/common/src/main/snippets/developer-guide/push-notifications.sh Outdated
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [HTML preview] [Download]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 1 findings (Normal: 1)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Developer Guide build artifacts are available for download from this workflow run:

Developer Guide quality checks:

  • AsciiDoc linter: No issues found (report)
  • Vale: No alerts found (report)
  • Paragraph capitalization: No paragraph capitalization issues (report)
  • LanguageTool: No grammar matches (report)
  • Image references: No unused images detected (report)

Copilot AI review requested due to automatic review settings July 23, 2026 06:39

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 36 out of 37 changed files in this pull request and generated 2 comments.

Files not reviewed (1)
  • Ports/JavaScriptPort/src/main/webapp/sw.js: Generated file

Comment thread CodenameOne/src/com/codename1/push/PushClient.java
Copilot AI review requested due to automatic review settings July 23, 2026 11:47

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 36 out of 41 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • Ports/JavaScriptPort/src/main/webapp/sw.js: Generated file
Comments suppressed due to low confidence (1)

scripts/run-push-e2e.sh:1

  • Bash exit codes are limited to 0-255; returning the raw failure count will wrap modulo 256 for larger values (and can mistakenly report success if it wraps to 0). Consider exiting with 0 when failures==0 and 1 otherwise (while still printing the total failure count to stderr/stdout).

Comment thread CodenameOne/src/com/codename1/push/PushClient.java Outdated
Comment thread CodenameOne/src/com/codename1/surfaces/LiveActivity.java
Copilot AI review requested due to automatic review settings July 23, 2026 12:07

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 36 out of 41 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • Ports/JavaScriptPort/src/main/webapp/sw.js: Generated file
Comments suppressed due to low confidence (2)

CodenameOne/src/com/codename1/push/PushClient.java:72

  • register() sets the global active client and installs the compatibility PushCallback before checking whether a custom transport is supported. If transport.isSupported() is false, this leaves the PushClient active and overwrites any existing callback even though registration cannot proceed, which can break legacy push behavior and misroute future native events.
    public void register() {
        active = this;
        CodenameOneImplementation.setPushCallback(compatibilityCallback);
        if (transport == null) {
            Display.getInstance().registerPush();
        } else if (!transport.isSupported()) {
            fireError(new PushError("unsupported_transport", transport.getId() + " is unavailable", false));
        } else {
            transport.register(new TransportCallback());
        }

Ports/JavaScriptPort/src/main/webapp/sw.js:143

  • notificationclick opens data.deepLink directly for v3 messages and then always posts the push payload to the window. This (1) allows a push payload to open arbitrary URLs (open-redirect/phishing risk) and (2) can duplicate delivery when the push was already posted to an existing client during the original push event. Validate deep links to same-origin destinations and skip posting when the message ID was already delivered.

Comment thread Ports/JavaScriptPort/src/main/webapp/sw.js Outdated
@shai-almog

shai-almog commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 148 screenshots: 148 matched.
✅ Native Mac screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 203 seconds

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 56ms / native 3ms = 18.6x speedup
SIMD float-mul (64K x300) java 54ms / native 3ms = 18.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 151.000 ms
Base64 CN1 decode 111.000 ms
Base64 native encode 465.000 ms
Base64 encode ratio (CN1/native) 0.325x (67.5% faster)
Base64 native decode 189.000 ms
Base64 decode ratio (CN1/native) 0.587x (41.3% faster)
Base64 SIMD encode 46.000 ms
Base64 encode ratio (SIMD/CN1) 0.305x (69.5% faster)
Base64 SIMD decode 43.000 ms
Base64 decode ratio (SIMD/CN1) 0.387x (61.3% faster)
Base64 encode ratio (SIMD/native) 0.099x (90.1% faster)
Base64 decode ratio (SIMD/native) 0.228x (77.2% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 6.000 ms
Image createMask (SIMD on) 1.000 ms
Image createMask ratio (SIMD on/off) 0.167x (83.3% faster)
Image applyMask (SIMD off) 39.000 ms
Image applyMask (SIMD on) 34.000 ms
Image applyMask ratio (SIMD on/off) 0.872x (12.8% faster)
Image modifyAlpha (SIMD off) 33.000 ms
Image modifyAlpha (SIMD on) 29.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.879x (12.1% faster)
Image modifyAlpha removeColor (SIMD off) 36.000 ms
Image modifyAlpha removeColor (SIMD on) 29.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.806x (19.4% faster)

@shai-almog

shai-almog commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 217 screenshots: 217 matched.
✅ Native Apple Watch (watchOS, Core Graphics) screenshot tests passed.

@shai-almog

shai-almog commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 144 screenshots: 144 matched.
✅ Native Apple TV (tvOS, Metal) screenshot tests passed.

@shai-almog

shai-almog commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 149 screenshots: 149 matched.
✅ Native iOS Metal screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 313 seconds

Build and Run Timing

Metric Duration
Simulator Boot 62000 ms
Simulator Boot (Run) 0 ms
App Install 13000 ms
App Launch 9000 ms
Test Execution 857000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 58ms / native 3ms = 19.3x speedup
SIMD float-mul (64K x300) java 62ms / native 4ms = 15.5x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 255.000 ms
Base64 CN1 decode 342.000 ms
Base64 native encode 581.000 ms
Base64 encode ratio (CN1/native) 0.439x (56.1% faster)
Base64 native decode 787.000 ms
Base64 decode ratio (CN1/native) 0.435x (56.5% faster)
Base64 SIMD encode 175.000 ms
Base64 encode ratio (SIMD/CN1) 0.686x (31.4% faster)
Base64 SIMD decode 71.000 ms
Base64 decode ratio (SIMD/CN1) 0.208x (79.2% faster)
Base64 encode ratio (SIMD/native) 0.301x (69.9% faster)
Base64 decode ratio (SIMD/native) 0.090x (91.0% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 9.000 ms
Image createMask (SIMD on) 4.000 ms
Image createMask ratio (SIMD on/off) 0.444x (55.6% faster)
Image applyMask (SIMD off) 74.000 ms
Image applyMask (SIMD on) 138.000 ms
Image applyMask ratio (SIMD on/off) 1.865x (86.5% slower)
Image modifyAlpha (SIMD off) 135.000 ms
Image modifyAlpha (SIMD on) 200.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.481x (48.1% slower)
Image modifyAlpha removeColor (SIMD off) 184.000 ms
Image modifyAlpha removeColor (SIMD on) 230.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 1.250x (25.0% slower)

@shai-almog

shai-almog commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 143 screenshots: 143 matched.
✅ Native iOS screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 207 seconds

Build and Run Timing

Metric Duration
Simulator Boot 63000 ms
Simulator Boot (Run) 0 ms
App Install 12000 ms
App Launch 3000 ms
Test Execution 588000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 54ms / native 3ms = 18.0x speedup
SIMD float-mul (64K x300) java 53ms / native 2ms = 26.5x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 213.000 ms
Base64 CN1 decode 156.000 ms
Base64 native encode 329.000 ms
Base64 encode ratio (CN1/native) 0.647x (35.3% faster)
Base64 native decode 338.000 ms
Base64 decode ratio (CN1/native) 0.462x (53.8% faster)
Base64 SIMD encode 49.000 ms
Base64 encode ratio (SIMD/CN1) 0.230x (77.0% faster)
Base64 SIMD decode 45.000 ms
Base64 decode ratio (SIMD/CN1) 0.288x (71.2% faster)
Base64 encode ratio (SIMD/native) 0.149x (85.1% faster)
Base64 decode ratio (SIMD/native) 0.133x (86.7% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 7.000 ms
Image createMask (SIMD on) 1.000 ms
Image createMask ratio (SIMD on/off) 0.143x (85.7% faster)
Image applyMask (SIMD off) 43.000 ms
Image applyMask (SIMD on) 32.000 ms
Image applyMask ratio (SIMD on/off) 0.744x (25.6% faster)
Image modifyAlpha (SIMD off) 32.000 ms
Image modifyAlpha (SIMD on) 30.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.938x (6.3% faster)
Image modifyAlpha removeColor (SIMD off) 35.000 ms
Image modifyAlpha removeColor (SIMD on) 28.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.800x (20.0% faster)

Copilot AI review requested due to automatic review settings July 23, 2026 14:59

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 36 out of 41 changed files in this pull request and generated 2 comments.

Files not reviewed (1)
  • Ports/JavaScriptPort/src/main/webapp/sw.js: Generated file

Comment thread CodenameOne/src/com/codename1/push/PushMessage.java
Comment thread CodenameOne/src/com/codename1/push/PushClient.java

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 36 out of 41 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • Ports/JavaScriptPort/src/main/webapp/sw.js: Generated file

Copilot AI review requested due to automatic review settings July 24, 2026 18:21
@shai-almog
shai-almog force-pushed the push-v3-client-framework branch from 853c2ff to e056224 Compare July 24, 2026 18:21

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 36 out of 41 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • Ports/JavaScriptPort/src/main/webapp/sw.js: Generated file

Comment thread Ports/JavaScriptPort/src/main/webapp/js/push.js Outdated
Copilot AI review requested due to automatic review settings July 24, 2026 20:16

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 36 out of 41 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • Ports/JavaScriptPort/src/main/webapp/sw.js: Generated file

Comment thread Ports/JavaScriptPort/src/main/webapp/sw.js Outdated
Copilot AI review requested due to automatic review settings July 24, 2026 20:59

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 36 out of 41 changed files in this pull request and generated 2 comments.

Files not reviewed (1)
  • Ports/JavaScriptPort/src/main/webapp/sw.js: Generated file
Comments suppressed due to low confidence (4)

CodenameOne/src/com/codename1/push/PushClient.java:220

  • Managed unregistration should still be sent to BuildCloud even when a PushRegistrationSink is present (mirroring). Right now unregisterManaged() only runs when there is no sink, so managed subscriptions may remain active on the server when apps use a sink.
        if (subscription != null && registrationSink != null) {
            registrationSink.unregistered(subscription);
        } else if (transport == null) {
            unregisterManaged();
        }

Ports/JavaScriptPort/src/main/java/com/codename1/impl/html5/HTML5Push.java:168

  • If the JS side generated a typed (V3) web registration id, calling _registerServerPush(id) here can register the device with the legacy push service unexpectedly (e.g., if the active PushClient was unregistered between starting registerPushNative() and receiving onSuccess). Gate the legacy registration path on the typedEnvelope decision captured when registration began.
                        PushCallback active = com.codename1.push.PushClient.getActiveCallback();
                        if (active != null) active.registeredForPush(id);
                        else HTML5Implementation.getInstance()._registerServerPush(id);

Ports/JavaScriptPort/src/main/java/com/codename1/impl/html5/HTML5Push.java:181

  • onPush() currently falls back to the legacy messageType decoder whenever PushClient.getActiveCallback() is null at delivery time. If registration began in typed-envelope mode, legacy decoding is incorrect; it should either dispatch to PushClient (when active) or no-op. Use the captured typedEnvelope flag to decide whether legacy decoding is allowed.
            public void onPush(final JSObject data) {
                if (com.codename1.push.PushClient.getActiveCallback() != null) {
                    com.codename1.push.PushClient.dispatch(stringify(data));
                    return;
                }

Ports/JavaScriptPort/src/main/java/com/codename1/impl/html5/HTML5Push.java:278

  • For consistency (and to prevent a race where typedEnvelope is computed differently), pass the captured typedEnvelope flag through to registerPushNative() rather than recomputing PushClient.getActiveCallback() here.
        registerPushNative(onSuccess, onFail, onPush, pushActionCategories,
                com.codename1.push.PushClient.getActiveCallback() != null);

Comment thread CodenameOne/src/com/codename1/push/PushClient.java
Comment thread Ports/JavaScriptPort/src/main/java/com/codename1/impl/html5/HTML5Push.java Outdated
Copilot AI review requested due to automatic review settings July 24, 2026 21:17

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 36 out of 41 changed files in this pull request and generated 2 comments.

Files not reviewed (1)
  • Ports/JavaScriptPort/src/main/webapp/sw.js: Generated file

Comment thread Ports/JavaScriptPort/src/main/webapp/sw.js
Comment thread Ports/Android/src/com/codename1/impl/android/AndroidImplementation.java Outdated
Copilot AI review requested due to automatic review settings July 24, 2026 21:27

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 36 out of 41 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • Ports/JavaScriptPort/src/main/webapp/sw.js: Generated file

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