Skip to content

Commit 6b88301

Browse files
committed
Dynamic side loading of cores
1 parent 77ba257 commit 6b88301

1 file changed

Lines changed: 72 additions & 1 deletion

File tree

pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
import android.os.Message;
1515
import com.retroarch.browser.preferences.util.ConfigFile;
1616
import com.retroarch.browser.preferences.util.UserPreferences;
17+
import java.io.File;
18+
import java.io.FileInputStream;
19+
import java.io.FileOutputStream;
20+
import java.io.IOException;
21+
import java.io.InputStream;
22+
import java.io.OutputStream;
1723
import java.lang.reflect.InvocationTargetException;
1824
import java.lang.reflect.Method;
1925

@@ -58,14 +64,79 @@ public void handleMessage(Message msg) {
5864
@Override
5965
public void onCreate(Bundle savedInstanceState) {
6066
super.onCreate(savedInstanceState);
61-
67+
6268
isRunning = true;
6369
mDecorView = getWindow().getDecorView();
6470

71+
// Copy external core .so to internal cores directory if needed
72+
copyExternalCoreIfNeeded();
73+
6574
// If QUITFOCUS parameter is provided then enable that Retroarch quits when focus is lost
6675
quitfocus = getIntent().hasExtra("QUITFOCUS");
6776
}
6877

78+
private void copyExternalCoreIfNeeded() {
79+
String libretroPath = getIntent().getStringExtra("LIBRETRO");
80+
if (libretroPath == null || !libretroPath.endsWith(".so"))
81+
return;
82+
83+
String dataDir = getApplicationInfo().dataDir;
84+
85+
// Normalize /data/data/ symlink to real dataDir path (/data/user/0/...)
86+
String datadataPrefix = "/data/data/" + getPackageName();
87+
if (libretroPath.startsWith(datadataPrefix)) {
88+
libretroPath = dataDir + libretroPath.substring(datadataPrefix.length());
89+
getIntent().putExtra("LIBRETRO", libretroPath);
90+
return;
91+
}
92+
93+
// Already using the real dataDir path
94+
if (libretroPath.startsWith(dataDir))
95+
return;
96+
97+
// External core — copy to internal cores directory
98+
File srcFile = new File(libretroPath);
99+
if (!srcFile.isFile())
100+
return;
101+
102+
File coresDir = new File(dataDir, "cores");
103+
if (!coresDir.exists())
104+
coresDir.mkdirs();
105+
106+
File destFile = new File(coresDir, srcFile.getName());
107+
108+
// Avoid self-copy if source and destination resolve to the same file
109+
try {
110+
if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) {
111+
getIntent().putExtra("LIBRETRO", destFile.getAbsolutePath());
112+
return;
113+
}
114+
} catch (IOException e) {
115+
// If we can't resolve, proceed with copy
116+
}
117+
118+
try {
119+
InputStream in = new FileInputStream(srcFile);
120+
try {
121+
OutputStream out = new FileOutputStream(destFile);
122+
try {
123+
byte[] buf = new byte[8192];
124+
int len;
125+
while ((len = in.read(buf)) > 0)
126+
out.write(buf, 0, len);
127+
} finally {
128+
out.close();
129+
}
130+
} finally {
131+
in.close();
132+
}
133+
getIntent().putExtra("LIBRETRO", destFile.getAbsolutePath());
134+
Log.i("RetroActivityFuture", "Copied external core to: " + destFile.getAbsolutePath());
135+
} catch (IOException e) {
136+
Log.e("RetroActivityFuture", "Failed to copy external core: " + e.getMessage());
137+
}
138+
}
139+
69140
@Override
70141
public void onNewIntent(Intent intent) {
71142
super.onNewIntent(intent);

0 commit comments

Comments
 (0)