Skip to content

Commerce SDK + Secrets API + developer-guide docs#5300

Open
shai-almog wants to merge 13 commits into
masterfrom
feat/commerce-sdk
Open

Commerce SDK + Secrets API + developer-guide docs#5300
shai-almog wants to merge 13 commits into
masterfrom
feat/commerce-sdk

Conversation

@shai-almog

Copy link
Copy Markdown
Collaborator

Client-side companion to the BuildCloud Commerce service
(codenameone/BuildCloud#78), plus a new secure secrets API.

Commerce SDK

  • com.codename1.payment.CommerceManager — facade on the payment API
    that talks to the BuildCloud Commerce service (reads build key /
    package name; default endpoint on cloud.codenameone.com).

Secrets API (new, all tiers)

  • com.codename1.secrets.Secrets — secure-by-default key/value store
    (set/get/contains/delete/keys/isHardwareBacked). Never writes a
    value as plaintext.
  • SecretsStore SPI — hardware keychain (iOS Keychain, Android
    Keystore) plugs in via Secrets.setStore; DefaultSecretsStore is an
    AES-256-CBC + HMAC-SHA256 encrypt-then-MAC software fallback over
    Storage (used in the simulator). Java-5 / ParparVM-compatible,
    ASCII-only.

Docs (docs/developer-guide)

  • New Secrets chapter (API, keychain SPI, AES fallback, the all-tier
    server-side vault), registered in developer-guide.asciidoc.
  • Commerce chapter gains an Analytics section (MRR/ARR/ARPU, cohort
    retention, realized LTV, forecast, store/product breakdowns).

Core compiles at -source 1.5 -target 1.5; secrets package verified
ASCII-only for the ParparVM build.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Jun 27, 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)

Comment thread CodenameOne/src/com/codename1/secrets/DefaultSecretsStore.java Fixed
Comment thread CodenameOne/src/com/codename1/secrets/DefaultSecretsStore.java Fixed
@github-actions

Copy link
Copy Markdown
Contributor

Cloudflare Preview

@shai-almog

shai-almog commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 139 screenshots: 139 matched.

