From 3c4adc3e66fbb2278a5912cd07eb6d99cf54afe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 21 Jan 2026 18:43:25 +0100 Subject: [PATCH] Fix a number of Android Studio lint warnings, a bad jni return type and an memory leak --- Common/Render/Text/draw_text_android.cpp | 6 +++-- Common/Render/Text/draw_text_android.h | 2 ++ android/jni/app-android.cpp | 24 ++++++++++--------- .../src/org/ppsspp/ppsspp/CameraHelper.java | 1 - .../src/org/ppsspp/ppsspp/InfraredHelper.java | 7 +++--- .../org/ppsspp/ppsspp/InputDeviceState.java | 2 +- android/src/org/ppsspp/ppsspp/LifeCycle.java | 2 +- .../src/org/ppsspp/ppsspp/LocationHelper.java | 9 ++----- .../src/org/ppsspp/ppsspp/PpssppActivity.java | 24 +++++++++---------- .../org/ppsspp/ppsspp/ShortcutActivity.java | 11 ++++----- .../src/org/ppsspp/ppsspp/TextRenderer.java | 6 +---- 11 files changed, 43 insertions(+), 51 deletions(-) diff --git a/Common/Render/Text/draw_text_android.cpp b/Common/Render/Text/draw_text_android.cpp index ab95022634..4f0ea7742e 100644 --- a/Common/Render/Text/draw_text_android.cpp +++ b/Common/Render/Text/draw_text_android.cpp @@ -16,13 +16,15 @@ #include +jobject TextDrawerAndroid::activity_; + TextDrawerAndroid::TextDrawerAndroid(Draw::DrawContext *draw) : TextDrawer(draw) { auto env = getEnv(); const char *textRendererClassName = "org/ppsspp/ppsspp/TextRenderer"; jclass localClass = findClass(textRendererClassName); cls_textRenderer = reinterpret_cast(env->NewGlobalRef(localClass)); if (cls_textRenderer) { - method_allocFont = env->GetStaticMethodID(cls_textRenderer, "allocFont", "(Ljava/lang/String;)I"); + method_allocFont = env->GetStaticMethodID(cls_textRenderer, "allocFont", "(Landroid/content/Context;Ljava/lang/String;)I"); method_freeAllFonts = env->GetStaticMethodID(cls_textRenderer, "freeAllFonts", "()V"); method_measureText = env->GetStaticMethodID(cls_textRenderer, "measureText", "(Ljava/lang/String;ID)I"); method_renderText = env->GetStaticMethodID(cls_textRenderer, "renderText", "(Ljava/lang/String;IDII)[I"); @@ -60,7 +62,7 @@ void TextDrawerAndroid::SetOrCreateFont(const FontStyle &style) { if (fontIter == allocatedFonts_.end()) { auto env = getEnv(); jstring jstr = env->NewStringUTF(filename.c_str()); - int fontId = env->CallStaticIntMethod(cls_textRenderer, method_allocFont, jstr); + int fontId = env->CallStaticIntMethod(cls_textRenderer, method_allocFont, activity_, jstr); env->DeleteLocalRef(jstr); if (fontId >= 0) { diff --git a/Common/Render/Text/draw_text_android.h b/Common/Render/Text/draw_text_android.h index 75dc56b5f0..a097694266 100644 --- a/Common/Render/Text/draw_text_android.h +++ b/Common/Render/Text/draw_text_android.h @@ -21,6 +21,7 @@ public: bool IsReady() const override; void SetOrCreateFont(const FontStyle &style) override; + static void SetActivity(jobject activity) { activity_ = activity; } bool DrawStringBitmap(std::vector &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, std::string_view str, int align, bool fullColor) override; protected: @@ -31,6 +32,7 @@ protected: private: // JNI functions + static jobject activity_; jclass cls_textRenderer; jmethodID method_allocFont; jmethodID method_freeAllFonts; diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index a9ba4f314f..5109ac12ce 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -19,6 +19,8 @@ #include #include +#include "Common/Render/Text/draw_text_android.h" + #elif !defined(JNIEXPORT) // Just for better highlighting in MSVC if opening this file. // Not having types makes it get confused and say everything is wrong. @@ -584,6 +586,7 @@ std::string GetJavaString(JNIEnv *env, jstring jstr) { extern "C" void Java_org_ppsspp_ppsspp_PpssppActivity_registerCallbacks(JNIEnv *env, jobject obj) { ppssppActivity = env->NewGlobalRef(obj); + TextDrawerAndroid::SetActivity(ppssppActivity); postCommand = env->GetMethodID(env->GetObjectClass(obj), "postCommand", "(Ljava/lang/String;Ljava/lang/String;)V"); getDebugString = env->GetMethodID(env->GetObjectClass(obj), "getDebugString", "(Ljava/lang/String;)Ljava/lang/String;"); getNativeCrashHistory = env->GetMethodID(env->GetObjectClass(obj), "getNativeCrashHistory", "(I)Ljava/util/ArrayList;"); @@ -1306,10 +1309,10 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_joystickAxis( env->ReleaseFloatArrayElements(values, valueBuffer, JNI_ABORT); // ABORT just means we don't want changes copied back! } -extern "C" jboolean Java_org_ppsspp_ppsspp_NativeApp_mouse( +extern "C" void Java_org_ppsspp_ppsspp_NativeApp_mouse( JNIEnv *env, jclass, jfloat x, jfloat y, int button, int action) { if (!renderer_inited) - return false; + return; TouchInput input{}; static float last_x = 0.0f; @@ -1354,20 +1357,19 @@ extern "C" jboolean Java_org_ppsspp_ppsspp_NativeApp_mouse( // Also send mouse button key events, for binding. if (button) { - KeyInput input{}; - input.deviceId = DEVICE_ID_MOUSE; + KeyInput keyInput{}; + keyInput.deviceId = DEVICE_ID_MOUSE; switch (button) { - case 1: input.keyCode = NKCODE_EXT_MOUSEBUTTON_1; break; - case 2: input.keyCode = NKCODE_EXT_MOUSEBUTTON_2; break; - case 3: input.keyCode = NKCODE_EXT_MOUSEBUTTON_3; break; + case 1: keyInput.keyCode = NKCODE_EXT_MOUSEBUTTON_1; break; + case 2: keyInput.keyCode = NKCODE_EXT_MOUSEBUTTON_2; break; + case 3: keyInput.keyCode = NKCODE_EXT_MOUSEBUTTON_3; break; default: WARN_LOG(Log::System, "Unexpected mouse button %d", button); } - input.flags = action == 1 ? KeyInputFlags::DOWN : KeyInputFlags::UP; - if (input.keyCode != 0) { - NativeKey(input); + keyInput.flags = action == 1 ? KeyInputFlags::DOWN : KeyInputFlags::UP; + if (keyInput.keyCode != 0) { + NativeKey(keyInput); } } - return true; } extern "C" jboolean Java_org_ppsspp_ppsspp_NativeApp_mouseWheelEvent( diff --git a/android/src/org/ppsspp/ppsspp/CameraHelper.java b/android/src/org/ppsspp/ppsspp/CameraHelper.java index 27eba3dbb1..996d84284d 100644 --- a/android/src/org/ppsspp/ppsspp/CameraHelper.java +++ b/android/src/org/ppsspp/ppsspp/CameraHelper.java @@ -18,7 +18,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -@TargetApi(23) @SuppressWarnings("deprecation") class CameraHelper { private static final String TAG = CameraHelper.class.getSimpleName(); diff --git a/android/src/org/ppsspp/ppsspp/InfraredHelper.java b/android/src/org/ppsspp/ppsspp/InfraredHelper.java index 656f27b32d..073879fa54 100644 --- a/android/src/org/ppsspp/ppsspp/InfraredHelper.java +++ b/android/src/org/ppsspp/ppsspp/InfraredHelper.java @@ -15,7 +15,7 @@ import java.util.List; class InfraredHelper { private static final String TAG = InfraredHelper.class.getSimpleName(); private static final int SIRC_FREQ = 40000; - private ConsumerIrManager mConsumerIrManager; + private final ConsumerIrManager mConsumerIrManager; InfraredHelper(Context context) throws Exception { mConsumerIrManager = (ConsumerIrManager) context.getSystemService(Context.CONSUMER_IR_SERVICE); @@ -41,8 +41,7 @@ class InfraredHelper { final List one = Arrays.asList(1200, 600); final List zero = Arrays.asList( 600, 600); - List iterList = new ArrayList<>(); - iterList.addAll(start); + List iterList = new ArrayList<>(start); for (int i = 0; i < version; i++) { List val = i < 7 @@ -55,7 +54,7 @@ class InfraredHelper { for (int i = 0; i < iterList.size() - 1; i++) { iterSum += iterList.get(i); } - int lastVal = 52000 - iterSum; // SIRC cicle = 52ms + int lastVal = 52000 - iterSum; // SIRC cycle = 52ms iterList.set(iterList.size() - 1, lastVal); List patternList = new ArrayList<>(); diff --git a/android/src/org/ppsspp/ppsspp/InputDeviceState.java b/android/src/org/ppsspp/ppsspp/InputDeviceState.java index f79be5a257..16e62bcd5d 100644 --- a/android/src/org/ppsspp/ppsspp/InputDeviceState.java +++ b/android/src/org/ppsspp/ppsspp/InputDeviceState.java @@ -9,7 +9,7 @@ import android.view.MotionEvent; public class InputDeviceState { private static final String TAG = "InputDeviceState"; - private int deviceId = NativeApp.DEVICE_ID_DEFAULT; + private int deviceId; private final InputDevice mDevice; private final int[] mAxes; diff --git a/android/src/org/ppsspp/ppsspp/LifeCycle.java b/android/src/org/ppsspp/ppsspp/LifeCycle.java index 42a988c743..b1bb236316 100644 --- a/android/src/org/ppsspp/ppsspp/LifeCycle.java +++ b/android/src/org/ppsspp/ppsspp/LifeCycle.java @@ -79,7 +79,7 @@ public class LifeCycle { Log.e(TAG, "Lifecycle: onDestroy, but state is " + state + ". Expected CREATED"); return false; } - state = State.CREATED; + state = State.LAUNCHED; Log.i(TAG, "onDestroy begin"); return true; } diff --git a/android/src/org/ppsspp/ppsspp/LocationHelper.java b/android/src/org/ppsspp/ppsspp/LocationHelper.java index d1cbe22fe6..06a3365d30 100644 --- a/android/src/org/ppsspp/ppsspp/LocationHelper.java +++ b/android/src/org/ppsspp/ppsspp/LocationHelper.java @@ -51,7 +51,7 @@ class LocationHelper implements LocationListener { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { mGnssStatusCallback = new GnssStatus.Callback() { @Override - public void onSatelliteStatusChanged(GnssStatus status) { + public void onSatelliteStatusChanged(@NonNull GnssStatus status) { onSatelliteStatus(status); } }; @@ -64,12 +64,7 @@ class LocationHelper implements LocationListener { }; mLocationManager.addNmeaListener(mNmeaMessageListener); } else { - mGpsStatusListener = new GpsStatus.Listener() { - @Override - public void onGpsStatusChanged(int event) { - onGpsStatus(event); - } - }; + mGpsStatusListener = this::onGpsStatus; mLocationManager.addGpsStatusListener(mGpsStatusListener); mNmeaListener = new GpsStatus.NmeaListener() { @Override diff --git a/android/src/org/ppsspp/ppsspp/PpssppActivity.java b/android/src/org/ppsspp/ppsspp/PpssppActivity.java index a9898e065a..4f03f39b0e 100644 --- a/android/src/org/ppsspp/ppsspp/PpssppActivity.java +++ b/android/src/org/ppsspp/ppsspp/PpssppActivity.java @@ -536,9 +536,8 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList mCameraHelper = new CameraHelper(this); } - @TargetApi(Build.VERSION_CODES.N) private void updateSustainedPerformanceMode() { - if (sustainedPerfSupported) { + if (sustainedPerfSupported && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // Query the native application on the desired rotation. String str = NativeApp.queryConfig("sustainedPerformanceMode"); try { @@ -550,6 +549,7 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList } } + @SuppressLint("SourceLockedOrientationActivity") private void updateScreenRotation(String cause) { // Query the native application on the desired rotation. int rot; @@ -743,7 +743,6 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList Log.i(TAG, "Got shortcutParam in onCreate on secondary run: " + shortcutParam); // Make sure we only send it once. NativeApp.sendMessageFromJava("shortcutParam", shortcutParam); - shortcutParam = null; } // Set up the back key handling to be future-compatible @@ -784,7 +783,7 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList Log.i(TAG, "applyFramerate"); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) return; - if (surface != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + if (surface != null) { try { int method = NativeApp.getDisplayFramerateMode(); if (method > 0) { @@ -839,10 +838,7 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList // Hack to make things symmetrical in landscape. Needed on Poco F1, for example. if (orientation == Configuration.ORIENTATION_LANDSCAPE && useImmersive()) { if (left > 0 && right > 0) { - int smallestNonZero = left; - if (right < left) { - smallestNonZero = right; - } + int smallestNonZero = Math.min(right, left); // Log.i(TAG, "Both left and right insets but not equal: " + left + " != " + right + " : Equalizing to " + smallest); left = smallestNonZero; right = smallestNonZero; @@ -1053,7 +1049,7 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList } @Override - public void onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) { + public void onMultiWindowModeChanged(boolean isInMultiWindowMode, @NonNull Configuration newConfig) { // onConfigurationChanged not called on multi-window change Log.i(TAG, "onMultiWindowModeChanged: isInMultiWindowMode = " + isInMultiWindowMode); super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig); @@ -1407,8 +1403,12 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList // doesn't need it. If we can't access it, we'll fail in some other way later. } DocumentFile documentFile = DocumentFile.fromTreeUri(this, selectedDirectoryUri); - Log.i(TAG, "Chosen document name: " + documentFile.getUri()); - NativeApp.sendRequestResult(requestId, true, documentFile.getUri().toString(), 0); + if (documentFile != null) { + Log.i(TAG, "Chosen document name: " + documentFile.getUri()); + NativeApp.sendRequestResult(requestId, true, documentFile.getUri().toString(), 0); + } else { + NativeApp.sendRequestResult(requestId, false, "", 0); + } } } else { Toast.makeText(getApplicationContext(), "Bad request code: " + requestCode, Toast.LENGTH_LONG).show(); @@ -1761,7 +1761,7 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList if (!askForPermissions(permissionsForCamera, REQUEST_CODE_CAMERA_PERMISSION)) { mCameraHelper.startCamera(); } - } else if (mCameraHelper != null && params.equals("stopVideo")) { + } else if (params.equals("stopVideo")) { mCameraHelper.stopCamera(); } return true; diff --git a/android/src/org/ppsspp/ppsspp/ShortcutActivity.java b/android/src/org/ppsspp/ppsspp/ShortcutActivity.java index 3a6eabd5c1..06b6c7d2f5 100644 --- a/android/src/org/ppsspp/ppsspp/ShortcutActivity.java +++ b/android/src/org/ppsspp/ppsspp/ShortcutActivity.java @@ -166,12 +166,9 @@ public class ShortcutActivity extends Activity { } // Event when a file is selected on file dialog. - private final SimpleFileChooser.FileSelectedListener onFileSelectedListener = new SimpleFileChooser.FileSelectedListener() { - @Override - public void onFileSelected(File file) { - // create shortcut using file path - Uri uri = Uri.fromFile(new File(file.getAbsolutePath())); - respondToShortcutRequest(uri); - } + private final SimpleFileChooser.FileSelectedListener onFileSelectedListener = file -> { + // create shortcut using file path + Uri uri = Uri.fromFile(new File(file.getAbsolutePath())); + respondToShortcutRequest(uri); }; } diff --git a/android/src/org/ppsspp/ppsspp/TextRenderer.java b/android/src/org/ppsspp/ppsspp/TextRenderer.java index 09e63b0d22..91bd85ef8e 100644 --- a/android/src/org/ppsspp/ppsspp/TextRenderer.java +++ b/android/src/org/ppsspp/ppsspp/TextRenderer.java @@ -26,15 +26,13 @@ public class TextRenderer { private static boolean highContrastFontsEnabled = false; - private static Context ctx; - static { bg = new Paint(); bg.setColor(0); } @Keep - public static int allocFont(String ttfFile) { + public static int allocFont(Context ctx, String ttfFile) { try { Typeface typeFace = Typeface.createFromAsset(ctx.getAssets(), ttfFile); if (typeFace != null) { @@ -47,7 +45,6 @@ public class TextRenderer { return id; } catch (Exception e) { Log.e(TAG, "Exception when loading typeface. shouldn't happen but is reported. We just fall back." + e); - e.printStackTrace(); return -1337; } } @@ -62,7 +59,6 @@ public class TextRenderer { textPaint = new Paint(Paint.SUBPIXEL_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG); textPaint.setColor(Color.WHITE); highContrastFontsEnabled = Settings.Secure.getInt(ctx.getContentResolver(), "high_text_contrast_enabled", 0) == 1; - TextRenderer.ctx = ctx; } private static Point measureLine(String string, int font, double textSize) {