Merge pull request #3113 from keymanapp/modify/android/use-keyboards-list-json

modify(android): Refactor KeyboardPickerActivity
This commit is contained in:
Darcy Wong 2020-05-20 13:17:58 +07:00 committed by GitHub
commit 00cd0aa4e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 347 additions and 572 deletions

View file

@ -11,6 +11,7 @@ import com.tavultesoft.kmea.KMHardwareKeyboardInterpreter;
import com.tavultesoft.kmea.KeyboardEventHandler.OnKeyboardEventListener;
import com.tavultesoft.kmea.LanguageSettingsActivity;
import com.tavultesoft.kmea.R;
import com.tavultesoft.kmea.data.Keyboard;
import android.content.Context;
import android.content.SharedPreferences;
@ -28,8 +29,6 @@ import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import java.util.HashMap;
import io.sentry.android.core.SentryAndroid;
import io.sentry.core.Sentry;
@ -139,9 +138,9 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
} else {
// Check if predictions needs to be re-enabled per Settings preference
Context appContext = getApplicationContext();
HashMap<String, String> kbInfo = KMManager.getCurrentKeyboardInfo(appContext);
Keyboard kbInfo = KMManager.getCurrentKeyboardInfo(appContext);
if (kbInfo != null) {
String langId = kbInfo.get(KMManager.KMKey_LanguageID);
String langId = kbInfo.getLanguageID();
SharedPreferences prefs = appContext.getSharedPreferences(appContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE);
boolean mayPredict = prefs.getBoolean(LanguageSettingsActivity.getLanguagePredictionPreferenceKey(langId), true);
KMManager.setBannerOptions(mayPredict);

View file

@ -10,6 +10,7 @@ import java.util.List;
import com.tavultesoft.kmea.KMManager;
import com.tavultesoft.kmea.KMPBrowserActivity;
import com.tavultesoft.kmea.data.Keyboard;
import android.os.Bundle;
import android.provider.Settings;
@ -156,7 +157,7 @@ public class GetStartedActivity extends AppCompatActivity {
String checkbox_on = String.valueOf(android.R.drawable.checkbox_on_background);
String info = String.valueOf(R.drawable.ic_info_outline);
ArrayList<HashMap<String, String>> kbList = KMManager.getKeyboardsList(this);
List<Keyboard> kbList = KMManager.getKeyboardsList(this);
if (kbList != null && kbList.size() > 1) {
list.get(0).put(iconKey, checkbox_on);
} else {

View file

@ -25,6 +25,7 @@ import com.tavultesoft.kmea.KMTextView;
import com.tavultesoft.kmea.KeyboardEventHandler.OnKeyboardDownloadEventListener;
import com.tavultesoft.kmea.KeyboardEventHandler.OnKeyboardEventListener;
import com.tavultesoft.kmea.cloud.CloudApiTypes;
import com.tavultesoft.kmea.data.Keyboard;
import com.tavultesoft.kmea.packages.PackageProcessor;
import com.tavultesoft.kmea.util.FileUtils;
import com.tavultesoft.kmea.util.FileProviderUtils;
@ -195,19 +196,10 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
// Add default keyboard
boolean installDefaultKeyboard = prefs.getBoolean(defaultKeyboardInstalled, false);
if (!installDefaultKeyboard) {
HashMap<String, String> kbInfo = new HashMap<String, String>();
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_PackageID, KMManager.KMDefault_KeyboardID));
kbInfo.put(KMManager.KMKey_Font, KMManager.KMDefault_KeyboardFont);
File welcomeFile = new File(KMManager.getPackagesDir(), KMManager.KMDefault_PackageID + File.separator + FileUtils.WELCOME_HTM);
kbInfo.put(KMManager.KMKey_CustomHelpLink, welcomeFile.getPath());
KMManager.addKeyboard(this, kbInfo);
if (!KMManager.keyboardExists(context, KMManager.KMDefault_PackageID, KMManager.KMDefault_KeyboardID,
KMManager.KMDefault_LanguageID)) {
KMManager.addKeyboard(this, Keyboard.DEFAULT_KEYBOARD);
}
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(defaultKeyboardInstalled, true);
editor.commit();
@ -315,7 +307,6 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
}
if (!didFail) {
KMManager.updateOldKeyboardsList(this);
SharedPreferences prefs = getSharedPreferences(getString(R.string.kma_prefs_name), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(MainActivity.didCheckUserDataKey, true);
@ -837,7 +828,7 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
boolean showGetStarted = prefs.getBoolean(GetStartedActivity.showGetStartedKey, true);
if (showGetStarted) {
boolean shouldShowGetStarted = false;
ArrayList<HashMap<String, String>> kbList = KMManager.getKeyboardsList(this);
List<Keyboard> kbList = KMManager.getKeyboardsList(this);
if (kbList != null && kbList.size() < 2)
shouldShowGetStarted = true;
@ -1074,17 +1065,22 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
@Override
public void onPackageInstalled(List<Map<String, String>> keyboardsInstalled) {
for(int i=0; i < keyboardsInstalled.size(); i++) {
HashMap<String, String> keyboardInfo = new HashMap<>(keyboardsInstalled.get(i));
HashMap<String, String> hashMap = new HashMap<>(keyboardsInstalled.get(i));
Keyboard keyboardInfo = new Keyboard(
hashMap.get(KMManager.KMKey_PackageID),
hashMap.get(KMManager.KMKey_KeyboardID),
hashMap.get(KMManager.KMKey_KeyboardName),
hashMap.get(KMManager.KMKey_LanguageID),
hashMap.get(KMManager.KMKey_LanguageName),
hashMap.get(KMManager.KMKey_Version),
hashMap.get(KMManager.KMKey_HelpLink),
true,
hashMap.get(KMManager.KMKey_Font),
hashMap.get(KMManager.KMKey_OskFont));
if (i == 0) {
if (KMManager.addKeyboard(this, keyboardInfo)) {
String packageID = keyboardInfo.get(KMManager.KMKey_PackageID);
String keyboardID = keyboardInfo.get(KMManager.KMKey_KeyboardID);
String languageID = keyboardInfo.get(KMManager.KMKey_LanguageID);
String keyboardName = keyboardInfo.get(KMManager.KMKey_KeyboardName);
String languageName = keyboardInfo.get(KMManager.KMKey_LanguageName);
String kFont = keyboardInfo.get(KMManager.KMKey_Font);
String kOskFont = keyboardInfo.get(KMManager.KMKey_OskFont);
KMManager.setKeyboard(packageID, keyboardID, languageID, keyboardName, languageName, kFont, kOskFont);
KMManager.setKeyboard(keyboardInfo);
}
} else {
KMManager.addKeyboard(this, keyboardInfo);
@ -1095,7 +1091,7 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
@Override
public void onLexicalModelInstalled(List<Map<String, String>> lexicalModelsInstalled) {
String langId = (KMManager.getCurrentKeyboardInfo(this) != null) ?
KMManager.getCurrentKeyboardInfo(this).get(KMManager.KMKey_LanguageID) :
KMManager.getCurrentKeyboardInfo(this).getLanguageID() :
KMManager.KMDefault_LanguageID;
boolean matchingModel = false;

View file

@ -8,6 +8,7 @@ import android.os.Bundle;
import android.widget.Toast;
import com.tavultesoft.kmea.cloud.CloudApiTypes;
import com.tavultesoft.kmea.data.KeyboardController;
import java.util.ArrayList;
@ -110,7 +111,7 @@ public class ConfirmDialogFragment extends DialogFragment {
break;
case DIALOG_TYPE_DELETE_KEYBOARD :
// Confirmation to delete keyboard
int keyboardIndex = KeyboardPickerActivity.getKeyboardIndex(getActivity(), itemKey);
int keyboardIndex = KeyboardController.getInstance().getKeyboardIndex(itemKey);
KeyboardPickerActivity.deleteKeyboard(getActivity(), keyboardIndex);
dismissOnSelect = true;
break;

View file

@ -7,11 +7,14 @@ package com.tavultesoft.kmea;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.tavultesoft.kmea.data.Keyboard;
import com.tavultesoft.kmea.data.KeyboardController;
import com.tavultesoft.kmea.KMManager.KeyboardType;
import com.tavultesoft.kmea.KeyboardEventHandler.EventType;
import com.tavultesoft.kmea.KeyboardEventHandler.OnKeyboardEventListener;
@ -149,9 +152,14 @@ final class KMKeyboard extends WebView {
Toast.makeText(context, "Fatal Error with " + currentKeyboard +
". Loading default keyboard", Toast.LENGTH_LONG).show();
setKeyboard(KMManager.KMDefault_PackageID, KMManager.KMDefault_KeyboardID,
KMManager.KMDefault_LanguageID, KMManager.KMDefault_KeyboardName,
KMManager.KMDefault_LanguageName, KMManager.KMDefault_KeyboardFont, null);
Keyboard firstKeyboard = KeyboardController.getInstance().getKeyboardInfo(0);
if (firstKeyboard != null) {
// Revert to first keyboard in the list
setKeyboard(firstKeyboard);
} else {
// Fallback to sil_euro_latin (though 3rd party keyboards wont have it)
setKeyboard(Keyboard.DEFAULT_KEYBOARD);
}
}
return true;
@ -604,6 +612,22 @@ final class KMKeyboard extends WebView {
return retVal;
}
public boolean setKeyboard(Keyboard k) {
boolean retVal = false;
if (k != null) {
retVal = setKeyboard(
k.getPackageID(),
k.getKeyboardID(),
k.getLanguageID(),
k.getKeyboardName(),
k.getLanguageName(),
k.getFont(),
k.getOSKFont());
}
return retVal;
}
public void setChirality(boolean flag) {
this.isChiral = flag;
}
@ -1212,7 +1236,7 @@ final class KMKeyboard extends WebView {
if (KMManager.getGlobeKeyAction(keyboardType) == KMManager.GlobeKeyAction.GLOBE_KEY_ACTION_SWITCH_TO_NEXT_KEYBOARD) {
// Help bubble is disabled if next keyboard is not available for this action
ArrayList<HashMap<String, String>> keyboardsList = KMManager.getKeyboardsList(context);
List<Keyboard> keyboardsList = KMManager.getKeyboardsList(context);
if (keyboardsList == null) {
return;
}

View file

@ -21,6 +21,7 @@ import android.widget.TextView;
import com.tavultesoft.kmea.data.Dataset;
import com.tavultesoft.kmea.data.Keyboard;
import com.tavultesoft.kmea.data.KeyboardController;
import com.tavultesoft.kmea.data.adapters.AdapterFilter;
import com.tavultesoft.kmea.data.adapters.NestedAdapter;
import com.tavultesoft.kmea.util.FileUtils;
@ -43,32 +44,9 @@ final class KMKeyboardPickerAdapter extends NestedAdapter<Keyboard, Dataset.Keyb
// should instead refer to this adapter.)
super(context, KEYBOARD_LAYOUT_RESOURCE, adapter, new AdapterFilter<Keyboard, Dataset.Keyboards, Void>() {
// Yeah, so this is a MASSIVE hack. Right now, it's either this or refactor up to 60
// separate references to keyboardList within KeyboardPickerActivity. Yikes.
public List<Keyboard> selectFrom(Dataset.Keyboards adapter, Void dummy) {
List<HashMap<String, String>> kbdMapList = KeyboardPickerActivity.getKeyboardsList(context);
List<Keyboard> kbdList = new ArrayList<>(kbdMapList.size());
for(HashMap<String, String> kbdMap: kbdMapList) {
boolean isNewKeyboard = kbdMap.containsKey(KeyboardPickerActivity.KMKEY_INTERNAL_NEW_KEYBOARD) &&
kbdMap.get(KeyboardPickerActivity.KMKEY_INTERNAL_NEW_KEYBOARD).equals(KeyboardPickerActivity.KMKEY_INTERNAL_NEW_KEYBOARD);
Keyboard k = new Keyboard(
kbdMap.get(KMManager.KMKey_PackageID),
kbdMap.get(KMManager.KMKey_KeyboardID),
kbdMap.get(KMManager.KMKey_KeyboardName),
kbdMap.get(KMManager.KMKey_LanguageID),
kbdMap.get(KMManager.KMKey_LanguageName),
MapCompat.getOrDefault(kbdMap, KMManager.KMKey_Version, "1.0"),
MapCompat.getOrDefault(kbdMap, KMManager.KMKey_CustomHelpLink, ""),
isNewKeyboard,
MapCompat.getOrDefault(kbdMap, KMManager.KMKey_Font, null),
MapCompat.getOrDefault(kbdMap, KMManager.KMKey_OskFont, null)
);
kbdList.add(k);
}
return kbdList;
// Return the keyboards list
return adapter.asList();
}
}, null);
}
@ -91,7 +69,7 @@ final class KMKeyboardPickerAdapter extends NestedAdapter<Keyboard, Dataset.Keyb
holder = (ViewHolder) convertView.getTag();
}
if(kbd.isNewKeyboard())
if(kbd.getNewKeyboard())
holder.textLang.setText(String.format("[%s]", getContext().getText(R.string.keyboard_picker_new_keyboard_prefix))
+ " " + kbd.getLanguageName());
else

View file

@ -63,6 +63,7 @@ import com.tavultesoft.kmea.KeyboardEventHandler.OnKeyboardEventListener;
import com.tavultesoft.kmea.cloud.CloudDataJsonUtil;
import com.tavultesoft.kmea.cloud.CloudDownloadMgr;
import com.tavultesoft.kmea.data.Dataset;
import com.tavultesoft.kmea.data.Keyboard;
import com.tavultesoft.kmea.data.KeyboardController;
import com.tavultesoft.kmea.logic.ResourcesUpdateTool;
import com.tavultesoft.kmea.packages.JSONUtils;
@ -281,7 +282,6 @@ public final class KMManager {
copyAssets(appContext);
migrateOldKeyboardFiles(appContext);
updateOldKeyboardsList(appContext);
didCopyAssets = true;
}
@ -712,87 +712,6 @@ public final class KMManager {
}
}
public static void updateOldKeyboardsList(Context context) {
ArrayList<HashMap<String, String>> kbList = KeyboardPickerActivity.getKeyboardsList(context);
if (kbList != null && kbList.size() > 0) {
boolean shouldUpdateList = false;
boolean shouldClearCache = false;
HashMap<String, String> kbInfo = kbList.get(0);
String pkgID = kbInfo.get(KMKey_PackageID);
String kbID = kbInfo.get(KMKey_KeyboardID);
if ( kbID.equals("us") || kbID.equals("european2") ||
(pkgID.equals(KMDefault_UndefinedPackageID) && kbID.equals(KMDefault_KeyboardID)) ) {
HashMap<String, String> newKbInfo = new HashMap<String, String>();
newKbInfo.put(KMManager.KMKey_PackageID, KMManager.KMDefault_PackageID);
newKbInfo.put(KMManager.KMKey_KeyboardID, KMManager.KMDefault_KeyboardID);
newKbInfo.put(KMManager.KMKey_LanguageID, KMManager.KMDefault_LanguageID);
newKbInfo.put(KMManager.KMKey_KeyboardName, KMManager.KMDefault_KeyboardName);
newKbInfo.put(KMManager.KMKey_LanguageName, KMManager.KMDefault_LanguageName);
newKbInfo.put(KMManager.KMKey_KeyboardVersion,
getLatestKeyboardFileVersion(context, KMManager.KMDefault_PackageID,
KMManager.KMDefault_KeyboardID));
newKbInfo.put(KMManager.KMKey_Font, KMManager.KMDefault_KeyboardFont);
kbList.set(0, newKbInfo);
shouldUpdateList = true;
shouldClearCache = true;
}
int index2Remove = -1;
int kblCount = kbList.size();
for (int i = 0; i < kblCount; i++) {
kbInfo = kbList.get(i);
kbID = kbInfo.get(KMKey_KeyboardID);
pkgID = kbInfo.get(KMKey_PackageID);
if (pkgID == null || pkgID.isEmpty()) {
pkgID = KMDefault_UndefinedPackageID;
kbInfo.put(KMManager.KMKey_PackageID, pkgID);
shouldUpdateList = true;
}
String langID = kbInfo.get(KMKey_LanguageID);
String kbVersion = kbInfo.get(KMManager.KMKey_KeyboardVersion);
String latestKbVersion = getLatestKeyboardFileVersion(context, pkgID, kbID);
if ((latestKbVersion != null) && (kbVersion == null || !kbVersion.equals(latestKbVersion))) {
kbInfo.put(KMManager.KMKey_KeyboardVersion, latestKbVersion);
kbList.set(i, kbInfo);
shouldUpdateList = true;
}
if (kbID.equals(KMManager.KMDefault_KeyboardID) && langID.equals(KMManager.KMDefault_LanguageID)) {
int defKbIndex = KMManager.getKeyboardIndex(context, KMManager.KMDefault_KeyboardID, KMManager.KMDefault_LanguageID);
if (defKbIndex == 0 && i > 0)
index2Remove = i;
}
}
if (index2Remove > 0) {
kbList.remove(index2Remove);
SharedPreferences prefs = appContext.getSharedPreferences(appContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
int index = prefs.getInt(KMManager.KMKey_UserKeyboardIndex, 0);
if (index == index2Remove) {
index = 0;
} else if (index > index2Remove) {
index--;
}
editor.putInt(KMManager.KMKey_UserKeyboardIndex, index);
editor.commit();
shouldUpdateList = true;
}
if (shouldUpdateList) {
KeyboardPickerActivity.updateKeyboardsList(context, kbList);
}
if (shouldClearCache) {
File cache = CloudDataJsonUtil.getKeyboardCacheFile(appContext);
if (cache.exists()) {
cache.delete();
}
}
}
}
/**
* Sets mayPredictOverride true if the InputType field is a hidden password text field
* (either TYPE_TEXT_VARIATION_PASSWORD or TYPE_TEXT_VARIATION_WEB_PASSWORD
@ -835,7 +754,7 @@ public final class KMManager {
return font;
}
public static ArrayList<HashMap<String, String>> getKeyboardsList(Context context) {
public static List<Keyboard> getKeyboardsList(Context context) {
return KeyboardPickerActivity.getKeyboardsList(context);
}
@ -963,9 +882,10 @@ public final class KMManager {
return null;
}
public static boolean addKeyboard(Context context, HashMap<String, String> keyboardInfo) {
String packageID = keyboardInfo.get(KMManager.KMKey_PackageID);
String keyboardID = keyboardInfo.get(KMManager.KMKey_KeyboardID);
public static boolean addKeyboard(Context context, Keyboard keyboardInfo) {
String packageID = keyboardInfo.getPackageID();
String keyboardID = keyboardInfo.getKeyboardID();
keyboardInfo.setNewKeyboard(true);
// Log Sentry analytic event, ignoring default keyboard
if (Sentry.isEnabled() && !(packageID.equalsIgnoreCase(KMManager.KMDefault_PackageID) &&
@ -974,12 +894,12 @@ public final class KMManager {
breadcrumb.setMessage("KMManager.addKeyboard");
breadcrumb.setCategory("addKeyboard");
breadcrumb.setLevel(SentryLevel.INFO);
breadcrumb.setData("packageID", keyboardInfo.get(KMManager.KMKey_PackageID));
breadcrumb.setData("keyboardID", keyboardInfo.get(KMManager.KMKey_KeyboardID));
breadcrumb.setData("keyboardName", keyboardInfo.get(KMManager.KMKey_KeyboardName));
breadcrumb.setData("keyboardVersion", keyboardInfo.get(KMManager.KMKey_KeyboardVersion));
breadcrumb.setData("languageID", keyboardInfo.get(KMManager.KMKey_LanguageID));
breadcrumb.setData("languageName", keyboardInfo.get(KMManager.KMKey_LanguageName));
breadcrumb.setData("packageID", packageID);
breadcrumb.setData("keyboardID", keyboardID);
breadcrumb.setData("keyboardName", keyboardInfo.getKeyboardName());
breadcrumb.setData("keyboardVersion", keyboardInfo.getVersion());
breadcrumb.setData("languageID", keyboardInfo.getLanguageID());
breadcrumb.setData("languageName", keyboardInfo.getLanguageName());
Sentry.addBreadcrumb(breadcrumb);
@ -990,6 +910,25 @@ public final class KMManager {
return KeyboardPickerActivity.addKeyboard(context, keyboardInfo);
}
// Intend to deprecate in Keyman 15.0
public static boolean addKeyboard(Context context, HashMap<String, String> keyboardInfo) {
String packageID = keyboardInfo.get(KMManager.KMKey_PackageID);
String keyboardID = keyboardInfo.get(KMManager.KMKey_KeyboardID);
String keyboardName = keyboardInfo.get(KMManager.KMKey_KeyboardName);
String languageID = keyboardInfo.get(KMManager.KMKey_LanguageID);
String languageName = keyboardInfo.get(KMManager.KMKey_LanguageName);
String version = keyboardInfo.get(KMManager.KMKey_KeyboardVersion);
String helpLink = keyboardInfo.get(KMManager.KMKey_CustomHelpLink);
String font = keyboardInfo.get(KMManager.KMKey_Font);
String oskFont = keyboardInfo.get(KMManager.KMKey_OskFont);
boolean isNewKeyboard = true;
Keyboard k = new Keyboard(packageID, keyboardID, keyboardName,
languageID, languageName, version, helpLink,
isNewKeyboard, font, oskFont);
return addKeyboard(context, k);
}
public static boolean removeKeyboard(Context context, int position) {
return KeyboardPickerActivity.removeKeyboard(context, position);
}
@ -1007,6 +946,24 @@ public final class KMManager {
return (result1 || result2);
}
public static boolean setKeyboard(Keyboard keyboardInfo) {
boolean result1 = false;
boolean result2 = false;
if (InAppKeyboard != null && InAppKeyboardLoaded && keyboardInfo != null) {
result1 = InAppKeyboard.setKeyboard(keyboardInfo);
}
if (SystemKeyboard != null && SystemKeyboardLoaded && keyboardInfo != null)
result2 = SystemKeyboard.setKeyboard(keyboardInfo);
if (keyboardInfo != null) {
registerAssociatedLexicalModel(keyboardInfo.getLanguageID());
}
return (result1 || result2);
}
/**
* Prepare keyboard switch for inapp keyboard and systemkeyboard
* @param packageID the package id
@ -1064,42 +1021,28 @@ public final class KMManager {
}
public static boolean setKeyboard(Context context, int position) {
HashMap<String, String> keyboardInfo = getKeyboardInfo(context, position);
Keyboard keyboardInfo = getKeyboardInfo(context, position);
if (keyboardInfo == null)
return false;
String pkgId = keyboardInfo.get(KMManager.KMKey_PackageID);
String kbId = keyboardInfo.get(KMManager.KMKey_KeyboardID);
String langId = keyboardInfo.get(KMManager.KMKey_LanguageID);
String kbName = keyboardInfo.get(KMManager.KMKey_KeyboardName);
String langName = keyboardInfo.get(KMManager.KMKey_LanguageName);
String kFont = keyboardInfo.get(KMManager.KMKey_Font);
String kOskFont = keyboardInfo.get(KMManager.KMKey_OskFont);
return setKeyboard(pkgId, kbId, langId, kbName, langName, kFont, kOskFont);
return setKeyboard(keyboardInfo);
}
public static void switchToNextKeyboard(Context context) {
int index = KeyboardPickerActivity.getCurrentKeyboardIndex(context);
int index = KeyboardController.getInstance().getKeyboardIndex(KMKeyboard.currentKeyboard());
index++;
HashMap<String, String> kbInfo = KeyboardPickerActivity.getKeyboardInfo(context, index);
Keyboard kbInfo = KeyboardController.getInstance().getKeyboardInfo(index);
if (kbInfo == null) {
index = 0;
kbInfo = KeyboardPickerActivity.getKeyboardInfo(context, index);
kbInfo = KeyboardController.getInstance().getKeyboardInfo(index);
}
String pkgId = kbInfo.get(KMManager.KMKey_PackageID);
String kbId = kbInfo.get(KMManager.KMKey_KeyboardID);
String langId = kbInfo.get(KMManager.KMKey_LanguageID);
String kbName = kbInfo.get(KMManager.KMKey_KeyboardName);
String langName = kbInfo.get(KMManager.KMKey_LanguageName);
String kFont = kbInfo.get(KMManager.KMKey_Font);
String kOskFont = kbInfo.get(KMManager.KMKey_OskFont);
if (InAppKeyboard != null) {
InAppKeyboard.setKeyboard(pkgId, kbId, langId, kbName, langName, kFont, kOskFont);
InAppKeyboard.setKeyboard(kbInfo);
}
if (SystemKeyboard != null) {
SystemKeyboard.setKeyboard(pkgId, kbId, langId, kbName, langName, kFont, kOskFont);
SystemKeyboard.setKeyboard(kbInfo);
}
}
@ -1452,26 +1395,28 @@ public final class KMManager {
}
public static int getCurrentKeyboardIndex(Context context) {
return KeyboardPickerActivity.getCurrentKeyboardIndex(context);
String key = KMKeyboard.currentKeyboard();
return KeyboardController.getInstance().getKeyboardIndex(key);
}
public static HashMap<String, String> getCurrentKeyboardInfo(Context context) {
return KeyboardPickerActivity.getCurrentKeyboardInfo(context);
public static Keyboard getCurrentKeyboardInfo(Context context) {
int index = getCurrentKeyboardIndex(context);
return KeyboardController.getInstance().getKeyboardInfo(index);
}
public static int getKeyboardIndex(Context context, String keyboardID, String languageID) {
int index = -1;
int index = KeyboardController.INDEX_NOT_FOUND;
if (keyboardID != null & languageID != null) {
String kbKey = String.format("%s_%s", languageID, keyboardID);
index = KeyboardPickerActivity.getKeyboardIndex(context, kbKey);
index = KeyboardController.getInstance().getKeyboardIndex(kbKey);
}
return index;
}
public static HashMap<String, String> getKeyboardInfo(Context context, int index) {
return KeyboardPickerActivity.getKeyboardInfo(context, index);
public static Keyboard getKeyboardInfo(Context context, int index) {
return KeyboardController.getInstance().getKeyboardInfo(index);
}
public static HashMap<String, String> getLexicalModelInfo(Context context, int index) {
@ -1483,7 +1428,7 @@ public final class KMManager {
if (packageID != null && keyboardID != null && languageID != null) {
String kbKey = String.format("%s_%s", languageID, keyboardID);
result = KeyboardPickerActivity.containsKeyboard(context, kbKey);
result = KeyboardController.getInstance().keyboardExists(kbKey);
}
return result;
@ -1588,7 +1533,6 @@ public final class KMManager {
}
private void pageLoaded(WebView view, String url) {
String langId = KMManager.KMKey_LanguageID;
Log.d("KMEA", "pageLoaded: [inapp] " + url);
if (url.startsWith("file")) { //endsWith(KMFilename_KeyboardHtml)) {
InAppKeyboardLoaded = true;
@ -1599,22 +1543,17 @@ public final class KMManager {
if (index < 0) {
index = 0;
}
HashMap<String, String> keyboardInfo = KMManager.getKeyboardInfo(context, index);
Keyboard keyboardInfo = KMManager.getKeyboardInfo(context, index);
String langId;
if (keyboardInfo != null) {
String pkgId = keyboardInfo.get(KMManager.KMKey_PackageID);
String kbId = keyboardInfo.get(KMManager.KMKey_KeyboardID);
langId = keyboardInfo.get(KMManager.KMKey_LanguageID);
String kbName = keyboardInfo.get(KMManager.KMKey_KeyboardName);
String langName = keyboardInfo.get(KMManager.KMKey_LanguageName);
String kFont = keyboardInfo.get(KMManager.KMKey_Font);
String kOskFont = keyboardInfo.get(KMManager.KMKey_OskFont);
InAppKeyboard.setKeyboard(pkgId, kbId, langId, kbName, langName, kFont, kOskFont);
langId = keyboardInfo.getLanguageID();
InAppKeyboard.setKeyboard(keyboardInfo);
} else {
InAppKeyboard.setKeyboard(KMDefault_PackageID, KMDefault_KeyboardID,
KMDefault_LanguageID, KMDefault_KeyboardName, KMDefault_LanguageName, KMDefault_KeyboardFont, null);
langId = KMDefault_LanguageID;
InAppKeyboard.setKeyboard(Keyboard.DEFAULT_KEYBOARD);
}
registerAssociatedLexicalModel(langId);
registerAssociatedLexicalModel(langId);
}
Handler handler = new Handler();
@ -1816,7 +1755,6 @@ public final class KMManager {
}
private void pageLoaded(WebView view, String url) {
String langId = KMManager.KMKey_LanguageID;
Log.d("KMEA", "pageLoaded: [system] " + url);
if (url.startsWith("file:")) {
SystemKeyboardLoaded = true;
@ -1826,23 +1764,19 @@ public final class KMManager {
if (index < 0) {
index = 0;
}
HashMap<String, String> keyboardInfo = KMManager.getKeyboardInfo(context, index);
Keyboard keyboardInfo = KMManager.getKeyboardInfo(context, index);
String langId;
if (keyboardInfo != null) {
String pkgId = keyboardInfo.get(KMManager.KMKey_PackageID);
String kbId = keyboardInfo.get(KMManager.KMKey_KeyboardID);
langId = keyboardInfo.get(KMManager.KMKey_LanguageID);
String kbName = keyboardInfo.get(KMManager.KMKey_KeyboardName);
String langName = keyboardInfo.get(KMManager.KMKey_LanguageName);
String kFont = keyboardInfo.get(KMManager.KMKey_Font);
String kOskFont = keyboardInfo.get(KMManager.KMKey_OskFont);
SystemKeyboard.setKeyboard(pkgId, kbId, langId, kbName, langName, kFont, kOskFont);
langId = keyboardInfo.getLanguageID();
SystemKeyboard.setKeyboard(keyboardInfo);
} else {
SystemKeyboard.setKeyboard(KMDefault_UndefinedPackageID, KMDefault_KeyboardID,
KMDefault_LanguageID, KMDefault_KeyboardName, KMDefault_LanguageName, KMDefault_KeyboardFont, null);
langId = KMDefault_LanguageID;
SystemKeyboard.setKeyboard(Keyboard.DEFAULT_KEYBOARD);
}
registerAssociatedLexicalModel(langId);
}
registerAssociatedLexicalModel(langId);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {

View file

@ -18,6 +18,7 @@ import com.tavultesoft.kmea.cloud.CloudDataJsonUtil;
import com.tavultesoft.kmea.data.CloudRepository;
import com.tavultesoft.kmea.data.Dataset;
import com.tavultesoft.kmea.data.Keyboard;
import com.tavultesoft.kmea.data.KeyboardController;
import com.tavultesoft.kmea.data.LexicalModel;
import com.tavultesoft.kmea.util.MapCompat;
@ -26,6 +27,7 @@ import androidx.appcompat.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
//import android.inputmethodservice.Keyboard;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
@ -52,9 +54,7 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
public static final String KMKEY_INTERNAL_NEW_KEYBOARD = "_internal_new_keyboard_";
// TODO: Refactoring to remove keyboard selection into own keyboard manager class (MVC)
// Lists of installed keyboards and installed lexical models
private static ArrayList<HashMap<String, String>> keyboardsList = null;
// List of installed lexical models
private static ArrayList<HashMap<String, String>> lexicalModelsList = null;
private static Dataset storageDataset = null;
@ -62,7 +62,7 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
private static int selectedIndex = 0;
private static final String TAG = "KeyboardPickerActivity";
protected static int selectedIndex() {
public static int selectedIndex() {
return selectedIndex;
}
@ -105,29 +105,6 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
listView = (ListView) findViewById(R.id.listView);
//TODO: put into a logic class
keyboardsList = getKeyboardsList(context);
if (keyboardsList == null) {
keyboardsList = new ArrayList<HashMap<String, String>>();
HashMap<String, String> kbInfo = new HashMap<String, String>();
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_PackageID, KMManager.KMDefault_KeyboardID));
kbInfo.put(KMManager.KMKey_Font, KMManager.KMDefault_KeyboardFont);
keyboardsList.add(kbInfo);
// We'd prefer not to overwrite a file if it exists
File file = new File(context.getDir("userdata", Context.MODE_PRIVATE),
KMManager.KMFilename_KeyboardsList);
if (!file.exists()) {
saveList(context, KMManager.KMFilename_KeyboardsList);
}
}
lexicalModelsList = getLexicalModelsList(context);
if (lexicalModelsList == null) {
lexicalModelsList = new ArrayList<HashMap<String, String>>();
@ -157,6 +134,7 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
listView.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
// Prevent the default keyboard from being removed
if (position > 0 && canRemoveKeyboard) {
PopupMenu popup = new PopupMenu(context, view);
popup.getMenuInflater().inflate(R.menu.popup, popup.getMenu());
@ -178,7 +156,7 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
}
});
int curKbPos = getCurrentKeyboardIndex();
int curKbPos = KeyboardController.getInstance().getKeyboardIndex(KMKeyboard.currentKeyboard());
setSelection(curKbPos);
KMKeyboard.addOnKeyboardEventListener(new KeyboardEventHandler.OnKeyboardEventListener() {
@ -189,16 +167,23 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
@Override
public void onKeyboardChanged(String newKeyboard) {
int _index = getKeyboardIndex(context,newKeyboard);
int _index = KeyboardController.getInstance().getKeyboardIndex(newKeyboard);
if(_index>=0)
{
Map<String,String> _keyboard = keyboardsList.get(_index);
if(_keyboard==null)
Keyboard _keyboard = KeyboardController.getInstance().getKeyboardInfo(_index);
if(_keyboard==null) {
return;
if(_keyboard.get(KMKEY_INTERNAL_NEW_KEYBOARD)==null)
}
if(!_keyboard.getNewKeyboard()) {
return;
_keyboard.remove(KMKEY_INTERNAL_NEW_KEYBOARD);
saveList(context, KMManager.KMFilename_KeyboardsList);
}
if (_keyboard.getNewKeyboard()) {
_keyboard.setNewKeyboard(false);
// Update entry
KeyboardController.getInstance().add(_keyboard);
KeyboardController.getInstance().save(context);
}
notifyKeyboardsUpdate(context);
}
}
@ -223,7 +208,7 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
adapter.notifyDataSetChanged();
}
int curKbPos = getCurrentKeyboardIndex();
int curKbPos = KeyboardController.getInstance().getKeyboardIndex(KMKeyboard.currentKeyboard());
setSelection(curKbPos);
if (!shouldCheckKeyboardUpdates)
return;
@ -252,41 +237,9 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
finish();
}
private static int getCurrentKeyboardIndex() {
int pos = 0;
if (keyboardsList != null) {
int length = keyboardsList.size();
for (int i = 0; i < length; i++) {
HashMap<String, String> kbInfo = keyboardsList.get(i);
String langId = kbInfo.get(KMManager.KMKey_LanguageID);
String kbId = kbInfo.get(KMManager.KMKey_KeyboardID);
String kbKey = String.format("%s_%s", langId, kbId);
if (kbKey.equals(KMKeyboard.currentKeyboard())) {
pos = i;
break;
}
}
}
return pos;
}
// Previously, keyboard from package = custom keyboard
// Now, keyboard from package has a package ID != "cloud"
protected static boolean hasKeyboardFromPackage() {
for(HashMap<String, String> kbInfo: keyboardsList) {
String pkgID = MapCompat.getOrDefault(kbInfo, KMManager.KMKey_PackageID, KMManager.KMDefault_UndefinedPackageID);
if (!pkgID.equalsIgnoreCase(KMManager.KMDefault_UndefinedPackageID)) {
return true;
}
}
return false;
}
private static boolean saveList(Context context, String listName) {
boolean result;
List<Keyboard> keyboardsList = KeyboardController.getInstance().get();
try {
File file = new File(context.getDir("userdata", Context.MODE_PRIVATE), listName);
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
@ -306,20 +259,6 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
return result;
}
/**
* Save the list of installed keyboards
* @param context
* @param list
* @return boolean - Status if the keyboard list was successfully saved
*/
protected static boolean updateKeyboardsList(Context context, ArrayList<HashMap<String, String>> list) {
boolean result;
keyboardsList = list;
result = saveList(context, KMManager.KMFilename_KeyboardsList);
notifyKeyboardsUpdate(context);
return result;
}
/**
* Save the list of installed lexical models
* @param context
@ -347,65 +286,35 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
*/
private static void switchKeyboard(int position, boolean aPrepareOnly) {
setSelection(position);
int listPosition = (position >= keyboardsList.size()) ? keyboardsList.size()-1 : position;
HashMap<String, String> kbInfo = keyboardsList.get(listPosition);
String pkgId = kbInfo.get(KMManager.KMKey_PackageID);
if (pkgId == null || pkgId.isEmpty()) {
pkgId = KMManager.KMDefault_UndefinedPackageID;
}
String kbId = kbInfo.get(KMManager.KMKey_KeyboardID);
String langId = kbInfo.get(KMManager.KMKey_LanguageID);
String kbName = kbInfo.get(KMManager.KMKey_KeyboardName);
String langName = kbInfo.get(KMManager.KMKey_LanguageName);
String kFont = kbInfo.get(KMManager.KMKey_Font);
String kOskFont = kbInfo.get(KMManager.KMKey_OskFont);
int size = KeyboardController.getInstance().get().size();
int listPosition = (position >= size) ? size-1 : position;
Keyboard kbInfo = KeyboardController.getInstance().getKeyboardInfo(listPosition);
String pkgId = kbInfo.getPackageID();
String kbId = kbInfo.getKeyboardID();
String langId = kbInfo.getLanguageID();
String kbName = kbInfo.getKeyboardName();
if(aPrepareOnly)
KMManager.prepareKeyboardSwitch(pkgId, kbId, langId, kbName);
else
KMManager.setKeyboard(pkgId, kbId, langId, kbName, langName, kFont, kOskFont);
KMManager.setKeyboard(kbInfo);
}
protected static boolean addKeyboard(Context context, HashMap<String, String> keyboardInfo) {
protected static boolean addKeyboard(Context context, Keyboard keyboardInfo) {
boolean result = false;
if (keyboardsList == null) {
keyboardsList = getKeyboardsList(context);
}
if (keyboardsList == null) {
keyboardsList = new ArrayList<HashMap<String, String>>();
}
List<Keyboard> keyboardsList = KeyboardController.getInstance().get();
if (keyboardInfo != null) {
String pkgID = keyboardInfo.get(KMManager.KMKey_PackageID);
String kbID = keyboardInfo.get(KMManager.KMKey_KeyboardID);
String langID = keyboardInfo.get(KMManager.KMKey_LanguageID);
// TODO: Possible optimization - do we have anything with this language code already?
// Only invalidate the lexical cache if not.
CloudRepository.shared.invalidateLexicalModelCache(context);
if (pkgID != null && kbID != null && langID != null) {
String kbKey = String.format("%s_%s", langID, kbID);
if (kbKey.length() >= 3) {
int x = getKeyboardIndex(context, kbKey);
if (x >= 0) {
if(keyboardsList.get(x).get(KMKEY_INTERNAL_NEW_KEYBOARD)!=null)
keyboardInfo.put(KMKEY_INTERNAL_NEW_KEYBOARD,KMKEY_INTERNAL_NEW_KEYBOARD);
keyboardsList.set(x, keyboardInfo);
result = saveList(context, KMManager.KMFilename_KeyboardsList);
} else {
keyboardInfo.put(KMKEY_INTERNAL_NEW_KEYBOARD,KMKEY_INTERNAL_NEW_KEYBOARD);
keyboardsList.add(keyboardInfo);
result = saveList(context, KMManager.KMFilename_KeyboardsList);
if (!result) {
keyboardsList.remove(keyboardsList.size() - 1);
}
}
}
keyboardInfo.setNewKeyboard(true);
KeyboardController.getInstance().add(keyboardInfo);
result = KeyboardController.getInstance().save(context);
if (!result) {
Log.e(TAG, "addKeyboard failed to save");
}
}
notifyKeyboardsUpdate(context);
return result;
@ -453,13 +362,11 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
protected static boolean removeKeyboard(Context context, int position) {
boolean result = false;
if (keyboardsList == null) {
keyboardsList = getKeyboardsList(context);
}
if (keyboardsList != null && position >= 0 && position < keyboardsList.size()) {
keyboardsList.remove(position);
result = saveList(context, KMManager.KMFilename_KeyboardsList);
// Prevent the first keyboard (index 0) from being removed
if (position > 0) {
KeyboardController.getInstance().remove(position);
result = KeyboardController.getInstance().save(context);
}
notifyKeyboardsUpdate(context);
@ -468,7 +375,7 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
}
protected static void deleteKeyboard(Context context, int position) {
int curKbPos = getCurrentKeyboardIndex();
int curKbPos = KeyboardController.getInstance().getKeyboardIndex(KMKeyboard.currentKeyboard());
boolean result = removeKeyboard(context, position);
if (result) {
@ -480,7 +387,7 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
if (position == curKbPos && listView != null) {
switchKeyboard(0,false);
} else if(listView != null) { // A bit of a hack, since LanguageSettingsActivity calls this method too.
curKbPos = getCurrentKeyboardIndex();
curKbPos = KeyboardController.getInstance().getKeyboardIndex(KMKeyboard.currentKeyboard());
setSelection(curKbPos);
}
}
@ -577,31 +484,7 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
return storageDataset;
}
List<HashMap<String, String>> kbdMapList = getKeyboardsList(context);
if (kbdMapList == null) {
kbdMapList = new ArrayList<>(0);
}
List<Keyboard> kbdsList = new ArrayList<>(kbdMapList.size());
for(HashMap<String, String> kbdMap: kbdMapList) {
boolean isNewKeyboard = kbdMap.containsKey(KeyboardPickerActivity.KMKEY_INTERNAL_NEW_KEYBOARD) &&
kbdMap.get(KeyboardPickerActivity.KMKEY_INTERNAL_NEW_KEYBOARD).equals(KeyboardPickerActivity.KMKEY_INTERNAL_NEW_KEYBOARD);
Keyboard k = new Keyboard(
kbdMap.get(KMManager.KMKey_PackageID),
kbdMap.get(KMManager.KMKey_KeyboardID),
kbdMap.get(KMManager.KMKey_KeyboardName),
kbdMap.get(KMManager.KMKey_LanguageID),
kbdMap.get(KMManager.KMKey_LanguageName),
MapCompat.getOrDefault(kbdMap, KMManager.KMKey_Version, "1.0"),
MapCompat.getOrDefault(kbdMap, KMManager.KMKey_CustomHelpLink, ""),
isNewKeyboard,
MapCompat.getOrDefault(kbdMap, KMManager.KMKey_Font, null),
MapCompat.getOrDefault(kbdMap, KMManager.KMKey_OskFont, null)
);
kbdsList.add(k);
}
List<Keyboard> kbdsList = getKeyboardsList(context);
List<HashMap<String, String>> lexMapList = getLexicalModelsList(context);
if(lexMapList == null) {
lexMapList = new ArrayList<>(0);
@ -636,26 +519,7 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
storage.keyboards.setNotifyOnChange(false);
storage.keyboards.clear();
List<HashMap<String, String>> mapList = getKeyboardsList(context);
List<Keyboard> kbdList = new ArrayList<>(mapList.size());
for(HashMap<String, String> kbdMap: mapList) {
boolean isNewKeyboard = kbdMap.containsKey(KeyboardPickerActivity.KMKEY_INTERNAL_NEW_KEYBOARD) &&
kbdMap.get(KeyboardPickerActivity.KMKEY_INTERNAL_NEW_KEYBOARD).equals(KeyboardPickerActivity.KMKEY_INTERNAL_NEW_KEYBOARD);
Keyboard k = new Keyboard(
kbdMap.get(KMManager.KMKey_PackageID),
kbdMap.get(KMManager.KMKey_KeyboardID),
kbdMap.get(KMManager.KMKey_KeyboardName),
kbdMap.get(KMManager.KMKey_LanguageID),
kbdMap.get(KMManager.KMKey_LanguageName),
MapCompat.getOrDefault(kbdMap, KMManager.KMKey_Version, "1.0"),
MapCompat.getOrDefault(kbdMap, KMManager.KMKey_CustomHelpLink, ""),
isNewKeyboard,
MapCompat.getOrDefault(kbdMap, KMManager.KMKey_Font, null),
MapCompat.getOrDefault(kbdMap, KMManager.KMKey_OskFont, null)
);
kbdList.add(k);
}
List<Keyboard> kbdList = KeyboardController.getInstance().get();
storage.keyboards.addAll(kbdList);
storage.keyboards.notifyDataSetChanged();
}
@ -684,33 +548,14 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
storage.lexicalModels.notifyDataSetChanged();
}
protected static ArrayList<HashMap<String, String>> getKeyboardsList(Context context) {
return getList(context, KMManager.KMFilename_KeyboardsList);
protected static List<Keyboard> getKeyboardsList(Context context) {
return KeyboardController.getInstance().get();
}
protected static ArrayList<HashMap<String, String>> getLexicalModelsList(Context context) {
return getList(context, KMManager.KMFilename_LexicalModelsList);
}
protected static boolean containsKeyboard(Context context, String keyboardKey) {
if (keyboardsList == null) {
keyboardsList = getKeyboardsList(context);
}
String kbKeys = "";
if (keyboardsList != null) {
int length = keyboardsList.size();
for (int i = 0; i < length; i++) {
kbKeys += String.format("%s_%s", keyboardsList.get(i).get(KMManager.KMKey_LanguageID), keyboardsList.get(i).get(KMManager.KMKey_KeyboardID));
if (i < length - 1) {
kbKeys += ",";
}
}
}
return kbKeys.contains(keyboardKey);
}
public static boolean containsLexicalModel(Context context, String lexicalModelKey) {
if (lexicalModelsList == null) {
lexicalModelsList = getLexicalModelsList(context);
@ -731,84 +576,6 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
return false;
}
protected static int getCurrentKeyboardIndex(Context context) {
int index = -1;
if (keyboardsList == null) {
keyboardsList = getKeyboardsList(context);
}
if (keyboardsList != null) {
int length = keyboardsList.size();
for (int i = 0; i < length; i++) {
HashMap<String, String> kbInfo = keyboardsList.get(i);
String langId = kbInfo.get(KMManager.KMKey_LanguageID);
String kbId = kbInfo.get(KMManager.KMKey_KeyboardID);
String kbKey = String.format("%s_%s", langId, kbId);
if (kbKey.equals(KMKeyboard.currentKeyboard())) {
index = i;
break;
}
}
}
return index;
}
protected static HashMap<String, String> getCurrentKeyboardInfo(Context context) {
int index = getCurrentKeyboardIndex(context);
if (index >= 0) {
return keyboardsList.get(index);
} else {
return null;
}
}
protected static int getKeyboardIndex(Context context, String keyboardKey) {
int index = -1;
if (keyboardsList == null) {
keyboardsList = getKeyboardsList(context);
}
if (keyboardsList != null) {
int length = keyboardsList.size();
for (int i = 0; i < length; i++) {
HashMap<String, String> kbInfo = keyboardsList.get(i);
String langId = kbInfo.get(KMManager.KMKey_LanguageID);
String kbId = kbInfo.get(KMManager.KMKey_KeyboardID);
String kbKey = String.format("%s_%s", langId, kbId);
if (kbKey.equals(keyboardKey)) {
index = i;
break;
}
}
}
return index;
}
/**
* Get the list of associated keyboards for a given language ID
* @param langId
* @return ArrayList of keyboard
*/
public static ArrayList<HashMap<String, String>> getAssociatedKeyboards(String langId) {
if (keyboardsList != null) {
ArrayList<HashMap<String, String>> associatedKeyboards = new ArrayList<HashMap<String, String>>();
for (HashMap<String, String> keyboardInfo: keyboardsList) {
if (keyboardInfo.get(KMManager.KMKey_LanguageID).equalsIgnoreCase(langId)) {
keyboardInfo.put(KMManager.KMKey_Icon, String.valueOf(R.drawable.ic_arrow_forward));
keyboardInfo.put("isEnabled", "true");
associatedKeyboards.add(keyboardInfo);
}
}
return associatedKeyboards;
}
return null;
}
/**
* Get the index of a lexical model key in the list of installed lexical models.
* @param context
@ -840,27 +607,6 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
return index;
}
protected static HashMap<String, String> getKeyboardInfo(Context context, int index) {
if (index < 0) {
return null;
}
if (keyboardsList == null) {
keyboardsList = getKeyboardsList(context);
}
if (keyboardsList != null && index < keyboardsList.size()) {
HashMap<String, String> kbInfo = keyboardsList.get(index);
String pkgID = kbInfo.get(KMManager.KMKey_PackageID);
if (pkgID == null || pkgID.isEmpty()) {
kbInfo.put(KMManager.KMKey_PackageID, KMManager.KMDefault_UndefinedPackageID);
}
return kbInfo;
}
return null;
}
protected static HashMap<String, String> getLexicalModelInfo(Context context,int index) {
if (index < 0) {
return null;
@ -884,16 +630,19 @@ public final class KeyboardPickerActivity extends AppCompatActivity {
}
public static void handleDownloadedKeyboard(Context context, HashMap<String, String> keyboardInfo) {
String keyboardID = keyboardInfo.get(KMManager.KMKey_KeyboardID);
String languageID = keyboardInfo.get(KMManager.KMKey_LanguageID);
String kbKey = String.format("%s_%s", languageID, keyboardID);
int index = getKeyboardIndex(context, kbKey);
if (index == -1) {
// Add the downloaded keyboard if not found
addKeyboard(context, keyboardInfo);
index = getKeyboardIndex(context, kbKey);
}
keyboardsList.set(index, keyboardInfo);
saveList(context, KMManager.KMFilename_KeyboardsList);
boolean isNewKeyboard = true;
Keyboard k = new Keyboard(
keyboardInfo.get(KMManager.KMKey_PackageID),
keyboardInfo.get(KMManager.KMKey_KeyboardID),
keyboardInfo.get(KMManager.KMKey_KeyboardName),
keyboardInfo.get(KMManager.KMKey_LanguageID),
keyboardInfo.get(KMManager.KMKey_LanguageName),
keyboardInfo.get(KMManager.KMKey_KeyboardVersion),
keyboardInfo.get(KMManager.KMKey_HelpLink),
isNewKeyboard,
keyboardInfo.get(KMManager.KMKey_Font),
keyboardInfo.get(KMManager.KMKey_OskFont));
KeyboardController.getInstance().add(k);
KeyboardController.getInstance().save(context);
}
}

View file

@ -123,9 +123,8 @@ public final class KeyboardSettingsActivity extends AppCompatActivity {
hashMap.put(iconKey, icon);
infoList.add(hashMap);
// Display uninstall keyboard
if (!packageID.equalsIgnoreCase(KMManager.KMDefault_PackageID) ||
!kbID.equalsIgnoreCase(KMManager.KMDefault_KeyboardID)) {
// If not default keyboard, display uninstall keyboard
if (!kbID.equalsIgnoreCase(KMManager.KMDefault_KeyboardID)) {
hashMap = new HashMap<>();
hashMap.put(titleKey, getString(R.string.uninstall_keyboard));
hashMap.put(subtitleKey, "");

View file

@ -90,7 +90,7 @@ public final class LanguageSettingsActivity extends AppCompatActivity {
}
// If the active keyboard is for this language, immediately enact the new pref setting.
String kbdLgCode = KMManager.getCurrentKeyboardInfo(context).get(KMManager.KMKey_LanguageID);
String kbdLgCode = KMManager.getCurrentKeyboardInfo(context).getLanguageID();
if (kbdLgCode.equals(lgCode)) {
// Not only registers the model but also applies our modeling preferences.
KMManager.registerAssociatedLexicalModel(lgCode);

View file

@ -177,7 +177,7 @@ public final class ModelPickerActivity extends AppCompatActivity {
if(immediateRegister) {
// Register associated lexical model if it matches the active keyboard's language code;
// it's safe since we're on the same thread. Needs to be called AFTER deinstalling the old one.
String kbdLgCode = KMManager.getCurrentKeyboardInfo(context).get(KMManager.KMKey_LanguageID);
String kbdLgCode = KMManager.getCurrentKeyboardInfo(context).getLanguageID();
if(kbdLgCode.equals(languageID)) {
KMManager.registerAssociatedLexicalModel(languageID);
}

View file

@ -86,7 +86,8 @@ public class Keyboard extends LanguageResource implements Serializable {
public String getKeyboardID() { return getResourceID(); }
public String getKeyboardName() { return getResourceName(); }
public boolean isNewKeyboard() { return isNewKeyboard; }
public boolean getNewKeyboard() { return isNewKeyboard; }
public void setNewKeyboard(boolean isNewKeyboard) { this.isNewKeyboard = isNewKeyboard; }
public String getFont() { return font; }

View file

@ -27,6 +27,7 @@ import java.util.List;
public class KeyboardController {
public static final String TAG = "KeyboardController";
public static final String KMFilename_Installed_KeyboardsList = "keyboards_list.json";
public static final int INDEX_NOT_FOUND = -1;
private static KeyboardController instance;
@ -105,13 +106,14 @@ public class KeyboardController {
list.add(Keyboard.DEFAULT_KEYBOARD);
}
} else {
// No installed keyboards lists so assume default
// TODO: What about 3rd-party apps w/o sil_euro_latin?
list.add(Keyboard.DEFAULT_KEYBOARD);
// No installed keyboards lists
// 3rd-party OEM may not have sil_euro_latin, so don't assign a default keyboard
//list.add(Keyboard.DEFAULT_KEYBOARD);
Log.w(TAG, "initialize with no default keyboard");
}
// We'd prefer not to overwrite a file if it exists
if (!keyboards_json.exists()) {
if (!keyboards_json.exists() && list != null && list.size() > 0) {
save(context);
}
@ -129,7 +131,9 @@ public class KeyboardController {
Log.e(TAG, "get while KeyboardController() not initialized");
return null;
}
return list;
synchronized (list) {
return list;
}
}
/**
@ -146,18 +150,58 @@ public class KeyboardController {
return null;
}
if (list != null && index < list.size()) {
Keyboard k = list.get(index);
return k;
synchronized (list) {
if (list != null && index < list.size()) {
Keyboard k = list.get(index);
return k;
}
}
Log.e(TAG, "getKeyboardInfo failed with index " + index);
return null;
}
/**
* Given a key, return the index of the matching keyboard.
* If no match, returns INDEX_NOT_FOUND
* @param key - String of the key to find
* @return int - Index of the matching keyboard
*/
public int getKeyboardIndex(String key) {
int index = INDEX_NOT_FOUND;
if (!isInitialized || list == null) {
Log.e(TAG, "getIndexOfKey while KeyboardController() not initialized");
return index;
}
if (key == null || key.isEmpty()) {
return index;
}
synchronized (list) {
for (int i=0; i<list.size(); i++) {
Keyboard k = list.get(i);
if (k.getKey().equalsIgnoreCase(key)) {
return i;
}
}
}
Log.e(TAG, "getKeyboardIndex failed for key " + key);
return index;
}
/**
* Given a key, return if the keyboard exists in the installed keyboards list
* @param key - String of the key to find
* @return boolean whether the matching keyboard exists
*/
public boolean keyboardExists(String key) {
return getKeyboardIndex(key) != INDEX_NOT_FOUND;
}
/**
* Add a new keyboard to the keyboard list. If the keyboard already exists, the keyboard
* information is updated
* information is updated.
* @param newKeyboard
*/
public void add(Keyboard newKeyboard) {
@ -166,30 +210,60 @@ public class KeyboardController {
return;
}
for (int i=0; i<list.size(); i++) {
// Update existing keyboard entry
if (newKeyboard.equals(list.get(i))) {
Log.d(TAG, "Updating keyboard with newKeyboard");
list.set(i, newKeyboard);
return;
synchronized (list) {
for (int i = 0; i < list.size(); i++) {
// Update existing keyboard entry
if (newKeyboard.equals(list.get(i))) {
Log.d(TAG, "Updating keyboard with newKeyboard");
list.set(i, newKeyboard);
return;
}
}
}
// Add new keyboard
list.add(newKeyboard);
// Add new keyboard
list.add(newKeyboard);
}
}
/**
* Remove the keyboard at the specified index.
* @param index
*/
public void remove(int index) {
// Check initialized, and disallow removing default keyboard
if (!isInitialized) {
return;
}
synchronized (list) {
if (index != INDEX_NOT_FOUND && index < list.size()) {
list.remove(index);
}
}
}
/**
* Convert the installed keyboard list to JSONArray and write to file
* @param context
* @return boolean - Status if the keyboard list was successfully saved
*/
public void save(Context context) {
public boolean save(Context context) {
boolean result = false;
if (list == null || list.size() < 1) {
return result;
}
JSONArray arr = new JSONArray();
for (Keyboard k : list) {
JSONObject o = k.toJSON();
arr.put(o);
}
FileUtils.saveList(context, KMFilename_Installed_KeyboardsList, arr);
if (arr.length() < 1) {
return result;
}
result = FileUtils.saveList(context, KMFilename_Installed_KeyboardsList, arr);
return result;
}
}

View file

@ -2,6 +2,7 @@ package com.tavultesoft.kmea.data.adapters;
import android.content.Context;
import android.database.DataSetObserver;
import android.util.Log;
import android.widget.ArrayAdapter;
import androidx.annotation.NonNull;
@ -20,6 +21,7 @@ import java.util.List;
* @param <A> The type specification of the Adapter to be nested/linked.
*/
public class NestedAdapter<Element, A extends ArrayAdapter<Element> & ListBacked<Element>, FilterArg> extends ArrayAdapter<Element> implements ListBacked<Element> {
private final static String TAG = "NestedAdapter";
final A wrappedAdapter;
final AdapterFilter<Element, A, FilterArg> filter;
final List<Element> filteredList;
@ -173,11 +175,19 @@ public class NestedAdapter<Element, A extends ArrayAdapter<Element> & ListBacked
// These methods allow bypassing of our externally-visible 'linking' versions for operations
// triggered by the other end of the link.
protected void _internalAddAll(@NonNull Collection<? extends Element> collection) {
super.addAll(collection);
try {
super.addAll(collection);
} catch (UnsupportedOperationException e) {
Log.e(TAG, "_internalAddAll exception " + e);
}
}
protected void _internalClear() {
super.clear();
try {
super.clear();
} catch (UnsupportedOperationException e) {
Log.e(TAG, "_internalClear exception " + e);
}
}
// TODO: As needed, override mutation functions so that we can reflect the changes onto

View file

@ -9,6 +9,7 @@ import android.util.Log;
import androidx.test.core.app.ApplicationProvider;
import com.tavultesoft.kmea.KMManager;
import com.tavultesoft.kmea.data.Keyboard;
import com.tavultesoft.kmea.packages.PackageProcessor;
import com.tavultesoft.kmea.util.FileUtils;
@ -48,12 +49,7 @@ class FunctionalTestHelper {
*/
static void setInitialKeyboard()
{
KMManager.setKeyboard(KMManager.KMDefault_PackageID,
KMManager.KMDefault_KeyboardID,
KMManager.KMDefault_LanguageID,
KMManager.KMDefault_KeyboardName,
KMManager.KMDefault_LanguageName,
KMManager.KMDefault_KeyboardFont, null);
KMManager.setKeyboard(Keyboard.DEFAULT_KEYBOARD);
}
/**

View file

@ -2,6 +2,7 @@ package com.tavultesoft.kmea.view;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
@ -11,6 +12,7 @@ import com.tavultesoft.kmea.KMManager;
import com.tavultesoft.kmea.KeyboardInfoActivity;
import com.tavultesoft.kmea.KeyboardPickerActivity;
import com.tavultesoft.kmea.R;
import com.tavultesoft.kmea.data.Keyboard;
import org.json.JSONException;
import org.junit.After;
@ -34,6 +36,7 @@ public class KeyboardPickerTest {
private static final File TEST_RESOURCE_ROOT = new File("test_resources");
private static final File TEST_DEFAULT_KMP_FILE = new File(TEST_RESOURCE_ROOT, "v14" + File.separator + "sil_euro_latin.kmp");
private static final String TEST_GFF_KMP_NAME = "gff_amh_7_test_json";
private static final File TEST_GFF_KMP_FILE = new File(TEST_RESOURCE_ROOT, "v14" + File.separator + TEST_GFF_KMP_NAME + ".kmp");
@ -50,6 +53,14 @@ public class KeyboardPickerTest {
//initializes the keyboard picker (and keyboard list in background)
keyboardPickerActivityActivityController = Robolectric.buildActivity(KeyboardPickerActivity.class).setup();
// install new custom keyboard programmatically
try {
FunctionalTestHelper.installCustomKeyboard(TEST_DEFAULT_KMP_FILE);
} catch (IOException | JSONException e) {
Log.e("KeyboardPickerTest", "Exception installing default kmp");
}
//Initial keyboard load (normally done by webview)
// should be done directly in FunctionalTestHelper.initializeKeyman();
// but we need to initialize the keyboardpicker first, because auf initialization process
@ -102,10 +113,6 @@ public class KeyboardPickerTest {
{
KeyboardPickerActivity activity = keyboardPickerActivityActivityController.get();
// get current keyboard
Map<String,String> _old = KMManager.getCurrentKeyboardInfo(ApplicationProvider.getApplicationContext());
Assert.assertNotNull(_old);
// install new custom keyboard programmatically
FunctionalTestHelper.installCustomKeyboard(TEST_GFF_KMP_FILE);
@ -122,10 +129,9 @@ public class KeyboardPickerTest {
Assert.assertTrue(activity.isFinishing());
// check if keyboardswitch is done
Map<String,String> _current = KMManager.getCurrentKeyboardInfo(ApplicationProvider.getApplicationContext());
int index = KeyboardPickerActivity.selectedIndex();
Keyboard _current = KMManager.getKeyboardInfo(ApplicationProvider.getApplicationContext(), index);
Assert.assertNotNull(_current);
Assert.assertNotEquals(_old.get(KMManager.KMKey_KeyboardID),_current.get(KMManager.KMKey_KeyboardID));
}
/**
@ -151,7 +157,8 @@ public class KeyboardPickerTest {
Assert.assertNotNull(_view);
// click the info button to open keyboard info activity
View _itemview = _view.getAdapter().getView(1, null, null);
int expectedKeyboardID = 0; // Index for expected keyboard
View _itemview = _view.getAdapter().getView(expectedKeyboardID, null, null);
Assert.assertNotNull(_itemview);
_itemview.findViewById(R.id.imageButton1).performClick();
@ -169,7 +176,7 @@ public class KeyboardPickerTest {
Assert.assertNotNull(_infolistview);
//find helplink and click
View _helplink = _view.getAdapter().getView(1, null, null);
View _helplink = _view.getAdapter().getView(expectedKeyboardID, null, null);
Assert.assertNotNull(_helplink);
_infolistview.performItemClick(_helplink,1,_infolistview.getAdapter().getItemId(1));

Binary file not shown.

View file

@ -7,6 +7,8 @@ import android.content.res.AssetManager;
import android.net.Uri;
import android.util.Log;
import com.tavultesoft.kmea.KMManager;
import com.tavultesoft.kmea.data.Keyboard;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
@ -19,6 +21,7 @@ import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
final class FVShared {
private static FVShared instance = null;
@ -224,7 +227,7 @@ final class FVShared {
private void updateActiveKeyboardsList() {
// Clear existing active keyboards list
ArrayList<HashMap<String, String>> activeKbList = KMManager.getKeyboardsList(context);
List<Keyboard> activeKbList = KMManager.getKeyboardsList(context);
if (activeKbList != null) {
int len = activeKbList.size();
for (int i = len-1; i >= 0; i--)
@ -236,15 +239,18 @@ final class FVShared {
for(FVKeyboard keyboard : region.keyboards) {
if(loadedKeyboards.contains(keyboard.id)) {
// Load the .keyboard_info file and find its first language code
HashMap<String, String> kbInfo = new HashMap<>();
kbInfo.put(KMManager.KMKey_PackageID, FVDefault_PackageID); //TODO: we want to share keyboard build scripts between ios and android; can we do this?
kbInfo.put(KMManager.KMKey_KeyboardID, keyboard.id);
kbInfo.put(KMManager.KMKey_LanguageID, "en"); //TODO: use language code from kmp.json
kbInfo.put(KMManager.KMKey_KeyboardName, keyboard.name);
kbInfo.put(KMManager.KMKey_LanguageName, keyboard.name);
kbInfo.put(KMManager.KMKey_KeyboardVersion, "1.0"); //TODO: use keyboard version from kmp.json
kbInfo.put(KMManager.KMKey_Font, "NotoSansCanadianAboriginal.ttf");
kbInfo.put(KMManager.KMKey_CustomHelpLink, String.format("%s%s", FVKeyboardHelpLink, keyboard.id));
Keyboard kbInfo = new Keyboard(
FVDefault_PackageID, //TODO: we want to share keyboard build scripts between ios and android; can we do this?
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),
false,
"NotoSansCanadianAboriginal.ttf",
"NotoSansCanadianAboriginal.ttf");
KMManager.addKeyboard(context, kbInfo);
}
}