Native Android coverage

  • 📊 Line coverage: 14.62% (8986/61459 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 11.85% (44203/373047), branch 5.25% (1841/35083), complexity 6.31% (2120/33613), method 10.92% (1715/15708), class 17.78% (396/2227)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 14.62% (8986/61459 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 11.85% (44203/373047), branch 5.25% (1841/35083), complexity 6.31% (2120/33613), method 10.92% (1715/15708), class 17.78% (396/2227)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend scalar fallback (no native SIMD)
SIMD int-add (64K x300) java 257ms / native 270ms = 0.9x speedup
SIMD float-mul (64K x300) java 163ms / native 124ms = 1.3x 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 265.000 ms
Base64 CN1 decode 369.000 ms
Base64 native encode 927.000 ms
Base64 encode ratio (CN1/native) 0.286x (71.4% faster)
Base64 native decode 1003.000 ms
Base64 decode ratio (CN1/native) 0.368x (63.2% faster)
Image encode benchmark status skipped (SIMD unsupported)

@shai-almog

shai-almog commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator Author

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

@shai-almog

shai-almog commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator Author

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

@shai-almog

shai-almog commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator Author

Mac native screenshot updates

Compared 137 screenshots: 116 matched, 21 missing actuals.

  • DesktopMode — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • FloatingActionButtonTheme_dark — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • Gpu3DAnimation — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • Gpu3DCube — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • Gpu3DModel — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • Gpu3DTexturedCube — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • LottieAnimatedScreenshotTest — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • PaletteOverrideTheme_dark — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • PaletteOverrideTheme_light — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • RealOsmVector — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • SVGAnimatedScreenshotTest — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • SVGStatic — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • ShowcaseTheme_dark — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • ShowcaseTheme_light — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • SpanLabelTheme_dark — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • SpanLabelTheme_light — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • VectorMapDarkStyle — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • VectorMapMarkers — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • VectorMapShapes — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • css-gradients — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • landscape — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

Benchmark Results

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

@shai-almog

shai-almog commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator Author

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

Benchmark Results

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

Build and Run Timing

Metric Duration
Simulator Boot 85000 ms
Simulator Boot (Run) 1000 ms
App Install 13000 ms
App Launch 5000 ms
Test Execution 453000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 334ms / native 4ms = 83.5x speedup
SIMD float-mul (64K x300) java 104ms / native 3ms = 34.6x 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 523.000 ms
Base64 CN1 decode 266.000 ms
Base64 native encode 1335.000 ms
Base64 encode ratio (CN1/native) 0.392x (60.8% faster)
Base64 native decode 741.000 ms
Base64 decode ratio (CN1/native) 0.359x (64.1% faster)
Base64 SIMD encode 84.000 ms
Base64 encode ratio (SIMD/CN1) 0.161x (83.9% faster)
Base64 SIMD decode 83.000 ms
Base64 decode ratio (SIMD/CN1) 0.312x (68.8% faster)
Base64 encode ratio (SIMD/native) 0.063x (93.7% faster)
Base64 decode ratio (SIMD/native) 0.112x (88.8% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 65.000 ms
Image createMask (SIMD on) 120.000 ms
Image createMask ratio (SIMD on/off) 1.846x (84.6% slower)
Image applyMask (SIMD off) 458.000 ms
Image applyMask (SIMD on) 383.000 ms
Image applyMask ratio (SIMD on/off) 0.836x (16.4% faster)
Image modifyAlpha (SIMD off) 359.000 ms
Image modifyAlpha (SIMD on) 436.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.214x (21.4% slower)
Image modifyAlpha removeColor (SIMD off) 408.000 ms
Image modifyAlpha removeColor (SIMD on) 227.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.556x (44.4% faster)

@shai-almog

shai-almog commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator Author

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

Benchmark Results

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

Build and Run Timing

Metric Duration
Simulator Boot 91000 ms
Simulator Boot (Run) 1000 ms
App Install 11000 ms
App Launch 1000 ms
Test Execution 452000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 68ms / native 4ms = 17.0x speedup
SIMD float-mul (64K x300) java 111ms / native 33ms = 3.3x 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 709.000 ms
Base64 CN1 decode 222.000 ms
Base64 native encode 1448.000 ms
Base64 encode ratio (CN1/native) 0.490x (51.0% faster)
Base64 native decode 453.000 ms
Base64 decode ratio (CN1/native) 0.490x (51.0% faster)
Base64 SIMD encode 60.000 ms
Base64 encode ratio (SIMD/CN1) 0.085x (91.5% faster)
Base64 SIMD decode 80.000 ms
Base64 decode ratio (SIMD/CN1) 0.360x (64.0% faster)
Base64 encode ratio (SIMD/native) 0.041x (95.9% faster)
Base64 decode ratio (SIMD/native) 0.177x (82.3% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 21.000 ms
Image createMask (SIMD on) 20.000 ms
Image createMask ratio (SIMD on/off) 0.952x (4.8% faster)
Image applyMask (SIMD off) 300.000 ms
Image applyMask (SIMD on) 292.000 ms
Image applyMask ratio (SIMD on/off) 0.973x (2.7% faster)
Image modifyAlpha (SIMD off) 292.000 ms
Image modifyAlpha (SIMD on) 179.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.613x (38.7% faster)
Image modifyAlpha removeColor (SIMD off) 139.000 ms
Image modifyAlpha removeColor (SIMD on) 192.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 1.381x (38.1% slower)

shai-almog and others added 11 commits June 27, 2026 23:51
Optional client facade over Purchase that adds cloud-side receipt validation
and store-agnostic entitlement checks via the Codename One Commerce service.
- isEntitled(entitlementId) with store-direct fallback (paying users never
  locked out when the cloud is unreachable or over the monthly cap).
- refresh() posts receipts to /validate, folds returned entitlements into a
  cache; isDegraded() reflects over-cap/offline.
- purchase/subscribe/unsubscribe delegate to Purchase; reads the
  build-stamped codename1.commerce.cloud.* properties; inert no-op when the
  build did not enable commerce.
- Java 5 source-compatible (framework constraint); compiles against
  codenameone-core with JDK 8 at -source 1.5; ASCII-only for the ParparVM
  build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Covers entitlements-not-SKUs, CommerceManager client usage, the build_key
auto-wiring, Apple/Google server-notification setup, the ordered/idempotent
lifecycle webhooks, the validated-volume meter + graceful degradation, the
console, and privacy. Registered in developer-guide.asciidoc after Analytics.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…als)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds com.codename1.secrets.Secrets, a simple set/get/contains/delete/
keys API for app secrets (auth tokens, API keys) that never stores a
value as plaintext:

  - SecretsStore SPI — a platform port / keychain cn1lib registers a
    hardware-backed store (iOS Keychain, Android Keystore) via
    Secrets.setStore; isHardwareBacked() reports which is active.
  - DefaultSecretsStore — software fallback used when no hardware store
    is registered (notably the simulator): AES-256-CBC + HMAC-SHA256
    encrypt-then-MAC over Storage, CSPRNG master key in Preferences,
    constant-time MAC compare. Written at the Java-5 API level so it
    compiles for core / ParparVM; ASCII-only source.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New Secrets developer-guide chapter (registered in developer-guide.asciidoc):
the secure-by-default API, the hardware-keychain SPI, the AES at-rest
fallback, and the all-tier server-side secrets vault.

Commerce chapter gains an Analytics section documenting the parity
dashboard: MRR/ARR/ARPU/churn, cohort retention, realized LTV, forecast,
and store/product breakdowns.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The repo's validate-java25-markdown-docs gate forbids classic /** **/
Javadoc markers under CodenameOne/ and Ports/CLDC11/. Convert the new
Secrets API and CommerceManager doc comments to /// markdown style and
add com/codename1/secrets/package-info.java (build-javadocs requires a
package-info for every documented package).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fix the 11 Vale findings in the new Secrets/Commerce chapters
(contractions, redundant adverbs, needless hyphens) so the
developer-guide quality gate passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the hand-rolled AES-256-CBC + HMAC-SHA256 software fallback with
authenticated AES-256-GCM through com.codename1.security.Cipher (which
runs on the platform's native crypto provider and is portable across the
simulator/Android/iOS). GCM provides confidentiality + integrity in one
pass, so the separate HMAC is gone.

Fixes the two CodeQL high-severity java/weak-cryptographic-algorithm
alerts (CBC + PKCS#5 padding-oracle) and the SpotBugs DM_DEFAULT_ENCODING
finding (the unreachable getBytes() fallback now throws instead).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Update the Secrets chapter to describe the AES-256-GCM software fallback,
and clear the 5 LanguageTool findings in the Secrets/Commerce chapters
(British spelling, verb-as-noun, "backoff" typo, sentence-start casing in
list items).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- RCN_REDUNDANT_NULLCHECK (CommerceManager.validateReceipt): drop the
  redundant `resp == null` check; Rest.getAsJsonMap() never returns null.
- REC_CATCH_EXCEPTION (DefaultSecretsStore.get): catch
  UnsupportedEncodingException and RuntimeException explicitly instead of
  the broad Exception (Java-5 source, so no multi-catch).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
shai-almog and others added 2 commits June 28, 2026 00:41
Verified clean against the full core SpotBugs gate (effort=Max,
threshold=Low) locally:

- RV_ABSOLUTE_VALUE_OF_HASHCODE (getAppUserId): mask the sign bit with
  & 0x7fffffff instead of Math.abs(hashCode()) (which is negative for
  Integer.MIN_VALUE).
- WMI_WRONG_MAP_ITERATOR x2 (getActiveEntitlements, applyEntitlements):
  iterate entrySet() instead of keySet()+get().

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- CommerceManager: mark the class final (only private constructors) and
  iterate the receipt list with a foreach.
- DefaultSecretsStore: add @OverRide to the six SecretsStore methods,
  convert the entry-scan and hex loops to foreach, and make the
  un-decodable-entry catch non-empty.

Verified clean against the full core static-analysis gate (PMD + SpotBugs
+ 3638 unit tests) locally with -Plocal-dev-javase on JDK 8.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • 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.

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