diff --git a/Core/Core.cpp b/Core/Core.cpp
index 8beaecd685d5..87d3d40fd7cf 100644
--- a/Core/Core.cpp
+++ b/Core/Core.cpp
@@ -56,9 +56,10 @@ static bool windowHidden = false;
static double lastActivity = 0.0;
static double lastKeepAwake = 0.0;
static GraphicsContext *graphicsContext;
+static bool powerSaving = false;
void Core_SetGraphicsContext(GraphicsContext *ctx) {
- graphicsContext = ctx;
+ graphicsContext = ctx;
}
void Core_NotifyWindowHidden(bool hidden) {
@@ -120,6 +121,14 @@ void Core_WaitInactive(int milliseconds) {
}
}
+void Core_SetPowerSaving(bool mode) {
+ powerSaving = mode;
+}
+
+bool Core_GetPowerSaving() {
+ return powerSaving;
+}
+
bool UpdateScreenScale(int width, int height, bool smallWindow) {
g_dpi = 72;
g_dpi_scale = 1.0f;
diff --git a/Core/Core.h b/Core/Core.h
index 3cf96c8575f6..d21ec4847adb 100644
--- a/Core/Core.h
+++ b/Core/Core.h
@@ -52,3 +52,6 @@ bool UpdateScreenScale(int width, int height, bool smallWindow);
// Don't run the core when minimized etc.
void Core_NotifyWindowHidden(bool hidden);
void Core_NotifyActivity();
+
+void Core_SetPowerSaving(bool mode);
+bool Core_GetPowerSaving();
diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp
index 9b6012b07b29..e0a7ebaaf1c7 100644
--- a/Core/Reporting.cpp
+++ b/Core/Reporting.cpp
@@ -18,6 +18,7 @@
#include "Core/Reporting.h"
#include "Common/CPUDetect.h"
+#include "Core/Core.h"
#include "Core/CoreTiming.h"
#include "Core/Config.h"
#include "Core/CwCheat.h"
@@ -427,7 +428,7 @@ namespace Reporting
postdata.Add("graphics", StringFromFormat("%d", payload.int1));
postdata.Add("speed", StringFromFormat("%d", payload.int2));
postdata.Add("gameplay", StringFromFormat("%d", payload.int3));
- postdata.Add("crc", StringFromFormat("%08x", RetrieveCRC()));
+ postdata.Add("crc", StringFromFormat("%08x", Core_GetPowerSaving() ? 0 : RetrieveCRC()));
AddScreenshotData(postdata, payload.string2);
payload.string1.clear();
payload.string2.clear();
diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp
index 81669500d58f..fdf78a3d5d8f 100644
--- a/UI/EmuScreen.cpp
+++ b/UI/EmuScreen.cpp
@@ -196,6 +196,11 @@ void EmuScreen::bootComplete() {
}
}
+ if (Core_GetPowerSaving()) {
+ I18NCategory *sy = GetI18NCategory("System");
+ osm.Show(sy->T("WARNING: Battery save mode is on"), 2.0f, 0xFFFFFF, -1, true, "core_powerSaving");
+ }
+
System_SendMessage("event", "startgame");
}
diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp
index ba3401d71ac2..048a235c8a66 100644
--- a/UI/NativeApp.cpp
+++ b/UI/NativeApp.cpp
@@ -784,6 +784,14 @@ void HandleGlobalMessage(const std::string &msg, const std::string &value) {
// Show for the same duration as the preview.
osm.Show(msg, 2.0f, 0xFFFFFF, -1, true, "savestate_slot");
}
+ if (msg == "core_powerSaving") {
+ if (value != "false") {
+ I18NCategory *sy = GetI18NCategory("System");
+ osm.Show(sy->T("WARNING: Battery save mode is on"), 2.0f, 0xFFFFFF, -1, true, "core_powerSaving");
+ }
+
+ Core_SetPowerSaving(value != "false");
+ }
}
void NativeUpdate(InputState &input) {
diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp
index 3e3e5994af11..fcd7277e33ff 100644
--- a/UI/ReportScreen.cpp
+++ b/UI/ReportScreen.cpp
@@ -23,6 +23,7 @@
#include "UI/PauseScreen.h"
#include "UI/ReportScreen.h"
+#include "Core/Core.h"
#include "Core/Reporting.h"
#include "Core/Screenshot.h"
#include "Core/System.h"
@@ -224,7 +225,9 @@ void ReportScreen::CreateViews() {
}
#ifdef MOBILE_DEVICE
- leftColumnItems->Add(new TextView(rp->T("FeedbackIncludeCRC", "Note: Battery will be used to send a disc CRC"), new LinearLayoutParams(Margins(12, 5, 0, 5))))->SetEnabledPtr(&enableReporting_);
+ if (!Core_GetPowerSaving()) {
+ leftColumnItems->Add(new TextView(rp->T("FeedbackIncludeCRC", "Note: Battery will be used to send a disc CRC"), new LinearLayoutParams(Margins(12, 5, 0, 5))))->SetEnabledPtr(&enableReporting_);
+ }
#endif
std::string path = GetSysDirectory(DIRECTORY_SCREENSHOT);
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index aeb77b7acdec..6bbf4bf570d0 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -96,6 +96,14 @@
+
+
+
+
+
+
+
+
diff --git a/android/src/org/ppsspp/ppsspp/NativeActivity.java b/android/src/org/ppsspp/ppsspp/NativeActivity.java
index 7213323bb3e6..99899c821d38 100644
--- a/android/src/org/ppsspp/ppsspp/NativeActivity.java
+++ b/android/src/org/ppsspp/ppsspp/NativeActivity.java
@@ -28,6 +28,7 @@
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
+import android.os.PowerManager;
import android.os.Vibrator;
import android.text.InputType;
import android.util.DisplayMetrics;
@@ -272,6 +273,7 @@ public void Initialize() {
javaGL = "true".equalsIgnoreCase(NativeApp.queryConfig("androidJavaGL"));
sendInitialGrants();
+ PowerSaveModeReceiver.initAndSend(this);
// OK, config should be initialized, we can query for screen rotation.
if (Build.VERSION.SDK_INT >= 9) {
diff --git a/android/src/org/ppsspp/ppsspp/PowerSaveModeReceiver.java b/android/src/org/ppsspp/ppsspp/PowerSaveModeReceiver.java
new file mode 100644
index 000000000000..1a016910d035
--- /dev/null
+++ b/android/src/org/ppsspp/ppsspp/PowerSaveModeReceiver.java
@@ -0,0 +1,81 @@
+package org.ppsspp.ppsspp;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Build;
+import android.os.PowerManager;
+import android.provider.Settings;
+
+public class PowerSaveModeReceiver extends BroadcastReceiver {
+ private static boolean isPowerSaving = false;
+ private static boolean isBatteryLow = false;
+
+ @Override
+ public void onReceive(final Context context, final Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(Intent.ACTION_BATTERY_LOW)) {
+ isBatteryLow = true;
+ } else if (action.equals(Intent.ACTION_BATTERY_OKAY)) {
+ isBatteryLow = false;
+ }
+
+ sendPowerSaving(context);
+ }
+
+ public static void initAndSend(final Activity activity) {
+ sendPowerSaving(activity);
+
+ activity.getContentResolver().registerContentObserver(Settings.System.CONTENT_URI, true, new ContentObserver(null) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+
+ String key = uri.getPath();
+ key = key.substring(key.lastIndexOf("/") + 1, key.length());
+ if (key != null && (key.equals("user_powersaver_enable") || key.equals("psm_switch"))) {
+ PowerSaveModeReceiver.sendPowerSaving(activity);
+ }
+ }
+ });
+ }
+
+ @TargetApi(21)
+ private static boolean getNativePowerSaving(final Context context) {
+ final PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+ return pm.isPowerSaveMode();
+ }
+
+ private static boolean getExtraPowerSaving(final Context context) {
+ // http://stackoverflow.com/questions/25065635/checking-for-power-saver-mode-programically
+ // HTC (Sense)
+ String htcValue = Settings.System.getString(context.getContentResolver(), "user_powersaver_enable");
+ if (htcValue != null && htcValue.equals("1")) {
+ return true;
+ }
+ // Samsung (Touchwiz)
+ String samsungValue = Settings.System.getString(context.getContentResolver(), "psm_switch");
+ if (samsungValue != null && samsungValue.equals("1")) {
+ return true;
+ }
+ return false;
+ }
+
+ private static void sendPowerSaving(final Context context) {
+ if (Build.VERSION.SDK_INT >= 21) {
+ isPowerSaving = getNativePowerSaving(context) || getExtraPowerSaving(context);
+ } else {
+ isPowerSaving = getExtraPowerSaving(context);
+ }
+
+ if (isBatteryLow || isPowerSaving) {
+ NativeApp.sendMessage("core_powerSaving", "true");
+ } else {
+ NativeApp.sendMessage("core_powerSaving", "false");
+ }
+ }
+}