From c56420bbc19166cf3dc0659b7e2de705270c751a Mon Sep 17 00:00:00 2001 From: kari-ts <135075563+kari-ts@users.noreply.github.com> Date: Thu, 21 Nov 2024 09:12:26 -0800 Subject: [PATCH] android: lazily init app in Client (#563) -Lazily init app in Client to ensure that we aren't trying to make any local API calls before app has been initialized. -Add @Volatile to ensure that isInitialized is always visible across threads and uses the updated value Updates tailscale/tailscale#14125 Signed-off-by: kari-ts --- android/src/main/java/com/tailscale/ipn/App.kt | 13 ++++++++++++- .../java/com/tailscale/ipn/ui/localapi/Client.kt | 6 ++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/tailscale/ipn/App.kt b/android/src/main/java/com/tailscale/ipn/App.kt index 3e6af12..6427e91 100644 --- a/android/src/main/java/com/tailscale/ipn/App.kt +++ b/android/src/main/java/com/tailscale/ipn/App.kt @@ -90,6 +90,13 @@ class App : UninitializedApp(), libtailscale.AppContext, ViewModelStoreOwner { Log.d(s, s1) } + fun getLibtailscaleApp(): libtailscale.Application { + if (!isInitialized) { + initOnce() // Calls the synchronized initialization logic + } + return app + } + override fun onCreate() { super.onCreate() appInstance = this @@ -119,15 +126,19 @@ class App : UninitializedApp(), libtailscale.AppContext, ViewModelStoreOwner { viewModelStore.clear() } - private var isInitialized = false + @Volatile private var isInitialized = false @Synchronized private fun initOnce() { if (isInitialized) { return } + + initializeApp() isInitialized = true + } + private fun initializeApp() { val dataDir = this.filesDir.absolutePath // Set this to enable direct mode for taildrop whereby downloads will be saved directly diff --git a/android/src/main/java/com/tailscale/ipn/ui/localapi/Client.kt b/android/src/main/java/com/tailscale/ipn/ui/localapi/Client.kt index 3ec004c..5b12338 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/localapi/Client.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/localapi/Client.kt @@ -13,6 +13,7 @@ import com.tailscale.ipn.ui.model.StableNodeID import com.tailscale.ipn.ui.model.Tailcfg import com.tailscale.ipn.ui.util.InputStreamAdapter import com.tailscale.ipn.util.TSLog +import com.tailscale.ipn.App import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -67,6 +68,11 @@ typealias PingResultHandler = (Result) -> Unit class Client(private val scope: CoroutineScope) { private val TAG = Client::class.simpleName + // Access libtailscale.Application lazily + private val app: libtailscale.Application by lazy { + App.get().getLibtailscaleApp() +} + fun start(options: Ipn.Options, responseHandler: (Result) -> Unit) { val body = Json.encodeToString(options).toByteArray() return post(Endpoint.START, body, responseHandler = responseHandler)