Skip to content

Implement GPowerProfileMonitor for Android thermal and battery saver …#223

Open
maceip wants to merge 4 commits intoIgalia:mainfrom
maceip:maceip/agdk-thermal-architecture
Open

Implement GPowerProfileMonitor for Android thermal and battery saver …#223
maceip wants to merge 4 commits intoIgalia:mainfrom
maceip:maceip/agdk-thermal-architecture

Conversation

@maceip
Copy link
Copy Markdown

@maceip maceip commented Jan 25, 2026

  • GPowerProfileMonitor GIO extension aggregating NDK AThermalManager (API 30+) thermal status and Java PowerManager battery saver broadcasts
  • Runtime API detection via __builtin_available(android 30, *) for thermal monitoring with graceful fallback on older devices

this should be a draft -- my build env isnt up rn so its not passing local ci

…states

- **GPowerProfileMonitor GIO extension** aggregating NDK `AThermalManager` (API 30+) thermal status and Java `PowerManager` battery saver broadcasts
- **Runtime API detection** via `__builtin_available(android 30, *)` for thermal monitoring with graceful fallback on older devices
- **Thread-safe state management** using `std::atomic<bool>` with `g_main_context_invoke()` marshaling to GLib main thread
- **Android 13+ compatibility** with `RECEIVER_NOT_EXPORTED` flag for `BroadcastReceiver` registration
- **wpe-platform-core code style** with camelCase GObject functions, proper `dispose`/`get_property` handlers, and `g_object_class_override_property()`
@aperezdc aperezdc added the enhancement New feature or request label Jan 27, 2026
Copy link
Copy Markdown
Member

@aperezdc aperezdc left a comment

Choose a reason for hiding this comment

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

While I appreciate the intention of providing an implementation for the power monitor, I think this needs quite some work:

  • Naming is all over the place. Please see the comments.
  • The code does not even build, partly because of the naming inconsistencies.
  • The errors from the lint checker have not been taken into account, as shown by the failed CI job.
  • After massaging it a little bit to get it to build, the code does not seem to even work as intended: the Java part works and tries to call into C++ to change the battery status, but registration with the GIO extension point does not seem to have any effect and the WPEAndroidPowerProfileMonitor never gets instantiated, resulting in logged messages of the form WPEAndroidPowerProfileMonitor::set_battery_saver called before init, ignoring.

While I cannot be sure, overall this smells like an LLM hallucination, so @maceip please refrain from submitting patches that do not even build, and make sure that they at the very least can be built, pass the lint checks (which are part of the Git commit hooks, and should have been configured automatically in your working copy), and have been tested by hand. I will be happy to re-review if these basic guidelines are followed.

Thanks!

