From c3547ec8f8837b7908742b2dba158d390aa2f14c Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 16 Jan 2026 19:35:39 +0200 Subject: [PATCH 1/6] Add bytecode regression test to hello app --- .../BytecodeTranslatorRegressionTest.java | 76 +++++++++++++++++++ .../tests/Cn1ssDeviceRunner.java | 1 + 2 files changed, 77 insertions(+) create mode 100644 scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BytecodeTranslatorRegressionTest.java diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BytecodeTranslatorRegressionTest.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BytecodeTranslatorRegressionTest.java new file mode 100644 index 0000000000..e815f26b9d --- /dev/null +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BytecodeTranslatorRegressionTest.java @@ -0,0 +1,76 @@ +package com.codenameone.examples.hellocodenameone.tests; + +import com.codename1.ui.CN; + +public class BytecodeTranslatorRegressionTest extends BaseTest { + @FunctionalInterface + private interface Mapper { + String apply(String input); + + default String decorate(String input) { + return "<" + input + ">"; + } + + static String suffix(String input, String suffix) { + return input + suffix; + } + } + + private static final class Prefixer { + private final String prefix; + + private Prefixer(String prefix) { + this.prefix = prefix; + } + + private String applyPrefix(String input) { + return prefix + input; + } + } + + @Override + public boolean runTest() { + Thread worker = new Thread(() -> { + try { + String[] inputs = {"alpha", "beta", "gamma"}; + Prefixer prefixer = new Prefixer("pre-"); + Mapper upper = String::toUpperCase; + Mapper prefixed = prefixer::applyPrefix; + String suffix = "-suffix"; + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < 250; i++) { + for (String input : inputs) { + builder.append(combine(input, upper, prefixed, suffix)); + builder.append('|'); + } + } + String sample = combine("alpha", upper, prefixed, suffix); + String expected = "-suffix|-suffix"; + if (!expected.equals(sample)) { + fail("Unexpected output: " + sample); + return; + } + if (builder.length() == 0) { + fail("No output generated."); + return; + } + CN.callSerially(this::done); + } catch (Throwable t) { + fail("Regression test failed: " + t); + } + }, "cn1-bytecode-regression"); + worker.start(); + return true; + } + + @Override + public boolean shouldTakeScreenshot() { + return false; + } + + private static String combine(String input, Mapper first, Mapper second, String suffix) { + String left = Mapper.suffix(first.decorate(first.apply(input)), suffix); + String right = Mapper.suffix(second.decorate(second.apply(input)), suffix); + return left + "|" + right; + } +} diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunner.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunner.java index 5f458c33e0..23ea1b70e3 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunner.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunner.java @@ -70,6 +70,7 @@ public final class Cn1ssDeviceRunner extends DeviceRunner { new MediaPlaybackScreenshotTest(), new OrientationLockScreenshotTest(), new InPlaceEditViewTest(), + new BytecodeTranslatorRegressionTest(), new AccessibilityTest())); public static void addTest(BaseTest test) { From 20e28eadf5be6a1a91ccbe17a6f4230f8d52051d Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 16 Jan 2026 19:50:51 +0200 Subject: [PATCH 2/6] Fix regression test compliance warning --- .../hellocodenameone/tests/BytecodeTranslatorRegressionTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BytecodeTranslatorRegressionTest.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BytecodeTranslatorRegressionTest.java index e815f26b9d..2178419b3b 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BytecodeTranslatorRegressionTest.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BytecodeTranslatorRegressionTest.java @@ -3,7 +3,6 @@ import com.codename1.ui.CN; public class BytecodeTranslatorRegressionTest extends BaseTest { - @FunctionalInterface private interface Mapper { String apply(String input); From dd82bc60cfd32f1232411610eb055eb96a8c96df Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 16 Jan 2026 20:11:26 +0200 Subject: [PATCH 3/6] Expand bytecode regression test coverage --- .../BytecodeTranslatorRegressionTest.java | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BytecodeTranslatorRegressionTest.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BytecodeTranslatorRegressionTest.java index 2178419b3b..58c0a3a301 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BytecodeTranslatorRegressionTest.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BytecodeTranslatorRegressionTest.java @@ -10,11 +10,23 @@ default String decorate(String input) { return "<" + input + ">"; } + default Mapper andThen(Mapper next) { + return value -> next.apply(this.apply(value)); + } + static String suffix(String input, String suffix) { return input + suffix; } } + private interface Factory { + Prefixer create(String prefix); + } + + private interface Combiner { + String combine(String left, String right); + } + private static final class Prefixer { private final String prefix; @@ -32,19 +44,30 @@ public boolean runTest() { Thread worker = new Thread(() -> { try { String[] inputs = {"alpha", "beta", "gamma"}; - Prefixer prefixer = new Prefixer("pre-"); + Factory factory = Prefixer::new; + Prefixer prefixer = factory.create("pre-"); + Prefixer otherPrefixer = factory.create("other-"); Mapper upper = String::toUpperCase; Mapper prefixed = prefixer::applyPrefix; + Mapper otherPrefixed = otherPrefixer::applyPrefix; + Mapper reversed = new Mapper() { + @Override + public String apply(String input) { + return new StringBuilder(input).reverse().toString(); + } + }; + Mapper pipeline = upper.andThen(reversed).andThen(otherPrefixed); + Combiner combiner = BytecodeTranslatorRegressionTest::join; String suffix = "-suffix"; StringBuilder builder = new StringBuilder(); for (int i = 0; i < 250; i++) { for (String input : inputs) { - builder.append(combine(input, upper, prefixed, suffix)); + builder.append(combine(input, prefixed, pipeline, suffix, combiner)); builder.append('|'); } } - String sample = combine("alpha", upper, prefixed, suffix); - String expected = "-suffix|-suffix"; + String sample = combine("alpha", prefixed, pipeline, suffix, combiner); + String expected = "-suffix|-suffix"; if (!expected.equals(sample)) { fail("Unexpected output: " + sample); return; @@ -67,9 +90,13 @@ public boolean shouldTakeScreenshot() { return false; } - private static String combine(String input, Mapper first, Mapper second, String suffix) { + private static String combine(String input, Mapper first, Mapper second, String suffix, Combiner combiner) { String left = Mapper.suffix(first.decorate(first.apply(input)), suffix); String right = Mapper.suffix(second.decorate(second.apply(input)), suffix); + return combiner.combine(left, right); + } + + private static String join(String left, String right) { return left + "|" + right; } } From c012490542b38fc9c64f335b477b0d91a8e6b720 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 16 Jan 2026 21:00:21 +0200 Subject: [PATCH 4/6] Add background UI access regression test --- .../tests/BackgroundThreadUiAccessTest.java | 32 +++++++++++++++++++ .../tests/Cn1ssDeviceRunner.java | 1 + 2 files changed, 33 insertions(+) create mode 100644 scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BackgroundThreadUiAccessTest.java diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BackgroundThreadUiAccessTest.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BackgroundThreadUiAccessTest.java new file mode 100644 index 0000000000..14e8600613 --- /dev/null +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BackgroundThreadUiAccessTest.java @@ -0,0 +1,32 @@ +package com.codenameone.examples.hellocodenameone.tests; + +import com.codename1.ui.Display; +import com.codename1.ui.plaf.UIManager; + +public class BackgroundThreadUiAccessTest extends BaseTest { + @Override + public boolean runTest() { + Thread worker = new Thread(() -> { + try { + Display display = Display.getInstance(); + int width = display.getDisplayWidth(); + int pixels = display.convertToPixels(10.0f, true); + UIManager manager = UIManager.getInstance(); + if (width <= 0 || pixels <= 0 || manager == null) { + fail("Unexpected display metrics: width=" + width + " pixels=" + pixels); + return; + } + done(); + } catch (Throwable t) { + fail("Background UI access test failed: " + t); + } + }, "cn1-ui-access-bg"); + worker.start(); + return true; + } + + @Override + public boolean shouldTakeScreenshot() { + return false; + } +} diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunner.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunner.java index 23ea1b70e3..30e80f34a9 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunner.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunner.java @@ -71,6 +71,7 @@ public final class Cn1ssDeviceRunner extends DeviceRunner { new OrientationLockScreenshotTest(), new InPlaceEditViewTest(), new BytecodeTranslatorRegressionTest(), + new BackgroundThreadUiAccessTest(), new AccessibilityTest())); public static void addTest(BaseTest test) { From 2445238734ce095328ba2cd501aa3f3c12e5fc0a Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 16 Jan 2026 21:00:25 +0200 Subject: [PATCH 5/6] Cache iOS display size for thread-safe access --- .../CodenameOne_GLViewController.m | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Ports/iOSPort/nativeSources/CodenameOne_GLViewController.m b/Ports/iOSPort/nativeSources/CodenameOne_GLViewController.m index e8b8be6a08..6ae0ae07bf 100644 --- a/Ports/iOSPort/nativeSources/CodenameOne_GLViewController.m +++ b/Ports/iOSPort/nativeSources/CodenameOne_GLViewController.m @@ -158,6 +158,14 @@ JAVA_INT getSafeTop() { BOOL firstTime = YES; BOOL retinaBug; float scaleValue = 1; + +static void updateDisplayMetricsFromView(UIView *view) { + if (view == nil) { + return; + } + displayWidth = (int)(view.bounds.size.width * scaleValue); + displayHeight = (int)(view.bounds.size.height * scaleValue); +} BOOL forceSlideUpField; @@ -1435,10 +1443,6 @@ void vibrateDevice() { * Signature: ()I */ int Java_com_codename1_impl_ios_IOSImplementation_getDisplayWidthImpl() { - //if(displayWidth <= 0) { - displayWidth = [CodenameOne_GLViewController instance].view.bounds.size.width * scaleValue; - //} - //CN1Log(@"Display width %i", displayWidth); return displayWidth; } @@ -1450,10 +1454,6 @@ int Java_com_codename1_impl_ios_IOSImplementation_getDisplayWidthImpl() { int Java_com_codename1_impl_ios_IOSImplementation_getDisplayHeightImpl() { //GET_DIPLAY_HEIGHT_MARKER - - //if(displayHeight <= 0) { - displayHeight = [CodenameOne_GLViewController instance].view.bounds.size.height * scaleValue; - //} return displayHeight; } @@ -1895,6 +1895,7 @@ - (void)viewDidLoad { [self.view addSubview:self.adView]; [self.adView loadAd]; [super viewDidLoad]; + updateDisplayMetricsFromView(self.view); //replaceViewDidLoad [self initGoogleConnect]; } @@ -1906,6 +1907,7 @@ - (UIViewController *)viewControllerForPresentingModalView { #else - (void)viewDidLoad { [super viewDidLoad]; + updateDisplayMetricsFromView(self.view); //replaceViewDidLoad [self initGoogleConnect]; } @@ -1995,8 +1997,8 @@ -(void)updateCanvas:(BOOL)animated { // details, so it is possible that the size change event still needs to be sent // even if the display width already matches the value we're given here. [[self eaglView] updateFrameBufferSize:(int)self.view.bounds.size.width h:(int)self.view.bounds.size.height]; + updateDisplayMetricsFromView(self.view); displayWidth = currentWidth; - displayHeight = (int)self.view.bounds.size.height * scaleValue; screenSizeChanged(displayWidth, displayHeight); //} @@ -4029,5 +4031,3 @@ - (UIViewController *) documentInteractionControllerViewControllerForPreview: (U @end - - From 13eb0d6d6d5180908b8f039050edfdcd7321edbe Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 16 Jan 2026 21:24:56 +0200 Subject: [PATCH 6/6] Fix background UI access test conversion call --- .../hellocodenameone/tests/BackgroundThreadUiAccessTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BackgroundThreadUiAccessTest.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BackgroundThreadUiAccessTest.java index 14e8600613..0e699f2211 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BackgroundThreadUiAccessTest.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/BackgroundThreadUiAccessTest.java @@ -10,7 +10,7 @@ public boolean runTest() { try { Display display = Display.getInstance(); int width = display.getDisplayWidth(); - int pixels = display.convertToPixels(10.0f, true); + int pixels = display.convertToPixels(10, true); UIManager manager = UIManager.getInstance(); if (width <= 0 || pixels <= 0 || manager == null) { fail("Unexpected display metrics: width=" + width + " pixels=" + pixels);