diff --git a/app/src/main/java/org/fcitx/fcitx5/android/FcitxApplication.kt b/app/src/main/java/org/fcitx/fcitx5/android/FcitxApplication.kt index 31c35429..2e9085d6 100644 --- a/app/src/main/java/org/fcitx/fcitx5/android/FcitxApplication.kt +++ b/app/src/main/java/org/fcitx/fcitx5/android/FcitxApplication.kt @@ -14,6 +14,7 @@ import android.content.res.Configuration import android.os.Build import android.os.Process import android.util.Log +import androidx.core.content.ContextCompat import androidx.core.content.edit import androidx.preference.PreferenceManager import kotlinx.coroutines.CoroutineName @@ -59,6 +60,18 @@ class FcitxApplication : Application() { } } + private val restartFcitxInstanceReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action != ACTION_RESTART_FCITX_INSTANCE) return + if (FcitxDaemon.getFirstConnectionOrNull() != null) { + Timber.i("Received broadcast '${intent.action}', try to restart fcitx instance ...") + FcitxDaemon.restartFcitx() + } else { + Timber.i("Received broadcast '${intent.action}', but there's no fcitx instance") + } + } + } + var isDirectBootMode = false private set @@ -140,6 +153,14 @@ class FcitxApplication : Application() { AppPrefs.getInstance().syncToDeviceEncryptedStorage() ThemeManager.syncToDeviceEncryptedStorage() } + ContextCompat.registerReceiver( + this, + restartFcitxInstanceReceiver, + IntentFilter(ACTION_RESTART_FCITX_INSTANCE), + PERMISSION_TEST_INPUT_METHOD, + null, + ContextCompat.RECEIVER_EXPORTED + ) } override fun onConfigurationChanged(newConfig: Configuration) { @@ -156,5 +177,21 @@ class FcitxApplication : Application() { fun getLastPid() = lastPid private const val MAX_STACKTRACE_SIZE = 128000 + + const val ACTION_RESTART_FCITX_INSTANCE = + "${BuildConfig.APPLICATION_ID}.action.RESTART_FCITX_INSTANCE" + + /** + * This permission is requested by com.android.shell, makes it possible to restart + * fcitx instance from `adb shell am` command: + * ```sh + * adb shell am broadcast -a org.fcitx.fcitx5.android.action.RESTART_FCITX_INSTANCE + * ``` + * https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-7.0.0_r1/packages/Shell/AndroidManifest.xml#67 + * + * other candidate: android.permission.TEST_INPUT_METHOD requires Android 14 + * https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-14.0.0_r1/packages/Shell/AndroidManifest.xml#628 + */ + const val PERMISSION_TEST_INPUT_METHOD = "android.permission.READ_INPUT_STATE" } } \ No newline at end of file