diff --git a/android/KMAPro/build.sh b/android/KMAPro/build.sh index 8e25f67861..18982a7c10 100755 --- a/android/KMAPro/build.sh +++ b/android/KMAPro/build.sh @@ -91,11 +91,11 @@ fi # Download default keyboard and dictionary -if [ $DO_KEYBOARDS_DOWNLOAD = true ]; then +if [ "$DO_KEYBOARDS_DOWNLOAD" = true ]; then downloadKeyboardPackage "$KEYBOARD_PACKAGE_ID" "$KEYBOARDS_TARGET" fi -if [ $DO_MODELS_DOWNLOAD = true ]; then +if [ "$DO_MODELS_DOWNLOAD" = true ]; then downloadModelPackage "$MODEL_PACKAGE_ID" "$MODELS_TARGET" fi diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/packages/PackageProcessor.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/packages/PackageProcessor.java index 8b7b07a1d1..f7e1f1aebd 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/packages/PackageProcessor.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/packages/PackageProcessor.java @@ -479,6 +479,52 @@ public class PackageProcessor { return list; } + /** + * Parses kmp.json to get a specified keyboard with an associated language. If languageID not + * provided, return the keyboard with the first associated language. + * This differs from getKeyboardList because this method doesn't search through + * KeyboardController (installed keyboards) + * @param packageID String of the package ID + * @param keyboardID String of the keyboard ID + * @param languageID String of the language ID + * @return object + */ + public Keyboard getKeyboard(String packageID, String keyboardID, String languageID) { + File packagePath = new File(resourceRoot, KMManager.KMDefault_AssetPackages + File.separator + packageID); + Keyboard kbd = null; + JSONObject infoJSON = loadPackageInfo(packagePath); + String packageVersion = getPackageVersion(infoJSON); + + try { + JSONArray keyboards = infoJSON.getJSONArray("keyboards"); + + for (int i=0; i < keyboards.length(); i++) { + JSONObject keyboard = keyboards.getJSONObject(i); + if (keyboardID.equals(keyboard.getString("id"))) { + Map[] maps = processEntry(keyboard, packageID, packageVersion, languageID); + if (maps != null) { + // Only returning first keyboard map + kbd = new Keyboard( + maps[0].get(KMManager.KMKey_PackageID), + maps[0].get(KMManager.KMKey_KeyboardID), + maps[0].get(KMManager.KMKey_KeyboardName), + maps[0].get(KMManager.KMKey_LanguageID), + maps[0].get(KMManager.KMKey_LanguageName), + maps[0].get(KMManager.KMKey_KeyboardVersion), + maps[0].get(KMManager.KMKey_CustomHelpLink), // can be null + "", + false, + maps[0].get(KMManager.KMKey_Font), + maps[0].get(KMManager.KMKey_OskFont)); + } + } + } + } catch (Exception e) { + KMLog.LogException(TAG, "getKeyboard() ", e); + } + return kbd; + } + /** * The master KMP processing method; use after a .kmp download to fully install within the filesystem. * This will overwrite an existing package. diff --git a/oem/firstvoices/android/.gitignore b/oem/firstvoices/android/.gitignore index 8b8ddd2704..b49f700beb 100644 --- a/oem/firstvoices/android/.gitignore +++ b/oem/firstvoices/android/.gitignore @@ -22,6 +22,7 @@ app/src/main/assets/packages app/src/main/assets/keyboards.csv app/src/main/assets/fv_all.kmp +app/src/main/assets/nrc.str.sencoten.model.kmp # Legacy Eclipse IDE files .classpath diff --git a/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/FVShared.java b/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/FVShared.java index d757361e0d..ae716bd74c 100644 --- a/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/FVShared.java +++ b/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/FVShared.java @@ -8,6 +8,8 @@ import android.net.Uri; import android.util.Log; import com.tavultesoft.kmea.KMManager; import com.tavultesoft.kmea.data.Keyboard; +import com.tavultesoft.kmea.packages.PackageProcessor; +import com.tavultesoft.kmea.util.FileUtils; import java.io.BufferedReader; import java.io.File; @@ -37,7 +39,16 @@ final class FVShared { private static final String FVKeyboardHelpLink = "http://help.keyman.com/keyboard/"; - private static final String FVDefault_PackageID = "fv_all"; + public static final String FVDefault_PackageID = "fv_all"; + + // Default Dictionary Info + public static final String FVDefault_DictionaryPackageID = "nrc.str.sencoten"; + public static final String FVDefault_DictionaryModelID = "nrc.str.sencoten"; + public static final String FVDefault_DictionaryModelName = "SENĆOŦEN (Saanich Dialect) Lexical Model"; + public static final String FVDefault_DictionaryLanguageID = "str-latn"; + public static final String FVDefault_DictionaryLanguageName = "SENĆOŦEN"; + public static final String FVDefault_DictionaryVersion = "1.0.5"; + public static final String FVDefault_DictionaryKMP = FVDefault_DictionaryPackageID + FileUtils.MODELPACKAGE; /// Describes a keyboard used in FirstVoices Keyboards static class FVKeyboard { @@ -234,25 +245,21 @@ final class FVShared { KMManager.removeKeyboard(context, i); } + File resourceRoot = new File(context.getDir("data", Context.MODE_PRIVATE).toString() + File.separator); + PackageProcessor kmpProcessor = new PackageProcessor(resourceRoot); + // Recreate active keyboards list for(FVRegion region : regionList) { for(FVKeyboard keyboard : region.keyboards) { if(loadedKeyboards.contains(keyboard.id)) { - // Load the .keyboard_info file and find its first language code - Keyboard kbInfo = new Keyboard( - FVDefault_PackageID, //TODO: we want to share keyboard build scripts between ios and android; can we do this? + // Parse kmp.json for the keyboard info + Keyboard kbd = kmpProcessor.getKeyboard( + FVDefault_PackageID, keyboard.id, - keyboard.name, - "en", //TODO: use language code from kmp.json - keyboard.name, - "1.0", //TODO: use keyboard version from kmp.json - String.format("%s%s", FVKeyboardHelpLink, keyboard.id), - "", // kmp link - false, - "NotoSansCanadianAboriginal.ttf", - "NotoSansCanadianAboriginal.ttf"); - - KMManager.addKeyboard(context, kbInfo); + null); // get first associated language ID + if (kbd != null) { + KMManager.addKeyboard(context, kbd); + } } } } @@ -264,15 +271,8 @@ final class FVShared { KMManager.setKeyboard(context, 0); } else { - // Add a default keyboard in if none are available - HashMap kbInfo = new HashMap<>(); - kbInfo.put(KMManager.KMKey_PackageID, KMManager.KMDefault_PackageID); - kbInfo.put(KMManager.KMKey_KeyboardID, KMManager.KMDefault_KeyboardID); - kbInfo.put(KMManager.KMKey_LanguageID, KMManager.KMDefault_LanguageID); - kbInfo.put(KMManager.KMKey_KeyboardName, KMManager.KMDefault_KeyboardName); - kbInfo.put(KMManager.KMKey_LanguageName, KMManager.KMDefault_LanguageName); - //kbInfo.put(KMManager.KMKey_KeyboardVersion, KMManager.getLatestKeyboardFileVersion(context, KMManager.KMDefault_KeyboardID)); - kbInfo.put(KMManager.KMKey_Font, KMManager.KMDefault_KeyboardFont); + // Add a default keyboard if none are available + Keyboard kbInfo = KMManager.getDefaultKeyboard(context); KMManager.addKeyboard(context, kbInfo); } } diff --git a/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/MainActivity.java b/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/MainActivity.java index 5c32b21ebd..994356a38d 100644 --- a/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/MainActivity.java +++ b/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/MainActivity.java @@ -18,9 +18,10 @@ import io.sentry.core.Sentry; import com.tavultesoft.kmea.*; import com.tavultesoft.kmea.data.Keyboard; -public class MainActivity extends AppCompatActivity { - public static final String FVDefault_PackageID = "fv_all"; +import java.util.ArrayList; +import java.util.HashMap; +public class MainActivity extends AppCompatActivity { @SuppressWarnings("SetJavascriptEnabled") @Override protected void onCreate(Bundle savedInstanceState) { @@ -52,10 +53,10 @@ public class MainActivity extends AppCompatActivity { * as a system keyboard. */ String version = KMManager.getLatestKeyboardFileVersion( - context, FVDefault_PackageID, KMManager.KMDefault_KeyboardID); + context, FVShared.FVDefault_PackageID, KMManager.KMDefault_KeyboardID); KMManager.setDefaultKeyboard( new Keyboard( - FVDefault_PackageID, + FVShared.FVDefault_PackageID, KMManager.KMDefault_KeyboardID, KMManager.KMDefault_KeyboardName, KMManager.KMDefault_LanguageID, @@ -68,6 +69,19 @@ public class MainActivity extends AppCompatActivity { KMManager.KMDefault_KeyboardFont) ); + ArrayList> modelsList = KMManager.getLexicalModelsList(context); + if (modelsList == null || modelsList.size() == 0) { + // Add default dictionaries + HashMap lexicalModelInfo = new HashMap(); + lexicalModelInfo.put(KMManager.KMKey_PackageID, FVShared.FVDefault_DictionaryPackageID); + lexicalModelInfo.put(KMManager.KMKey_LanguageID, FVShared.FVDefault_DictionaryLanguageID); + lexicalModelInfo.put(KMManager.KMKey_LexicalModelID, FVShared.FVDefault_DictionaryModelID); + lexicalModelInfo.put(KMManager.KMKey_LexicalModelName, FVShared.FVDefault_DictionaryModelName); + lexicalModelInfo.put(KMManager.KMKey_LexicalModelVersion, FVShared.FVDefault_DictionaryVersion); + KMManager.addLexicalModel(context, lexicalModelInfo); + KMManager.registerAssociatedLexicalModel(FVShared.FVDefault_DictionaryLanguageID); + } + final String htmlPath = "file:///android_asset/setup/main.html"; WebView webView = findViewById(R.id.webView); webView.addJavascriptInterface(new JSHandler(context), "jsInterface"); diff --git a/oem/firstvoices/android/build.sh b/oem/firstvoices/android/build.sh index ee3a91e62d..211c38c04c 100755 --- a/oem/firstvoices/android/build.sh +++ b/oem/firstvoices/android/build.sh @@ -24,7 +24,7 @@ display_usage ( ) { echo " -no-update Don't copy or build the Keyman Engine library in (assumes already present)" echo " -lib-build Force rebuild of the Keyman Engine library" echo " -no-lib-build Only rebuild the Keyman Engine library if it doesn't exist in /android" - echo " -download-keyboards Download keyboards from downloads.keyman.com" + echo " -download-resources Download fv_all.kmp and nrc.str.sencoten.model.kmp from downloads.keyman.com" echo "" exit 1 } @@ -33,22 +33,26 @@ export TARGET=FirstVoices KEYBOARD_PACKAGE_ID="fv_all" KEYBOARDS_TARGET="$KEYMAN_ROOT/oem/firstvoices/android/app/src/main/assets/${KEYBOARD_PACKAGE_ID}.kmp" KEYBOARDS_CSV_TARGET="$KEYMAN_ROOT/oem/firstvoices/android/app/src/main/assets/keyboards.csv" +MODEL_PACKAGE_ID="nrc.str.sencoten" +MODELS_TARGET="$KEYMAN_ROOT/oem/firstvoices/android/app/src/main/assets/${MODEL_PACKAGE_ID}.model.kmp" # This build script assumes that the https://github.com/keymanapp/keyboards repo is in # the same parent folder as this repo, with the default name 'keyboards' -PARAM_DOWNLOAD_KEYBOARDS= PARAM_DEBUG= PARAM_NO_DAEMON= PARAM_NO_UPDATE= PARAM_LIB_BUILD= PARAM_NO_LIB_BUILD= +DO_KEYBOARDS_DOWNLOAD=false +DO_MODELS_DOWNLOAD=false while [[ $# -gt 0 ]] ; do key="$1" case $key in - -download-keyboards) - PARAM_DOWNLOAD_KEYBOARDS=-download-keyboards + -download-resources) + DO_KEYBOARDS_DOWNLOAD=true + DO_MODELS_DOWNLOAD=true ;; -h|-?) display_usage @@ -72,10 +76,15 @@ while [[ $# -gt 0 ]] ; do shift done -# Verify default keyboard package exists +# Verify default keyboard and dictionary packages exists if [[ ! -f "$KEYBOARDS_TARGET" || ! -f "$KEYBOARDS_CSV_TARGET" ]]; then echo "$KEYBOARDS_TARGET and $KEYBOARDS_CSV_TARGET required. Will download the latest version" - PARAM_DOWNLOAD_KEYBOARDS=-download-keyboards + DO_KEYBOARDS_DOWNLOAD=true +fi + +if [[ ! -f "$MODELS_TARGET" ]]; then + echo "$MODELS_TARGET doesn't exist. Will download the latest version" + DO_MODELS_DOWNLOAD=true fi if [ ! -z "$PARAM_LIB_BUILD" ] && [ ! -z "$PARAM_NO_LIB_BUILD" ]; then @@ -83,12 +92,17 @@ if [ ! -z "$PARAM_LIB_BUILD" ] && [ ! -z "$PARAM_NO_LIB_BUILD" ]; then exit 1 fi -if [ "$PARAM_DOWNLOAD_KEYBOARDS" == "-download-keyboards" ]; then +# Download default keyboard and dictionary packages +if [ "$DO_KEYBOARDS_DOWNLOAD" = true ]; then echo "Copying keyboards.csv" cp "$KEYMAN_ROOT/oem/firstvoices/keyboards.csv" "$KEYBOARDS_CSV_TARGET" downloadKeyboardPackage "$KEYBOARD_PACKAGE_ID" "$KEYBOARDS_TARGET" fi +if [ "$DO_MODELS_DOWNLOAD" = true ]; then + downloadModelPackage "$MODEL_PACKAGE_ID" "$MODELS_TARGET" +fi + # TODO: in the future build_common.sh should probably be shared with all oem products? ./build_common.sh $PARAM_DEBUG $PARAM_NO_DAEMON $PARAM_NO_UPDATE $PARAM_LIB_BUILD $PARAM_NO_LIB_BUILD