Repository navigation
Commit ebe0e64
Run classic Android applications as Codename One applications (#5941)
* Run classic Android applications as Codename One applications
An Android Studio module's src/main (manifest, res/, assets/, Java and
Kotlin) placed in common/src/main/android, or imported with
cn1:import-android-project, builds unmodified for every target.
- maven/android-res-compiler compiles the manifest and resources at build
time into R classes, a binary resource table and a generated AndroidApp
that news every activity and view: no XML parsing or reflection on the
device.
- maven/android-compat is the android.* API written over Codename One,
with AndroidX AppCompat, Fragment, Lifecycle, RecyclerView,
ConstraintLayout and Material Components.
- remap-android relocates android/, androidx/ and material classes so the
same shim runs on Android too, maps the JDK classes CLDC lacks to shims,
and generates the onClick, fragment, ViewModel and JS-bridge
dispatchers. Kotlin is compiled before javac and relocated after it.
- Maven goals and Gradle tasks for both steps, the archetype profile, an
integration test over scripts/android-compat-samples and its workflow.
- scripts/hellocodenameone compiles the gallery sample and runs 13
screenshot tests on every port.
- Developer guide chapter with side-by-side captures of the gallery built
natively and built with Codename One on the same emulator.
Fixes the work needed outside the new modules: Form.initLaf dropping the
toolbar's back command, DateFormatSymbols/SimpleDateFormat month handling,
Kotlin's static wrapper hashCode/compare, JavaSE clip restore under
transforms and hard-stop gradients, Maven local builds ignoring changed
dependencies, and a hello test leaking the Android keyboard.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix CI and address review findings on Android compatibility
CI:
- The Maven plugin declares codenameone-android-compat (provided, optional),
so the jobs that install "-pl codenameone-maven-plugin -am" build the
runtime hellocodenameone now depends on.
- SpotBugs: the Gradle remap action's lazy FileCollections join the
documented EI_EXPOSE_REP2 exclusions; File gets a serialVersionUID.
- PMD: Form's toolbar menu bar check compares identity on purpose.
- LiveDataTest ran on the JUnit thread, which stops counting as the main
thread once another test starts the EDT; MainThreadRule runs it there.
- The Android interop chapter's snippets are includes: shell in the common
snippets, Java in a new docs/demos/android-interop module that compiles
them against the runtime and a generated AndroidAppImpl.
Review:
- A generated main class is deleted once the application writes its own,
on unchanged-resource runs too.
- Deleting assets, the last one included, clears their index and copies.
- import-android-project wires the runtime, compile-android-res and
remap-android into an existing project's pom, or stops naming what to add.
- Kotlin compiles in process-resources, after the process-sources
generators.
- Three-letter locale languages (fil) match their resources.
- Intent.resolveActivity answers for implicit intents the runtime handles.
- LiveData.postValue hands the value to the EDT and shares no field across
threads.
- SharedPreferences: the last edit of a key wins.
- ACTION_SEND forwards its EXTRA_STREAM file, or refuses one it cannot open.
- Resuming refreshes the configuration changed in the background.
- The File shim is Serializable, as the JDK class is.
- Runtime extraction refuses entries outside the classes directory, and the
vendored ConstraintLayout solver spells out its float narrowing.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix native and JavaScript builds of Kotlin code; isolate runtime tests
ParparVM mangled '$' out of class and method names but left '-', which
Kotlin 1.4-1.7 put in lambda names (onCreate$lambda-1 and the classes
inlined into them). The generated C read "_lambda-1__inlined_sortedBy_1" as
a subtraction and did not compile on any native target. Every site that
maps '$' now maps '-' too; HyphenatedNamesIntegrationTest translates and runs
such names.
JavaScript port:
- build-javascript-port-hellocodenameone.sh copied the dependencies to a
relative path Maven resolved against the module, so the Kotlin runtime
never reached the translator.
- LocalForage.setItem unwrapped the host call's empty answer, so every
FileSystemStorage.mkdir threw.
Runtime:
- Letter-spaced text is measured a character at a time, as it is drawn;
measured whole it was narrower wherever the font kerns, and the browser
clipped every Material label.
- A Dialog host is put back without a second modal loop, which blocked
finish() forever.
- Notification action intents are pinned to the application's package
(CodeQL implicit PendingIntent).
Tests: every runtime test runs on the EDT (MainThreadRule), and activity
tests start from a clean display. A fragment test executing transactions on
the JUnit thread raced the EDT, Codename One's error dialog became the next
test's host form, and finish() hung the plugin test job.
Docs: the side-by-side images quote their alt text.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Refresh every edited constructor's inlining plan after dead field elimination
DeadFieldElimination collected the methods it edited in a HashSet, but
BytecodeMethod.equals compares name and signature only -- it serves override
matching -- so of two edited constructors with the same signature in
different classes only one was kept and re-planned. The other's call sites
kept inlining a store to the field just removed, and the generated C assigned
a struct member that no longer existed: the Windows build of the hello suite
failed on WindowsWindowManager.Peer.windowId once the Android compatibility
gallery added another (int, int) constructor with a write-only field.
The set is now by identity. DeadFieldInlinedConstructorIntegrationTest
builds and runs two such constructors.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Recapture the Android interop side-by-side images
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Memoize the static accessor fold so its include is never missing
optimize() drops CHECKCAST in place, so Kotlin's emptyList() body
(GETSTATIC; CHECKCAST; ARETURN) became foldable only after its class was
emitted. A later caller folded the call to the field read while the
dependency scan had not added the field owner's header, and clang
rejected the undeclared get_static_ accessor on the Windows target.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Bind the JavaScript port's static interop stubs
JSString.valueOf, JSNumber.valueOf, JSBoolean.valueOf, Int32Array.create,
Int16Array.create and Window.encodeURIComponent had Java bodies that
return null and no port.js binding, and the JSO bridge never dispatches
static members. JSString.valueOf answering null made every
LocalForage.setItem(String, String) a delete, so FileSystemStorage.mkdir
never created a directory and a write under a new one failed. A node gate
derives every stub's binding name and fails when one is unbound.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Seed the AndroidCompat goldens for Android and JavaScript
Taken from the CI captures of 9c45a32b. The JavaScript Data screen is left
out: it captured the file-system failure the interop binding fix addresses.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Return LocalForage values from the bridge without a cast
A stored string, such as the empty directory marker that mkdir now really
writes, crosses back as a java.lang.String; the JavaScript VM checks casts,
so the cast to JSObject threw ClassCastException out of every isDirectory.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Seed the AndroidCompat goldens for the Windows port
Taken from the cross-built Windows capture of c011d073. The action bar is
absent by design: in the desktop native title-bar mode the title and the
commands go to the OS window and its menu bar.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Seed the AndroidCompat goldens for the Linux port
Taken from the x64 and arm64 captures of c011d073 (the two are identical).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Unwrap JavaScript strings without casting them to JSString
The bridge hands every JS string to Java as a java.lang.String, whatever
type was declared, and the JavaScript VM checks casts. Assigning a key of
LocalForage.keys() to a JSString threw, keys() swallowed it and answered
no keys, so FileSystemStorage.listFiles was always empty on this port.
LocalForage.getString and JS.unwrapCharArray cast the same way.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Seed the JavaScript AndroidCompatData golden
Taken from the CI capture of 4fec0846, the first round in which the
JavaScript port lists the files directory.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Rebaseline hello's translation memory on the Windows AMD runners
hello now carries the Android compatibility gallery, the relocated runtime
and the Kotlin stdlib, so translating it holds more classes. Measured on two
AMD runs (0.93x, 1.02x); the Intel row stayed within tolerance.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Recalibrate hello's Windows AMD memory row from three runs
The third AMD run measured 1.19x on unchanged code: JDK 25's footprint
stays near its heap-policy floor while ParparVM's follows hello's larger
live set, and JDK's own rounds swing to 1.6-2 GB. Median and spread of the
three runs: 1.025, tolerance 25%.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Rebaseline hello's translation memory on Windows arm64 too
Same cause as the AMD row: one arm64 run measured 1.17x (rounds 0.84-1.27,
JDK 25 swinging 961-1387 MB). One run cannot estimate its own spread, so
the row takes the 25% the AMD row needed, as calibrate does for new rows.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Seed the AndroidCompat goldens for iOS (Metal, Xcode 27) and Mac Catalyst
Taken from the CI captures of 35421349.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix five Android compatibility runtime review findings
- ActivityThread: a result-producing child finishing while its caller has a
pending relaunch now re-points the finished record's caller at the
recreated instance, so onActivityResult is no longer dropped.
- SQLiteOpenHelper: onBeforeDelete receives the obsolete database while it
is still open, before it is closed, deleted and recreated, as on Android.
The delete goes through the context, the way the database was opened.
- SQLiteDatabase: transaction nesting is per thread (ThreadLocal stack). A
second thread beginning a transaction while another thread's is open on
the single engine connection gets SQLiteDatabaseLockedException instead of
silently nesting into it; no locks are added.
- Dialog: the Codename One host routes any dispose the wrapper did not ask
for through it -- an outside tap cancels, anything else dismisses -- so
cancel/dismiss listeners, onStop() and detach run and isShowing() clears.
- Looper: the main looper is bound lazily to the EDT (prepareMainLooper,
called before an activity starts, and any main-looper lookup on the EDT),
so getMainLooper().getThread() is no longer null.
Each fix has a test that fails without it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Match intent filters whole, name assets collision-free, compare resources by bytes
Intent filters: the resource compiler flattened every activity
<intent-filter> to its action strings, and activityForAction() picked the
first activity with the action before the platform got a turn, so an
ACTION_VIEW filter for a custom scheme captured every browser, dialer and
share intent. The compiler now keeps each filter whole (actions,
categories, schemes, host/port, path and ssp patterns, MIME types) and
generates IntentFilter calls; the runtime's IntentFilter implements
Android's match() rules and a new android.os.PatternMatcher reproduces
Android's simple glob. activityForIntent() adds CATEGORY_DEFAULT as
implicit starts do and picks the most specific match. A filter using a
constraint the runtime cannot evaluate (advanced patterns, mimeGroup,
resource references) is dropped with W0304 rather than kept without it.
Assets: flat names used String.hashCode() of the path, so Aa/file.txt and
BB/file.txt shared one output file. They now use a SHA-256 prefix of the
whole path, and two assets claiming one (case-folded) name fail the build.
Remap: a runtime-jar resource was re-extracted only when its length
changed, so a rebuilt resource table of the same length kept the stale
copy. Resources now get the same byte comparison as classes.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Rebaseline hello's translation memory on Linux x64 (EPYC 7763)
hello now translates the Android compatibility gallery with its relocated
runtime and the Kotlin stdlib, so ParparVM's peak RAM ratio rose from 0.84x
to 1.02x on the EPYC 7763 runners, as it already did on Windows.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Pin the light appearance for the AndroidCompat screenshots
The runtime answers night mode from CN.isDarkMode(). The tvOS simulator
defaults to dark, so the gallery resolved its values-night card colour
(#303030) under the light theme's dark text and AndroidCompatMain captured
an unreadable row. Pin light for the capture and restore the host setting
afterwards, so the baselines no longer depend on the host's appearance.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Seed the AndroidCompat goldens for watchOS, tvOS and macOS
From run 37173812053 (watch, tv) and 37173811895 (macos) at b0f0836a00.
macOS has no action bar (the desktop native title bar takes the form
title). tvOS AndroidCompatMain is left out: it was captured in dark mode,
which the previous commit pins away.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix four Android compatibility review findings, document two pushbacks
- Bundle.deepCopy() copies nested bundles, lists and arrays instead of
sharing them through the shallow copy constructor.
- Uri.normalizeScheme() lower-cases the scheme (ASCII fold, not the
locale-sensitive toLowerCase()).
- SharedPreferences: edit().clear() reports every key it removed to the
change listeners.
- Resource matching keeps the script of b+ locale qualifiers, so
values-b+zh+Hans and values-b+zh+Hant are chosen by the device's
script (explicit, or implied by a Chinese region). The locale parser
no longer reads a script segment as the language or the region.
- Intent.getExtras() stays a copy: Android's is new Bundle(mExtras).
- SQLiteStatement.executeInsert() gets no lock: the finding's premise
is two threads sharing one database; single-threaded use is exact.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Test that a theme refresh keeps a toolbar form's back command
Form.initLaf replaced any menu bar whose class was not the look and
feel's, and a Toolbar's ToolbarSideMenu never is, so every form of a
global-toolbar application lost its menu bar -- and with it the back
command the hardware back key runs -- on refreshTheme(), on a system
dark mode change (UIManager.refreshNativeThemeSettings), and on show()
under a theme without form transitions. The guard added earlier on this
branch fixes that in core; FormToolbarThemeRefreshTest fails without it
and the comment now says which ordinary paths it covers.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Clip paths within the clip, rotate bitmap pixels, keep spans in subsequences
- Canvas.clipPath intersects the path with the current clip when it
reaches outside it, instead of replacing the clip.
- Bitmap.createBitmap with a rotating, mirroring or skewing matrix samples
the source through the inverse matrix (bilinear when filtering); plain
positive scales still use the port's scaling.
- Handler.postAtFrontOfQueue / sendMessageAtFrontOfQueue go ahead of due
work on both the main and background loopers.
- WebView.canGoBackOrForward answers false for distances the browser
cannot confirm (more than one entry).
- SpannableString/SpannableStringBuilder subsequences keep their spans,
clipped and offset; SpannableStringBuilder.subSequence no longer
recurses into itself.
- ViewGroup: documented why the intercepting event only cancels the child.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Seed the AndroidCompat goldens for iOS Metal and the tvOS main screen
All 13 iOS Metal references and the tvOS AndroidCompatMain reference come
from run 37203007638's ios-ui-tests-metal and tv-ui-tests artifacts. The
tvOS capture is now light, because the test pins the light appearance.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Rebaseline hello's RAM ratio on the AMD family 26 Windows x64 runner
This is the same cause as the other rows: the Android compatibility gallery
makes hello's translation input larger. The value comes from run
37203007339's perf-results.json. The memory tolerance is widened to 0.25,
as it already is on the other single-run Windows rows.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix six Android compatibility review findings, document one pushback
- LifecycleRegistry: dispatch over a snapshot, so an observer removing
itself no longer makes the next one miss the event.
- ActivityThread: onRestoreInstanceState and onPostCreate run after
onStart, in the first start of a created activity.
- BackStackRecord: a self-replacement on the back stack uncounts the
fragment it no longer references; a primary navigation change counts
the previous primary fragment the pop uncounts.
- SupportFragmentManager: pending fragment results are saved with the
platform manager's state and restored into the recreated facade.
- View: every view posts through one main-thread handler, so
removeCallbacks cancels what post queued.
- GroupPeer: a root paint dispatches the tree observer's pre-draw and
draw listeners; a cancelling pre-draw schedules another pass.
- SavedStateViewModelFactory: comment why the owner is not kept (no
process death; relaunch always carries the view model store).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix six Android compatibility review findings
- ResourceManager keeps a three-digit UN M49 region (es_419), so
values-b+es+419 can match; it was cut to "41".
- Uri.fromFile keeps an existing file: scheme instead of producing
file://file:///... for context directories.
- PluralRules gives Persian Hindi's "i = 0 or n = 1" rule (0 and 1 are ONE).
- Intent.cloneFilter copies the package and categories.
- File.getCanonicalPath resolves . and .. segments, so containment checks
cannot be bypassed with root/../outside.
- Gradle relocates Kotlin's classes in cn1RemapAndroidKotlin, a task that
finalizes compileJava and runs every build; as a compileJava action it
never ran when javac was up to date (an ABI-unchanged Kotlin edit, or the
build right after a relocation).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix three Android compatibility review findings, document two pushbacks
- AndroidProjectImporter matches a dependency's whole group:artifact against
the covered list; prefix matching reported androidx.core:core-splashscreen
as covered by androidx.core:core. kotlin-stdlib-jdk7/jdk8 are listed
explicitly so they stay covered.
- Parcel writes at the current position and advances it, overwriting a
value already there, so a Parcelable can reserve a size slot and seek
back to fill it in.
- SQLiteDatabase opened OPEN_READONLY refuses writes through the Android
API (execSQL, insert, update, delete, setVersion, compiled statements)
with SQLiteReadOnlyDatabaseException; reads, pragmas and transactions
still run.
- SharedPreferences commit and SQLiteOpenHelper first-time open stay
unsynchronized: both findings assume concurrent threads, which the
single-threaded runtime does not guard. Explained in code comments.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix seven Android compatibility review findings
- Broadcast receivers match their whole IntentFilter (data, type,
categories), consistent with activity filters, not the action alone.
- getLaunchIntentForPackage answers null for any package but this one.
- getDrawableForDensity picks and scales image variants for the requested
density instead of the device's.
- A child finished below the top of the stack delivers its result to its
caller, queued until the caller's next resume.
- Window focus changes are dispatched through the decor view tree, so a
covered activity's views report hasWindowFocus() false.
- Single-line TextView and TextUtils.ellipsize honour START and MIDDLE.
- The resource compiler leaves out activities declared
android:enabled="false".
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Chain the Windows x64 family 25 hello rebaseline on #5940's
#5940 merged a noise recalibration of windows-x64@amd64-family-25 hello/all
(time 1.221, time tolerance 0.45) from the same row this pull request
rebaselines. perf_baseline.resolve refuses two rebaselines from one value,
which failed test_perf_gate.py and the baseline check in every perf-gate job
(Linux and Windows suites, screenshot-capture, check, build). Name #5940's
result as this row's "from" and keep its time and time tolerance, so the
rebaseline only raises the memory ratio this pull request measured.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix six Android compatibility review findings, document one pushback
- EditText: mutations through the live Editable (clear, replace, append)
now reach TextWatchers; the change hook reports the replaced range.
- Bitmap.compress: WebP requests fail instead of writing PNG bytes.
- BitmapFactory: outMimeType is read from the data's signature.
- ObjectAnimator: a naturally finished auto-cancel animator leaves the
static registry (and no longer pins its target).
- Looper.quitSafely: messages already due are delivered before exit.
- Path.transform: the current point and contour start are mapped too.
- RecyclerView child drawing order: documented as not applied, consistent
with the runtime ignoring every per-child paint order.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix six Android compatibility review findings, document one pushback
- Importer: a repeated import keeps the existing .pre-android-import backup
instead of overwriting the original main class with the generated one.
- PackageManager: resolveActivity/queryIntentActivities fill activityInfo
name and package from the component the runtime would start.
- ContentResolver: file: URIs keep their authority (file://home/... on
sandboxed ports) when opening storage streams.
- BufferedReader shim: mark/reset supported across refills, up to the
read-ahead limit.
- android:launchMode reaches the runtime: singleTop reuses the top
instance, singleTask/singleInstance clear onto the existing one and
deliver onNewIntent (one task, no affinity).
- SharedPreferences: committing an unchanged value notifies no listener.
- Resources formatting with the resource locale: pushed back in a code
comment; the device String.format is locale independent and no
String.format(Locale, ...) exists in JavaAPI or CLDC11.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix two Android compatibility review findings, document one pushback
- A plain FLAG_ACTIVITY_CLEAR_TOP launch of a standard-mode activity now
finishes the existing instance and creates a new one, as Android does;
only single-top and single-task targets are reused through onNewIntent.
- Path.addRoundRect honours Direction.CCW, so an inner CCW rounded
rectangle cuts a hole in a CW contour under the non-zero rule.
- Intent.getExtras() keeps returning a copy: AOSP returns
new Bundle(mExtras) too; the comment now says so unambiguously.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Diff the perf-baseline check against the merged base; recalibrate hello RAM on Windows AMD family 26
perf-baseline's check diffed `pull_request.base.sha...HEAD`, but CI
checks out the pull request merged into the current base branch while
base.sha is not refreshed when that branch moves. Everything master gained
since -- here #5940's pr/5940.json -- read as this pull request writing
another one's overlay. On a merge commit whose first parent descends from
the given base, the first parent is now the base.
The family 26 Windows x64 hello RAM row was set from one run (0.879x);
the next measured 0.62x with JDK 25's peak swinging 1.2-1.9 GB between
rounds. Recalibrated from both runs.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix six Android compatibility review findings, document one pushback
- A finishing activity is no longer asked to save its state; destroy()
marks it finishing before pause/stop, as Android does.
- Uri.getQueryParameters keeps a literal '+', as Android's does;
getQueryParameter still reads it as a space (documented Android
behaviour, so that half of the finding's premise does not hold).
- MessageQueue.removeIdleHandler now cancels pending and future runs.
- AbsSpinner refreshes the selected row id after a data change that
keeps the selected position.
- An android:theme on <include> themes the included tree and overrides
the included root's own theme.
- The Android importer XML-escapes the values it injects into the copied
manifest (a versionName like "1.0 & beta").
- Pushback, documented in ActivityThread: explicit-component and
setPackage() packages are not checked, because the runtime's package
is the manifest namespace rather than the Gradle applicationId.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix five Android compatibility review findings
- Matrix.mapPoints walks backwards when an in-array destination overlaps
the source further along, so no point is mapped from an already
mapped one.
- SpannableStringBuilder.replace copies the inserted text's spans, so
append(Spanned) and TextUtils.concat keep their styling.
- ViewGroup hit-tests and dispatches touches through the inverse of a
child's scale/rotation about its pivot (legacy animations stay
excluded, as on Android).
- Canvas.save/restore keeps a clipPath shape instead of its bounds.
- Canvas.drawColor(..., CLEAR) erases the clip of a bitmap canvas with
Graphics.clearRect; on a view canvas it stays a no-op.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix three Android compatibility review findings
- MessageQueue: a background looper's idle handlers run on that looper's
thread, once each time its queue runs out of due messages, instead of on
the EDT. Looper keeps one queue (getQueue() used to return a new one per
call, so removal through a second call did nothing) and gains myQueue().
- Handler: a message sent to a background looper after quit() or
quitSafely() is refused and not retained, as on Android.
- LayoutInflater: children of a <merge> root (included or top level) join
the parent without calling its onFinishInflate(), which ran early and
twice.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Recalibrate hello RAM on Windows x64 AMD family 25 from eight runs
The row was set from three runs at 1.025x +-25%; the merge with master's
hybrid GC measured 0.94x and 0.74x on two consecutive runs of the same
code, and earlier runs ranged 0.93x-1.19x. Recalibrated from all eight
family-25 runs: 0.938x +-45%. Time is unchanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix six Android compatibility review findings, document one pushback
- A no-history activity is finished when another activity covers it,
so finishing the new one returns to the activity beneath.
- The back key dispatches ACTION_UP after ACTION_DOWN, so a handler
that claims the down and acts in onKeyUp runs.
- Dialog.isShowing() is false after hide().
- Unchecking the checked RadioButton clears the group's checked id.
- Fragment result launchers register when the fragment is created,
under a request code derived from the fragment's identity, so a
result returning to a recreated activity reaches the new fragment.
- An item added to a filtered ArrayAdapter shows only when the active
constraint keeps it.
- AbstractCursor keeps AOSP's answer for an empty cursor (both before
first and after last); documented in place.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix six Android compatibility review findings
- SharedPreferences commit() returns the storage write's result instead of
always true.
- Bitmap.createBitmap of a mutable source (full-size crop, plain copy) and
copy(config, false) snapshot the image instead of aliasing it.
- TextUtils.split evaluates its separator as a regular expression through
Codename One's RE, keeping trailing empty strings; plain separators keep the
literal fast path.
- LengthFilter backs the cut off a high surrogate, as Android does.
- Writing to Bundle.EMPTY throws UnsupportedOperationException.
- The Android project importer records what it copied (path and SHA-256) and a
re-import removes recorded files the project no longer has, keeping any file
the developer added or edited.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix five Android compatibility review findings
- SharedPreferences: a commit consumes the editor's batch, so a reused
editor neither re-applies old values nor repeats an earlier clear().
- Uri.decode: an unescaped surrogate pair is UTF-8 encoded whole instead
of as two replacement characters.
- recreate()/config relaunch destroys without finishing: isFinishing()
stays false in onDestroy, as on Android.
- A reused singleTop/singleTask activity keeps its launch intent; the
new one reaches onNewIntent only.
- Canvas drawing into a bitmap drops the bitmap's cached pixel array, and
follows the image a later setPixel replaced, so reads and writes see
the drawing.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix two Android compatibility review findings
Gradle read the android:onClick names from build/android-res/onclick.txt,
but compileAndroidRes hands build/android-res to the runner as its build
directory and the runner writes android-res/onclick.txt beneath it, so
every Gradle build generated no onClick handlers. Both plugins now take
the path from AndroidResourceRunner.onClickNamesFile.
A re-import overwrote the generated entry point unconditionally once the
.pre-android-import backup existed, losing a developer's customization.
It is now kept, as an edited imported file is.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Rebaseline hello RAM on Linux x64 AMD EPYC 9V74
The first run of this pull request on that runner model measured hello's
RAM ratio at 0.96x against master's 0.79x; the larger translation input
is the same cause recorded for the other runner models.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Rebaseline objectAllocation on the Linux x64 AMD EPYC 9V74 runner
#5940's hybrid GC made objectAllocation about 4x faster and #5940
rebaselined it on other runner models, but not on the 9V74, so a pull
request landing there failed as IMPROVED. Calibrated on top of master.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Give the iOS Metal screenshot jobs room for the larger hello suite
The hello suite now compiles the Android compatibility gallery, its
runtime and the Kotlin stdlib. build-ios-metal-27 took 55-76 minutes on
this branch against 54 on master and timed out at its 75-minute limit
mid-compile. Raise both Metal jobs to 95 minutes and their UI-test step
to 80.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix four Android compatibility review findings
- TextView.setText runs the InputFilter chain over the new text, so
android:maxLength and custom filters bind programmatic and XML text.
- A TextView with watchers keeps an editable buffer, so afterTextChanged
is delivered (setText and append), as on Android.
- ImageView pushes a cleared color filter / tint (null) to its drawable
once the view has set one, instead of leaving the stale value.
- ProgressBar draws a configured indeterminate drawable over its content
box, sweeping its level like Android does.
setOnClickListener(null) still makes the view clickable: that is what
Android itself does; the reason is recorded beside the code.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix four Android compatibility review findings
- MessageQueue.isIdle answers from a background looper's queue: a due
message makes it busy, a later one does not. The main looper still
answers true; its messages are per-handler EDT callbacks with no single
queue to ask, and idle work belongs in addIdleHandler.
- Uri.getEncodedQuery returns null for an opaque URI (the ? in a mailto is
part of its scheme-specific part) and for a ? inside the fragment.
- Bitmap.setPixel, setPixels and eraseColor throw IllegalStateException on
an immutable or recycled bitmap, as on Android; an immutable bitmap can
be the same object another createBitmap call returned.
- AbsListView cancels the press and pending long press when the pointer
leaves the list by more than the touch slop, and a release beside the
list clicks nothing.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix three Android compatibility review findings
- CLEAR_TOP finishes the activities it removes: a result they owe
(RESULT_CANCELED by default) reaches their caller, as Android does.
- A GetContent launcher's gallery result goes through the registration
map, so a launcher unregistered while the picker is open hears nothing.
- Implicit resolution asks the same question startActivity() does, so a
resolveActivity() guard no longer passes a dial without a number or a
chooser without an intent.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix four more Android compatibility review findings
- GridView STRETCH_SPACING_UNIFORM shares the leftover among n + 1 gaps
for a single column too, centring it instead of pushing it to the edge.
- A layout-direction change re-resolves the start/end padding of every
descendant that inherits the direction, and a view joining a parent
resolves its relative padding against that parent.
- A ViewGroup's visibility change reaches every descendant's
onVisibilityChanged, as on AOSP.
- ValueAnimator.reverse() on a repeated animator mirrors against the end
of the last iteration (or within the current one when infinite), so the
value carries over instead of snapping to an endpoint.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix four more Android compatibility review findings
- A singleTop activity reused at the top is paused before onNewIntent()
and resumed after it, as Android does.
- Dialog.cancel() notifies its OnCancelListener once until the next show().
- RippleDrawable restores the child's own color filter after the pressed
overlay instead of clearing it.
- InsetDrawable.setDrawable() brings the replacement up to the wrapper's
visibility, state, level and inset bounds, and invalidates.
- ImageView.getImageMatrix() keeps returning the draw matrix, which is
what AOSP returns; documented why.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Rebaseline objectAllocation RAM on the AMD EPYC 9V45
#5940's hybrid GC rebaselined objectAllocation's time on this runner model
but carried the pre-hybrid RAM ratio (0.363) forward. The run on this PR
measured 0.24x (rounds 0.22-0.30), failing the Linux x64 perf gate as
IMPROVED. Every AMD x64 model measured since #5940 shows the same drop
(EPYC 7763 -21%/-25%, 9V74 -7% to -22%), so record the measured ratio
as a PR overlay row, the way objectAllocation's time was recorded for
the 9V74.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix five more Android compatibility review findings
- A read-only database refuses PRAGMAs stored in the file
(user_version, journal_mode, ...); connection-local ones still run.
- A recycled bitmap refuses pixel reads, copy and compress.
- Private-file names refuse a backslash, which the File shim treats
as a separator.
- new Handler() on a thread without a looper throws, as on Android,
instead of binding to the main looper.
- An unchanged incremental build regenerates the entry point after
the application deletes its own main class.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Show the Playground smoke host on the EDT and fail fast on a failed check
HarnessSupport.context() called show() from the main thread, which only
queues the form switch, so smokeFormShowIsCaptured raced the EDT and
failed whenever a slow frame was still painting. A failed check then left
the JavaSE port's non-daemon threads running until the CI watchdog killed
the JVM 15 minutes later; main now exits non-zero instead.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix six more Android compatibility review findings
- rawQuery and simple queries on an OPEN_READONLY database go through the
same read-only check as statements; WITH-led statements read unless they
contain a data-changing keyword.
- Database names refuse a backslash, like file names.
- getStringExtra answers null for a non-String extra.
- A detached View has no handler and holds posted work until it is attached.
- SystemClock reads the monotonic System.nanoTime(); input events are
stamped in the uptime base.
- A finishing child's result is queued so the stopped caller is restarted
before onActivityResult.
- Clarify the push-back comments on SharedPreferences commits,
SQLiteOpenHelper initialization and intercepted touch dispatch.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix four more Android compatibility review findings
- ActivityThread: FLAG_ACTIVITY_REORDER_TO_FRONT moves the existing
instance to the top (onNewIntent, activities above it kept) instead of
stacking a duplicate.
- ActivityThread: an activity recreated for a configuration change keeps
FLAG_ACTIVITY_NO_HISTORY.
- ComponentActivity: a contract's synchronous result is posted to the
main queue, as AndroidX does, rather than delivered inside launch().
- ArrayAdapter: insert() under an active filter places the item after
its displayed predecessors, not at the unfiltered index.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix five more Android compatibility review findings
- Canvas.drawText covers the width measureText reports when textScaleX is
not 1: glyphs are stretched where the graphics can transform, and their
advances are scaled elsewhere.
- SharedPreferences.getString/getStringSet throw ClassCastException for a
present value of another type, as on Android and as the other getters.
- SharedPreferences.apply updates memory at once and writes once later
through the main thread's queue; a commit in between writes everything.
- BitmapDrawable honours its target density (the screen's with Resources,
160 without, or setTargetDensity) for intrinsic size, gravity and tiles;
a bitmap's density now defaults to the device's, as on Android.
- File.renameTo fails, and takes back a copy it created, when the source
of a cross-directory move cannot be deleted.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix four more Android compatibility review findings
- TextView: BufferType.SPANNABLE text is kept as a SpannableString.
- Uri: getBooleanQueryParameter reads "false" in any case as false
(equalsIgnoreCase, no locale-sensitive folding).
- CookieManager: cookies set with Expires or Max-Age survive
removeSessionCookies()/removeSessionCookie().
- SimpleAdapter: the filter keeps rows whose bound values, or a word of
them, start with the constraint, and an empty one restores every row.
- CancellationSignal: documented why the state stays unsynchronized.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix three more Android compatibility review findings
- BitmapFactory: outWidth/outHeight are written before the density
scaling, where AOSP's decoder writes them, so a bounds probe over a
resource reports the image's own (sampled) size. inSampleSize keeps
dividing exactly: AOSP fine-scales to width / inSampleSize rather than
rounding to a power of two, despite the Options javadoc.
- Canvas: drawBitmap refuses a recycled bitmap, as BaseCanvas does.
- Matrix: IDENTITY_MATRIX is immutable; every mutator throws.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix Path.addPath(this) loop; document Android-matching Rect/LayerDrawable/MatrixCursor behaviour
Path.addPath with itself as the source read operations it was appending
and never terminated; snapshot the source first. Rect.union(x, y),
LayerDrawable.findDrawableByLayerId and MatrixCursor.RowBuilder.add(name)
already match AOSP exactly, so they keep that behaviour with a comment
saying why.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix five more Android compatibility review findings
- TextView: NORMAL setText keeps an immutable snapshot through a real
TextUtils.stringOrSpannedString, so later edits of a caller's builder
no longer change getText() behind filters, watchers and layout.
- View: the background tint mode is stored on the view and applied to
replacement backgrounds, like the tint list.
- Message.obtain(Message) copies replyTo and gives the copy its own Bundle.
- SpannableString/SpannedString/SpannableStringBuilder equality and hash
include spans and only match other Spanned values (symmetric with String).
- SpannedString no longer extends SpannableString; both share a
package-private SpannableStringInternal, so SpannedString is not Spannable.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix three more Android compatibility review findings
- Paint.getTextWidths and breakText include letter spacing in each
character's advance, matching measureText and Canvas.drawText.
- Matrix.setValues refuses a non-affine third row instead of storing
perspective terms that mapping, concatenation, inversion and drawing
all ignored.
- Bitmap getPixel/setPixel/getPixels/setPixels validate each coordinate
against its own dimension, as Android does, instead of indexing into
a neighbouring row of the flattened pixel array.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix four more Android compatibility review findings
- View.getGlobalVisibleRect/getLocalVisibleRect cut the view's bounds to
every ancestor's on-screen box and the display, so a scrolled-out or
overhanging child is no longer reported fully visible.
- setKeepScreenOn is held per view and aggregated over attached views;
one view clearing it (or detaching) no longer re-enables the screen
saver while another still asks, and getKeepScreenOn reports the flag.
- TextView keeps start/end compound drawables relative and re-resolves
them from the new View.onRtlPropertiesChanged hook when the layout
direction changes, directly or by inheritance.
- ViewTreeObserver keeps window-focus listeners and the root view notifies
them from dispatchWindowFocusChanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Composite translucent saveLayer offscreen; clip rotated rects as shapes; honour drawPaint shader
saveLayer/saveLayerAlpha with a translucent alpha now draw into an
offscreen image the size of the clip and composite it once on restore, so
overlapping draws inside the layer no longer darken each other. Where the
context already carries a transform, the alpha falls back to per-draw.
clipRect under a rotation or skew clips to the transformed quadrilateral
through clipPath instead of its bounding box. drawPaint with a shader
fills the clip through drawRect, so a LinearGradient is no longer a solid
fill.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix three more Android compatibility review findings
- The import replaces the copied manifest's package with the Gradle
namespace: the Android Gradle plugin generates R there whatever the
manifest says, and the copied tree has no build script left to say so.
- A re-import keeps an imported file (the manifest included) the developer
edited since the earlier import, warning instead of overwriting it, as
stale removal and the entry point already do.
- The generated ViewModelFactory tries every supported constructor in
AndroidX's preference order and takes the first the calling factory can
supply, so NewInstanceFactory reaches the no-argument constructor of a
class that also declares an injected one.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix five more Android compatibility review findings
- SQLiteDatabase: a statement or query from another thread while one
thread's transaction is open is refused with
SQLiteDatabaseLockedException, as beginTransaction already was; it ran
inside that transaction on the shared connection.
- Uri.fromFile percent-encodes the path (all but '/'), so '#' and '?' in
a file name no longer become a fragment or query.
- WebView.loadDataWithBaseURL reports the page by historyUrl, also when
navigating back to it.
- SpannableStringBuilder copies spans from any Spanned source.
- SharedPreferences holds change listeners weakly, as Android does.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix five more Android compatibility review findings
- Carry the manifest's android:noHistory through the resource compiler
into ActivityInfo, so it means the same as FLAG_ACTIVITY_NO_HISTORY.
- A no-history activity finished by being covered still returns its
result (RESULT_CANCELED unless it set one), on both the start and the
REORDER_TO_FRONT paths.
- A gallery result reaches the instance that replaced the activity when
it was recreated while the gallery was open.
- sendBroadcast snapshots the intent, so reusing it afterwards does not
change the queued broadcast.
- AlertDialog.setMessage updates the message view of a built dialog.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix four more Android compatibility review findings
- Bitmap.createBitmap(DisplayMetrics, ...) keeps the metrics' density.
- BitmapDrawable applies each axis's tile mode on its own: REPEAT tiles,
MIRROR flips every other tile, an unset or CLAMP axis stretches the
bitmap's edge pixels instead of tiling.
- GradientDrawable runs diagonal orientations corner to corner; Canvas
fills a diagonal LinearGradient through the port's angled gradient and
honours reversed axis-aligned endpoints.
- ObjectAnimator.setProperty renames the animator and its values holder
after the new property.
- DatePicker.setSpinnersShown: pushed back in a code comment; there is no
calendar view to swap in, so hiding the wheels would leave it empty.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix four more Android compatibility review findings
- Menu XML android:onClick: the resource compiler records menu item handler
names (menu: prefix in the onClick names file), the remapper generates
OnClickDispatch.dispatchMenu for name(MenuItem) methods returning boolean
or void, and inflation installs a listener that dispatches through it --
no reflection, same path for Maven and Gradle.
- IntentFilter.match: a null action skips the action test, as on Android.
- Uri.Builder: authority, path and query setters clear the opaque part.
- Html.fromHtml: numeric entities above U+FFFF decode to surrogate pairs.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix three more Android compatibility review findings
- File.renameTo onto the same (canonical) path succeeds without copying;
the copy path truncated and then deleted the file.
- BufferedWriter rejects write/flush after close and a second close is a
no-op, so post-close data never reaches the underlying writer.
- Letter-spaced text draws, measures and breaks a surrogate pair as one
character instead of two lone surrogates with spacing between them.
- SQLiteDatabase: document why the transaction owner stays a plain field
(single-threaded runtime; a stale read degrades to the unchecked case).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix four more Android compatibility review findings
- Back key: Activity's default onKeyDown only starts tracking and the
default onKeyUp navigates on a tracked, uncanceled up, as on Android.
ActivityThread.onBack marks the up tracked when the down asked for it,
so an onKeyUp-only override sees the key and a down claimed without
tracking still blocks back.
- startActivity snapshots the Intent, so a caller mutating it afterwards
does not reach getIntent() or onNewIntent().
- Hiding a view clears the focus of it or its focused descendant.
- EditText keeps the requested selection range and applies one requested
before the native field exists.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix four more Android compatibility review findings
- Bitmap: every derived bitmap (copy, crop, scale, matrix transform,
extractAlpha) keeps the source density, as AOSP does.
- BitmapFactory: an unscaled decode reports the source density rather
than the target's (AOSP setDensityFromOptions).
- ImageView: adjust-view-bounds and the maximum sizes request a layout
when they change, so an already laid out view re-measures.
- Color: parseColor accepts darkgrey like AOSP; transparent stays
rejected because Android rejects it too (comment in code).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix three more Android compatibility review findings
- Activity saves and restores the view hierarchy across recreation:
View/ViewGroup dispatch save/restore by id, EditText (and TextView with
freezesText) keep their text and selection, CompoundButton its checked
state; AdapterView and RecyclerView freeze only themselves, as on
Android, so recycled rows sharing an id are not all restored from one.
- A fragment detached while its started activity runs still gets the
result; only a fragment removed for good drops it.
- A child removed mid-gesture gets ACTION_CANCEL before it is unlinked.
- SQLiteDatabase keeps the transaction owner in an AtomicReference,
claimed before BEGIN and released after COMMIT/ROLLBACK, so another
thread's statement is refused reliably for the whole transaction.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Declare each Maven plugin and dependency once, which Maven 3.10 requires
The ubuntu-24.04 runner image 20261004 moved from Maven 3.9.16 to 3.10.0,
and 3.10 fails model building on a plugin or a dependency declared twice in
one list; 3.9 only warned and merged them. The Windows cross-build job died
before compiling anything, on maven/backend (build-helper twice) and
maven/cn1-admob/android (antrun twice).
The plugins' executions are merged into their first declaration, which is
the effective model 3.9 already built. The javase poms of the archetype and
the in-tree apps declared codenameone-core and codenameone-javase at both
test and provided scope; 3.9 kept the later, provided one, so the test
entries go. The archetype one matters most: every project generated from it
would fail to build on Maven 3.10. The initializr and playground templates
inside common.zip carry the same pair but their generators already strip
one of them before writing a project, so they are unchanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Recalibrate hello RAM on Windows arm64 from eleven runs
The row was set from one run at 1.167x; this pull request's eleven runs on
the Family 8 Model D49 runner put the median between 0.82x and 1.20x, with
rounds clustering near 0.8x and near 1.2x, and two of them failed as
IMPROVED. The baseline is now the median of those runs and the tolerance
their spread.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Give vm-tests room for the larger hello translation
CleanTargetIntegrationTest takes about 2450s on this branch against 1411s
on master because hello now includes the Android compatibility runtime
and the Kotlin stdlib, and the job hit its 90-minute limit seconds after
every test passed. Raise it to 120.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Close buffered streams for good and fix two TextUtils gaps
A closed BufferedReader or BufferedInputStream kept serving the data it
had already buffered; both now drop the buffer on close and throw
"Stream closed" from every later read, as the JDK classes do.
TextUtils.split with an empty expression returned the whole text instead
of one string per character plus a trailing empty one, and
commaEllipsize cut the list mid-item instead of keeping whole items and
appending the oneMore/more count suffix as Android does.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix four Android compatibility widget review findings
- ProgressBar: setMin/setMax clamp the secondary progress too (and the
primary even on an indeterminate bar), so a shrunk range no longer
leaves it past the end of the track.
- TimePicker: a null passed to setCurrentHour/setCurrentMinute leaves the
time alone instead of resetting it to midnight.
- SimpleAdapter: the default text and integer-image bindings go through
setViewText and setViewImage(ImageView, int), so subclass overrides apply.
- Spinner: dialog mode lists the adapter's getDropDownView rows in a
single-choice ListView instead of flattening items to toString().
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix five Android compatibility review findings
- BufferedOutputStream rejects write and flush after close, like the
buffered reader, writer and input stream.
- AlertDialog keeps a custom title view and shows it in place of the
title row (AppCompat's builder delegates to it).
- DatePicker tells its listeners when setMinDate/setMaxDate moves the
selection to the new bound.
- BitmapFactory answers bounds-only requests for PNG, JPEG and GIF from
the encoded header instead of decoding every pixel.
- Canvas refuses an immutable bitmap target with IllegalStateException.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix dividers, foreground gravity, scroll margins and seek capture
Weighted LinearLayout passes now add the divider space back into the
total length, so BOTTOM/CENTER gravity no longer pushes children past
the edge, and horizontal layouts draw the ending divider they reserve.
View honours a non-fill foreground gravity (FrameLayout delegates to it).
ScrollView and HorizontalScrollView include the child's margins in the
scroll range and every clamp. AbsSeekBar inside a scrolling container
waits for horizontal movement past the touch slop before claiming the
gesture; LinearLayout and GridLayout report that they never scroll.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Keep spans in AllCaps and hand selector tints to every child
InputFilter.AllCaps returned a plain String for Spanned input, dropping
every span in the inserted range; it now returns a SpannableString with
the source spans copied, as Android does.
StateListDrawable forwarded only the tint list to its children; the tint
mode stayed on the container, which never paints. It now keeps tint list,
tint mode, alpha and color filter and applies them to existing children
and to states added later.
AbsSpinner.setSelection(INVALID_POSITION) keeps the old selection; that
matches Android, whose Spinner/Gallery layout adopts only a next position
>= 0, so it is documented in code rather than changed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Redial the JS screenshot sink after the server sheds its idle socket
VideoIODecodedFrames intermittently failed on the JavaScript leg with
websocket-unavailable and screenshot-missing_actual. Most browser tests
ship through port.js's own socket, so the Java-side async sink's socket
sits unused from LottieAnimated until VideoIODecodedFrames. The CI test
server sheds a websocket idle past CN1_WS_IDLE_TIMEOUT_MS with a bare
close (browser close code 1006, logged as ws-sink-unavailable
reason=closed:1006 tests earlier in both failing runs), and the sink
latched FAILED on any close, refusing every later send.
The async state machine moves into Cn1ssAsyncSink, which names no
Codename One API: a socket that worked and then drops returns to IDLE
and is redialled by the next send, an unacknowledged send is resent once
on the new socket, stale callbacks from a replaced socket are ignored by
generation, and consecutive failed dials stay bounded so a dead server
still fails the run. The fidelity app shares the same copy.
scripts/ci/tests/cn1ss-async-sink-test.sh drives it against a fake
socket on a plain JVM (and fails if the two copies drift); it runs in
scripts-javascript.yml ahead of the build.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Navigate Up to the manifest parent and honour two Android contracts
- The JS-bridge dispatcher skips a subclass that overrides an
@JavascriptInterface method without the annotation, as Android only
exposes methods annotated on the runtime class.
- startActivityIfNeeded returns false, delivering nothing, when the intent
would only reach the calling top activity again.
- android:parentActivityName (or the android.support.PARENT_ACTIVITY
meta-data) is compiled into AndroidAppImpl; onNavigateUp and
onSupportNavigateUp go to that parent, recreate it when it is not on the
stack, and do nothing when there is none.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci: raise iOS packaging and native-ios limits for the larger hello app
The hello app now also translates the Android compatibility gallery, its
runtime and the Kotlin stdlib. On 5f80b8356a the cold Release device
compile took 42.5 of its 45 minutes (master: 19-25), the UI smoke's -O1
compile alone took 52 minutes (master: 33) so the 65-minute step timed
out, and native-ios was still compiling when its 45-minute job limit
fired -- a limit master's own push runs already hit.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Reconcile list checks by id, close PrintWriter, mirror view drawables
- AbsListView: with stable ids, checked rows follow their ids across
notifyDataSetChanged() and removed ids are dropped; without them a
check past the new end is dropped, so getCheckedItemIds() no longer
reads past the adapter.
- PrintWriter: close() drops the delegate like the JDK, so later writes
are suppressed and reported by checkError() even over a writer whose
close is a no-op; a second close does nothing.
- View: the background and foreground take the view's resolved layout
direction when attached and on every direction change, direct or
inherited.
- AndroidPomUpdater: the compile-android-res execution is only inserted
into the Codename One plugin's own executions block, never a later
plugin's; otherwise it is reported for a manual update.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Define Android compatibility release limits and fix retained text and state
* Fix Android compatibility lifecycle and UI review findings and guide lint
* Preserve Android form state and fix sharing, grid rows, and deleted spans
* Preserve Android widget state and defer cosmetic compatibility gaps
* Fix Android launch reentrancy, task reset, and localized month parsing
* Observe Playground animation startup within a bounded interval
* Clear weak references before reclaiming fresh legacy arrays
* Fix Android review regressions and copyright CI gate
* Fix modal cleanup race and bound Android review scope
* Fix Android review regressions and resume reattached GPU rendering
* Fix lifecycle review issues and stabilize CI validation
* Fix compatibility regressions and isolate GC benchmarks
* Fix URI, list, clock, and toast review findings
* Guard reentrant Android callbacks and snapshot queued results
* Calibrate expanded hello RAM on Windows Model 173
* Record Linux translator RAM improvement on EPYC 9V74
* Wake continuous WebGL surface after first layout
* Fix reentrant Android compatibility callbacks and chooser dispatch
* Use guide prose conventions for restoration limitation
* Keep native foreach layouts within surviving classes
Avoid emitting HashMap field accesses when culling leaves only a standalone HashSet. Cover that exact generated-code dependency and preserve map-backed view behavior. Record two five-round Windows Model 207 recursion measurements against its obsolete two-run baseline without changing tolerances.
* Handle reentrant Android callbacks and stale asynchronous deliveries
* Exclude watchOS from iOS hinge implementation
* Guard Android result delivery and matching edge cases
* Guard Android canvas targets and reentrant UI state
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>1 parent 07e3d75 commit ebe0e64
1,355 files changed
Lines changed: 191362 additions & 517 deletions
File tree
- .github/workflows
- CodenameOne/src/com/codename1
- impl
- l10n
- ui
- Ports
- Android/src/com/codename1/impl/android
- JavaSE/src/com/codename1/impl/javase
- JavaScriptPort/src/main
- java/com/codename1
- impl/html5
- teavm
- ext/localforage
- jso/util
- webapp
- iOSPort/nativeSources
- docs
- demos
- android-interop
- src/main
- android
- java/com/codenameone/developerguide/androidinterop
- java/com/codenameone/developerguide/androidinterop
- common/src/main/snippets/developer-guide
- developer-guide
- img
- website
- data
- scripts
- maven
- android-compat
- src
- main
- framework-res
- anim
- drawable
- interpolator
- layout
- values
- java
- androidx
- activity
- result
- contract
- annotation
- appcompat
- app
- widget
- arch/core/util
- cardview/widget
- constraintlayout
- core
- widgets
- analyzer
- helper/widget
- widget
- core
- app
- content
- res
- graphics
- drawable
- os
- view
- widget
- fragment/app
- lifecycle
- recyclerview/widget
- savedstate
- viewpager2/widget
- android
- animation
- annotation
- app
- content
- pm
- res
- database
- sqlite
- graphics
- drawable
- net
- os
- text
- method
- style
- util
- view
- animation
- inputmethod
- webkit
- widget
- com
- codename1/androidcompat
- jdk
- runtime
- google/android/material
- appbar
- bottomsheet
- button
- card
- checkbox
- chip
- color
- dialog
- divider
- floatingactionbutton
- internal
- materialswitch
- progressindicator
- radiobutton
- shape
- slider
- snackbar
- switchmaterial
- tabs
- textfield
- textview
- theme
- org/xmlpull/v1
- library-res
- androidx.appcompat
- drawable
- values-night
- values
- androidx.cardview/values
- androidx.constraintlayout.widget/values
- androidx.core/values
- androidx.recyclerview/values
- androidx.viewpager2/values
- com.google.android.material
- drawable
- values-night
- values
- test/java
- androidx
- activity
- constraintlayout/widget
- lifecycle
- recyclerview/widget
- android
- animation
- app
- content
- database
- sqlite
- graphics
- drawable
- net
- os
- text
- view
- animation
- webkit
- widget
- com
- codename1
- androidcompat
- jdk
- runtime
- testing
- impl
- google/android/material
- android-res-compiler
- src
- main/java/com/codename1/android/rescompiler
- test/java/com/codename1/android/rescompiler
- build-engine
- src
- main/java/com/codename1/maven
- test/java/com/codename1/maven
- cn1app-archetype/src/main/resources
- META-INF/maven
- archetype-resources
- common
- codenameone-gradle-plugin
- src
- main/java/com/codename1/gradle
- tasks
- test/java/com/codename1/gradle
- codenameone-maven-plugin
- src
- main/java/com/codename1/maven
- test
- java/com/codename1/maven
- resources/android-pom
- core-unittests/src/test/java/com/codename1
- impl
- l10n
- ui
- integration-tests
- javase/src/test/java/com/codename1/impl/javase
- project-model/src/main/java/com/codename1/project
- scripts
- android-compat-samples
- gallery
- app
- src/main
- assets
- java/com/example/droid
- kotlin/com/example/droid
- res
- anim
- drawable
- layout
- values-night
- values
- xml
- android/screenshots
- ci/tests
- cn1playground/tools
- fidelity-app
- common/src/main/java/com/codenameone/fidelity
- javase
- hellocodenameone
- android/src/main/java/com/codenameone/examples/hellocodenameone
- common
- src/main/java/com/codenameone/examples/hellocodenameone/tests
- androidcompat
- javase
- initializr
- common/src/main/resources/skill/references
- javase
- ios
- screenshots-metal-27
- screenshots-metal
- screenshots-tv
- screenshots-watch
- javascript/screenshots
- linux
- screenshots-arm
- screenshots
- mac-catalyst/screenshots
- macos/screenshots
- windows/screenshots
- vm
- ByteCodeTranslator/src
- com/codename1/tools/translator
- bytecodes
- selfhost
- perf-baseline/pr
- tests
- src/test
- java/com/codename1/tools/translator
- resources/com/codename1/tools/translator
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
33 | | - | |
| 33 | + | |
| 34 | + | |
34 | 35 | | |
35 | 36 | | |
36 | 37 | | |
| |||
163 | 164 | | |
164 | 165 | | |
165 | 166 | | |
166 | | - | |
| 167 | + | |
| 168 | + | |
167 | 169 | | |
168 | 170 | | |
169 | 171 | | |
| |||
219 | 221 | | |
220 | 222 | | |
221 | 223 | | |
222 | | - | |
| 224 | + | |
| 225 | + | |
223 | 226 | | |
224 | 227 | | |
225 | 228 | | |
| |||
247 | 250 | | |
248 | 251 | | |
249 | 252 | | |
250 | | - | |
251 | | - | |
| 253 | + | |
| 254 | + | |
252 | 255 | | |
253 | 256 | | |
254 | 257 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
177 | 177 | | |
178 | 178 | | |
179 | 179 | | |
180 | | - | |
| 180 | + | |
| 181 | + | |
181 | 182 | | |
182 | 183 | | |
183 | 184 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
| 43 | + | |
| 44 | + | |
43 | 45 | | |
44 | 46 | | |
45 | 47 | | |
| |||
108 | 110 | | |
109 | 111 | | |
110 | 112 | | |
| 113 | + | |
| 114 | + | |
111 | 115 | | |
112 | 116 | | |
113 | 117 | | |
| |||
387 | 391 | | |
388 | 392 | | |
389 | 393 | | |
390 | | - | |
| 394 | + | |
391 | 395 | | |
392 | 396 | | |
393 | 397 | | |
| |||
602 | 606 | | |
603 | 607 | | |
604 | 608 | | |
605 | | - | |
| 609 | + | |
606 | 610 | | |
607 | 611 | | |
608 | 612 | | |
| |||
622 | 626 | | |
623 | 627 | | |
624 | 628 | | |
| 629 | + | |
| 630 | + | |
625 | 631 | | |
626 | 632 | | |
627 | 633 | | |
| |||
752 | 758 | | |
753 | 759 | | |
754 | 760 | | |
755 | | - | |
| 761 | + | |
756 | 762 | | |
757 | 763 | | |
758 | 764 | | |
759 | | - | |
| 765 | + | |
760 | 766 | | |
761 | 767 | | |
762 | 768 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
| 32 | + | |
32 | 33 | | |
33 | 34 | | |
34 | 35 | | |
| |||
134 | 135 | | |
135 | 136 | | |
136 | 137 | | |
137 | | - | |
| 138 | + | |
| 139 | + | |
138 | 140 | | |
139 | 141 | | |
140 | 142 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
159 | 159 | | |
160 | 160 | | |
161 | 161 | | |
162 | | - | |
| 162 | + | |
| 163 | + | |
163 | 164 | | |
164 | 165 | | |
165 | 166 | | |
| |||
415 | 416 | | |
416 | 417 | | |
417 | 418 | | |
418 | | - | |
| 419 | + | |
419 | 420 | | |
420 | 421 | | |
421 | 422 | | |
| |||
545 | 546 | | |
546 | 547 | | |
547 | 548 | | |
548 | | - | |
| 549 | + | |
| 550 | + | |
549 | 551 | | |
550 | 552 | | |
551 | 553 | | |
| |||
831 | 833 | | |
832 | 834 | | |
833 | 835 | | |
834 | | - | |
| 836 | + | |
835 | 837 | | |
836 | 838 | | |
837 | 839 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
26 | 30 | | |
27 | 31 | | |
28 | 32 | | |
| |||
67 | 71 | | |
68 | 72 | | |
69 | 73 | | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
70 | 78 | | |
71 | 79 | | |
72 | 80 | | |
| |||
177 | 185 | | |
178 | 186 | | |
179 | 187 | | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
180 | 201 | | |
181 | 202 | | |
182 | 203 | | |
| |||
0 commit comments