diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/BootReceiver.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/BootReceiver.kt index 8f6767e58..71bbba754 100644 --- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/BootReceiver.kt +++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/BootReceiver.kt @@ -34,6 +34,7 @@ class BootReceiver : BroadcastReceiver() { val it = Intent(context, MainService::class.java).apply { action = ACT_INIT_MEDIA_PROJECTION_AND_SERVICE + putExtra(EXT_INIT_FROM_BOOT, true) } Toast.makeText(context, "RustDesk is Open", Toast.LENGTH_LONG).show() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt index 79fb60790..52a5ff75e 100644 --- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt +++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt @@ -15,7 +15,6 @@ import android.os.Build import android.os.IBinder import android.util.Log import android.view.WindowManager -import androidx.annotation.RequiresApi import com.hjq.permissions.XXPermissions import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine @@ -31,7 +30,6 @@ class MainActivity : FlutterActivity() { private val logTag = "mMainActivity" private var mainService: MainService? = null - @RequiresApi(Build.VERSION_CODES.M) override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) if (MainService.isReady) { @@ -208,6 +206,17 @@ class MainActivity : FlutterActivity() { result.success(false) } } + SYNC_APP_DIR_CONFIG_PATH -> { + if (call.arguments is String) { + val prefs = getSharedPreferences(KEY_SHARED_PREFERENCES, MODE_PRIVATE) + val edit = prefs.edit() + edit.putString(KEY_APP_DIR_CONFIG_PATH, call.arguments as String) + edit.apply() + result.success(true) + } else { + result.success(false) + } + } else -> { result.error("-1", "No such method", null) } diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt index 6b6169c61..fa7440c8d 100644 --- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt +++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt @@ -35,6 +35,7 @@ import androidx.annotation.RequiresApi import androidx.core.app.ActivityCompat import androidx.core.app.NotificationCompat import androidx.core.content.ContextCompat +import io.flutter.embedding.android.FlutterActivity import java.util.concurrent.Executors import kotlin.concurrent.thread import org.json.JSONException @@ -143,7 +144,11 @@ class MainService : Service() { // jvm call rust private external fun init(ctx: Context) - private external fun startServer() + + /// When app start on boot, app_dir will not be passed from flutter + /// so pass a app_dir here to rust server + private external fun startServer(app_dir: String) + private external fun startService() private external fun onVideoFrameUpdate(buf: ByteBuffer) private external fun onAudioFrameUpdate(buf: ByteBuffer) private external fun translateLocale(localeName: String, input: String): String @@ -199,7 +204,12 @@ class MainService : Service() { } updateScreenInfo(resources.configuration.orientation) initNotification() - startServer() + + // keep the config dir same with flutter + val prefs = applicationContext.getSharedPreferences(KEY_SHARED_PREFERENCES, FlutterActivity.MODE_PRIVATE) + val configPath = prefs.getString(KEY_APP_DIR_CONFIG_PATH, "") ?: "" + startServer(configPath) + createForegroundNotification() } @@ -279,6 +289,10 @@ class MainService : Service() { super.onStartCommand(intent, flags, startId) if (intent?.action == ACT_INIT_MEDIA_PROJECTION_AND_SERVICE) { createForegroundNotification() + + if (intent.getBooleanExtra(EXT_INIT_FROM_BOOT, false)) { + startService() + } Log.d(logTag, "service starting: ${startId}:${Thread.currentThread()}") val mediaProjectionManager = getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt index bd91d582c..f8ef07fd1 100644 --- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt +++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt @@ -27,6 +27,7 @@ import java.util.* const val ACT_REQUEST_MEDIA_PROJECTION = "REQUEST_MEDIA_PROJECTION" const val ACT_INIT_MEDIA_PROJECTION_AND_SERVICE = "INIT_MEDIA_PROJECTION_AND_SERVICE" const val ACT_LOGIN_REQ_NOTIFY = "LOGIN_REQ_NOTIFY" +const val EXT_INIT_FROM_BOOT = "EXT_INIT_FROM_BOOT" const val EXT_MEDIA_PROJECTION_RES_INTENT = "MEDIA_PROJECTION_RES_INTENT" const val EXT_LOGIN_REQ_NOTIFY = "LOGIN_REQ_NOTIFY" @@ -41,9 +42,11 @@ const val RES_FAILED = -100 const val START_ACTION = "start_action" const val GET_START_ON_BOOT_OPT = "get_start_on_boot_opt" const val SET_START_ON_BOOT_OPT = "set_start_on_boot_opt" +const val SYNC_APP_DIR_CONFIG_PATH = "sync_app_dir" const val KEY_SHARED_PREFERENCES = "KEY_SHARED_PREFERENCES" const val KEY_START_ON_BOOT_OPT = "KEY_START_ON_BOOT_OPT" +const val KEY_APP_DIR_CONFIG_PATH = "KEY_APP_DIR_CONFIG_PATH" @SuppressLint("ConstantLocale") val LOCAL_NAME = Locale.getDefault().toString() diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index b075ee76f..95e4d17e7 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -153,6 +153,7 @@ class AndroidChannel { static final kStartAction = "start_action"; static final kGetStartOnBootOpt = "get_start_on_boot_opt"; static final kSetStartOnBootOpt = "set_start_on_boot_opt"; + static final kSyncAppDirConfigPath = "sync_app_dir"; } /// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _keyLabels diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart index baf7193b3..6d3f863e7 100644 --- a/flutter/lib/main.dart +++ b/flutter/lib/main.dart @@ -153,6 +153,7 @@ void runMainApp(bool startService) async { void runMobileApp() async { await initEnv(kAppTypeMain); if (isAndroid) androidChannelInit(); + platformFFI.syncAndroidServiceAppDirConfigPath(); runApp(App()); } diff --git a/flutter/lib/models/native_model.dart b/flutter/lib/models/native_model.dart index 13f5b4587..28dc8085e 100644 --- a/flutter/lib/models/native_model.dart +++ b/flutter/lib/models/native_model.dart @@ -30,7 +30,7 @@ typedef F4Dart = int Function(Pointer); typedef F5 = Void Function(Pointer); typedef F5Dart = void Function(Pointer); typedef HandleEvent = Future Function(Map evt); -// pub fn session_register_texture(id: *const char, ptr: usize) +// pub fn session_register_texture(id: *const char, ptr: usize) typedef F6 = Void Function(Pointer, Uint64); typedef F6Dart = void Function(Pointer, int); @@ -56,7 +56,6 @@ class PlatformFFI { F4Dart? _session_get_rgba_size; F5Dart? _session_next_rgba; F6Dart? _session_register_texture; - static get localeName => Platform.localeName; @@ -162,7 +161,8 @@ class PlatformFFI { dylib.lookupFunction("session_get_rgba_size"); _session_next_rgba = dylib.lookupFunction("session_next_rgba"); - _session_register_texture = dylib.lookupFunction("session_register_texture"); + _session_register_texture = + dylib.lookupFunction("session_register_texture"); try { // SYSTEM user failed _dir = (await getApplicationDocumentsDirectory()).path; @@ -301,4 +301,8 @@ class PlatformFFI { if (!isAndroid) return Future(() => false); return await _toAndroidChannel.invokeMethod(method, arguments); } + + void syncAndroidServiceAppDirConfigPath() { + invokeMethod(AndroidChannel.kSyncAppDirConfigPath, _dir); + } } diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index e49ba65f7..e5b24fa53 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -1361,7 +1361,7 @@ pub fn send_url_scheme(_url: String) { #[cfg(target_os = "android")] pub mod server_side { - use hbb_common::log; + use hbb_common::{log, config}; use jni::{ objects::{JClass, JString}, sys::jstring, @@ -1374,11 +1374,25 @@ pub mod server_side { pub unsafe extern "system" fn Java_com_carriez_flutter_1hbb_MainService_startServer( env: JNIEnv, _class: JClass, + app_dir: JString, ) { - log::debug!("startServer from java"); + log::debug!("startServer from jvm"); + if let Ok(app_dir) = env.get_string(app_dir) { + *config::APP_DIR.write().unwrap() = app_dir.into(); + } std::thread::spawn(move || start_server(true)); } + #[no_mangle] + pub unsafe extern "system" fn Java_com_carriez_flutter_1hbb_MainService_startService( + env: JNIEnv, + _class: JClass, + ) { + log::debug!("startService from jvm"); + config::Config::set_option("stop-service".into(), "".into()); + crate::rendezvous_mediator::RendezvousMediator::restart(); + } + #[no_mangle] pub unsafe extern "system" fn Java_com_carriez_flutter_1hbb_MainService_translateLocale( env: JNIEnv,