0
0
mirror of https://github.com/florisboard/florisboard.git synced 2024-09-19 19:42:20 +02:00

Add template LatinLanguageProviderService

This commit is contained in:
Patrick Goldinger 2023-05-26 01:45:37 +02:00
parent d604d78109
commit 7e482ef9ee
No known key found for this signature in database
GPG Key ID: 533467C3DC7B9262
5 changed files with 159 additions and 4 deletions

View File

@ -20,8 +20,9 @@
<uses-permission android:name="android.permission.VIBRATE"/>
<!-- Android 11+ only: Define that FlorisBoard requests to see all apps that
ship with an IME or Spell Check service. This is used to guide the user
in the Settings Ui why FlorisBoard may not be working.
ship with an IME, Spell Check or FlorisBoard Plugin service. This is used
to guide the user in the Settings UI why FlorisBoard may not be working and
to provide plugin support.
-->
<queries>
<intent>
@ -30,6 +31,9 @@
<intent>
<action android:name="android.service.textservice.SpellCheckerService"/>
</intent>
<intent>
<action android:name="org.florisboard.plugin.FlorisPluginService"/>
</intent>
</queries>
<application
@ -72,6 +76,16 @@
<meta-data android:name="android.view.textservice.scs" android:resource="@xml/spellchecker"/>
</service>
<!-- Internal LatinLanguageProvider plugin service -->
<service
android:name=".ime.nlp.latin.LatinLanguageProviderService"
android:exported="false">
<intent-filter>
<action android:name="org.florisboard.plugin.FlorisPluginService"/>
</intent-filter>
<meta-data android:name="org.florisboard.plugin.flp" android:resource="@xml/latin_language_provider"/>
</service>
<!-- Main App Activity -->
<activity
android:name="dev.patrickgold.florisboard.app.FlorisAppActivity"

View File

@ -14,7 +14,7 @@ add_library(
florisboard-native
SHARED
FlorisApplication.cpp
LatinLanguageProvider.cpp
LatinLanguageProviderService.cpp
LatinNlpSession.cpp
)

View File

@ -21,7 +21,7 @@
#include <jni.h>
extern "C" JNIEXPORT void JNICALL
Java_dev_patrickgold_florisboard_ime_nlp_latin_LatinLanguageProvider_00024Companion_nativeInitEmptyDictionary( //
Java_dev_patrickgold_florisboard_ime_nlp_latin_LatinLanguageProviderService_00024Companion_nativeInitEmptyDictionary( //
JNIEnv* env,
jobject,
fl::jni::NativeStr j_dict_path

View File

@ -0,0 +1,122 @@
/*
* Copyright (C) 2023 Patrick Goldinger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.patrickgold.florisboard.ime.nlp.latin
import dev.patrickgold.florisboard.ime.core.ComputedSubtype
import dev.patrickgold.florisboard.ime.keyboard.KeyProximityChecker
import dev.patrickgold.florisboard.lib.io.subFile
import dev.patrickgold.florisboard.lib.io.writeJson
import dev.patrickgold.florisboard.lib.kotlin.guardedByLock
import dev.patrickgold.florisboard.native.NativeStr
import dev.patrickgold.florisboard.native.toNativeStr
import dev.patrickgold.florisboard.plugin.FlorisPluginService
import dev.patrickgold.florisboard.subtypeManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
private val DEFAULT_PREDICTION_WEIGHTS = LatinPredictionWeights(
lookup = LatinPredictionLookupWeights(
maxCostSum = 1.5,
costIsEqual = 0.0,
costIsEqualIgnoringCase = 0.25,
costInsert = 0.5,
costInsertStartOfStr = 1.0,
costDelete = 0.5,
costDeleteStartOfStr = 1.0,
costSubstitute = 0.5,
costSubstituteInProximity = 0.25,
costSubstituteStartOfStr = 1.0,
costTranspose = 0.0,
),
training = LatinPredictionTrainingWeights(
usageBonus = 128,
usageReductionOthers = 1,
),
)
private val DEFAULT_KEY_PROXIMITY_CHECKER = KeyProximityChecker(
enabled = false,
mapping = mapOf(),
)
private data class LatinNlpSessionWrapper(
var subtype: ComputedSubtype,
var session: LatinNlpSession,
)
class LatinLanguageProviderService : FlorisPluginService() {
companion object {
const val NlpSessionConfigFileName = "nlp_session_config.json"
const val UserDictionaryFileName = "user_dict.fldic"
external fun nativeInitEmptyDictionary(dictPath: NativeStr)
}
private val subtypeManager by subtypeManager()
private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
private val cachedSessionWrappers = guardedByLock {
mutableListOf<LatinNlpSessionWrapper>()
}
override fun create() {
// Do nothing
}
override fun preload(subtype: ComputedSubtype) {
if (subtype.isFallback()) return
scope.launch {
cachedSessionWrappers.withLock { sessionWrappers ->
var sessionWrapper = sessionWrappers.find { it.subtype.id == subtype.id }
if (sessionWrapper == null || sessionWrapper.subtype != subtype) {
if (sessionWrapper == null) {
sessionWrapper = LatinNlpSessionWrapper(
subtype = subtype,
session = LatinNlpSession(),
)
sessionWrappers.add(sessionWrapper)
} else {
sessionWrapper.subtype = subtype
}
val cacheDir = subtypeManager.cacheDirFor(subtype)
val filesDir = subtypeManager.filesDirFor(subtype)
val configFile = cacheDir.subFile(NlpSessionConfigFileName)
val userDictFile = filesDir.subFile(UserDictionaryFileName)
if (!userDictFile.exists()) {
nativeInitEmptyDictionary(userDictFile.absolutePath.toNativeStr())
}
val config = LatinNlpSessionConfig(
primaryLocale = subtype.primaryLocale,
secondaryLocales = subtype.secondaryLocales,
// TODO: dynamically find base dictionaries
baseDictionaryPaths = listOf(),
userDictionaryPath = userDictFile.absolutePath,
predictionWeights = DEFAULT_PREDICTION_WEIGHTS,
keyProximityChecker = DEFAULT_KEY_PROXIMITY_CHECKER,
)
configFile.writeJson(config)
sessionWrapper.session.loadFromConfigFile(configFile)
}
}
}
}
override fun destroy() {
//
}
}

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<plugin xmlns:fl="https://schemas.florisboard.org/plugin"
fl:id="org.florisboard.plugins.latin"
fl:version="0.4.0"
fl:title="@string/floris_app_name"
fl:description="@string/floris_app_name"
fl:maintainers="Patrick Goldinger &lt;patrick@patrickgold.dev&gt;"
fl:license="Apache-2.0"
fl:homepage="https://florisboard.org"
fl:issueTracker="https://github.com/florisboard/florisboard/issues"
fl:privacyPolicy="https://florisboard.org/legal/privacy">
<!-- Spelling config -->
<spelling/>
<!-- Suggestion config -->
<suggestion/>
</plugin>