Comment on lines +119 to +122
static void wpeAndroidPowerProfileMonitorIfaceInit(GPowerProfileMonitorInterface* iface)
{
// Interface implemented via "power-saver-enabled" property override
(void)iface;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

C++ allows omitting the argument variable name, so we can do this:

Suggested change
static void wpeAndroidPowerProfileMonitorIfaceInit(GPowerProfileMonitorInterface* iface)
{
// Interface implemented via "power-saver-enabled" property override
(void)iface;
static void wpeAndroidPowerProfileMonitorIfaceInit(GPowerProfileMonitorInterface*)
{
// Interface implemented via "power-saver-enabled" property override

* mode is enabled, the monitor reports power-saver-enabled=TRUE to WebKit.
*/
struct _WPEAndroidPowerMonitor {
GObject parentInstance;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The convention when defining a subclass using GObject is to use the name parent for the base/parent instance member. This is not super important because GObject does not enforce the naming, but it is good practice to follow the conventions 😉:

Suggested change
GObject parentInstance;
GObject parent;

Comment on lines +45 to +46
WPEAndroidPowerProfileMonitor::configureJNIMappings();
WPEAndroidPowerProfileMonitor::registerExtension();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For the classes that may be registered using JNI we use the WK prefix, so this should be called WKPowerProfileMonitor.

* When either thermal throttling is active (SEVERE or higher) or Battery Saver
* mode is enabled, the monitor reports power-saver-enabled=TRUE to WebKit.
*/
struct _WPEAndroidPowerMonitor {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should be _WPEAndroidPowerProfileMonitor, to match the naming in the rest of the file.

Suggested change
struct _WPEAndroidPowerMonitor {
struct _WPEAndroidPowerProfileMonitor {

Comment on lines +47 to +48
std::atomic<bool> isBatterySaverActive;
std::atomic<bool> isThermalThrottling;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Using C++ types directly inside a struct allocated by GLib won't run constructors/destructors; the fact that this works in this case is by pure chance.

Either use an inner struct that gets initialized using placement-new, or use plain int values in combination with g_atomic_int_get() and g_atomic_int_set()

Comment on lines +210 to +216
g_main_context_invoke(
nullptr,
+[](gpointer userData) -> gboolean {
updatePowerStateOnMainThread(WPE_ANDROID_POWER_PROFILE_MONITOR(userData));
return G_SOURCE_REMOVE;
},
s_singleton);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This piece of code is repeated in three different places. I would put the call to g_main_context_invoke() inside the updatePowerStateOnMainThread() helper function to factor it out.

Then probably wpe_android_power_profile_monitor_set_battery_saver() can be removed.

Comment on lines +70 to +72
// AThermalStatus values:
// ATHERMAL_STATUS_NONE = 0, LIGHT = 1, MODERATE = 2, SEVERE = 3,
// CRITICAL = 4, EMERGENCY = 5, SHUTDOWN = 6
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This comment does not really add any interesting information, IMO it could be removed.

Comment on lines +25 to +40
#define WPE_TYPE_ANDROID_POWER_PROFILE_MONITOR (wpe_android_power_profile_monitor_get_type())
G_DECLARE_FINAL_TYPE(
WPEAndroidPowerMonitor, wpe_android_power_profile_monitor, WPE, ANDROID_POWER_PROFILE_MONITOR, GObject)

/**
* Updates the battery saver state from Java layer.
* Called via JNI when the battery saver mode changes.
*/
void wpe_android_power_profile_monitor_set_battery_saver(gboolean isPowerSaveMode);

/**
* Updates the thermal throttling state.
* Can be called from native code, though thermal status is typically
* monitored internally via AThermalManager.
*/
void wpe_android_power_profile_monitor_set_thermal_throttling(gboolean isThermalThrottling);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is all implementation details of the power profile monitor and do not need to be in the header.

* sees "power-saver-enabled" as TRUE, causing reduced timer precision, stopped
* smooth animations, and throttled background tabs.
*/
class WPEAndroidPowerProfileMonitor {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
class WPEAndroidPowerProfileMonitor {
class WKPowerProfileMonitor {

Comment thread wpeview/src/main/cpp/CMakeLists.txt Outdated
Runtime/WKWebsiteDataManager.cpp
Runtime/WKWebView.cpp)
Runtime/WKWebView.cpp
Runtime/WPEAndroidPowerProfileMonitor.cpp)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
Runtime/WPEAndroidPowerProfileMonitor.cpp)
Runtime/WKPowerProfileMonitor.cpp)

@maceip
Copy link
Copy Markdown
Author

maceip commented Jan 29, 2026 via email

maceip and others added 3 commits January 29, 2026 21:26
…states

GPowerProfileMonitor GIO extension aggregating NDK AThermalManager (API 30+)
thermal status and Java PowerManager battery saver broadcasts.

- Runtime API detection via __builtin_available(android 30, *) for thermal
  monitoring with graceful fallback on older devices
- Thread-safe state management using g_atomic_int_* for GLib compatibility
- Memory-safe callbacks with proper g_object_ref/unref lifecycle
- WKPowerProfileMonitor C++ wrapper with JNI mappings for Java integration

When either thermal throttling is active (SEVERE or higher) or Battery Saver
mode is enabled, the monitor reports power-saver-enabled=TRUE to WebKit,
causing reduced timer precision, stopped smooth animations, and throttled
background tabs.

https://claude.ai/code/session_01QfbnP3t2TsjoSLJA37TtME
Implement GPowerProfileMonitor for Android thermal and battery saver …
@aperezdc
Copy link
Copy Markdown
Member

aperezdc commented Feb 5, 2026

@maceip Right now we are busy trying to get the support for WPEPlatform merged in main, so this will have to wait at least until that is completed and then this PR will need a rebase—we'll let you know when it is a good moment for that. Thanks for your patience 🙏🏼

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants