[Scummvm-git-logs] scummvm master -> 30b8842885414662c0371943e63da7c6eee2b9e1
antoniou79
a.antoniou79 at gmail.com
Mon Sep 14 13:22:57 UTC 2020
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
30b8842885 ANDROID: Use custom handler for long key press detection
Commit: 30b8842885414662c0371943e63da7c6eee2b9e1
https://github.com/scummvm/scummvm/commit/30b8842885414662c0371943e63da7c6eee2b9e1
Author: antoniou (a.antoniou79 at gmail.com)
Date: 2020-09-14T16:16:46+03:00
Commit Message:
ANDROID: Use custom handler for long key press detection
To avoid possible mem leaks (see "This Handler Class Should Be Static Or Leaks Might Occurâ warning
Also a few optimizations based on recommendations from the Android Studio error highlighting/fix suggestions (F2)
Changed paths:
backends/platform/android/org/scummvm/scummvm/ExternalStorage.java
backends/platform/android/org/scummvm/scummvm/ScummVM.java
backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
diff --git a/backends/platform/android/org/scummvm/scummvm/ExternalStorage.java b/backends/platform/android/org/scummvm/scummvm/ExternalStorage.java
index 01482a3d5a..31b754280a 100644
--- a/backends/platform/android/org/scummvm/scummvm/ExternalStorage.java
+++ b/backends/platform/android/org/scummvm/scummvm/ExternalStorage.java
@@ -51,13 +51,13 @@ public class ExternalStorage {
}
private static Pattern
- /** Pattern that SD card device should match */
+ // Pattern that SD card device should match
devicePattern = Pattern.compile("/dev/(block/.*vold.*|fuse)|/mnt/.*"),
- /** Pattern that SD card mount path should match */
+ // Pattern that SD card mount path should match
pathPattern = Pattern.compile("/(mnt|storage|external_sd|extsd|_ExternalSD|Removable|.*MicroSD).*", Pattern.CASE_INSENSITIVE),
- /** Pattern that the mount path should not match.
- * 'emulated' indicates an internal storage location, so skip it.
- * 'asec' is an encrypted package file, decrypted and mounted as a directory. */
+ // Pattern that the mount path should not match.
+ //' emulated' indicates an internal storage location, so skip it.
+ // 'asec' is an encrypted package file, decrypted and mounted as a directory.
pathAntiPattern = Pattern.compile(".*(/secure|/asec|/emulated).*"),
/** These are expected fs types, including vfat. tmpfs is not OK.
* fuse can be removable SD card (as on Moto E or Asus ZenPad), or can be internal (Huawei G610). */
@@ -116,14 +116,14 @@ public class ExternalStorage {
public static LinkedHashSet<File> findSdCardPath() {
String[] mountFields;
BufferedReader bufferedReader = null;
- String lineRead = null;
+ String lineRead;
- /** Possible SD card paths */
- LinkedHashSet<File> candidatePaths = new LinkedHashSet<File>();
+ // Possible SD card paths
+ LinkedHashSet<File> candidatePaths = new LinkedHashSet<>();
- /** Build a list of candidate paths, roughly in order of preference. That way if
- * we can't definitively detect removable storage, we at least can pick a more likely
- * candidate. */
+ // Build a list of candidate paths, roughly in order of preference. That way if
+ // we can't definitively detect removable storage, we at least can pick a more likely
+ // candidate.
// Could do: use getExternalStorageState(File path), with and without an argument, when
// available. With an argument is available since API level 21.
@@ -153,7 +153,7 @@ public class ExternalStorage {
}
// Get listing of mounted devices with their properties.
- ArrayList<File> mountedPaths = new ArrayList<File>();
+ ArrayList<File> mountedPaths = new ArrayList<>();
try {
// Note: Despite restricting some access to /proc (http://stackoverflow.com/a/38728738/423105),
// Android 7.0 does *not* block access to /proc/mounts, according to our test on George's Alcatel A30 GSM.
@@ -334,10 +334,7 @@ public class ExternalStorage {
*/
public static boolean isAvailable() {
String state = Environment.getExternalStorageState();
- if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
- return true;
- }
- return false;
+ return Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
}
public static String getSdCardPath() {
@@ -349,10 +346,7 @@ public class ExternalStorage {
*/
public static boolean isWritable() {
String state = Environment.getExternalStorageState();
- if (Environment.MEDIA_MOUNTED.equals(state)) {
- return true;
- }
- return false;
+ return Environment.MEDIA_MOUNTED.equals(state);
}
@@ -360,10 +354,10 @@ public class ExternalStorage {
* @return list of locations available. Odd elements are names, even are paths
*/
public static List<String> getAllStorageLocations() {
- List<String> map = new ArrayList<String>(20);
+ List<String> map = new ArrayList<>(20);
- List<String> mMounts = new ArrayList<String>(10);
- List<String> mVold = new ArrayList<String>(10);
+ List<String> mMounts = new ArrayList<>(10);
+ List<String> mVold = new ArrayList<>(10);
mMounts.add("/mnt/sdcard");
mVold.add("/mnt/sdcard");
@@ -417,27 +411,27 @@ public class ExternalStorage {
}
mVold.clear();
- List<String> mountHash = new ArrayList<String>(10);
+ List<String> mountHash = new ArrayList<>(10);
for (String mount : mMounts) {
File root = new File(mount);
if (root.exists() && root.isDirectory() && root.canRead()) {
File[] list = root.listFiles();
- String hash = "[";
+ StringBuilder hash = new StringBuilder("[");
if (list != null) {
for (File f : list) {
- hash += f.getName().hashCode() + ":" + f.length() + ", ";
+ hash.append(f.getName().hashCode()).append(":").append(f.length()).append(", ");
}
}
- hash += "]";
- if (!mountHash.contains(hash)) {
+ hash.append("]");
+ if (!mountHash.contains(hash.toString())) {
String key = SD_CARD + "_" + (map.size() / 2);
if (map.size() == 0) {
key = SD_CARD;
} else if (map.size() == 2) {
key = EXTERNAL_SD_CARD;
}
- mountHash.add(hash);
+ mountHash.add(hash.toString());
map.add(key);
map.add(root.getAbsolutePath());
}
@@ -456,7 +450,6 @@ public class ExternalStorage {
//Retrieve the External Storages root directory:
String externalStorageRootDir;
- int count = 0;
if ((externalStorageRootDir = primaryExternalStorage.getParent()) == null) { // no parent...
String key = primaryExternalStorage.getAbsolutePath();
if (!map.contains(key)) {
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
index 22cf3fceca..0c28a83f47 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVM.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
@@ -1,23 +1,21 @@
package org.scummvm.scummvm;
-import android.util.Log;
import android.content.res.AssetManager;
-import android.view.SurfaceHolder;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import java.io.UnsupportedEncodingException;
+import java.util.LinkedHashMap;
-import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
-
-import java.io.File;
-import java.io.UnsupportedEncodingException;
-import java.util.LinkedHashMap;
-import java.util.List;
+import javax.microedition.khronos.opengles.GL10;
public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
final protected static String LOG_TAG = "ScummVM";
@@ -37,13 +35,15 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
private String[] _args;
- final private native void create(AssetManager asset_manager,
- EGL10 egl, EGLDisplay egl_display,
- AudioTrack audio_track,
- int sample_rate, int buffer_size);
- final private native void destroy();
- final private native void setSurface(int width, int height);
- final private native int main(String[] args);
+ private native void create(AssetManager asset_manager,
+ EGL10 egl,
+ EGLDisplay egl_display,
+ AudioTrack audio_track,
+ int sample_rate,
+ int buffer_size);
+ private native void destroy();
+ private native void setSurface(int width, int height);
+ private native int main(String[] args);
// pause the engine and all native threads
final public native void setPause(boolean pause);
@@ -152,7 +152,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
System.exit(res);
}
- final private void initEGL() throws Exception {
+ private void initEGL() throws Exception {
_egl = (EGL10)EGLContext.getEGL();
_egl_display = _egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
@@ -219,7 +219,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
_egl_surface = EGL10.EGL_NO_SURFACE;
}
- final private void deinitEGL() {
+ private void deinitEGL() {
if (_egl_display != EGL10.EGL_NO_DISPLAY) {
_egl.eglMakeCurrent(_egl_display, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
@@ -240,7 +240,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
_egl = null;
}
- final private void initAudio() throws Exception {
+ private void initAudio() throws Exception {
_sample_rate = AudioTrack.getNativeOutputSampleRate(
AudioManager.STREAM_MUSIC);
_buffer_size = AudioTrack.getMinBufferSize(_sample_rate,
@@ -273,7 +273,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
_audio_track.getState()));
}
- final private void deinitAudio() {
+ private void deinitAudio() {
if (_audio_track != null)
_audio_track.stop();
@@ -406,9 +406,9 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
return s;
}
- };
+ }
- final private EGLConfig chooseEglConfig(EGLConfig[] configs) {
+ private EGLConfig chooseEglConfig(EGLConfig[] configs) {
EGLConfig res = configs[0];
int bestScore = -1;
@@ -447,7 +447,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
if (sleep_for_debugger) {
try {
Thread.sleep(20 * 1000);
- } catch (InterruptedException e) {
+ } catch (InterruptedException ignored) {
}
}
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index 31a9ee8dab..07965ae275 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -334,6 +334,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
super.onDestroy();
if (_events != null) {
+ _events.clearEventHandler();
_events.sendQuitEvent();
try {
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
index 07c4233f0a..414033ab78 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
@@ -1,5 +1,6 @@
package org.scummvm.scummvm;
+import androidx.annotation.NonNull;
import android.os.Handler;
import android.os.Message;
import android.content.Context;
@@ -12,6 +13,8 @@ import android.view.GestureDetector;
import android.view.InputDevice;
import android.view.inputmethod.InputMethodManager;
+import java.lang.ref.WeakReference;
+
public class ScummVMEvents implements
android.view.View.OnKeyListener,
android.view.View.OnTouchListener,
@@ -48,6 +51,8 @@ public class ScummVMEvents implements
final protected int _longPress;
final protected MouseHelper _mouseHelper;
+ final private ScummVMEventHandler keyHandler;
+
public ScummVMEvents(Context context, ScummVM scummvm, MouseHelper mouseHelper) {
_context = context;
_scummvm = scummvm;
@@ -58,6 +63,28 @@ public class ScummVMEvents implements
_gd.setIsLongpressEnabled(false);
_longPress = ViewConfiguration.getLongPressTimeout();
+
+ keyHandler = new ScummVMEventHandler(new ScummVMEventHandler.OnMessageReceivedListener() {
+ @Override
+ public void handleMessage(final Message msg) {
+ if (msg.what == MSG_SMENU_LONG_PRESS) {
+ // this displays the android keyboard (see showVirtualKeyboard() in ScummVMActivity.java)
+ // when menu key is long-pressed
+ InputMethodManager imm = (InputMethodManager)
+ _context.getSystemService(Context.INPUT_METHOD_SERVICE);
+
+ if (imm != null)
+ imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
+ } else if (msg.what == MSG_SBACK_LONG_PRESS) {
+ _scummvm.pushEvent(JE_SYS_KEY, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU, 0, 0, 0, 0);
+ _scummvm.pushEvent(JE_SYS_KEY, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU, 0, 0, 0, 0);
+ }
+ }
+ });
+ }
+
+ public void clearEventHandler() {
+ keyHandler.clear();
}
final public void sendQuitEvent() {
@@ -79,23 +106,31 @@ public class ScummVMEvents implements
final static int MSG_SMENU_LONG_PRESS = 1;
final static int MSG_SBACK_LONG_PRESS = 2;
- final private Handler keyHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == MSG_SMENU_LONG_PRESS) {
- // this displays the android keyboard (see showVirtualKeyboard() in ScummVMActivity.java)
- // when menu key is long-pressed
- InputMethodManager imm = (InputMethodManager)
- _context.getSystemService(Context.INPUT_METHOD_SERVICE);
-
- if (imm != null)
- imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
- } else if (msg.what == MSG_SBACK_LONG_PRESS) {
- _scummvm.pushEvent(JE_SYS_KEY, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU, 0, 0, 0, 0);
- _scummvm.pushEvent(JE_SYS_KEY, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU, 0, 0, 0, 0);
+ // Custom handler code (to avoid mem leaks, see warning "This Handler Class Should Be Static Or Leaks Might Occurâ) based on:
+ // https://stackoverflow.com/a/57926736
+ public static class ScummVMEventHandler extends Handler {
+
+ WeakReference<OnMessageReceivedListener> mListenerReference;
+
+ public ScummVMEventHandler(OnMessageReceivedListener listener) {
+ mListenerReference = new WeakReference<>(listener);
+ }
+
+ public synchronized void handleMessage(@NonNull Message msg) {
+ OnMessageReceivedListener listener = mListenerReference.get();
+ if(listener != null) {
+ listener.handleMessage(msg);
}
}
- };
+
+ public void clear() {
+ mListenerReference.clear();
+ }
+
+ public interface OnMessageReceivedListener {
+ void handleMessage(final Message message);
+ }
+ }
// OnKeyListener
@Override
More information about the Scummvm-git-logs
mailing list