game launch callback
This commit is contained in:
parent
c42e70cace
commit
75f4e46625
|
@ -37,6 +37,8 @@
|
|||
android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission
|
||||
android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission
|
||||
android:name="android.permission.RECORD_AUDIO" />
|
||||
|
||||
<application
|
||||
android:name=".FCLApplication"
|
||||
|
|
|
@ -5,11 +5,19 @@ import android.os.Bundle;
|
|||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tungsten.fcllibrary.component.FCLActivity;
|
||||
import com.tungsten.fcllibrary.component.theme.ThemeEngine;
|
||||
import com.tungsten.fcllibrary.component.view.FCLImageView;
|
||||
|
||||
public class ControllerActivity extends FCLActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
FCLImageView contentView = new FCLImageView(this);
|
||||
contentView.setBackground(ThemeEngine.getInstance().getTheme().getBackground(this));
|
||||
setContentView(contentView);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.tungsten.fcl.activity;
|
|||
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.TextureView;
|
||||
|
||||
|
@ -9,10 +10,10 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tungsten.fcl.R;
|
||||
import com.tungsten.fcl.control.ControllerCallback;
|
||||
import com.tungsten.fcl.control.ControllerType;
|
||||
import com.tungsten.fcl.control.GameController;
|
||||
import com.tungsten.fcl.control.JavaGuiController;
|
||||
import com.tungsten.fcl.control.MenuCallback;
|
||||
import com.tungsten.fcl.control.MenuType;
|
||||
import com.tungsten.fcl.control.GameMenu;
|
||||
import com.tungsten.fcl.control.JavaGuiMenu;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridge;
|
||||
import com.tungsten.fclcore.util.Logging;
|
||||
import com.tungsten.fcllibrary.component.FCLActivity;
|
||||
|
@ -23,13 +24,13 @@ public class JVMActivity extends FCLActivity implements TextureView.SurfaceTextu
|
|||
|
||||
private TextureView textureView;
|
||||
|
||||
private ControllerCallback controller;
|
||||
private static ControllerType controllerType;
|
||||
private MenuCallback menuCallback;
|
||||
private static MenuType menuType;
|
||||
private static FCLBridge fclBridge;
|
||||
|
||||
public static void setFClBridge(FCLBridge fclBridge, ControllerType controllerType) {
|
||||
public static void setFClBridge(FCLBridge fclBridge, MenuType menuType) {
|
||||
JVMActivity.fclBridge = fclBridge;
|
||||
JVMActivity.controllerType = controllerType;
|
||||
JVMActivity.menuType = menuType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -37,23 +38,22 @@ public class JVMActivity extends FCLActivity implements TextureView.SurfaceTextu
|
|||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_jvm);
|
||||
|
||||
if (controllerType == null || fclBridge == null) {
|
||||
if (menuType == null || fclBridge == null) {
|
||||
Logging.LOG.log(Level.WARNING, "Failed to get ControllerType or FCLBridge, task canceled.");
|
||||
return;
|
||||
}
|
||||
|
||||
controller = controllerType == ControllerType.GAME ? new GameController() : new JavaGuiController();
|
||||
controller.setup(this);
|
||||
menuCallback = menuType == MenuType.GAME ? new GameMenu() : new JavaGuiMenu();
|
||||
menuCallback.setup(this, fclBridge);
|
||||
textureView = findViewById(R.id.texture_view);
|
||||
textureView.setSurfaceTextureListener(this);
|
||||
textureView.setFocusable(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {
|
||||
Logging.LOG.log(Level.INFO, "surface ready, start jvm now!");
|
||||
surfaceTexture.setDefaultBufferSize((int) (i * fclBridge.getScaleFactor()), (int) (i1 * fclBridge.getScaleFactor()));
|
||||
fclBridge.execute(new Surface(surfaceTexture), controller.getCallbackBridge());
|
||||
fclBridge.execute(new Surface(surfaceTexture), menuCallback.getCallbackBridge());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,13 +66,43 @@ public class JVMActivity extends FCLActivity implements TextureView.SurfaceTextu
|
|||
return false;
|
||||
}
|
||||
|
||||
private int output = 0;
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surfaceTexture) {
|
||||
if (output == 1) {
|
||||
menuCallback.onGraphicOutput();
|
||||
output++;
|
||||
}
|
||||
if (output < 1) {
|
||||
output++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
menuCallback.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
menuCallback.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
return menuCallback.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
return menuCallback.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
|
||||
menuCallback.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.tungsten.fcl.activity;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -14,4 +16,14 @@ public class JVMCrashActivity extends FCLActivity {
|
|||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_jvm_crash);
|
||||
}
|
||||
|
||||
public static void startCrashActivity(Context context, int exitCode) {
|
||||
Intent intent = new Intent(context, JVMCrashActivity.class);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("exitCode", exitCode);
|
||||
intent.putExtras(bundle);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
package com.tungsten.fcl.control;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tungsten.fcl.activity.JVMActivity;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridgeCallback;
|
||||
|
||||
public interface ControllerCallback {
|
||||
|
||||
View getLayout();
|
||||
|
||||
void setup(JVMActivity activity);
|
||||
|
||||
FCLBridgeCallback getCallbackBridge();
|
||||
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
package com.tungsten.fcl.control;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.view.View;
|
||||
|
||||
import com.tungsten.fcl.activity.JVMActivity;
|
||||
import com.tungsten.fcl.activity.JVMCrashActivity;
|
||||
import com.tungsten.fclauncher.FCLPath;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridgeCallback;
|
||||
import com.tungsten.fclcore.util.Logging;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class GameController implements ControllerCallback {
|
||||
|
||||
@Override
|
||||
public View getLayout() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(JVMActivity activity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public FCLBridgeCallback getCallbackBridge() {
|
||||
return new FCLProcessListener();
|
||||
}
|
||||
|
||||
static class FCLProcessListener implements FCLBridgeCallback {
|
||||
|
||||
@Override
|
||||
public void onCursorModeChange(int mode) {
|
||||
// TODO: Handle mouse event
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExit(int code) {
|
||||
if (code != 0) {
|
||||
Logging.LOG.log(Level.INFO, "JVM crashed, start jvm crash activity to show errors now!");
|
||||
Intent intent = new Intent(FCLPath.CONTEXT, JVMCrashActivity.class);
|
||||
FCLPath.CONTEXT.startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
package com.tungsten.fcl.control;
|
||||
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
import com.tungsten.fcl.activity.JVMActivity;
|
||||
import com.tungsten.fcl.activity.JVMCrashActivity;
|
||||
import com.tungsten.fcl.setting.Controllers;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridge;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridgeCallback;
|
||||
import com.tungsten.fclcore.util.Logging;
|
||||
import com.tungsten.fclcore.util.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class GameMenu implements MenuCallback {
|
||||
|
||||
private JVMActivity activity;
|
||||
private FCLBridge fclBridge;
|
||||
|
||||
@Override
|
||||
public View getLayout() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(JVMActivity activity, FCLBridge fclBridge) {
|
||||
this.activity = activity;
|
||||
this.fclBridge = fclBridge;
|
||||
if (!Controllers.isInitialized()) {
|
||||
Controllers.init();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FCLBridgeCallback getCallbackBridge() {
|
||||
return new FCLProcessListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGraphicOutput() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCursorModeChange(int mode) {
|
||||
|
||||
}
|
||||
|
||||
private boolean firstLog = true;
|
||||
|
||||
@Override
|
||||
public void onLog(String log) {
|
||||
try {
|
||||
if (firstLog) {
|
||||
FileUtils.writeText(new File(fclBridge.getLogPath()), log + "\n");
|
||||
firstLog = false;
|
||||
} else {
|
||||
FileUtils.writeTextWithAppendMode(new File(fclBridge.getLogPath()), log + "\n");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Logging.LOG.log(Level.WARNING, "Can't log game log to target file", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExit(int exitCode) {
|
||||
if (exitCode != 0) {
|
||||
JVMCrashActivity.startCrashActivity(activity, exitCode);
|
||||
Logging.LOG.log(Level.INFO, "JVM crashed, start jvm crash activity to show errors now!");
|
||||
}
|
||||
}
|
||||
|
||||
static class FCLProcessListener implements FCLBridgeCallback {
|
||||
|
||||
private final GameMenu gameMenu;
|
||||
|
||||
public FCLProcessListener(GameMenu gameMenu) {
|
||||
this.gameMenu = gameMenu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCursorModeChange(int mode) {
|
||||
gameMenu.onCursorModeChange(mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLog(String log) {
|
||||
gameMenu.onLog(log);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExit(int code) {
|
||||
gameMenu.onExit(code);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package com.tungsten.fcl.control;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tungsten.fcl.activity.JVMActivity;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridgeCallback;
|
||||
|
||||
public class JavaGuiController implements ControllerCallback {
|
||||
|
||||
@Override
|
||||
public View getLayout() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(JVMActivity activity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public FCLBridgeCallback getCallbackBridge() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package com.tungsten.fcl.control;
|
||||
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
import com.tungsten.fcl.activity.JVMActivity;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridge;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridgeCallback;
|
||||
|
||||
public class JavaGuiMenu implements MenuCallback {
|
||||
|
||||
@Override
|
||||
public View getLayout() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(JVMActivity activity, FCLBridge fclBridge) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public FCLBridgeCallback getCallbackBridge() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGraphicOutput() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCursorModeChange(int mode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLog(String log) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExit(int exitCode) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.tungsten.fcl.control;
|
||||
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
import com.tungsten.fcl.activity.JVMActivity;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridge;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridgeCallback;
|
||||
|
||||
public interface MenuCallback {
|
||||
|
||||
View getLayout();
|
||||
|
||||
void setup(JVMActivity activity, FCLBridge fclBridge);
|
||||
|
||||
FCLBridgeCallback getCallbackBridge();
|
||||
|
||||
void onPause();
|
||||
|
||||
void onResume();
|
||||
|
||||
boolean onKeyDown(int keyCode, KeyEvent event);
|
||||
|
||||
boolean onKeyUp(int keyCode, KeyEvent event);
|
||||
|
||||
void onBackPressed();
|
||||
|
||||
void onGraphicOutput();
|
||||
|
||||
void onCursorModeChange(int mode);
|
||||
|
||||
void onLog(String log);
|
||||
|
||||
void onExit(int exitCode);
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@ package com.tungsten.fcl.control;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
public enum ControllerType implements Serializable {
|
||||
public enum MenuType implements Serializable {
|
||||
GAME,
|
||||
JAVA_GUI
|
||||
}
|
|
@ -12,13 +12,12 @@ import androidx.annotation.NonNull;
|
|||
|
||||
import com.tungsten.fcl.R;
|
||||
import com.tungsten.fcl.activity.JVMActivity;
|
||||
import com.tungsten.fcl.control.ControllerType;
|
||||
import com.tungsten.fcl.control.MenuType;
|
||||
import com.tungsten.fcl.setting.Profile;
|
||||
import com.tungsten.fcl.setting.VersionSetting;
|
||||
import com.tungsten.fcl.ui.TaskDialog;
|
||||
import com.tungsten.fcl.ui.account.AccountListItem;
|
||||
import com.tungsten.fcl.util.TaskCancellationAction;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridge;
|
||||
import com.tungsten.fclcore.auth.Account;
|
||||
import com.tungsten.fclcore.auth.AuthInfo;
|
||||
import com.tungsten.fclcore.auth.AuthenticationException;
|
||||
|
@ -133,7 +132,8 @@ public final class LauncherHelper {
|
|||
}).thenAcceptAsync(fclBridge -> Schedulers.androidUIThread().execute(() -> {
|
||||
Intent intent = new Intent(context, JVMActivity.class);
|
||||
fclBridge.setScaleFactor(repository.getVersionSetting(selectedVersion).getScaleFactor());
|
||||
JVMActivity.setFClBridge(fclBridge, ControllerType.GAME);
|
||||
fclBridge.setController(repository.getVersionSetting(selectedVersion).getController());
|
||||
JVMActivity.setFClBridge(fclBridge, MenuType.GAME);
|
||||
LOG.log(Level.INFO, "Start JVMActivity!");
|
||||
context.startActivity(intent);
|
||||
})).withStage("launch.state.waiting_launching"))
|
||||
|
|
|
@ -84,7 +84,7 @@ public class Controllers {
|
|||
controllers.addListener(onInvalidating(Controllers::checkControllers));
|
||||
}
|
||||
|
||||
static void init() {
|
||||
public static void init() {
|
||||
if (initialized)
|
||||
throw new IllegalStateException("Already initialized");
|
||||
|
||||
|
|
|
@ -3,12 +3,14 @@ package com.tungsten.fcl.ui.controller;
|
|||
import static com.tungsten.fcl.util.FXUtils.onInvalidating;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
|
||||
import androidx.appcompat.widget.LinearLayoutCompat;
|
||||
|
||||
import com.tungsten.fcl.R;
|
||||
import com.tungsten.fcl.activity.ControllerActivity;
|
||||
import com.tungsten.fcl.setting.Controller;
|
||||
import com.tungsten.fcl.setting.Controllers;
|
||||
import com.tungsten.fclcore.fakefx.beans.binding.Bindings;
|
||||
|
@ -158,7 +160,8 @@ public class ControllerUI extends FCLCommonUI implements View.OnClickListener {
|
|||
dialog.show();
|
||||
}
|
||||
if (view == editController) {
|
||||
|
||||
Intent intent = new Intent(getContext(), ControllerActivity.class);
|
||||
getActivity().startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,13 +8,17 @@ import androidx.annotation.Nullable;
|
|||
|
||||
import com.tungsten.fclauncher.FCLConfig;
|
||||
import com.tungsten.fclauncher.FCLauncher;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridge;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridgeCallback;
|
||||
import com.tungsten.fclauncher.utils.LogFileUtil;
|
||||
import com.tungsten.fclcore.util.Logging;
|
||||
import com.tungsten.fclcore.util.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class ProcessService extends Service {
|
||||
|
||||
|
@ -28,7 +32,6 @@ public class ProcessService extends Service {
|
|||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
LogFileUtil.getInstance().writeLog("ProcessService started!");
|
||||
String[] command = intent.getExtras().getStringArray("command");
|
||||
FCLConfig config = new FCLConfig(
|
||||
getApplicationContext(),
|
||||
|
@ -41,20 +44,36 @@ public class ProcessService extends Service {
|
|||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
|
||||
private boolean firstLog = true;
|
||||
|
||||
public void startProcess(FCLConfig config) {
|
||||
FCLBridge bridge = FCLauncher.launchAPIInstaller(config);
|
||||
FCLBridgeCallback callback = new FCLBridgeCallback() {
|
||||
@Override
|
||||
public void onCursorModeChange(int mode) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLog(String log) {
|
||||
try {
|
||||
if (firstLog) {
|
||||
FileUtils.writeText(new File(bridge.getLogPath()), log + "\n");
|
||||
firstLog = false;
|
||||
} else {
|
||||
FileUtils.writeTextWithAppendMode(new File(bridge.getLogPath()), log + "\n");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Logging.LOG.log(Level.WARNING, "Can't log game log to target file", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExit(int code) {
|
||||
sendCode(code);
|
||||
}
|
||||
};
|
||||
CompletableFuture<Integer> future = FCLauncher.launchAPIInstaller(config, callback);
|
||||
future.whenComplete((integer, throwable) -> sendCode(integer));
|
||||
bridge.execute(null, callback);
|
||||
}
|
||||
|
||||
private void sendCode(int code) {
|
||||
|
@ -65,7 +84,6 @@ public class ProcessService extends Service {
|
|||
DatagramPacket packet = new DatagramPacket(data, data.length);
|
||||
socket.send(packet);
|
||||
socket.close();
|
||||
LogFileUtil.getInstance().writeLog("Code = " + code + ", send the code now!");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -74,7 +92,6 @@ public class ProcessService extends Service {
|
|||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
LogFileUtil.getInstance().writeLog("Destroy the service now!");
|
||||
super.onDestroy();
|
||||
android.os.Process.killProcess(android.os.Process.myPid());
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.tungsten.fclcore.fakefx.property.adapter;
|
||||
|
||||
import com.tungsten.fclauncher.utils.LogFileUtil;
|
||||
|
||||
import java.lang.ref.PhantomReference;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
|
@ -46,7 +44,7 @@ public class Disposer implements Runnable {
|
|||
Runnable rec = (Runnable)records.remove(obj);
|
||||
rec.run();
|
||||
} catch (Exception e) {
|
||||
LogFileUtil.getInstance().writeLog("Exception while removing reference: " + e);
|
||||
System.out.println("Exception while removing reference: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,6 +106,19 @@ public final class FileUtils {
|
|||
return new String(Files.readAllBytes(file), charset);
|
||||
}
|
||||
|
||||
public static void writeTextWithAppendMode(File file, String text) throws IOException {
|
||||
writeBytesWithAppendMode(file.toPath(), text.getBytes(UTF_8));
|
||||
}
|
||||
|
||||
public static void writeTextWithAppendMode(Path file, String text) throws IOException {
|
||||
writeBytesWithAppendMode(file, text.getBytes(UTF_8));
|
||||
}
|
||||
|
||||
public static void writeBytesWithAppendMode(Path file, byte[] data) throws IOException {
|
||||
Files.createDirectories(file.getParent());
|
||||
Files.write(file, data, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write plain text to file. Characters are encoded into bytes using UTF-8.
|
||||
* <p>
|
||||
|
|
|
@ -12,7 +12,6 @@ import android.widget.Toast;
|
|||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.tungsten.fclauncher.utils.LogFileUtil;
|
||||
import com.tungsten.fcllibrary.R;
|
||||
import com.tungsten.fcllibrary.browser.adapter.FileBrowserAdapter;
|
||||
import com.tungsten.fcllibrary.browser.adapter.FileBrowserListener;
|
||||
|
@ -127,11 +126,9 @@ public class FileBrowserActivity extends FCLActivity implements View.OnClickList
|
|||
}
|
||||
adapter1.setSelectedFiles(selectedFiles);
|
||||
adapter1.notifyDataSetChanged();
|
||||
LogFileUtil.getInstance().writeLog(selectedFiles);
|
||||
}
|
||||
});
|
||||
listView.setAdapter(adapter);
|
||||
LogFileUtil.getInstance().writeLog(selectedFiles);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -8,9 +8,7 @@ import android.util.ArrayMap;
|
|||
|
||||
import com.jaredrummler.android.device.DeviceName;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridge;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridgeCallback;
|
||||
import com.tungsten.fclauncher.utils.Architecture;
|
||||
import com.tungsten.fclauncher.utils.LogFileUtil;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
|
@ -20,23 +18,21 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class FCLauncher {
|
||||
|
||||
// Todo : don't crash when launch 1.17+ with OpenGL 2.1
|
||||
// Todo : mouse scroll event
|
||||
// Todo : custom logger
|
||||
// Todo : mesa
|
||||
|
||||
private static void printTaskTitle(String task) {
|
||||
LogFileUtil.getInstance().writeLog("==================== " + task + " ====================");
|
||||
private static void printTaskTitle(FCLBridge bridge, String task) {
|
||||
bridge.getCallback().onLog("==================== " + task + " ====================");
|
||||
}
|
||||
|
||||
private static void logStartInfo(String task) {
|
||||
printTaskTitle("Start " + task);
|
||||
LogFileUtil.getInstance().writeLog("Device: " + DeviceName.getDeviceName());
|
||||
LogFileUtil.getInstance().writeLog("Architecture: " + Architecture.archAsString(Architecture.getDeviceArchitecture()));
|
||||
private static void logStartInfo(FCLBridge bridge, String task) {
|
||||
printTaskTitle(bridge, "Start " + task);
|
||||
bridge.getCallback().onLog("Device: " + DeviceName.getDeviceName());
|
||||
bridge.getCallback().onLog("Architecture: " + Architecture.archAsString(Architecture.getDeviceArchitecture()));
|
||||
}
|
||||
|
||||
private static Map<String, String> readJREReleaseProperties(String javaPath) throws IOException {
|
||||
|
@ -166,12 +162,12 @@ public class FCLauncher {
|
|||
if (render) {
|
||||
addRendererEnv(config, envMap);
|
||||
}
|
||||
printTaskTitle("Env Map");
|
||||
printTaskTitle(bridge, "Env Map");
|
||||
for (String key : envMap.keySet()) {
|
||||
LogFileUtil.getInstance().writeLog("Env: " + key + "=" + envMap.get(key));
|
||||
bridge.getCallback().onLog("Env: " + key + "=" + envMap.get(key));
|
||||
bridge.setenv(key, envMap.get(key));
|
||||
}
|
||||
printTaskTitle("Env Map");
|
||||
printTaskTitle(bridge, "Env Map");
|
||||
}
|
||||
|
||||
private static void setUpJavaRuntime(FCLConfig config, FCLBridge bridge) throws IOException {
|
||||
|
@ -228,27 +224,27 @@ public class FCLauncher {
|
|||
}
|
||||
|
||||
private static int launch(FCLConfig config, FCLBridge bridge, String task) throws IOException {
|
||||
printTaskTitle(task + " Arguments");
|
||||
printTaskTitle(bridge, task + " Arguments");
|
||||
String[] args = rebaseArgs(config);
|
||||
for (String arg : args) {
|
||||
LogFileUtil.getInstance().writeLog(task + " argument: " + arg);
|
||||
bridge.getCallback().onLog(task + " argument: " + arg);
|
||||
}
|
||||
bridge.setupJLI();
|
||||
bridge.setLdLibraryPath(getLibraryPath(config.getContext(), config.getJavaPath()));
|
||||
LogFileUtil.getInstance().writeLog("Hook exit " + (bridge.setupExitTrap(bridge) == 0 ? "success" : "failed"));
|
||||
bridge.getCallback().onLog("Hook exit " + (bridge.setupExitTrap(bridge) == 0 ? "success" : "failed"));
|
||||
int exitCode = bridge.jliLaunch(args);
|
||||
LogFileUtil.getInstance().writeLog("OpenJDK exited with code : " + exitCode);
|
||||
bridge.getCallback().onLog("OpenJDK exited with code : " + exitCode);
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
public static FCLBridge launchMinecraft(FCLConfig config) {
|
||||
|
||||
// initialize FCLBridge
|
||||
FCLBridge bridge = new FCLBridge(null);
|
||||
FCLBridge bridge = new FCLBridge();
|
||||
bridge.setLogPath(config.getLogDir() + "/latest_game.log");
|
||||
Thread gameThread = new Thread(() -> {
|
||||
try {
|
||||
logStartInfo("Minecraft");
|
||||
logStartInfo(bridge, "Minecraft");
|
||||
|
||||
// env
|
||||
setEnv(config, bridge, true);
|
||||
|
@ -260,11 +256,12 @@ public class FCLauncher {
|
|||
setupGraphicAndSoundEngine(config, bridge);
|
||||
|
||||
// set working directory
|
||||
LogFileUtil.getInstance().writeLog("Working directory: " + config.getWorkingDir());
|
||||
bridge.getCallback().onLog("Working directory: " + config.getWorkingDir());
|
||||
bridge.chdir(config.getWorkingDir());
|
||||
|
||||
// launch game
|
||||
launch(config, bridge, "Minecraft");
|
||||
int code = launch(config, bridge, "Minecraft");
|
||||
bridge.onExit(code);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -279,12 +276,12 @@ public class FCLauncher {
|
|||
public static FCLBridge launchJavaGUI(FCLConfig config) {
|
||||
|
||||
// initialize FCLBridge
|
||||
FCLBridge bridge = new FCLBridge(null);
|
||||
FCLBridge bridge = new FCLBridge();
|
||||
bridge.setLogPath(config.getLogDir() + "/latest_java_gui.log");
|
||||
Thread javaGUIThread = new Thread(() -> {
|
||||
try {
|
||||
|
||||
logStartInfo("Java GUI");
|
||||
logStartInfo(bridge, "Java GUI");
|
||||
|
||||
// env
|
||||
setEnv(config, bridge, true);
|
||||
|
@ -296,11 +293,12 @@ public class FCLauncher {
|
|||
setupGraphicAndSoundEngine(config, bridge);
|
||||
|
||||
// set working directory
|
||||
LogFileUtil.getInstance().writeLog("Working directory: " + config.getWorkingDir());
|
||||
bridge.getCallback().onLog("Working directory: " + config.getWorkingDir());
|
||||
bridge.chdir(config.getWorkingDir());
|
||||
|
||||
// launch java gui
|
||||
launch(config, bridge, "Java GUI");
|
||||
int code = launch(config, bridge, "Java GUI");
|
||||
bridge.onExit(code);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -311,17 +309,15 @@ public class FCLauncher {
|
|||
return bridge;
|
||||
}
|
||||
|
||||
public static CompletableFuture<Integer> launchAPIInstaller(FCLConfig config, FCLBridgeCallback callback) {
|
||||
public static FCLBridge launchAPIInstaller(FCLConfig config) {
|
||||
|
||||
// initialize FCLBridge
|
||||
FCLBridge bridge = new FCLBridge(callback);
|
||||
FCLBridge bridge = new FCLBridge();
|
||||
bridge.setLogPath(config.getLogDir() + "/latest_api_installer.log");
|
||||
CompletableFuture<Integer> future = new CompletableFuture<>();
|
||||
|
||||
Thread apiInstallerThread = new Thread(() -> {
|
||||
try {
|
||||
|
||||
logStartInfo("API Installer");
|
||||
logStartInfo(bridge, "API Installer");
|
||||
|
||||
// env
|
||||
setEnv(config, bridge, false);
|
||||
|
@ -330,18 +326,20 @@ public class FCLauncher {
|
|||
setUpJavaRuntime(config, bridge);
|
||||
|
||||
// set working directory
|
||||
LogFileUtil.getInstance().writeLog("Working directory: " + config.getWorkingDir());
|
||||
bridge.getCallback().onLog("Working directory: " + config.getWorkingDir());
|
||||
bridge.chdir(config.getWorkingDir());
|
||||
|
||||
// launch api installer
|
||||
future.complete(launch(config, bridge, "API Installer"));
|
||||
int code = launch(config, bridge, "API Installer");
|
||||
bridge.onExit(code);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
apiInstallerThread.start();
|
||||
return future;
|
||||
bridge.setThread(apiInstallerThread);
|
||||
|
||||
return bridge;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@ import android.content.ClipboardManager;
|
|||
import android.content.Context;
|
||||
import android.view.Surface;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.tungsten.fclauncher.FCLPath;
|
||||
import com.tungsten.fclauncher.utils.LogFileUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class FCLBridge implements Serializable {
|
||||
|
||||
|
@ -43,14 +43,14 @@ public class FCLBridge implements Serializable {
|
|||
|
||||
public static final int CloseRequest = 0;
|
||||
|
||||
public FCLBridgeCallback callback;
|
||||
private FCLBridgeCallback callback;
|
||||
|
||||
private double scaleFactor = 1f;
|
||||
private String controller = "Default";
|
||||
private String logPath;
|
||||
private Thread thread;
|
||||
private Thread fclLogThread;
|
||||
private boolean isLogPipeReady = false;
|
||||
private WeakReference<LogReceiver> logReceiver;
|
||||
|
||||
static {
|
||||
System.loadLibrary("xhook");
|
||||
|
@ -58,10 +58,7 @@ public class FCLBridge implements Serializable {
|
|||
System.loadLibrary("glfw");
|
||||
}
|
||||
|
||||
public static int cursorMode = CursorEnabled;
|
||||
|
||||
public FCLBridge(FCLBridgeCallback callback) {
|
||||
this.callback = callback;
|
||||
public FCLBridge() {
|
||||
}
|
||||
|
||||
public native void setFCLNativeWindow(Surface surface);
|
||||
|
@ -86,11 +83,13 @@ public class FCLBridge implements Serializable {
|
|||
return thread;
|
||||
}
|
||||
|
||||
public FCLBridgeCallback getCallback() {
|
||||
return callback;
|
||||
}
|
||||
|
||||
public void execute(Surface surface, FCLBridgeCallback callback) {
|
||||
this.callback = callback;
|
||||
|
||||
LogFileUtil logFileUtil = LogFileUtil.getInstance();
|
||||
logFileUtil.setLogFilePath(getLogPath());
|
||||
fclLogThread = new Thread(() -> redirectStdio(getLogPath()));
|
||||
fclLogThread.setName("FCLLogThread");
|
||||
fclLogThread.start();
|
||||
|
@ -139,7 +138,6 @@ public class FCLBridge implements Serializable {
|
|||
|
||||
// FCLBridge callbacks
|
||||
public void setCursorMode(int mode) {
|
||||
cursorMode = mode;
|
||||
if (callback != null) {
|
||||
callback.onCursorModeChange(mode);
|
||||
}
|
||||
|
@ -168,6 +166,15 @@ public class FCLBridge implements Serializable {
|
|||
return scaleFactor;
|
||||
}
|
||||
|
||||
public void setController(String controller) {
|
||||
this.controller = controller;
|
||||
}
|
||||
|
||||
public String getController() {
|
||||
return controller;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getLogPath() {
|
||||
return logPath;
|
||||
}
|
||||
|
@ -181,10 +188,8 @@ public class FCLBridge implements Serializable {
|
|||
}
|
||||
|
||||
public void receiveLog(String log) {
|
||||
if (logReceiver == null || logReceiver.get() == null) {
|
||||
logReceiver = new WeakReference<>(log1 -> LogFileUtil.getInstance().writeLog(log1));
|
||||
} else {
|
||||
logReceiver.get().pushLog(log);
|
||||
if (callback != null) {
|
||||
callback.onLog(log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.tungsten.fclauncher.bridge;
|
|||
public interface FCLBridgeCallback {
|
||||
|
||||
void onCursorModeChange(int mode);
|
||||
void onLog(String log);
|
||||
void onExit(int code);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
package com.tungsten.fclauncher.bridge;
|
||||
|
||||
public interface LogReceiver {
|
||||
void pushLog(String log);
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
package com.tungsten.fclauncher.utils;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.tungsten.fclauncher.FCLPath;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author mio
|
||||
*/
|
||||
public class LogFileUtil {
|
||||
|
||||
private static final LogFileUtil INSTANCE = new LogFileUtil();
|
||||
private String logFilePath;
|
||||
private boolean firstWrite = true;
|
||||
private boolean isWrite = true;
|
||||
|
||||
protected LogFileUtil() {
|
||||
|
||||
}
|
||||
|
||||
public static LogFileUtil getInstance(){
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public void setLogFilePath(String logFilePath){
|
||||
this.logFilePath = logFilePath;
|
||||
}
|
||||
|
||||
public void writeLog(String log) {
|
||||
Log.e("FCL", log);
|
||||
if (this.logFilePath == null) {
|
||||
this.logFilePath = FCLPath.SHARED_COMMON_DIR + "/latest.log";
|
||||
}
|
||||
log += "\n";
|
||||
if (!isWrite) {
|
||||
return;
|
||||
}
|
||||
File logFile = new File(this.logFilePath);
|
||||
if (!logFile.exists()) {
|
||||
try {
|
||||
if (!logFile.createNewFile()) {
|
||||
isWrite = false;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (firstWrite) {
|
||||
writeData(logFile.getAbsolutePath(), log);
|
||||
firstWrite = false;
|
||||
} else {
|
||||
addStringLineToFile(log, logFile);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeLog(ArrayList<String> arrayList) {
|
||||
for (String s:arrayList) {
|
||||
writeLog(s);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeData(String path, String fileData) {
|
||||
File file = new File(path);
|
||||
try (FileOutputStream out = new FileOutputStream(file, false)) {
|
||||
out.write(fileData.getBytes(StandardCharsets.UTF_8));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean addStringLineToFile(String content, File file) {
|
||||
try (FileWriter fw = new FileWriter(file, true)) {
|
||||
fw.write(content);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -41,35 +41,33 @@ jstring CStr2Jstring(JNIEnv *env, char *buffer) {
|
|||
return (jstring) (*env)->NewObject(env, strClass, ctorID, bytes, encoding);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_redirectStdio(JNIEnv* env, jclass clazz,
|
||||
jstring path){
|
||||
JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_redirectStdio(JNIEnv* env, jclass clazz, jstring path) {
|
||||
|
||||
int fclFd[2];
|
||||
if (pipe(fclFd) < 0){
|
||||
if (pipe(fclFd) < 0) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "FCL", "Failed to create log pipe!");
|
||||
}
|
||||
|
||||
if(dup2(fclFd[1], STDOUT_FILENO) != STDOUT_FILENO && dup2(fclFd[1], STDERR_FILENO) != STDERR_FILENO){
|
||||
if (dup2(fclFd[1], STDOUT_FILENO) != STDOUT_FILENO && dup2(fclFd[1], STDERR_FILENO) != STDERR_FILENO) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "FCL", "failed to redirect stdio !");
|
||||
}
|
||||
char buffer[1024];
|
||||
jclass birdge = (*env) -> FindClass(env, "com/tungsten/fclauncher/bridge/FCLBridge");
|
||||
jmethodID method_setLogPipeReady = (*env) ->GetMethodID(env, birdge,"setLogPipeReady", "()V");
|
||||
if(!method_setLogPipeReady){
|
||||
__android_log_print(ANDROID_LOG_ERROR, "FCL", "Failed to find setLogPipeReady method !");
|
||||
jclass bridge = (*env) -> FindClass(env, "com/tungsten/fclauncher/bridge/FCLBridge");
|
||||
jmethodID method_setLogPipeReady = (*env) -> GetMethodID(env, bridge,"setLogPipeReady", "()V");
|
||||
if (!method_setLogPipeReady) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "FCL", "Failed to find setLogPipeReady method!");
|
||||
}
|
||||
fcl.logFile=fdopen(fclFd[1],"a");
|
||||
fcl.logFile = fdopen(fclFd[1],"a");
|
||||
FCL_INTERNAL_LOG("Log pipe ready.");
|
||||
(*env)->CallVoidMethod(env,clazz,method_setLogPipeReady);
|
||||
jmethodID method_receiveLog = (*env) ->GetMethodID(env, birdge,"receiveLog",
|
||||
"(Ljava/lang/String;)V");
|
||||
if(!method_receiveLog){
|
||||
__android_log_print(ANDROID_LOG_ERROR, "FCL", "Failed to find receive method !");
|
||||
(*env) -> CallVoidMethod(env,clazz,method_setLogPipeReady);
|
||||
jmethodID method_receiveLog = (*env) -> GetMethodID(env, bridge, "receiveLog", "(Ljava/lang/String;)V");
|
||||
if (!method_receiveLog) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "FCL", "Failed to find receive method!");
|
||||
}
|
||||
while (1){
|
||||
while (1) {
|
||||
memset(buffer, '\0', sizeof(buffer));
|
||||
ssize_t _s = read(fclFd[0], buffer, sizeof(buffer) - 1);
|
||||
if (_s < 0){
|
||||
if (_s < 0) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "FCL", "Failed to read log !");
|
||||
close(fclFd[0]);
|
||||
close(fclFd[1]);
|
||||
|
@ -77,7 +75,7 @@ JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_redirectStd
|
|||
} else {
|
||||
buffer[_s] = '\0';
|
||||
}
|
||||
if(buffer[0] == '\0')
|
||||
if (buffer[0] == '\0')
|
||||
continue;
|
||||
else {
|
||||
(*env)->CallVoidMethod(env, clazz, method_receiveLog, CStr2Jstring(env, buffer));
|
||||
|
@ -114,7 +112,9 @@ JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_dlopen(JNIE
|
|||
void* handle;
|
||||
dlerror();
|
||||
handle = dlopen(lib_name, RTLD_GLOBAL | RTLD_LAZY);
|
||||
__android_log_print(dlerror() == NULL ? ANDROID_LOG_INFO : ANDROID_LOG_ERROR, "FCL", "loading %s (error = %s)", lib_name, dlerror());
|
||||
|
||||
char * error = dlerror();
|
||||
__android_log_print(error == NULL ? ANDROID_LOG_INFO : ANDROID_LOG_ERROR, "FCL", "loading %s (error = %s)", lib_name, error);
|
||||
|
||||
if (handle == NULL) {
|
||||
ret = -1;
|
||||
|
@ -130,7 +130,8 @@ JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_setLdLibrar
|
|||
void *updateLdLibPath = dlsym(libdl_handle, "android_update_LD_LIBRARY_PATH");
|
||||
if (updateLdLibPath == NULL) {
|
||||
updateLdLibPath = dlsym(libdl_handle, "__loader_android_update_LD_LIBRARY_PATH");
|
||||
__android_log_print(dlerror() == NULL ? ANDROID_LOG_INFO : ANDROID_LOG_ERROR, "FCL", "loading %s (error = %s)", "libdl.so", dlerror());
|
||||
char * error = dlerror();
|
||||
__android_log_print(error == NULL ? ANDROID_LOG_INFO : ANDROID_LOG_ERROR, "FCL", "loading %s (error = %s)", "libdl.so", error);
|
||||
}
|
||||
android_update_LD_LIBRARY_PATH = (android_update_LD_LIBRARY_PATH_t) updateLdLibPath;
|
||||
const char* ldLibPathUtf = (*env)->GetStringUTFChars(env, ldLibraryPath, 0);
|
||||
|
@ -155,6 +156,7 @@ JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_setupExitTr
|
|||
jclass exitTrap_exitClass = (*env)->NewGlobalRef(env,(*env)->FindClass(env, "com/tungsten/fclauncher/bridge/FCLBridge"));
|
||||
exitTrap_method = (*env)->GetMethodID(env, exitTrap_exitClass, "onExit", "(I)V");
|
||||
(*env)->DeleteGlobalRef(env, exitTrap_exitClass);
|
||||
// Enable xhook debug mode here
|
||||
// xhook_enable_debug(1);
|
||||
xhook_register(".*\\.so$", "exit", custom_exit, (void **) &old_exit);
|
||||
return xhook_refresh(1);
|
||||
|
|
Loading…
Reference in New Issue