diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c index ee6a9e27b7..0b806a9d3d 100644 --- a/frontend/drivers/platform_unix.c +++ b/frontend/drivers/platform_unix.c @@ -95,7 +95,7 @@ enum INTERNAL_STORAGE_NOT_WRITABLE }; -struct android_app *g_android; +struct android_app *g_android = NULL; static pthread_key_t thread_key; @@ -1139,7 +1139,24 @@ static enum frontend_powerstate frontend_unix_get_powerstate( { enum frontend_powerstate ret = FRONTEND_POWERSTATE_NONE; -#ifndef ANDROID +#ifdef ANDROID + jint powerstate = ret; + jint battery_level = 0; + JNIEnv *env = jni_thread_getenv(); + + if (!env || !g_android) + return ret; + + CALL_INT_METHOD(env, powerstate, + g_android->activity->clazz, g_android->getPowerstate); + + CALL_INT_METHOD(env, battery_level, + g_android->activity->clazz, g_android->getBatteryLevel); + + *percent = battery_level; + + ret = (enum frontend_powerstate)powerstate; +#else if (frontend_unix_powerstate_check_acpi_sysfs(&ret, seconds, percent)) return ret; @@ -1992,6 +2009,10 @@ static void frontend_unix_init(void *data) "onRetroArchExit", "()V"); GET_METHOD_ID(env, android_app->isAndroidTV, class, "isAndroidTV", "()Z"); + GET_METHOD_ID(env, android_app->getPowerstate, class, + "getPowerstate", "()I"); + GET_METHOD_ID(env, android_app->getBatteryLevel, class, + "getBatteryLevel", "()I"); CALL_OBJ_METHOD(env, obj, android_app->activity->clazz, android_app->getIntent); diff --git a/frontend/drivers/platform_unix.h b/frontend/drivers/platform_unix.h index c5a028ccc8..27163961af 100644 --- a/frontend/drivers/platform_unix.h +++ b/frontend/drivers/platform_unix.h @@ -160,6 +160,8 @@ struct android_app jmethodID getPendingIntentDownloadsLocation; jmethodID getPendingIntentScreenshotsLocation; jmethodID isAndroidTV; + jmethodID getPowerstate; + jmethodID getBatteryLevel; }; diff --git a/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityCommon.java b/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityCommon.java index 06e1a8c7ba..5136ba6e08 100644 --- a/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityCommon.java +++ b/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityCommon.java @@ -2,7 +2,10 @@ package com.retroarch.browser.retroactivity; import com.retroarch.browser.preferences.util.UserPreferences; import android.content.res.Configuration; +import android.content.Intent; +import android.content.IntentFilter; import android.app.UiModeManager; +import android.os.BatteryManager; import android.util.Log; /** @@ -10,6 +13,12 @@ import android.util.Log; */ public class RetroActivityCommon extends RetroActivityLocation { + public static int FRONTEND_POWERSTATE_NONE = 0; + public static int FRONTEND_POWERSTATE_NO_SOURCE = 1; + public static int FRONTEND_POWERSTATE_CHARGING = 2; + public static int FRONTEND_POWERSTATE_CHARGED = 3; + public static int FRONTEND_POWERSTATE_ON_POWER_SOURCE = 4; + // Exiting cleanly from NDK seems to be nearly impossible. // Have to use exit(0) to avoid weird things happening, even with runOnUiThread() approaches. // Use a separate JNI function to explicitly trigger the readback. @@ -18,6 +27,46 @@ public class RetroActivityCommon extends RetroActivityLocation finish(); } + public int getBatteryLevel() + { + IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); + // This doesn't actually register anything (or need to) because we know this particular intent is sticky and we do not specify a BroadcastReceiver anyway + Intent batteryStatus = registerReceiver(null, ifilter); + int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); + int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, 100); + + float percent = ((float)level / (float)scale) * 100.0f; + + Log.i("RetroActivity", "battery: level = " + level + ", scale = " + scale + ", percent = " + percent); + + return (int)percent; + } + + public int getPowerstate() + { + IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); + // This doesn't actually register anything (or need to) because we know this particular intent is sticky and we do not specify a BroadcastReceiver anyway + Intent batteryStatus = registerReceiver(null, ifilter); + int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1); + boolean hasBattery = batteryStatus.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false); + boolean isCharging = (status == BatteryManager.BATTERY_STATUS_CHARGING); + boolean isCharged = (status == BatteryManager.BATTERY_STATUS_FULL); + int powerstate = FRONTEND_POWERSTATE_NONE; + + if (isCharged) + powerstate = FRONTEND_POWERSTATE_CHARGED; + else if (isCharging) + powerstate = FRONTEND_POWERSTATE_CHARGING; + else if (!hasBattery) + powerstate = FRONTEND_POWERSTATE_NO_SOURCE; + else + powerstate = FRONTEND_POWERSTATE_ON_POWER_SOURCE; + + Log.i("RetroActivity", "power state = " + powerstate); + + return powerstate; + } + public boolean isAndroidTV() { Configuration config = getResources().getConfiguration();