Skip to content

[CoreCLR] Invalidate time zone caches after device changes#12223

Open
jonathanpeppers wants to merge 6 commits into
mainfrom
jonathanpeppers-fix-coreclr-timezone-change
Open

[CoreCLR] Invalidate time zone caches after device changes#12223
jonathanpeppers wants to merge 6 commits into
mainfrom
jonathanpeppers-fix-coreclr-timezone-change

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Android registers a receiver for ACTION_TIMEZONE_CHANGED, but the CoreCLR JNI entry point was empty. As a result, a running CoreCLR application continued using the cached TimeZoneInfo.Local value after the device time zone changed.

Route the notification through the existing JNIEnvInit.Initialize unmanaged-callers-only callback table and invoke AndroidEnvironment.NotifyTimeZoneChanged() from an attached CoreCLR reverse P/Invoke transition. The managed wrapper catches unexpected exceptions before they cross the native boundary.

Add a CoreCLR live-process regression test and schedule it only in the dedicated nightly time-zone stage so PR validation does not mutate emulator time-zone state.


  • Useful description of why the change is necessary.
  • Links to issues fixed
  • Unit tests

Route Android timezone broadcasts through a CoreCLR reverse P/Invoke callback so managed culture and TimeZoneInfo caches are cleared in a live process. Add MonoVM/CoreCLR device coverage for changing timezone without restarting the app.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: aeee62e5-04ed-40dd-9f0e-a9c7e145ace0
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: aeee62e5-04ed-40dd-9f0e-a9c7e145ace0
Keep the live timezone mutation test out of PR validation while adding it to the dedicated nightly timezone stage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: aeee62e5-04ed-40dd-9f0e-a9c7e145ace0
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: aeee62e5-04ed-40dd-9f0e-a9c7e145ace0
Match the MonoVM timezone notification contract while catching and logging unexpected managed exceptions before they reach native code.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: aeee62e5-04ed-40dd-9f0e-a9c7e145ace0
Copilot AI review requested due to automatic review settings July 23, 2026 21:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes CoreCLR apps not updating TimeZoneInfo.Local after an Android device time-zone change by wiring the ACTION_TIMEZONE_CHANGED notification through the existing JNIEnvInit.Initialize unmanaged-callback table and invoking AndroidEnvironment.NotifyTimeZoneChanged() from a CoreCLR reverse P/Invoke transition. Adds a CoreCLR device regression test and schedules it in nightly to avoid destabilizing regular PR validation.

Changes:

  • Add a CoreCLR unmanaged-callers-only callback (JNIEnvInit.NotifyTimeZoneChanged) and pass its function pointer to native initialization.
  • Implement CoreCLR’s Java_mono_android_Runtime_notifyTimeZoneChanged JNI entry point to call the managed callback.
  • Add a live-process CoreCLR device test for time-zone cache invalidation and run it in a dedicated nightly job.

Reviewed changes

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

Show a summary per file
File Description
tests/MSBuildDeviceIntegration/Tests/TimeZoneInfoTests.cs Adds a CoreCLR-only device regression test that changes device TZ and verifies TimeZoneInfo.Local updates in-process.
src/native/common/include/managed-interface.hh Extends the JnienvInitializeArgs callback table with a notifyTimeZoneChangedFn function pointer.
src/native/clr/include/host/host.hh Adds CoreCLR host declarations/state for the notify-time-zone callback.
src/native/clr/host/host.cc Stores the callback pointer from managed init and adds a host helper to invoke it safely.
src/native/clr/host/host-jni.cc Routes the CoreCLR Runtime.notifyTimeZoneChanged() JNI entry point to the host helper.
src/Mono.Android/Android.Runtime/JNIEnvInit.cs Adds the unmanaged-callers-only callback and exports its function pointer during initialization.
src/Mono.Android/Android.Runtime/AndroidEnvironment.cs Makes NotifyTimeZoneChanged() callable from JNIEnvInit (internal) while preserving the native-invoked entry point.
build-tools/automation/azure-pipelines-nightly.yaml Adds a nightly emulator job that runs only the new time-zone change regression test.

Comment thread tests/MSBuildDeviceIntegration/Tests/TimeZoneInfoTests.cs
Comment thread src/native/clr/host/host.cc
Ensure shared device cleanup runs even when restoring time-zone settings fails.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: aeee62e5-04ed-40dd-9f0e-a9c7e145ace0
@jonathanpeppers

Copy link
Copy Markdown
Member Author

This needs to be rebased after this is merged:

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