]> git.lizzy.rs Git - minetest.git/commitdiff
Android: Segmentation fault fix, PendingIntent flag, and other fixes (#12960)
authorMuhammad Rifqi Priyo Susanto <muhammadrifqipriyosusanto@gmail.com>
Wed, 30 Nov 2022 15:50:06 +0000 (22:50 +0700)
committerGitHub <noreply@github.com>
Wed, 30 Nov 2022 15:50:06 +0000 (10:50 -0500)
* Android: Segmentation fault fix, PendingIntent flag, and other fixes

- Information about the crosshair is sent after camera initialization.
- Since API 31, PendingIntent requires mutability flag.
- super (class) is called in onRequestPermissionsResult().
- GameActivity suppresses "unused" warning since most of its methods are called from native code.
- Non-null safety is added for nullable function calls.
- Warning/error logging is added for various function calls' return value.

* Move utility functions into Utils.java

- Some nullable functions are changed to be non-null functions.
- Some null checking outside it is removed.
- More annotations are added to functions and parameters.

android/app/src/main/java/net/minetest/minetest/GameActivity.java
android/app/src/main/java/net/minetest/minetest/MainActivity.java
android/app/src/main/java/net/minetest/minetest/UnzipService.java
android/app/src/main/java/net/minetest/minetest/Utils.java
src/client/game.cpp

index f5e9fd6d08a303c653e9fd661f9d609ccc60e0e8..d2dd6a4bda229ce8cc9e1c3c4285b5e4eb25d1d6 100644 (file)
@@ -45,6 +45,7 @@ import java.util.Objects;
 // Native code finds these methods by name (see porting_android.cpp).
 // This annotation prevents the minifier/Proguard from mangling them.
 @Keep
+@SuppressWarnings("unused")
 public class GameActivity extends NativeActivity {
        static {
                System.loadLibrary("c++_shared");
index b6567b4b75845de0f74d900219903fededff44c8..7678bbb015a8758db915e0c7a59f25614ee873e1 100644 (file)
@@ -127,8 +127,12 @@ public class MainActivity extends AppCompatActivity {
        }
 
        @Override
-       public void onRequestPermissionsResult(int requestCode,
-                                                                       @NonNull String[] permissions, @NonNull int[] grantResults) {
+       public void onRequestPermissionsResult(
+               int requestCode,
+               @NonNull String[] permissions,
+               @NonNull int[] grantResults
+       ) {
+               super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                if (requestCode == PERMISSIONS) {
                        for (int grantResult : grantResults) {
                                if (grantResult != PackageManager.PERMISSION_GRANTED) {
index a61a491398422488910d542ff586f63c50659862..c7690c237035f06406e59b89a4ebaa3defb436cf 100644 (file)
@@ -29,10 +29,10 @@ import android.content.Context;
 import android.content.Intent;
 import android.os.Build;
 import android.os.Environment;
+import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.annotation.StringRes;
 
 import java.io.File;
@@ -77,9 +77,6 @@ public class UnzipService extends IntentService {
                try {
                        setIsRunning(true);
                        File userDataDirectory = Utils.getUserDataDirectory(this);
-                       if (userDataDirectory == null) {
-                               throw new IOException("Unable to find user data directory");
-                       }
 
                        try (InputStream in = this.getAssets().open(zipFile.getName())) {
                                try (OutputStream out = new FileOutputStream(zipFile)) {
@@ -98,7 +95,9 @@ public class UnzipService extends IntentService {
                        failureMessage = e.getLocalizedMessage();
                } finally {
                        setIsRunning(false);
-                       zipFile.delete();
+                       if (!zipFile.delete()) {
+                               Log.w("UnzipService", "Minetest installation ZIP cannot be deleted");
+                       }
                }
        }
 
@@ -131,8 +130,12 @@ public class UnzipService extends IntentService {
                Intent notificationIntent = new Intent(this, MainActivity.class);
                notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                        | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+               int pendingIntentFlag = 0;
+               if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+                       pendingIntentFlag = PendingIntent.FLAG_MUTABLE;
+               }
                PendingIntent intent = PendingIntent.getActivity(this, 0,
-                       notificationIntent, 0);
+                       notificationIntent, pendingIntentFlag);
 
                builder.setContentTitle(getString(R.string.notification_title))
                                .setSmallIcon(R.mipmap.ic_launcher)
@@ -210,7 +213,9 @@ public class UnzipService extends IntentService {
                        return;
 
                publishProgress(notificationBuilder, R.string.migrating, 0);
-               newLocation.mkdir();
+               if (!newLocation.mkdir()) {
+                       Log.e("UnzipService", "New installation folder cannot be made");
+               }
 
                String[] dirs = new String[] { "worlds", "games", "mods", "textures", "client" };
                for (int i = 0; i < dirs.length; i++) {
@@ -228,7 +233,9 @@ public class UnzipService extends IntentService {
                        }
                }
 
-               recursivelyDeleteDirectory(oldLocation);
+               if (!recursivelyDeleteDirectory(oldLocation)) {
+                       Log.w("UnzipService", "Old installation files cannot be deleted successfully");
+               }
        }
 
        private void publishProgress(@Nullable  Notification.Builder notificationBuilder, @StringRes int message, int progress) {
index b2553c844c93274c5ea8b8198d36d5dcc5059744..7fbdf3b14174d8a4bab542670ddb13f1a64e3e17 100644 (file)
@@ -1,36 +1,43 @@
 package net.minetest.minetest;
 
 import android.content.Context;
+import android.util.Log;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import java.io.File;
+import java.util.Objects;
 
 public class Utils {
-       public static @NonNull File createDirs(File root, String dir) {
+       @NonNull
+       public static File createDirs(@NonNull File root, @NonNull String dir) {
                File f = new File(root, dir);
                if (!f.isDirectory())
-                       f.mkdirs();
+                       if (!f.mkdirs())
+                               Log.e("Utils", "Directory " + dir + " cannot be created");
 
                return f;
        }
 
-       public static @Nullable File getUserDataDirectory(Context context) {
-               File extDir = context.getExternalFilesDir(null);
-               if (extDir == null) {
-                       return null;
-               }
-
+       @NonNull
+       public static File getUserDataDirectory(@NonNull Context context) {
+               File extDir = Objects.requireNonNull(
+                       context.getExternalFilesDir(null),
+                       "Cannot get external file directory"
+               );
                return createDirs(extDir, "Minetest");
        }
 
-       public static @Nullable File getCacheDirectory(Context context) {
-               return context.getCacheDir();
+       @NonNull
+       public static File getCacheDirectory(@NonNull Context context) {
+               return Objects.requireNonNull(
+                       context.getCacheDir(),
+                       "Cannot get cache directory"
+               );
        }
 
-       public static boolean isInstallValid(Context context) {
+       public static boolean isInstallValid(@NonNull Context context) {
                File userDataDirectory = getUserDataDirectory(context);
-               return userDataDirectory != null && userDataDirectory.isDirectory() &&
+               return userDataDirectory.isDirectory() &&
                        new File(userDataDirectory, "games").isDirectory() &&
                        new File(userDataDirectory, "builtin").isDirectory() &&
                        new File(userDataDirectory, "client").isDirectory() &&
index 179557cf56317193337ab8100df4b077843e8488..e180c88b2c2ba60d8a22387b4782467f6dcc8959 100644 (file)
@@ -1421,7 +1421,6 @@ bool Game::createClient(const GameStartData &start_data)
        if (g_touchscreengui) {
                g_touchscreengui->init(texture_src);
                g_touchscreengui->hide();
-               g_touchscreengui->setUseCrosshair(!isNoCrosshairAllowed());
        }
 #endif
        if (!connectToServer(start_data, &could_connect, &connect_aborted))
@@ -1458,6 +1457,11 @@ bool Game::createClient(const GameStartData &start_data)
        if (client->modsLoaded())
                client->getScript()->on_camera_ready(camera);
        client->setCamera(camera);
+#ifdef HAVE_TOUCHSCREENGUI
+       if (g_touchscreengui) {
+               g_touchscreengui->setUseCrosshair(!isNoCrosshairAllowed());
+       }
+#endif
 
        /* Clouds
         */