Skip to content

Commit

Permalink
fix: rebind to the key event relay service when receiving a broadcast…
Browse files Browse the repository at this point in the history
… to do so
  • Loading branch information
sds100 committed Aug 4, 2024
1 parent df54fd6 commit dfac963
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package io.github.sds100.keymapper.inputmethod.latin

import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.ServiceConnection
import android.os.DeadObjectException
import android.os.IBinder
import android.os.RemoteException
import android.util.Log
import android.view.KeyEvent
import androidx.core.content.ContextCompat
import io.github.sds100.keymapper.api.IKeyEventRelayService
import io.github.sds100.keymapper.api.IKeyEventRelayServiceCallback

Expand All @@ -29,7 +32,10 @@ class KeyEventRelayServiceWrapperImpl(
) : KeyEventRelayServiceWrapper {

companion object {
const val ACTION_BIND_RELAY_SERVICE = "io.github.sds100.keymapper.ACTION_BIND_RELAY_SERVICE"
/**
* This is used to listen to when the key event relay service is restarted in Key Mapper.
*/
const val ACTION_REBIND_RELAY_SERVICE = "io.github.sds100.keymapper.ACTION_REBIND_RELAY_SERVICE"
}

private val ctx: Context = context.applicationContext
Expand All @@ -46,23 +52,44 @@ class KeyEventRelayServiceWrapperImpl(
) {
synchronized(keyEventRelayServiceLock) {
keyEventRelayService = IKeyEventRelayService.Stub.asInterface(service)
Log.d(LatinIME.TAG, "Register with key event relay service")
Log.d(LatinIME.TAG, "Key event relay service started: $servicePackageName")
keyEventRelayService?.registerCallback(callback)
}
}

override fun onServiceDisconnected(name: ComponentName?) {
synchronized(keyEventRelayServiceLock) {
try {
Log.d(LatinIME.TAG, "Unregister with key event relay service")
keyEventRelayService?.unregisterCallback()
} catch (_: RemoteException) {
} finally {
keyEventRelayService = null
}
// Do not unregister the callback in onServiceDisconnected
// because the connection is already broken at that point and it
// will fail.

Log.d(LatinIME.TAG, "Key event relay service stopped: $servicePackageName")

keyEventRelayService = null
}
}
}

private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
context ?: return
intent ?: return

when (intent.action) {
ACTION_REBIND_RELAY_SERVICE -> {
bind()
}
}
}
}

init {
val intentFilter = IntentFilter().apply {
addAction(ACTION_REBIND_RELAY_SERVICE)
}

ContextCompat.registerReceiver(ctx, broadcastReceiver, intentFilter, ContextCompat.RECEIVER_EXPORTED)
}

override fun sendKeyEvent(
event: KeyEvent?,
Expand Down Expand Up @@ -106,6 +133,15 @@ class KeyEventRelayServiceWrapperImpl(
// an exception is thrown if you unbind from a service
// while there is no registered connection.
if (isBound) {
// Unregister the callback if this input method is unbinding
// from the relay service. This should not happen in onServiceDisconnected
// because the connection is already broken at that point and it
// will fail.
try {
keyEventRelayService?.unregisterCallback()
} catch (e: RemoteException) {
// do nothing
}
ctx.unbindService(serviceConnection)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@

import javax.annotation.Nonnull;

import androidx.core.content.ContextCompat;
import io.github.sds100.keymapper.api.IKeyEventRelayServiceCallback;
import io.github.sds100.keymapper.inputmethod.accessibility.AccessibilityUtils;
import io.github.sds100.keymapper.inputmethod.annotations.UsedForTesting;
Expand Down Expand Up @@ -744,39 +745,39 @@ public void onCreate() {
// Register to receive ringer mode change.
final IntentFilter filter = new IntentFilter();
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
registerReceiver(mRingerModeChangeReceiver, filter);
ContextCompat.registerReceiver(this, mRingerModeChangeReceiver, filter, ContextCompat.RECEIVER_EXPORTED);

// Register to receive installation and removal of a dictionary pack.
final IntentFilter packageFilter = new IntentFilter();
packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
packageFilter.addDataScheme(SCHEME_PACKAGE);
registerReceiver(mDictionaryPackInstallReceiver, packageFilter);
ContextCompat.registerReceiver(this, mDictionaryPackInstallReceiver, packageFilter, ContextCompat.RECEIVER_EXPORTED);

final IntentFilter newDictFilter = new IntentFilter();
newDictFilter.addAction(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION);
registerReceiver(mDictionaryPackInstallReceiver, newDictFilter);
ContextCompat.registerReceiver(this, mDictionaryPackInstallReceiver, newDictFilter, ContextCompat.RECEIVER_NOT_EXPORTED);

final IntentFilter dictDumpFilter = new IntentFilter();
dictDumpFilter.addAction(DictionaryDumpBroadcastReceiver.DICTIONARY_DUMP_INTENT_ACTION);
registerReceiver(mDictionaryDumpBroadcastReceiver, dictDumpFilter);
ContextCompat.registerReceiver(this, mDictionaryDumpBroadcastReceiver, dictDumpFilter, ContextCompat.RECEIVER_NOT_EXPORTED);

final IntentFilter hideSoftInputFilter = new IntentFilter();
hideSoftInputFilter.addAction(ACTION_HIDE_SOFT_INPUT);
registerReceiver(mHideSoftInputReceiver, hideSoftInputFilter, PERMISSION_HIDE_SOFT_INPUT,
null /* scheduler */);
ContextCompat.registerReceiver(this, mHideSoftInputReceiver, hideSoftInputFilter, PERMISSION_HIDE_SOFT_INPUT,
null /* scheduler */, ContextCompat.RECEIVER_EXPORTED);

final IntentFilter restartAfterUnlockFilter = new IntentFilter();
restartAfterUnlockFilter.addAction(Intent.ACTION_USER_UNLOCKED);
registerReceiver(mRestartAfterDeviceUnlockReceiver, restartAfterUnlockFilter);
ContextCompat.registerReceiver(this, mRestartAfterDeviceUnlockReceiver, restartAfterUnlockFilter, ContextCompat.RECEIVER_EXPORTED);

final IntentFilter keyMapperIntentFilter = new IntentFilter();
keyMapperIntentFilter.addAction(KEY_MAPPER_INPUT_METHOD_ACTION_INPUT_DOWN_UP);
keyMapperIntentFilter.addAction(KEY_MAPPER_INPUT_METHOD_ACTION_INPUT_DOWN);
keyMapperIntentFilter.addAction(KEY_MAPPER_INPUT_METHOD_ACTION_INPUT_UP);
keyMapperIntentFilter.addAction(KEY_MAPPER_INPUT_METHOD_ACTION_TEXT);

registerReceiver(mKeyMapperBroadcastReceiver, keyMapperIntentFilter);
ContextCompat.registerReceiver(this, mKeyMapperBroadcastReceiver, keyMapperIntentFilter, ContextCompat.RECEIVER_EXPORTED);

// Connect to the different key mapper build types.
mKeyEventRelayServiceWrapperRelease =
Expand Down

0 comments on commit dfac963

Please sign in to comment.