From 0d053477d27da455b2dc47104ee8e980a09403f6 Mon Sep 17 00:00:00 2001 From: txl Date: Sat, 15 Nov 2025 17:47:02 +0100 Subject: [PATCH 1/3] Custom core loading --- .../browser/mainmenu/MainMenuActivity.java | 22 +++- .../retroactivity/RetroActivityFuture.java | 110 ++++++++++++++++++ 2 files changed, 126 insertions(+), 6 deletions(-) diff --git a/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java b/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java index 35eaac836a96..f40a7641a7e1 100644 --- a/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java +++ b/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java @@ -126,14 +126,24 @@ public void finalStartup() retro.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + // Check if we received intent extras from external launcher + Intent originalIntent = getIntent(); + String romPath = originalIntent.getStringExtra("ROM"); + String corePath = originalIntent.getStringExtra("LIBRETRO"); + String configPath = originalIntent.getStringExtra("CONFIGFILE"); + String imePath = originalIntent.getStringExtra("IME"); + String dataDirPath = originalIntent.getStringExtra("DATADIR"); + String dataSourcePath = originalIntent.getStringExtra("APK"); + + // Use provided values or defaults startRetroActivity( retro, - null, - prefs.getString("libretro_path", getApplicationInfo().dataDir + "/cores/"), - UserPreferences.getDefaultConfigPath(this), - Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD), - getApplicationInfo().dataDir, - getApplicationInfo().sourceDir); + romPath, + corePath != null ? corePath : prefs.getString("libretro_path", getApplicationInfo().dataDir + "/cores/"), + configPath != null ? configPath : UserPreferences.getDefaultConfigPath(this), + imePath != null ? imePath : Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD), + dataDirPath != null ? dataDirPath : getApplicationInfo().dataDir, + dataSourcePath != null ? dataSourcePath : getApplicationInfo().sourceDir); } startActivity(retro); diff --git a/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java b/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java index f74c9d14580d..31dedaadd0c0 100644 --- a/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java +++ b/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java @@ -14,8 +14,17 @@ import android.os.Message; import com.retroarch.browser.preferences.util.ConfigFile; import com.retroarch.browser.preferences.util.UserPreferences; +import com.retroarch.browser.mainmenu.MainMenuActivity; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import android.content.pm.PackageManager; +import android.Manifest; public final class RetroActivityFuture extends RetroActivityCamera { @@ -62,10 +71,111 @@ public void onCreate(Bundle savedInstanceState) { isRunning = true; mDecorView = getWindow().getDecorView(); + // Check if we need permissions before proceeding + if (!checkPermissions()) { + // Redirect to MainMenuActivity to get permissions + Intent mainMenuIntent = new Intent(this, MainMenuActivity.class); + mainMenuIntent.putExtras(getIntent()); + startActivity(mainMenuIntent); + finish(); + return; + } + + // Handle core sideloading if external core path provided + handleCoreSideloading(); + // If QUITFOCUS parameter is provided then enable that Retroarch quits when focus is lost quitfocus = getIntent().hasExtra("QUITFOCUS"); } + private boolean checkPermissions() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + List permissionsNeeded = new ArrayList(); + + if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + permissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE); + } + if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + permissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); + } + + return permissionsNeeded.isEmpty(); + } + return true; + } + + private void handleCoreSideloading() { + String corePath = getIntent().getStringExtra("LIBRETRO"); + if (corePath == null || corePath.isEmpty()) { + return; + } + + File coreFile = new File(corePath); + if (!coreFile.exists()) { + Log.w("RetroActivityFuture", "Core file does not exist: " + corePath); + return; + } + + // Get the cores directory + String coresDir = getApplicationInfo().dataDir + "/cores/"; + File coresDirFile = new File(coresDir); + + // Create cores directory if it doesn't exist + if (!coresDirFile.exists()) { + if (!coresDirFile.mkdirs()) { + Log.e("RetroActivityFuture", "Failed to create cores directory: " + coresDir); + return; + } + } + + // Check if core is outside RetroArch cores folder - if so, sideload it + if (!corePath.startsWith(coresDir)) { + String coreFileName = coreFile.getName(); + File destinationFile = new File(coresDir, coreFileName); + + try { + copyFile(coreFile, destinationFile); + Log.i("RetroActivityFuture", "Sideloaded core from " + corePath + " to " + destinationFile.getAbsolutePath()); + + // Update intent to point to the new location + getIntent().putExtra("LIBRETRO", destinationFile.getAbsolutePath()); + } catch (IOException e) { + Log.e("RetroActivityFuture", "Failed to sideload core: " + e.getMessage()); + } + } + } + + private void copyFile(File source, File destination) throws IOException { + FileInputStream inStream = null; + FileOutputStream outStream = null; + + try { + inStream = new FileInputStream(source); + outStream = new FileOutputStream(destination); + + byte[] buffer = new byte[8192]; + int length; + while ((length = inStream.read(buffer)) > 0) { + outStream.write(buffer, 0, length); + } + } finally { + if (inStream != null) { + try { + inStream.close(); + } catch (IOException e) { + // Ignore + } + } + if (outStream != null) { + try { + outStream.close(); + } catch (IOException e) { + // Ignore + } + } + } + } + @Override public void onNewIntent(Intent intent) { super.onNewIntent(intent); From 5c104267324dab866d80254749fa821cce33c269 Mon Sep 17 00:00:00 2001 From: txl Date: Sat, 15 Nov 2025 17:51:32 +0100 Subject: [PATCH 2/3] Revert "Custom core loading" This reverts commit 0d053477d27da455b2dc47104ee8e980a09403f6. --- .../browser/mainmenu/MainMenuActivity.java | 22 +--- .../retroactivity/RetroActivityFuture.java | 110 ------------------ 2 files changed, 6 insertions(+), 126 deletions(-) diff --git a/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java b/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java index f40a7641a7e1..35eaac836a96 100644 --- a/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java +++ b/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java @@ -126,24 +126,14 @@ public void finalStartup() retro.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - // Check if we received intent extras from external launcher - Intent originalIntent = getIntent(); - String romPath = originalIntent.getStringExtra("ROM"); - String corePath = originalIntent.getStringExtra("LIBRETRO"); - String configPath = originalIntent.getStringExtra("CONFIGFILE"); - String imePath = originalIntent.getStringExtra("IME"); - String dataDirPath = originalIntent.getStringExtra("DATADIR"); - String dataSourcePath = originalIntent.getStringExtra("APK"); - - // Use provided values or defaults startRetroActivity( retro, - romPath, - corePath != null ? corePath : prefs.getString("libretro_path", getApplicationInfo().dataDir + "/cores/"), - configPath != null ? configPath : UserPreferences.getDefaultConfigPath(this), - imePath != null ? imePath : Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD), - dataDirPath != null ? dataDirPath : getApplicationInfo().dataDir, - dataSourcePath != null ? dataSourcePath : getApplicationInfo().sourceDir); + null, + prefs.getString("libretro_path", getApplicationInfo().dataDir + "/cores/"), + UserPreferences.getDefaultConfigPath(this), + Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD), + getApplicationInfo().dataDir, + getApplicationInfo().sourceDir); } startActivity(retro); diff --git a/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java b/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java index 31dedaadd0c0..f74c9d14580d 100644 --- a/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java +++ b/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java @@ -14,17 +14,8 @@ import android.os.Message; import com.retroarch.browser.preferences.util.ConfigFile; import com.retroarch.browser.preferences.util.UserPreferences; -import com.retroarch.browser.mainmenu.MainMenuActivity; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.List; -import java.util.ArrayList; -import android.content.pm.PackageManager; -import android.Manifest; public final class RetroActivityFuture extends RetroActivityCamera { @@ -71,111 +62,10 @@ public void onCreate(Bundle savedInstanceState) { isRunning = true; mDecorView = getWindow().getDecorView(); - // Check if we need permissions before proceeding - if (!checkPermissions()) { - // Redirect to MainMenuActivity to get permissions - Intent mainMenuIntent = new Intent(this, MainMenuActivity.class); - mainMenuIntent.putExtras(getIntent()); - startActivity(mainMenuIntent); - finish(); - return; - } - - // Handle core sideloading if external core path provided - handleCoreSideloading(); - // If QUITFOCUS parameter is provided then enable that Retroarch quits when focus is lost quitfocus = getIntent().hasExtra("QUITFOCUS"); } - private boolean checkPermissions() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - List permissionsNeeded = new ArrayList(); - - if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - permissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE); - } - if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - permissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); - } - - return permissionsNeeded.isEmpty(); - } - return true; - } - - private void handleCoreSideloading() { - String corePath = getIntent().getStringExtra("LIBRETRO"); - if (corePath == null || corePath.isEmpty()) { - return; - } - - File coreFile = new File(corePath); - if (!coreFile.exists()) { - Log.w("RetroActivityFuture", "Core file does not exist: " + corePath); - return; - } - - // Get the cores directory - String coresDir = getApplicationInfo().dataDir + "/cores/"; - File coresDirFile = new File(coresDir); - - // Create cores directory if it doesn't exist - if (!coresDirFile.exists()) { - if (!coresDirFile.mkdirs()) { - Log.e("RetroActivityFuture", "Failed to create cores directory: " + coresDir); - return; - } - } - - // Check if core is outside RetroArch cores folder - if so, sideload it - if (!corePath.startsWith(coresDir)) { - String coreFileName = coreFile.getName(); - File destinationFile = new File(coresDir, coreFileName); - - try { - copyFile(coreFile, destinationFile); - Log.i("RetroActivityFuture", "Sideloaded core from " + corePath + " to " + destinationFile.getAbsolutePath()); - - // Update intent to point to the new location - getIntent().putExtra("LIBRETRO", destinationFile.getAbsolutePath()); - } catch (IOException e) { - Log.e("RetroActivityFuture", "Failed to sideload core: " + e.getMessage()); - } - } - } - - private void copyFile(File source, File destination) throws IOException { - FileInputStream inStream = null; - FileOutputStream outStream = null; - - try { - inStream = new FileInputStream(source); - outStream = new FileOutputStream(destination); - - byte[] buffer = new byte[8192]; - int length; - while ((length = inStream.read(buffer)) > 0) { - outStream.write(buffer, 0, length); - } - } finally { - if (inStream != null) { - try { - inStream.close(); - } catch (IOException e) { - // Ignore - } - } - if (outStream != null) { - try { - outStream.close(); - } catch (IOException e) { - // Ignore - } - } - } - } - @Override public void onNewIntent(Intent intent) { super.onNewIntent(intent); From 4f392c983c1fd62ca1918c6d3322ab33dbeed8fd Mon Sep 17 00:00:00 2001 From: txl Date: Sat, 15 Nov 2025 17:47:02 +0100 Subject: [PATCH 3/3] Custom core loading --- .../browser/mainmenu/MainMenuActivity.java | 22 +++- .../retroactivity/RetroActivityFuture.java | 110 ++++++++++++++++++ 2 files changed, 126 insertions(+), 6 deletions(-) diff --git a/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java b/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java index 35eaac836a96..f40a7641a7e1 100644 --- a/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java +++ b/pkg/android/phoenix/src/com/retroarch/browser/mainmenu/MainMenuActivity.java @@ -126,14 +126,24 @@ public void finalStartup() retro.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + // Check if we received intent extras from external launcher + Intent originalIntent = getIntent(); + String romPath = originalIntent.getStringExtra("ROM"); + String corePath = originalIntent.getStringExtra("LIBRETRO"); + String configPath = originalIntent.getStringExtra("CONFIGFILE"); + String imePath = originalIntent.getStringExtra("IME"); + String dataDirPath = originalIntent.getStringExtra("DATADIR"); + String dataSourcePath = originalIntent.getStringExtra("APK"); + + // Use provided values or defaults startRetroActivity( retro, - null, - prefs.getString("libretro_path", getApplicationInfo().dataDir + "/cores/"), - UserPreferences.getDefaultConfigPath(this), - Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD), - getApplicationInfo().dataDir, - getApplicationInfo().sourceDir); + romPath, + corePath != null ? corePath : prefs.getString("libretro_path", getApplicationInfo().dataDir + "/cores/"), + configPath != null ? configPath : UserPreferences.getDefaultConfigPath(this), + imePath != null ? imePath : Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD), + dataDirPath != null ? dataDirPath : getApplicationInfo().dataDir, + dataSourcePath != null ? dataSourcePath : getApplicationInfo().sourceDir); } startActivity(retro); diff --git a/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java b/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java index f74c9d14580d..31dedaadd0c0 100644 --- a/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java +++ b/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java @@ -14,8 +14,17 @@ import android.os.Message; import com.retroarch.browser.preferences.util.ConfigFile; import com.retroarch.browser.preferences.util.UserPreferences; +import com.retroarch.browser.mainmenu.MainMenuActivity; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import android.content.pm.PackageManager; +import android.Manifest; public final class RetroActivityFuture extends RetroActivityCamera { @@ -62,10 +71,111 @@ public void onCreate(Bundle savedInstanceState) { isRunning = true; mDecorView = getWindow().getDecorView(); + // Check if we need permissions before proceeding + if (!checkPermissions()) { + // Redirect to MainMenuActivity to get permissions + Intent mainMenuIntent = new Intent(this, MainMenuActivity.class); + mainMenuIntent.putExtras(getIntent()); + startActivity(mainMenuIntent); + finish(); + return; + } + + // Handle core sideloading if external core path provided + handleCoreSideloading(); + // If QUITFOCUS parameter is provided then enable that Retroarch quits when focus is lost quitfocus = getIntent().hasExtra("QUITFOCUS"); } + private boolean checkPermissions() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + List permissionsNeeded = new ArrayList(); + + if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + permissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE); + } + if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + permissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); + } + + return permissionsNeeded.isEmpty(); + } + return true; + } + + private void handleCoreSideloading() { + String corePath = getIntent().getStringExtra("LIBRETRO"); + if (corePath == null || corePath.isEmpty()) { + return; + } + + File coreFile = new File(corePath); + if (!coreFile.exists()) { + Log.w("RetroActivityFuture", "Core file does not exist: " + corePath); + return; + } + + // Get the cores directory + String coresDir = getApplicationInfo().dataDir + "/cores/"; + File coresDirFile = new File(coresDir); + + // Create cores directory if it doesn't exist + if (!coresDirFile.exists()) { + if (!coresDirFile.mkdirs()) { + Log.e("RetroActivityFuture", "Failed to create cores directory: " + coresDir); + return; + } + } + + // Check if core is outside RetroArch cores folder - if so, sideload it + if (!corePath.startsWith(coresDir)) { + String coreFileName = coreFile.getName(); + File destinationFile = new File(coresDir, coreFileName); + + try { + copyFile(coreFile, destinationFile); + Log.i("RetroActivityFuture", "Sideloaded core from " + corePath + " to " + destinationFile.getAbsolutePath()); + + // Update intent to point to the new location + getIntent().putExtra("LIBRETRO", destinationFile.getAbsolutePath()); + } catch (IOException e) { + Log.e("RetroActivityFuture", "Failed to sideload core: " + e.getMessage()); + } + } + } + + private void copyFile(File source, File destination) throws IOException { + FileInputStream inStream = null; + FileOutputStream outStream = null; + + try { + inStream = new FileInputStream(source); + outStream = new FileOutputStream(destination); + + byte[] buffer = new byte[8192]; + int length; + while ((length = inStream.read(buffer)) > 0) { + outStream.write(buffer, 0, length); + } + } finally { + if (inStream != null) { + try { + inStream.close(); + } catch (IOException e) { + // Ignore + } + } + if (outStream != null) { + try { + outStream.close(); + } catch (IOException e) { + // Ignore + } + } + } + } + @Override public void onNewIntent(Intent intent) { super.onNewIntent(intent);