diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java index 1049fc750d..dea80cfc9e 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java +++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java @@ -854,20 +854,12 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi kbInfo.put(KMManager.KMKey_KeyboardVersion, kbVersion); kbInfo.put(KMManager.KMKey_Font, kFont); kbInfo.put(KMManager.KMKey_OskFont, kOskFont); - if (i == 0) { - if (KMManager.addKeyboard(this, kbInfo)) { - if (!KMKeyboardDownloaderActivity.USE_DOWNLOAD_MANAGER) - KMManager.setKeyboard(packageID, keyboardID, langId, keyboardName, langName, kFont, kOskFont); - } - } else { - KMManager.addKeyboard(this, kbInfo); - } + + KMManager.addKeyboard(this, kbInfo); + } } else { - if (KMManager.addKeyboard(this, keyboardInfo)) { - if (!KMKeyboardDownloaderActivity.USE_DOWNLOAD_MANAGER) - KMManager.setKeyboard(packageID, keyboardID, languageID, keyboardName, languageName, kFont, kOskFont); - } + KMManager.addKeyboard(this, keyboardInfo); } } else { // Error notifications handled in LanguageListActivity diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/ConfirmDialogFragment.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/ConfirmDialogFragment.java index e093a11314..1b0a8bfe1f 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/ConfirmDialogFragment.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/ConfirmDialogFragment.java @@ -1,6 +1,5 @@ package com.tavultesoft.kmea; -import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; @@ -8,14 +7,23 @@ import android.content.DialogInterface; import android.os.Bundle; import android.widget.Toast; +import com.tavultesoft.kmea.cloud.CloudApiTypes; + +import java.util.ArrayList; + + /** * Confirmation dialog for downloading or deleting a Keyman keyboard/model */ public class ConfirmDialogFragment extends DialogFragment { - public static final String ARG_DIALOG_TYPE = "ConfirmDialogFragment.dialogType"; - public static final String ARG_TITLE = "ConfirmDialogFragment.title"; - public static final String ARG_MESSAGE = "ConfirmDialogFragment.message"; - public static final String ARG_ITEM_KEY = "confirmDialogFragment.itemKey"; + private static final String ARG_DIALOG_TYPE = "ConfirmDialogFragment.dialogType"; + private static final String ARG_TITLE = "ConfirmDialogFragment.title"; + private static final String ARG_MESSAGE = "ConfirmDialogFragment.message"; + private static final String ARG_ITEM_KEY = "confirmDialogFragment.itemKey"; + private static final String ARG_DOWNLOAD_QUERIES_KEY = "confirmDialogFragment.downloadQueries"; + private static final String ARG_MODEL_ID_KEY = "confirmDialogFragment.modelId"; + private static final String ARG_LANG_ID_KEY = "confirmDialogFragment.langId"; + private static final String ARG_KB_ID_KEY = "confirmDialogFragment.kbId"; private boolean dismissOnSelect = false; public enum DialogType { @@ -25,17 +33,36 @@ public class ConfirmDialogFragment extends DialogFragment { DIALOG_TYPE_DELETE_MODEL } - public static ConfirmDialogFragment newInstance(DialogType dialogType, String title, String message) { + public static ConfirmDialogFragment newInstanceForKeyboard(DialogType dialogType, String title, String message, + String aLangId, String aKbId, + ArrayList aQueries) { ConfirmDialogFragment frag = new ConfirmDialogFragment(); Bundle args = new Bundle(); args.putSerializable(ARG_DIALOG_TYPE, dialogType); args.putString(ARG_TITLE, title); args.putString(ARG_MESSAGE, message); + args.putString(ARG_LANG_ID_KEY, aLangId); + args.putString(ARG_KB_ID_KEY, aKbId); + args.putSerializable(ARG_DOWNLOAD_QUERIES_KEY,aQueries); frag.setArguments(args); return frag; } - public static ConfirmDialogFragment newInstance(DialogType dialogType, String title, String message, String itemKey) { + public static ConfirmDialogFragment newInstanceForLexicalModel(DialogType dialogType, String title, String message, + String aModelId, + ArrayList aQueries) { + ConfirmDialogFragment frag = new ConfirmDialogFragment(); + Bundle args = new Bundle(); + args.putSerializable(ARG_DIALOG_TYPE, dialogType); + args.putString(ARG_TITLE, title); + args.putString(ARG_MESSAGE, message); + args.putString(ARG_MODEL_ID_KEY, aModelId); + args.putSerializable(ARG_DOWNLOAD_QUERIES_KEY,aQueries); + frag.setArguments(args); + return frag; + } + + public static ConfirmDialogFragment newInstanceForItemKeyBasedAction(DialogType dialogType, String title, String message, String itemKey) { ConfirmDialogFragment frag = new ConfirmDialogFragment(); Bundle args = new Bundle(); args.putSerializable(ARG_DIALOG_TYPE, dialogType); @@ -48,12 +75,17 @@ public class ConfirmDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - Dialog dialog = super.onCreateDialog(savedInstanceState); + super.onCreateDialog(savedInstanceState); final DialogType dialogType = (DialogType)getArguments().getSerializable(ARG_DIALOG_TYPE); final String title = getArguments().getString(ARG_TITLE); final String message = getArguments().getString(ARG_MESSAGE); final String itemKey = getArguments().getString(ARG_ITEM_KEY); + final String _langId = getArguments().getString(ARG_LANG_ID_KEY); + final String _kbId = getArguments().getString(ARG_KB_ID_KEY); + final String _modelId = getArguments().getString(ARG_MODEL_ID_KEY); + final ArrayList _preparedCloudApiParams = + (ArrayList)getArguments().getSerializable(ARG_DOWNLOAD_QUERIES_KEY); String positiveLabel = (dialogType == DialogType.DIALOG_TYPE_DOWNLOAD_KEYBOARD || dialogType == DialogType.DIALOG_TYPE_DOWNLOAD_MODEL) ? getString(R.string.label_download) : getString(R.string.label_delete); @@ -66,9 +98,11 @@ public class ConfirmDialogFragment extends DialogFragment { public void onClick(DialogInterface dialog, int which) { switch (dialogType) { case DIALOG_TYPE_DOWNLOAD_KEYBOARD : + // Confirmation to download keyboard if (KMManager.hasConnection(getActivity())) { - KMKeyboardDownloaderActivity.download(getActivity(), true); + KMKeyboardDownloaderActivity.downloadKeyboard( + getActivity(), _langId, _kbId,_preparedCloudApiParams); } else { Toast.makeText(getActivity(), "No internet connection", Toast.LENGTH_SHORT).show(); } @@ -82,7 +116,8 @@ public class ConfirmDialogFragment extends DialogFragment { case DIALOG_TYPE_DOWNLOAD_MODEL : // Confirmation to download lexical model if (KMManager.hasConnection(getActivity())) { - KMKeyboardDownloaderActivity.download(getActivity(), true, true); + KMKeyboardDownloaderActivity.downloadLexicalModel(getActivity(), + _modelId, _preparedCloudApiParams); } else { Toast.makeText(getActivity(), "No internet connection", Toast.LENGTH_SHORT).show(); } diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMKeyboardDownloaderActivity.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMKeyboardDownloaderActivity.java index d4c2b036ab..c2d7a1e9f9 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMKeyboardDownloaderActivity.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMKeyboardDownloaderActivity.java @@ -1,46 +1,29 @@ package com.tavultesoft.kmea; -import android.os.Build; -import androidx.appcompat.app.AppCompatActivity; import android.app.DialogFragment; -import android.app.ProgressDialog; import android.content.Context; -import android.os.AsyncTask; import android.os.Bundle; -import android.util.Log; import android.widget.Toast; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; +import androidx.appcompat.app.AppCompatActivity; + +import com.tavultesoft.kmea.cloud.CloudApiTypes; +import com.tavultesoft.kmea.cloud.CloudDataJsonUtil; +import com.tavultesoft.kmea.cloud.CloudDownloadMgr; +import com.tavultesoft.kmea.cloud.impl.CloudKeyboardDataDownloadCallback; +import com.tavultesoft.kmea.cloud.impl.CloudKeyboardMetaDataDownloadCallback; +import com.tavultesoft.kmea.cloud.impl.CloudLexicalPackageDownloadCallback; -import java.io.File; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; - -import com.tavultesoft.kmea.data.CloudApiTypes; -import com.tavultesoft.kmea.data.CloudDataJsonUtil; -import com.tavultesoft.kmea.data.CloudDownloadMgr; -import com.tavultesoft.kmea.data.CloudKeyboardDataDownloadCallback; -import com.tavultesoft.kmea.data.CloudKeyboardMetaDataDownloadCallback; -import com.tavultesoft.kmea.data.CloudLexicalPackageDownloadCallback; -import com.tavultesoft.kmea.packages.LexicalModelPackageProcessor; -import com.tavultesoft.kmea.packages.PackageProcessor; -import com.tavultesoft.kmea.util.FileUtils; import static com.tavultesoft.kmea.ConfirmDialogFragment.DialogType.DIALOG_TYPE_DOWNLOAD_KEYBOARD; import static com.tavultesoft.kmea.ConfirmDialogFragment.DialogType.DIALOG_TYPE_DOWNLOAD_MODEL; -import static com.tavultesoft.kmea.KMManager.KMDefault_UndefinedPackageID; public class KMKeyboardDownloaderActivity extends AppCompatActivity { // Bundle Keys // Cloud - //TODO: Should be removed with the old implementation when downloadmanager impl works - public static boolean USE_DOWNLOAD_MANAGER = true; - public static final String ARG_PKG_ID = "KMKeyboardActivity.pkgID"; public static final String ARG_KB_ID = "KMKeyboardActivity.kbID"; public static final String ARG_LANG_ID = "KMKeyboardActivity.langID"; @@ -77,23 +60,24 @@ public class KMKeyboardDownloaderActivity extends AppCompatActivity { public static final String KMKey_KeyboardBaseURI = "keyboardBaseUri"; public static final String KMKey_FontBaseURI = "fontBaseUri"; - //TODO: use keyboard model class, should not be static - private static String pkgID; - private static String kbID; - private static String langID; - private static String modelID; - private static String modelName; - private static String kbName; - private static String langName; - private static Boolean isCustom; - private static Boolean downloadOnlyLexicalModel; + //TODO: use keyboard model class + private String pkgID; + private String kbID; + private String langID; + private String modelID; + private String modelName; + private String kbName; + private String langName; + private Boolean isCustom; + private Boolean downloadOnlyLexicalModel; - private static String customKeyboard; - private static String customLanguage; - private static Boolean isDirect; - private static String url; - private static String filename; + private String customKeyboard; + private String customLanguage; + private Boolean isDirect; + private String url; + private String filename; + //TODO: move to keyboard manager class private static ArrayList kbDownloadEventListeners = null; @Override @@ -136,7 +120,7 @@ public class KMKeyboardDownloaderActivity extends AppCompatActivity { } } - String title = ""; + String title; if (url != null) { title = String.format("%s: %s", getString(R.string.custom_keyboard), filename); } else if (customKeyboard != null && customLanguage != null && @@ -158,429 +142,47 @@ public class KMKeyboardDownloaderActivity extends AppCompatActivity { DialogFragment dialog; if (downloadOnlyLexicalModel) { title = String.format("%s: %s", langName, modelName); - dialog = ConfirmDialogFragment.newInstance( - DIALOG_TYPE_DOWNLOAD_MODEL, title, getString(R.string.confirm_download_model)); + dialog = ConfirmDialogFragment.newInstanceForLexicalModel( + DIALOG_TYPE_DOWNLOAD_MODEL, title, getString(R.string.confirm_download_model), + modelID, + prepareCloudApiParamsForLexicalModelDownload()); } else { - dialog = ConfirmDialogFragment.newInstance( - DIALOG_TYPE_DOWNLOAD_KEYBOARD, title, getString(R.string.confirm_download_keyboard)); + dialog = ConfirmDialogFragment.newInstanceForKeyboard( + DIALOG_TYPE_DOWNLOAD_KEYBOARD, title, getString(R.string.confirm_download_keyboard), + langID, kbID, + prepareCloudApiParamsForKeyboardDownload()); } dialog.show(getFragmentManager(), "dialog"); } /** - * Used by the download method to handle asynchronous downloading and evaluation of - * packages and keyboards. + * prepare cloud api params for lexical models download. + * @return the result */ - @Deprecated - static class DownloadTask extends AsyncTask { - static class Result { - public final Integer kbdResult; - public final List> installedLexicalModels; - - public Result(Integer i) { - this(i, null); - } - - public Result(Integer i, List> installedLexicalModels) { - this.kbdResult = i; - this.installedLexicalModels = installedLexicalModels; - } - } - - private ProgressDialog progressDialog; - private String kbVersion = "1.0"; - private String kbIsCustom = isCustom ? "Y" : "N"; - private String font = ""; - private String oskFont = ""; - - private Context context; - private boolean showProgressDialog; - private boolean downloadOnlyLexicalModel; - - public DownloadTask(Context context, boolean showProgressDialog) { - this.context = context; - this.showProgressDialog = showProgressDialog; - this.downloadOnlyLexicalModel = false; - } - - public DownloadTask(Context context, boolean showProgressDialog, boolean downloadOnlyLexicalModel) { - this.context = context; - this.showProgressDialog = showProgressDialog; - this.downloadOnlyLexicalModel = downloadOnlyLexicalModel; - } - - @Override - protected void onPreExecute() { - super.onPreExecute(); - if (showProgressDialog) { - progressDialog = new ProgressDialog(context); - if (!downloadOnlyLexicalModel) { - progressDialog.setMessage(context.getString(R.string.downloading_keyboard)); - } else { - progressDialog.setMessage(context.getString(R.string.downloading_model)); - } - progressDialog.setCancelable(false); - if (!((AppCompatActivity) context).isFinishing()) { - progressDialog.show(); - } else { - cancel(true); - progressDialog = null; - } - } - } - - @Override - protected Result doInBackground(Void... voids) { - int ret = -1; - - if (isCancelled()) - return new Result(-1); - - try { - - if (downloadOnlyLexicalModel) { - return downloadKMPLexicalModel(); - } - - String exceptionStr = "Invalid keyboard"; - if (pkgID == null || pkgID.trim().isEmpty() || - (!isCustom && (langID == null || langID.trim().isEmpty() || kbID == null || kbID.trim().isEmpty()))) { - throw new Exception(exceptionStr); - } - - String deviceType = context.getString(R.string.device_type); - if (deviceType.equals("AndroidTablet")) { - deviceType = "androidtablet"; - } else { - deviceType = "androidphone"; - } - - String remoteUrl = "",remoteLexicalModelUrl = ""; - if (isCustom) { - //TODO: Doesn't work, because this case will end up in an exception during download??? - // See downloadNonKMPKeyboard - remoteUrl = url; - } else { - // Keyman cloud - remoteUrl = String.format("%s/%s/%s?version=%s&device=%s&languageidtype=bcp47", - kKeymanApiBaseURL, langID, kbID, BuildConfig.VERSION_NAME, deviceType); - remoteLexicalModelUrl = String.format("%s?q=bcp47:%s", kKeymanApiModelURL, langID); - - } - - return downloadNonKMPKeyboard(remoteUrl, remoteLexicalModelUrl); - } catch (Exception e) { - ret = -1; - Log.e(TAG, "Error: " + e, e); - } - - return new Result(ret); - } - - @Override - protected void onProgressUpdate(Integer... progress) { - // Do nothing - } - - @Override - protected void onPostExecute(Result result) { - try { - if (progressDialog != null && progressDialog.isShowing()) { - progressDialog.dismiss(); - progressDialog = null; - } - } catch (Exception e) { - progressDialog = null; - } - - ((AppCompatActivity) context).finish(); - - if (!downloadOnlyLexicalModel) { - notifyListeners(KeyboardEventHandler.EventType.KEYBOARD_DOWNLOAD_FINISHED, result.kbdResult); - } - - if(result.installedLexicalModels != null) { - notifyLexicalModelInstallListeners(KeyboardEventHandler.EventType.LEXICAL_MODEL_INSTALLED, - result.installedLexicalModels, 1); - } - } - - /** - * Download a KMP Keyman lexical model from Keyman cloud - * @return A Result object with a success code and any successfully downloaded lexical models. - * @throws Exception - */ - protected Result downloadKMPLexicalModel() throws Exception { - int result = -1; - File resourceRoot = new File(context.getDir("data", Context.MODE_PRIVATE).toString() + File.separator); - LexicalModelPackageProcessor kmpProcessor = new LexicalModelPackageProcessor(resourceRoot); - List> installedLexicalModels = null; - - if (downloadOnlyLexicalModel) { - String destination = (context.getCacheDir() + File.separator).toString(); - filename = FileUtils.getFilename(url); - - result = FileUtils.download(context, url, destination, filename); - if (result > 0 && FileUtils.hasKeymanPackageExtension(url)) { - // Extract the kmp. Validate it contains only lexical models, and then process the lexical model package - File kmpFile = new File(context.getCacheDir(), filename); - String pkgTarget = kmpProcessor.getPackageTarget(kmpFile); - if (pkgTarget.equals(PackageProcessor.PP_TARGET_LEXICAL_MODELS)) { - File unzipPath = kmpProcessor.unzipKMP(kmpFile); - installedLexicalModels = kmpProcessor.processKMP(kmpFile, unzipPath, PackageProcessor.PP_LEXICAL_MODELS_KEY); - } - } - } - - // We'll notify any listeners of the successful download in onPostExecute. - return new Result(result, installedLexicalModels); - } - - /** - * Download a non-KMP Keyman keyboard from Keyman cloud via JSON. - * If an associated lexical model keyboard package is available, download the first one. - * @param remoteUrl String - * @param remoteLexicalModelUrl String API query for lexical model associated with the language ID - * @return ret int -1 for fail; >0 for success; 2 for keyboard downloading but not font - * @throws Exception - */ - protected Result downloadNonKMPKeyboard(String remoteUrl, String remoteLexicalModelUrl) throws Exception { - int ret = -1; - JSONParser jsonParser = new JSONParser(); - JSONObject kbData = jsonParser.getJSONObjectFromUrl(remoteUrl); - String exceptionStr = "Could not reach server"; - if (kbData == null) { - throw new Exception(exceptionStr); - } - - if (isCustom) { - exceptionStr = "Cannot download custom non-KMP keyboard"; - throw new Exception(exceptionStr); - } - - exceptionStr = "JSON file does not contain a valid \"options\" object"; - JSONObject options = kbData.optJSONObject(KMKey_Options); - if (options == null) { - throw new Exception(exceptionStr); - } - String kbBaseUri = options.optString(KMKey_KeyboardBaseURI, ""); - if (kbBaseUri.isEmpty()) { - throw new Exception(exceptionStr); - } - - String fontBaseUri = options.optString(KMKey_FontBaseURI, ""); - - // Keyman cloud keyboard distribution via JSON - JSONObject language = kbData.optJSONObject(KMKey_Language); - if (language == null) { - throw new Exception(exceptionStr); - } - - langName = language.optString(KMManager.KMKey_Name, ""); - - JSONArray keyboards = language.getJSONArray(KMKey_LanguageKeyboards); - - JSONObject keyboard = CloudDataJsonUtil.findMatchingKeyboardByID(keyboards,kbID); - - kbID = keyboard.getString(KMManager.KMKey_ID); - pkgID = keyboard.optString(KMManager.KMKey_PackageID, KMManager.KMDefault_UndefinedPackageID); - - kbName = keyboard.optString(KMManager.KMKey_Name, ""); - kbVersion = keyboard.optString(KMManager.KMKey_KeyboardVersion, "1.0"); - String kbFilename = keyboard.optString(KMKey_Filename, ""); - if (kbName.isEmpty() || langName.isEmpty() || kbFilename.isEmpty()) - throw new Exception(exceptionStr); - - String kbUrl = kbBaseUri + kbFilename; - ArrayList urls = new ArrayList(); - urls.add(kbUrl); - - JSONObject jsonFont = keyboard.optJSONObject(KMManager.KMKey_Font); - JSONObject jsonOskFont = keyboard.optJSONObject(KMManager.KMKey_OskFont); - - if (jsonFont != null) { - CloudDataJsonUtil.updateFontSourceToTTFFont(jsonFont); - } - if (jsonOskFont != null) { - CloudDataJsonUtil.updateFontSourceToTTFFont(jsonOskFont); - } - ArrayList fontUrls = CloudDataJsonUtil.fontUrls(jsonFont, fontBaseUri, false); - ArrayList oskFontUrls = CloudDataJsonUtil.fontUrls(jsonOskFont, fontBaseUri, true); - if (fontUrls != null) - urls.addAll(fontUrls); - if (oskFontUrls != null) { - for (String url : oskFontUrls) { - if (!urls.contains(url)) - urls.add(url); - } - } - - font = keyboard.optString(KMManager.KMKey_Font); - oskFont = keyboard.optString(KMManager.KMKey_OskFont); - - // Also download first associated lexical model if it exists - JSONArray lmData = jsonParser.getJSONObjectFromUrl(remoteLexicalModelUrl, JSONArray.class); - if (lmData != null && lmData.length() > 0) { - try { - JSONObject modelInfo = lmData.getJSONObject(0); - if (modelInfo.has("packageFilename")) { - // TODO: Confirm if user wants to overwrite exisiting model version - urls.add(modelInfo.getString("packageFilename")); - } - } catch (JSONException e) { - Log.e(TAG, "Error parsing lexical model from api.keyman.com. " + e); - } - } - - notifyListeners(KeyboardEventHandler.EventType.KEYBOARD_DOWNLOAD_STARTED, 0); - - String destination = context.getDir("data", Context.MODE_PRIVATE).toString() + - File.separator + KMDefault_UndefinedPackageID + File.separator + File.separator; - - ret = 1; - int result = 0; - File resourceRoot = new File(context.getDir("data", Context.MODE_PRIVATE).toString() + File.separator); - LexicalModelPackageProcessor kmpProcessor = new LexicalModelPackageProcessor(resourceRoot); - List> installedLexicalModels = new ArrayList<>(); - for (String url : urls) { - String filename = ""; - if (FileUtils.hasJavaScriptExtension(url)) { - - int start = kbFilename.lastIndexOf("/"); - if (start < 0) { - start = 0; - } else { - start++; - } - if (!kbFilename.contains("-")) { - filename = kbFilename.substring(start, kbFilename.length() - 3) + "-" + kbVersion + ".js"; - } else { - filename = kbFilename.substring(start); - } - } else if (FileUtils.hasKeymanPackageExtension(url)) { - // Save the kmp file in the app cache - destination = (context.getCacheDir() + File.separator).toString(); - filename = FileUtils.getFilename(url); - } - - result = FileUtils.download(context, url, destination, filename); - if (result > 0 && FileUtils.hasKeymanPackageExtension(url)) { - // Extract the kmp. Validate it contains only lexical models, and then process the lexical model package - File kmpFile = new File(context.getCacheDir(), filename); - String pkgTarget = kmpProcessor.getPackageTarget(kmpFile); - if (pkgTarget.equals(PackageProcessor.PP_TARGET_LEXICAL_MODELS)) { - File unzipPath = kmpProcessor.unzipKMP(kmpFile); - // Assumption: only one lexical model KMP will occur per download. - installedLexicalModels = kmpProcessor.processKMP(kmpFile, unzipPath, PackageProcessor.PP_LEXICAL_MODELS_KEY); - } - } - - if (result < 0) { - if (FileUtils.hasFontExtension(url)) { - // Propagate warning about font failing to download - ret = 2; - } else { - ret = -1; - break; - } - } - } - - if (installedLexicalModels.size() != 0) { - // Let the postExecute method signal the listeners - it's triggered on the main thread. - return new Result(ret, installedLexicalModels); - } - - return new Result(ret); - } - - /** - * Notify listeners when an event happens - * @param eventType - * @param result - */ - protected void notifyListeners(KeyboardEventHandler.EventType eventType, int result) { - if (kbDownloadEventListeners != null) { - HashMap keyboardInfo = - CloudDataJsonUtil.createKeyboardInfoMap(pkgID,langID,langName,kbID,kbName,kbVersion,kbIsCustom,font,oskFont); - - KeyboardEventHandler.notifyListeners(kbDownloadEventListeners, eventType, keyboardInfo, result); - } - } - - /** - * Notify listeners when a lexical model is installed - * @param eventType - * @param models - * @param result - */ - protected void notifyLexicalModelInstallListeners(KeyboardEventHandler.EventType eventType, - List> models, int result) { - if (kbDownloadEventListeners != null) { - KeyboardEventHandler.notifyListeners(kbDownloadEventListeners, eventType, models, result); - } - } - } - - /** - * Async task to download a Keyman keyboard from either Keyman cloud server or custom url - * @param context - * @param showProgressDialog - */ - public static void download(final Context context, final boolean showProgressDialog) { - if(USE_DOWNLOAD_MANAGER) - downloadKeyboardUsingDownloadManager(context); - else - new DownloadTask(context, showProgressDialog).execute(); - } - - public static void download(final Context context, final boolean showProgressDialog, - final boolean aDownloadOnlyLexicalModel) { - if(USE_DOWNLOAD_MANAGER) - downloadUsingDownloadManager(context,aDownloadOnlyLexicalModel); - else - new DownloadTask(context, showProgressDialog, aDownloadOnlyLexicalModel).execute(); - } - - /** - * Download in keyboards and lexical model using download manager. - * @param context the context - * @param aDownloadOnlyLexicalModel is lexical model download - */ - private static void downloadUsingDownloadManager(final Context context, - final boolean aDownloadOnlyLexicalModel) - { - if(aDownloadOnlyLexicalModel) - { - downloadLexicalModelUsingDownloadManager(context); - } - else - { - downloadKeyboardUsingDownloadManager(context); - } + private ArrayList prepareCloudApiParamsForLexicalModelDownload() { + ArrayList _params = new ArrayList<>(); + _params.add(new CloudApiTypes.CloudApiParam( + CloudApiTypes.ApiTarget.LexicalModelPackage, url)); + return _params; } /** * prepare and execute keyboard download using downloadmanager. * @param context the context + * @param aLangId the language id + * @param aKbId the keyman keyboard id + * @param aPreparedCloudApiParams the prepared api params */ - private static void downloadKeyboardUsingDownloadManager(Context context) + public static void downloadKeyboard(Context context, + String aLangId, String aKbId, + List aPreparedCloudApiParams) { - if (pkgID == null || pkgID.trim().isEmpty() || - (!isCustom && (langID == null || langID.trim().isEmpty() || kbID == null || kbID.trim().isEmpty()))) { - throw new IllegalStateException("Invalid keyboard"); - } - - - - List cloudQueries = getPrepareCloudQueriesForKeyboardDownload(context); - - String _downloadid= CloudKeyboardMetaDataDownloadCallback.createDownloadId(langID , kbID); + String _downloadid= CloudKeyboardMetaDataDownloadCallback.createDownloadId(aLangId , aKbId); if( CloudDownloadMgr.getInstance().alreadyDownloadingData(_downloadid) || CloudDownloadMgr.getInstance().alreadyDownloadingData( - CloudKeyboardDataDownloadCallback.createDownloadId(kbID))) + CloudKeyboardDataDownloadCallback.createDownloadId(aKbId))) { Toast.makeText(context, context.getString(R.string.keyboard_download_is_running_in_background), @@ -589,7 +191,6 @@ public class KMKeyboardDownloaderActivity extends AppCompatActivity { else { CloudKeyboardMetaDataDownloadCallback _callback = new CloudKeyboardMetaDataDownloadCallback(); - _callback.setDownloadEventListeners(kbDownloadEventListeners); Toast.makeText(context, context.getString(R.string.keyboard_download_start_in_background), @@ -597,22 +198,26 @@ public class KMKeyboardDownloaderActivity extends AppCompatActivity { CloudDownloadMgr.getInstance().executeAsDownload( context, _downloadid, null, _callback, - cloudQueries.toArray(new CloudApiTypes.CloudApiParam[0])); + aPreparedCloudApiParams.toArray(new CloudApiTypes.CloudApiParam[0])); } ((AppCompatActivity) context).finish(); } /** - * Prepare the cloud queries for keyboard metadata download. - * @param context the context + * Prepare the cloud api params for keyboard metadata download. * @return the result */ - private static List getPrepareCloudQueriesForKeyboardDownload(Context context) + private ArrayList prepareCloudApiParamsForKeyboardDownload() { - List cloudQueries = new ArrayList<>(); + if (pkgID == null || pkgID.trim().isEmpty() || + (!isCustom && (langID == null || langID.trim().isEmpty() || kbID == null || kbID.trim().isEmpty()))) { + throw new IllegalStateException("Invalid keyboard"); + } - String deviceType = CloudDataJsonUtil.getDeviceTypeForCloudQuery(context); + ArrayList cloudQueries = new ArrayList<>(); + + String deviceType = CloudDataJsonUtil.getDeviceTypeForCloudQuery(this); if (isCustom) { //TODO: will end up in an exception during download??? @@ -643,11 +248,15 @@ public class KMKeyboardDownloaderActivity extends AppCompatActivity { /** * prepare and execute lexical model download using downloadmanager. * @param context the context + * @param aModelId the lexical model id + * @param aPreparedCloudApiParams the prepared api params */ - private static void downloadLexicalModelUsingDownloadManager(Context context) { + public static void downloadLexicalModel(Context context, + String aModelId, + List aPreparedCloudApiParams) { - String _downloadid= CloudLexicalPackageDownloadCallback.createDownloadId(modelID); + String _downloadid= CloudLexicalPackageDownloadCallback.createDownloadId(aModelId); if( CloudDownloadMgr.getInstance().alreadyDownloadingData(_downloadid)) { @@ -658,17 +267,14 @@ public class KMKeyboardDownloaderActivity extends AppCompatActivity { else { CloudLexicalPackageDownloadCallback _callback = new CloudLexicalPackageDownloadCallback(); - _callback.setDownloadEventListeners(kbDownloadEventListeners); - - CloudApiTypes.CloudApiParam _param = new CloudApiTypes.CloudApiParam( - CloudApiTypes.ApiTarget.LexicalModelPackage, url); Toast.makeText(context, context.getString(R.string.dictionary_download_start_in_background), Toast.LENGTH_SHORT).show(); CloudDownloadMgr.getInstance().executeAsDownload( - context, _downloadid, null, _callback, _param); + context, _downloadid, null, _callback, + aPreparedCloudApiParams.toArray(new CloudApiTypes.CloudApiParam[0])); } ((AppCompatActivity) context).finish(); @@ -688,7 +294,7 @@ public class KMKeyboardDownloaderActivity extends AppCompatActivity { public static void addKeyboardDownloadEventListener(KeyboardEventHandler.OnKeyboardDownloadEventListener listener) { if (kbDownloadEventListeners == null) { - kbDownloadEventListeners = new ArrayList(); + kbDownloadEventListeners = new ArrayList<>(); } if (listener != null && !kbDownloadEventListeners.contains(listener)) { @@ -701,4 +307,8 @@ public class KMKeyboardDownloaderActivity extends AppCompatActivity { kbDownloadEventListeners.remove(listener); } } + + public static ArrayList getKbDownloadEventListeners() { + return kbDownloadEventListeners; + } } diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMManager.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMManager.java index da0ae135da..a13d1eaad1 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMManager.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMManager.java @@ -53,8 +53,8 @@ import com.google.firebase.analytics.FirebaseAnalytics; import com.tavultesoft.kmea.KeyboardEventHandler.EventType; import com.tavultesoft.kmea.KeyboardEventHandler.OnKeyboardDownloadEventListener; import com.tavultesoft.kmea.KeyboardEventHandler.OnKeyboardEventListener; -import com.tavultesoft.kmea.data.CloudDataJsonUtil; -import com.tavultesoft.kmea.data.CloudDownloadMgr; +import com.tavultesoft.kmea.cloud.CloudDataJsonUtil; +import com.tavultesoft.kmea.cloud.CloudDownloadMgr; import com.tavultesoft.kmea.data.Dataset; import com.tavultesoft.kmea.packages.JSONUtils; import com.tavultesoft.kmea.packages.PackageProcessor; diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardListActivity.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardListActivity.java index a2741b4eaa..18c85627e5 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardListActivity.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardListActivity.java @@ -145,8 +145,6 @@ public final class KeyboardListActivity extends AppCompatActivity implements OnK String kOskFont = keyboardInfo.get(KMManager.KMKey_OskFont); KeyboardPickerActivity.addKeyboard(this, keyboardInfo); - if (!KMKeyboardDownloaderActivity.USE_DOWNLOAD_MANAGER) - KMManager.setKeyboard(packageID, keyboardID, languageID, keyboardName, languageName, kFont, kOskFont); } finish(); } diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardPickerActivity.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardPickerActivity.java index 2174904063..9691189f80 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardPickerActivity.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardPickerActivity.java @@ -14,7 +14,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import com.tavultesoft.kmea.data.CloudDataJsonUtil; +import com.tavultesoft.kmea.cloud.CloudDataJsonUtil; import com.tavultesoft.kmea.data.CloudRepository; import com.tavultesoft.kmea.data.Dataset; import com.tavultesoft.kmea.data.Keyboard; diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardSettingsActivity.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardSettingsActivity.java index 209dfc3186..89b1d07ebc 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardSettingsActivity.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardSettingsActivity.java @@ -1,20 +1,17 @@ -/** +/* * Copyright (C) 2019 SIL International. All rights reserved. */ - package com.tavultesoft.kmea; import java.io.File; import java.util.ArrayList; import java.util.HashMap; -import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import android.app.DialogFragment; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.graphics.Typeface; import android.net.Uri; @@ -39,15 +36,11 @@ import static com.tavultesoft.kmea.ConfirmDialogFragment.DialogType.DIALOG_TYPE_ // Public access is necessary to avoid IllegalAccessException public final class KeyboardSettingsActivity extends AppCompatActivity { private static final String TAG = "KbSettingsActivity"; - - private static Toolbar toolbar = null; - private static ListView listView = null; - private DialogFragment dialog; private static ArrayList> infoList = null; - protected static Typeface titleFont = null; - private final String titleKey = "title"; - private final String subtitleKey = "subtitle"; - private final String iconKey = "icon"; + private static Typeface titleFont = null; + private static final String titleKey = "title"; + private static final String subtitleKey = "subtitle"; + private static final String iconKey = "icon"; @Override public void onCreate(Bundle savedInstanceState) { @@ -57,13 +50,13 @@ public final class KeyboardSettingsActivity extends AppCompatActivity { final String authority = FileProviderUtils.getAuthority(context); setContentView(R.layout.activity_list_layout); - toolbar = (Toolbar) findViewById(R.id.list_toolbar); + final Toolbar toolbar = findViewById(R.id.list_toolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayShowHomeEnabled(true); getSupportActionBar().setDisplayShowTitleEnabled(false); - listView = (ListView) findViewById(R.id.listView); + final ListView listView = findViewById(R.id.listView); final String packageID = getIntent().getStringExtra(KMManager.KMKey_PackageID); final String languageID = getIntent().getStringExtra(KMManager.KMKey_LanguageID); @@ -72,22 +65,22 @@ public final class KeyboardSettingsActivity extends AppCompatActivity { final String kbName = getIntent().getStringExtra(KMManager.KMKey_KeyboardName); final String kbVersion = getIntent().getStringExtra(KMManager.KMKey_KeyboardVersion); - final TextView textView = (TextView) findViewById(R.id.bar_title); + final TextView textView = findViewById(R.id.bar_title); textView.setText(kbName); if (titleFont != null) textView.setTypeface(titleFont, Typeface.BOLD); - infoList = new ArrayList>(); + infoList = new ArrayList<>(); // Display keyboard version title final String noIcon = "0"; - HashMap hashMap = new HashMap(); + HashMap hashMap = new HashMap<>(); hashMap.put(titleKey, getString(R.string.keyboard_version)); hashMap.put(subtitleKey, kbVersion); hashMap.put(iconKey, noIcon); infoList.add(hashMap); // Display keyboard help link - hashMap = new HashMap(); + hashMap = new HashMap<>(); final String helpUrlStr = getIntent().getStringExtra(KMManager.KMKey_HelpLink); final String customHelpLink = getIntent().getStringExtra(KMManager.KMKey_CustomHelpLink); // Check if app declared FileProvider @@ -105,7 +98,7 @@ public final class KeyboardSettingsActivity extends AppCompatActivity { // Display uninstall keyboard if (!packageID.equalsIgnoreCase(KMManager.KMDefault_UndefinedPackageID) || !kbID.equalsIgnoreCase(KMManager.KMDefault_KeyboardID)) { - hashMap = new HashMap(); + hashMap = new HashMap<>(); hashMap.put(titleKey, getString(R.string.uninstall_keyboard)); hashMap.put(subtitleKey, ""); hashMap.put(iconKey, noIcon); @@ -118,7 +111,7 @@ public final class KeyboardSettingsActivity extends AppCompatActivity { ListAdapter adapter = new SimpleAdapter(context, infoList, R.layout.list_row_layout2, from, to) { @Override public boolean isEnabled(int position) { - HashMap hashMap = (HashMap)infoList.get(position); + HashMap hashMap = infoList.get(position); String itemTitle = MapCompat.getOrDefault(hashMap, titleKey, ""); String icon = MapCompat.getOrDefault(hashMap, iconKey, noIcon); if (itemTitle.equals(getString(R.string.keyboard_version))) { @@ -174,7 +167,7 @@ public final class KeyboardSettingsActivity extends AppCompatActivity { // Uninstall selected keyboard String title = String.format("%s: %s", languageName, kbName); String keyboardKey = String.format("%s_%s", languageID, kbID); - DialogFragment dialog = ConfirmDialogFragment.newInstance( + DialogFragment dialog = ConfirmDialogFragment.newInstanceForItemKeyBasedAction( DIALOG_TYPE_DELETE_KEYBOARD, title, getString(R.string.confirm_delete_keyboard), keyboardKey); dialog.show(getFragmentManager(), "dialog"); } @@ -191,9 +184,7 @@ public final class KeyboardSettingsActivity extends AppCompatActivity { @Override public void onDestroy(){ super.onDestroy(); - if ( dialog !=null ){ - dialog.dismiss(); - } + } } diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/LanguageListActivity.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/LanguageListActivity.java index 0cc20e4fc3..5bbc6974d8 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/LanguageListActivity.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/LanguageListActivity.java @@ -4,9 +4,6 @@ package com.tavultesoft.kmea; -import java.io.File; -import java.io.FileInputStream; -import java.io.ObjectInputStream; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -15,7 +12,7 @@ import org.json.JSONArray; import org.json.JSONObject; import com.tavultesoft.kmea.KeyboardEventHandler.OnKeyboardDownloadEventListener; -import com.tavultesoft.kmea.data.CloudDataJsonUtil; +import com.tavultesoft.kmea.cloud.CloudDataJsonUtil; import com.tavultesoft.kmea.data.CloudRepository; import com.tavultesoft.kmea.data.Dataset; import com.tavultesoft.kmea.data.Keyboard; @@ -138,8 +135,6 @@ public final class LanguageListActivity extends AppCompatActivity implements OnK // Custom keyboard already exists in packages/ so just add the language association KeyboardPickerActivity.addKeyboard(context, kbInfo); - if (!KMKeyboardDownloaderActivity.USE_DOWNLOAD_MANAGER) - KMManager.setKeyboard(pkgID, kbID, langID, kbName, language.name, kFont, kOskFont); Toast.makeText(context, "Keyboard installed", Toast.LENGTH_SHORT).show(); setResult(RESULT_OK); ((AppCompatActivity) context).finish(); @@ -209,8 +204,6 @@ public final class LanguageListActivity extends AppCompatActivity implements OnK String kOskFont = keyboardInfo.get(KMManager.KMKey_OskFont); KeyboardPickerActivity.addKeyboard(this, keyboardInfo); - if (!KMKeyboardDownloaderActivity.USE_DOWNLOAD_MANAGER) - KMManager.setKeyboard(packageID, keyboardID, languageID, keyboardName, languageName, kFont, kOskFont); if (result == 2) { Toast.makeText(context, context.getString(R.string.font_failed_to_download), Toast.LENGTH_LONG).show(); diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/LanguagesSettingsActivity.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/LanguagesSettingsActivity.java index ad9aca38b4..9696331b1b 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/LanguagesSettingsActivity.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/LanguagesSettingsActivity.java @@ -27,7 +27,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; -import com.tavultesoft.kmea.data.CloudDataJsonUtil; +import com.tavultesoft.kmea.cloud.CloudDataJsonUtil; import com.tavultesoft.kmea.data.CloudRepository; import com.tavultesoft.kmea.data.Dataset; import com.tavultesoft.kmea.data.adapters.AdapterFilter; diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/ModelInfoActivity.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/ModelInfoActivity.java index ab38e1e198..8f78d3a359 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/ModelInfoActivity.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/ModelInfoActivity.java @@ -1,7 +1,6 @@ -/** +/* * Copyright (C) 2017 SIL International. All rights reserved. */ - package com.tavultesoft.kmea; import java.io.File; @@ -18,14 +17,11 @@ import android.net.Uri; import android.os.Bundle; import androidx.core.content.FileProvider; import android.util.Log; -import android.view.MenuItem; import android.view.View; import android.view.Window; import android.widget.AdapterView; -import android.widget.BaseAdapter; import android.widget.ListAdapter; import android.widget.ListView; -import android.widget.PopupMenu; import android.widget.SimpleAdapter; import android.widget.TextView; import android.widget.Toast; @@ -39,10 +35,7 @@ import static com.tavultesoft.kmea.ConfirmDialogFragment.DialogType.DIALOG_TYPE_ // Public access is necessary to avoid IllegalAccessException public final class ModelInfoActivity extends AppCompatActivity { - private static Toolbar toolbar = null; - private static ListView listView = null; private static ArrayList> infoList = null; - protected static Typeface titleFont = null; private final String titleKey = "title"; private final String subtitleKey = "subtitle"; private final String iconKey = "icon"; @@ -55,13 +48,13 @@ public final class ModelInfoActivity extends AppCompatActivity { final String authority = FileProviderUtils.getAuthority(context); setContentView(R.layout.activity_list_layout); - toolbar = (Toolbar) findViewById(R.id.list_toolbar); + final Toolbar toolbar = findViewById(R.id.list_toolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayShowHomeEnabled(true); getSupportActionBar().setDisplayShowTitleEnabled(false); - listView = (ListView) findViewById(R.id.listView); + final ListView listView = findViewById(R.id.listView); final String packageID = getIntent().getStringExtra(KMManager.KMKey_PackageID); final String languageID = getIntent().getStringExtra(KMManager.KMKey_LanguageID); @@ -69,23 +62,20 @@ public final class ModelInfoActivity extends AppCompatActivity { final String modelName = getIntent().getStringExtra(KMManager.KMKey_LexicalModelName); final String modelVersion = getIntent().getStringExtra(KMManager.KMKey_LexicalModelVersion); - final TextView textView = (TextView) findViewById(R.id.bar_title); + final TextView textView = findViewById(R.id.bar_title); textView.setText(String.format(getString(R.string.model_info_header), modelName)); - if (titleFont != null) - textView.setTypeface(titleFont, Typeface.BOLD); - - infoList = new ArrayList>(); + infoList = new ArrayList<>(); // Display model version title final String noIcon = "0"; - HashMap hashMap = new HashMap(); + HashMap hashMap = new HashMap<>(); hashMap.put(titleKey, getString(R.string.model_version)); hashMap.put(subtitleKey, modelVersion); hashMap.put(iconKey, noIcon); infoList.add(hashMap); // Display model help link - hashMap = new HashMap(); + hashMap = new HashMap<>(); final String customHelpLink = getIntent().getStringExtra(KMManager.KMKey_CustomHelpLink); // Check if app declared FileProvider // Currently, model help only available if custom link exists @@ -102,7 +92,7 @@ public final class ModelInfoActivity extends AppCompatActivity { infoList.add(hashMap); // Display link to uninstall model - hashMap = new HashMap(); + hashMap = new HashMap<>(); hashMap.put(titleKey, getString(R.string.uninstall_model)); hashMap.put(subtitleKey, ""); hashMap.put(iconKey, noIcon); @@ -114,7 +104,7 @@ public final class ModelInfoActivity extends AppCompatActivity { ListAdapter adapter = new SimpleAdapter(context, infoList, R.layout.list_row_layout2, from, to) { @Override public boolean isEnabled(int position) { - HashMap hashMap = (HashMap)infoList.get(position); + HashMap hashMap = infoList.get(position); String itemTitle = MapCompat.getOrDefault(hashMap, titleKey, ""); String icon = MapCompat.getOrDefault(hashMap, iconKey, noIcon); if (itemTitle.equals(getString(R.string.model_version))) { @@ -168,7 +158,7 @@ public final class ModelInfoActivity extends AppCompatActivity { } else if (itemTitle.equals(getString(R.string.uninstall_model))) { // Uninstall selected model String lexicalModelKey = String.format("%s_%s_%s", packageID, languageID, modelID); - DialogFragment dialog = ConfirmDialogFragment.newInstance( + DialogFragment dialog = ConfirmDialogFragment.newInstanceForItemKeyBasedAction( DIALOG_TYPE_DELETE_MODEL, modelName, getString(R.string.confirm_delete_model), lexicalModelKey); dialog.show(getFragmentManager(), "dialog"); diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudApiTypes.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/CloudApiTypes.java similarity index 87% rename from android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudApiTypes.java rename to android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/CloudApiTypes.java index ecc758e2eb..4f55ba367b 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudApiTypes.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/CloudApiTypes.java @@ -1,4 +1,4 @@ -package com.tavultesoft.kmea.data; +package com.tavultesoft.kmea.cloud; import android.app.DownloadManager; @@ -8,14 +8,14 @@ import org.json.JSONArray; import org.json.JSONObject; import java.io.File; +import java.io.Serializable; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; -import java.util.Map; public class CloudApiTypes { - protected static class CloudApiReturns { + public static class CloudApiReturns { public final ApiTarget target; public final JSONArray jsonArray; @@ -69,11 +69,14 @@ public class CloudApiTypes { Object } - public static class CloudApiParam { + public static class CloudApiParam implements Serializable { + + static final long serialVersionUID = 1L; + public final ApiTarget target; public final String url; public JSONType type; - private Map additionalProperties = new HashMap<>(); + private final HashMap additionalProperties = new HashMap<>(); public CloudApiParam(ApiTarget target, String url) { this.target = target; @@ -84,24 +87,24 @@ public class CloudApiTypes { this.type = type; return this; } - public CloudApiParam setAdditionalProperty(String aProperty, Object aValue) + public CloudApiParam setAdditionalProperty(String aProperty, Serializable aValue) { additionalProperties.put(aProperty,aValue); return this; } - public T getAdditionalProperty(String aProperty,Class aType) + public T getAdditionalProperty(String aProperty,Class aType) { - return (T)additionalProperties.get(aProperty); + return aType.cast(additionalProperties.get(aProperty)); } } public static class SingleCloudDownload { - private DownloadManager.Request request; + private final DownloadManager.Request request; private boolean downloadFinished =false; private long downloadId; - private File destinationFile; + private final File destinationFile; private CloudApiParam cloudParams; public SingleCloudDownload(DownloadManager.Request aRequest,File aDestinationFile) @@ -142,9 +145,9 @@ public class CloudApiTypes { * @param the result type of the download */ public static class CloudDownloadSet { - private String downloadIdentifier; - private ModelType targetModel; - private LinkedList downloads = new LinkedList<>(); + private final String downloadIdentifier; + private final ModelType targetModel; + private final LinkedList downloads = new LinkedList<>(); private ICloudDownloadCallback callback; @@ -213,7 +216,6 @@ public class CloudApiTypes { return; } } - return; } diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudDataJsonUtil.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/CloudDataJsonUtil.java similarity index 95% rename from android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudDataJsonUtil.java rename to android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/CloudDataJsonUtil.java index 3072627d0d..7de552c436 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudDataJsonUtil.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/CloudDataJsonUtil.java @@ -1,4 +1,4 @@ -package com.tavultesoft.kmea.data; +package com.tavultesoft.kmea.cloud; import android.content.Context; import android.os.Build; @@ -8,6 +8,9 @@ import com.tavultesoft.kmea.JSONParser; import com.tavultesoft.kmea.KMKeyboardDownloaderActivity; import com.tavultesoft.kmea.KMManager; import com.tavultesoft.kmea.R; +import com.tavultesoft.kmea.cloud.CloudApiTypes; +import com.tavultesoft.kmea.data.Keyboard; +import com.tavultesoft.kmea.data.LexicalModel; import com.tavultesoft.kmea.util.FileUtils; import org.json.JSONArray; @@ -52,7 +55,7 @@ public class CloudDataJsonUtil { return keyboardInfo; } - static List processKeyboardJSON(JSONObject query, boolean fromKMP) { + public static List processKeyboardJSON(JSONObject query, boolean fromKMP) { List keyboardsList = new ArrayList<>(); //keyboardModifiedDates = new HashMap(); @@ -96,7 +99,7 @@ public class CloudDataJsonUtil { return keyboardsList; } - static List processLexicalModelJSON(JSONArray models) { + public static List processLexicalModelJSON(JSONArray models) { List modelList = new ArrayList<>(models.length()); try { @@ -158,7 +161,7 @@ public class CloudDataJsonUtil { return modelList; } - static JSONArray getCachedJSONArray(File file) { + public static JSONArray getCachedJSONArray(File file) { JSONArray lmData = null; try { // Read from cache file @@ -198,7 +201,7 @@ public class CloudDataJsonUtil { * be used for each API call, such as for keyboards vs lexical models. * @param json - Array of JSON objects containing API return info */ - protected static void saveJSONArrayToCache(File file, JSONArray json) { + public static void saveJSONArrayToCache(File file, JSONArray json) { ObjectOutput objOutput; try { // Save to cache file @@ -216,7 +219,7 @@ public class CloudDataJsonUtil { * be used for each API call, such as for keyboards vs lexical models. * @param json - JSON object containing API return info */ - protected static void saveJSONObjectToCache(File file, JSONObject json) { + public static void saveJSONObjectToCache(File file, JSONObject json) { ObjectOutput objOutput; try { // Save to cache file @@ -243,7 +246,7 @@ public class CloudDataJsonUtil { * @param aDownload the download * @return the result */ - public static CloudApiTypes.CloudApiReturns retrieveJsonFromDownload( CloudApiTypes.SingleCloudDownload aDownload) + public static CloudApiTypes.CloudApiReturns retrieveJsonFromDownload(CloudApiTypes.SingleCloudDownload aDownload) { JSONParser jsonParser = new JSONParser(); JSONArray dataArray = null; @@ -258,7 +261,7 @@ public class CloudDataJsonUtil { dataObject = jsonParser.getJSONObjectFromFile(aDownload.getDestinationFile(),JSONObject.class); } } catch (Exception e) { - Log.d(TAG, e.getMessage()); + Log.d(TAG, e.getMessage(),e); } finally { aDownload.getDestinationFile().delete(); } diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudDownloadMgr.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/CloudDownloadMgr.java similarity index 96% rename from android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudDownloadMgr.java rename to android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/CloudDownloadMgr.java index 321b281131..11278a4eb7 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudDownloadMgr.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/CloudDownloadMgr.java @@ -1,4 +1,4 @@ -package com.tavultesoft.kmea.data; +package com.tavultesoft.kmea.cloud; import android.app.DownloadManager; import android.content.BroadcastReceiver; @@ -126,6 +126,8 @@ public class CloudDownloadMgr{ synchronized (downloadSetByDownloadIdentifier) { CloudApiTypes.CloudDownloadSet _parentSet = getDownloadSetForInternalDownloadId(anInternalDownloadId); + if(_parentSet==null) + throw new IllegalStateException("Download with ID " + anInternalDownloadId + " is not available"); _parentSet.setDone(anInternalDownloadId); if(!_parentSet.hasOpenDownloads()) { @@ -188,7 +190,8 @@ public class CloudDownloadMgr{ return; DownloadManager downloadManager = (DownloadManager) aContext.getSystemService(Context.DOWNLOAD_SERVICE); - + if(downloadManager==null) + throw new IllegalStateException("Downloadmanager is not available"); aCallback.initializeContext(aContext); diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/ICloudDownloadCallback.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/ICloudDownloadCallback.java similarity index 86% rename from android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/ICloudDownloadCallback.java rename to android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/ICloudDownloadCallback.java index 5fe73b75c6..f730479b53 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/ICloudDownloadCallback.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/ICloudDownloadCallback.java @@ -1,7 +1,10 @@ -package com.tavultesoft.kmea.data; +package com.tavultesoft.kmea.cloud; import android.content.Context; +import com.tavultesoft.kmea.cloud.CloudApiTypes; +import com.tavultesoft.kmea.cloud.CloudDownloadMgr; + /** * Interface for {@link CloudDownloadMgr} as callback to do use case specific task. * @param the model objects type diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudCatalogDownloadCallback.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/impl/CloudCatalogDownloadCallback.java similarity index 94% rename from android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudCatalogDownloadCallback.java rename to android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/impl/CloudCatalogDownloadCallback.java index cffbd79627..e56ea494d6 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudCatalogDownloadCallback.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/impl/CloudCatalogDownloadCallback.java @@ -1,13 +1,20 @@ -package com.tavultesoft.kmea.data; +package com.tavultesoft.kmea.cloud.impl; import android.content.Context; import android.os.Bundle; import android.util.Log; import android.widget.Toast; -import com.tavultesoft.kmea.JSONParser; import com.tavultesoft.kmea.KeyboardPickerActivity; import com.tavultesoft.kmea.R; +import com.tavultesoft.kmea.cloud.CloudApiTypes; +import com.tavultesoft.kmea.cloud.CloudDataJsonUtil; +import com.tavultesoft.kmea.cloud.ICloudDownloadCallback; +import com.tavultesoft.kmea.data.CloudRepository; +import com.tavultesoft.kmea.data.Dataset; +import com.tavultesoft.kmea.data.Keyboard; +import com.tavultesoft.kmea.data.LanguageResource; +import com.tavultesoft.kmea.data.LexicalModel; import com.tavultesoft.kmea.util.FileUtils; import org.json.JSONArray; @@ -20,7 +27,7 @@ import java.util.List; * Callback for cloud catalogue download. * Is used for download with progress and download with Clientdownloadmanager. */ -public class CloudCatalogDownloadCallback implements ICloudDownloadCallback{ +public class CloudCatalogDownloadCallback implements ICloudDownloadCallback { private static final String TAG = "CloudCatalogDownloadCb"; private static final boolean DEBUG_SIMULATE_UPDATES = false; @@ -127,10 +134,6 @@ public class CloudCatalogDownloadCallback implements ICloudDownloadCallback downloadEventListeners = new ArrayList<>(); private HashMap keyboardInfo; /** @@ -44,16 +43,6 @@ public class CloudKeyboardDataDownloadCallback implements ICloudDownloadCallback */ public static final String PARAM_PACKAGE = "package"; - /** - * listeners to inform after installation is completed. - * @param aDownloadEventListeners the listeners - */ - public void setDownloadEventListeners(ArrayList aDownloadEventListeners) - { - downloadEventListeners.clear(); - downloadEventListeners.addAll(aDownloadEventListeners); - } - /** * Keyboard meta data. * @param aKeyboardInfo the keyboard @@ -121,7 +110,8 @@ public class CloudKeyboardDataDownloadCallback implements ICloudDownloadCallback if(keyboardInfo!=null) { - KeyboardEventHandler.notifyListeners(downloadEventListeners, KeyboardEventHandler.EventType.KEYBOARD_DOWNLOAD_FINISHED, + KeyboardEventHandler.notifyListeners(KMKeyboardDownloaderActivity.getKbDownloadEventListeners(), + KeyboardEventHandler.EventType.KEYBOARD_DOWNLOAD_FINISHED, keyboardInfo, aCloudResult.kbdResult); } } diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudKeyboardDownloadReturns.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/impl/CloudKeyboardDownloadReturns.java similarity index 92% rename from android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudKeyboardDownloadReturns.java rename to android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/impl/CloudKeyboardDownloadReturns.java index 8aaaa21d84..4801b01583 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudKeyboardDownloadReturns.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/impl/CloudKeyboardDownloadReturns.java @@ -1,4 +1,4 @@ -package com.tavultesoft.kmea.data; +package com.tavultesoft.kmea.cloud.impl; import java.util.List; import java.util.Map; diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudKeyboardMetaDataDownloadCallback.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/impl/CloudKeyboardMetaDataDownloadCallback.java similarity index 93% rename from android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudKeyboardMetaDataDownloadCallback.java rename to android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/impl/CloudKeyboardMetaDataDownloadCallback.java index 6971be7bb3..07c7fb5f9c 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudKeyboardMetaDataDownloadCallback.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/impl/CloudKeyboardMetaDataDownloadCallback.java @@ -1,4 +1,4 @@ -package com.tavultesoft.kmea.data; +package com.tavultesoft.kmea.cloud.impl; import android.content.Context; import android.util.Log; @@ -8,6 +8,10 @@ import com.tavultesoft.kmea.KMKeyboardDownloaderActivity; import com.tavultesoft.kmea.KMManager; import com.tavultesoft.kmea.KeyboardEventHandler; import com.tavultesoft.kmea.R; +import com.tavultesoft.kmea.cloud.CloudApiTypes; +import com.tavultesoft.kmea.cloud.CloudDataJsonUtil; +import com.tavultesoft.kmea.cloud.CloudDownloadMgr; +import com.tavultesoft.kmea.cloud.ICloudDownloadCallback; import com.tavultesoft.kmea.util.FileUtils; import org.json.JSONArray; @@ -27,7 +31,7 @@ public class CloudKeyboardMetaDataDownloadCallback implements ICloudDownloadCall /** * the metadata result and all necessary downloads which should be started. */ - public static class MetaDataResult + static class MetaDataResult { CloudApiTypes.CloudApiReturns returnjson; CloudApiTypes.CloudApiParam params; @@ -38,8 +42,6 @@ public class CloudKeyboardMetaDataDownloadCallback implements ICloudDownloadCall private static final String TAG = "CloudKeyboardMetaDldCb"; - private ArrayList downloadEventListeners = new ArrayList<>(); - /** * Additional Cloud API parameter: Is custom keyboard. */ @@ -53,14 +55,7 @@ public class CloudKeyboardMetaDataDownloadCallback implements ICloudDownloadCall */ public static final String PARAM_KB_ID = "kb_id"; - /** - * Listeners to notify about starting the data download. - * @param aDownloadEventListeners - */ - public void setDownloadEventListeners(ArrayList aDownloadEventListeners) { - downloadEventListeners.clear(); - downloadEventListeners.addAll(aDownloadEventListeners); - } + @Override public void initializeContext(Context context) { @@ -118,7 +113,6 @@ public class CloudKeyboardMetaDataDownloadCallback implements ICloudDownloadCall if(_r.returnjson.target== CloudApiTypes.ApiTarget.Keyboard) { CloudKeyboardDataDownloadCallback _callback = new CloudKeyboardDataDownloadCallback(); - _callback.setDownloadEventListeners(downloadEventListeners); _callback.setKeyboardInfo(_r.keyboardInfo); if( CloudDownloadMgr.getInstance().alreadyDownloadingData(_r.additionalDownloadid)) @@ -126,7 +120,8 @@ public class CloudKeyboardMetaDataDownloadCallback implements ICloudDownloadCall continue; } - KeyboardEventHandler.notifyListeners(downloadEventListeners, + KeyboardEventHandler.notifyListeners( + KMKeyboardDownloaderActivity.getKbDownloadEventListeners(), KeyboardEventHandler.EventType.KEYBOARD_DOWNLOAD_STARTED, _r.keyboardInfo, 0); CloudDownloadMgr.getInstance().executeAsDownload(aContext, _r.additionalDownloadid, null, _callback, @@ -142,7 +137,6 @@ public class CloudKeyboardMetaDataDownloadCallback implements ICloudDownloadCall continue; } CloudLexicalPackageDownloadCallback _callback = new CloudLexicalPackageDownloadCallback(); - _callback.setDownloadEventListeners(downloadEventListeners); Toast.makeText(aContext, aContext.getString(R.string.dictionary_download_start_in_background), @@ -266,11 +260,12 @@ public class CloudKeyboardMetaDataDownloadCallback implements ICloudDownloadCall } if (oskFontUrls != null) { for (String url : oskFontUrls) { - if (!urls.contains(url)) + if (fontUrls==null || ! fontUrls.contains(url)) { urls.add(new CloudApiTypes.CloudApiParam(CloudApiTypes.ApiTarget.KeyboardData, url) .setAdditionalProperty( CloudKeyboardDataDownloadCallback.PARAM_PACKAGE, _pkgID)); - ; + } + } } diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudLexicalPackageDownloadCallback.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/impl/CloudLexicalPackageDownloadCallback.java similarity index 80% rename from android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudLexicalPackageDownloadCallback.java rename to android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/impl/CloudLexicalPackageDownloadCallback.java index 91106ad61a..71ef0f4e3d 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudLexicalPackageDownloadCallback.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/cloud/impl/CloudLexicalPackageDownloadCallback.java @@ -1,13 +1,14 @@ -package com.tavultesoft.kmea.data; +package com.tavultesoft.kmea.cloud.impl; import android.content.Context; import android.util.Log; import android.widget.Toast; -import androidx.appcompat.app.AppCompatActivity; - +import com.tavultesoft.kmea.KMKeyboardDownloaderActivity; import com.tavultesoft.kmea.KeyboardEventHandler; import com.tavultesoft.kmea.R; +import com.tavultesoft.kmea.cloud.CloudApiTypes; +import com.tavultesoft.kmea.cloud.ICloudDownloadCallback; import com.tavultesoft.kmea.packages.LexicalModelPackageProcessor; import com.tavultesoft.kmea.packages.PackageProcessor; import com.tavultesoft.kmea.util.FileUtils; @@ -16,14 +17,10 @@ import org.json.JSONException; import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; -import static com.tavultesoft.kmea.KMManager.KMDefault_UndefinedPackageID; - /** * Install lexical model. */ @@ -36,18 +33,6 @@ public class CloudLexicalPackageDownloadCallback implements ICloudDownloadCallba private File resourceRoot; private File cacheDir; - private ArrayList downloadEventListeners = new ArrayList<>(); - - /** - * listeners to inform after installation is completed. - * @param aDownloadEventListeners the listeners - */ - public void setDownloadEventListeners(ArrayList aDownloadEventListeners) - { - downloadEventListeners.clear(); - downloadEventListeners.addAll(aDownloadEventListeners); - } - @Override public void initializeContext(Context context) { @@ -108,7 +93,8 @@ public class CloudLexicalPackageDownloadCallback implements ICloudDownloadCallba if(aCloudResult.installedLexicalModels != null) { - KeyboardEventHandler.notifyListeners(downloadEventListeners, KeyboardEventHandler.EventType.LEXICAL_MODEL_INSTALLED, + KeyboardEventHandler.notifyListeners(KMKeyboardDownloaderActivity.getKbDownloadEventListeners(), + KeyboardEventHandler.EventType.LEXICAL_MODEL_INSTALLED, aCloudResult.installedLexicalModels, aCloudResult.kbdResult); } } diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudCatalogDownloadTask.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudCatalogDownloadTask.java deleted file mode 100644 index 98b50f4119..0000000000 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudCatalogDownloadTask.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.tavultesoft.kmea.data; - -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.os.AsyncTask; -import android.os.Build; -import android.util.Log; - -import androidx.appcompat.app.AppCompatActivity; - -import com.tavultesoft.kmea.JSONParser; -import com.tavultesoft.kmea.KMManager; - -import com.tavultesoft.kmea.R; - -import org.json.JSONArray; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.List; - -class CloudCatalogDownloadTask extends AsyncTask { - - private static final String TAG = "CloudCatDownloadTask"; - - private final boolean hasConnection; - private ProgressDialog progressDialog; - - private final Context context; - - private final Dataset dataset; - - private final CloudCatalogDownloadCallback callback; - - - - public CloudCatalogDownloadTask(Context context, Dataset dataset, CloudCatalogDownloadCallback aCallback) { - this.context = context; - this.dataset = dataset; - - this.hasConnection = KMManager.hasConnection(context); - - - callback = aCallback; - } - - protected void showProgressDialog(final Runnable finishCallback) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - progressDialog = new ProgressDialog(context, R.style.AppTheme_Dialog_Progress); - } else { - progressDialog = new ProgressDialog(context); - } - progressDialog.setMessage(context.getString(R.string.getting_cloud_catalog)); - progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.label_cancel), - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialogInterface, int which) { - cancel(true); - progressDialog.dismiss(); - progressDialog = null; - if (finishCallback != null) { - finishCallback.run(); - } - return; - } - }); - progressDialog.setCancelable(true); - if (!((AppCompatActivity) context).isFinishing()) { - progressDialog.show(); - } else { - cancel(true); - progressDialog = null; - } - } - - @Override - protected void onPreExecute() { - super.onPreExecute(); - - if (hasConnection) { - showProgressDialog(new Runnable() { - @Override - public void run() { // runs on 'cancel' selection. - callback.handleDownloadError(); - } - }); - } - } - - @Override - protected CloudCatalogDownloadReturns doInBackground(CloudApiTypes.CloudApiParam... params) { - if (isCancelled()) { - return null; - } - - List retrievedJSON = new ArrayList<>(params.length); - if (progressDialog != null) { - progressDialog.setMax(params.length); - } - - for (CloudApiTypes.CloudApiParam param : params) { - JSONParser jsonParser = new JSONParser(); - JSONArray dataArray = null; - JSONObject dataObject = null; - - if (hasConnection) { - try { - String remoteUrl = param.url; - - if (param.type == CloudApiTypes.JSONType.Array) { - dataArray = jsonParser.getJSONObjectFromUrl(remoteUrl, JSONArray.class); - } else { - dataObject = jsonParser.getJSONObjectFromUrl(remoteUrl, JSONObject.class); - } - } catch (Exception e) { - Log.d(TAG, e.getMessage()); - } - } else { - // Offline trouble! That said, we can't get anything, so we simply shouldn't add anything. - } - - if (param.type == CloudApiTypes.JSONType.Array) { - retrievedJSON.add(new CloudApiTypes.CloudApiReturns(param.target, dataArray)); // Null if offline. - } else { - retrievedJSON.add(new CloudApiTypes.CloudApiReturns(param.target, dataObject)); // Null if offline. - } - if (progressDialog != null) { - progressDialog.setProgress(progressDialog.getProgress()); - } - } - - return new CloudCatalogDownloadReturns(retrievedJSON); // Will report empty arrays/objects if offline. - } - - - - @Override - protected void onPostExecute(CloudCatalogDownloadReturns jsonTuple) { - - callback.saveDataToCache(jsonTuple); - - if (progressDialog != null && progressDialog.isShowing()) { - try { - progressDialog.dismiss(); - progressDialog = null; - } catch (Exception e) { - progressDialog = null; - } - } - - callback.ensureInitCloudReturn(context,dataset,jsonTuple); - - callback.processCloudReturns(dataset,jsonTuple, true); - } - - - - -} \ No newline at end of file diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudRepository.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudRepository.java index dc843a7281..c4dc76bb8d 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudRepository.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/data/CloudRepository.java @@ -12,6 +12,11 @@ import com.tavultesoft.kmea.KMKeyboardDownloaderActivity; import com.tavultesoft.kmea.KMManager; import com.tavultesoft.kmea.KeyboardPickerActivity; import com.tavultesoft.kmea.R; +import com.tavultesoft.kmea.cloud.CloudApiTypes; +import com.tavultesoft.kmea.cloud.impl.CloudCatalogDownloadCallback; +import com.tavultesoft.kmea.cloud.impl.CloudCatalogDownloadReturns; +import com.tavultesoft.kmea.cloud.CloudDataJsonUtil; +import com.tavultesoft.kmea.cloud.CloudDownloadMgr; import com.tavultesoft.kmea.packages.JSONUtils; import org.json.JSONArray; @@ -28,9 +33,6 @@ public class CloudRepository { static public final CloudRepository shared = new CloudRepository(); private static final String TAG = "CloudRepository"; - //TODO: Should be removed with the old implementation when downloadmanager impl works - public static final boolean USE_DOWNLOAD_MANAGER = true; - public static final String DOWNLOAD_IDENTIFIER_CATALOGUE = "catalogue"; private Dataset memCachedDataset; @@ -165,8 +167,7 @@ public class CloudRepository { { preCacheDataSet(context,updateHandler,onSuccess,onFailure); - if(USE_DOWNLOAD_MANAGER) - downloadMetaDataFromServer(context,updateHandler,onSuccess,onFailure); + downloadMetaDataFromServer(context,updateHandler,onSuccess,onFailure); } /** @@ -292,7 +293,7 @@ public class CloudRepository { preCacheDataSet(context,null,null,null); - if(USE_DOWNLOAD_MANAGER && CloudDownloadMgr.getInstance().alreadyDownloadingData(DOWNLOAD_IDENTIFIER_CATALOGUE)) { + if(CloudDownloadMgr.getInstance().alreadyDownloadingData(DOWNLOAD_IDENTIFIER_CATALOGUE)) { String msg = context.getString(R.string.catalog_download_is_running_in_background); Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); } @@ -307,7 +308,6 @@ public class CloudRepository { * @param updateHandler An object that can handle update notification if desired. * @param onSuccess A callback to be triggered on completion of all queries and operations. * @param onFailure A callback to be triggered upon failure of a query. - * @return A Dataset object implementing the Adapter interface to be asynchronously filled. */ private void downloadMetaDataFromServer(@NonNull Context context, UpdateHandler updateHandler, Runnable onSuccess, Runnable onFailure) { boolean loadKeyboardsFromCache = this.shouldUseCache(context, CloudDataJsonUtil.getKeyboardCacheFile(context)); @@ -355,23 +355,15 @@ public class CloudRepository { // We need the array to be exactly the same size as our entry count. CloudApiTypes.CloudApiParam[] params = new CloudApiTypes.CloudApiParam[cloudQueryEntries]; cloudQueries.toArray(params); - if (USE_DOWNLOAD_MANAGER) { - if (CloudDownloadMgr.getInstance().alreadyDownloadingData(DOWNLOAD_IDENTIFIER_CATALOGUE)) { - String msg = context.getString(R.string.catalog_download_is_running_in_background); - Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); - } else { - String msg = context.getString(R.string.catalog_download_start_in_background); - Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); - CloudDownloadMgr.getInstance().executeAsDownload( - context, DOWNLOAD_IDENTIFIER_CATALOGUE, memCachedDataset, _download_callback, params); - } - + if (CloudDownloadMgr.getInstance().alreadyDownloadingData(DOWNLOAD_IDENTIFIER_CATALOGUE)) { + String msg = context.getString(R.string.catalog_download_is_running_in_background); + Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); } else { - CloudCatalogDownloadTask downloadTask = new CloudCatalogDownloadTask(context, memCachedDataset, _download_callback); - - // We can pass in multiple URLs; this format is extensible if we need extra catalogs in the future. - downloadTask.execute(params); + String msg = context.getString(R.string.catalog_download_start_in_background); + Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); + CloudDownloadMgr.getInstance().executeAsDownload( + context, DOWNLOAD_IDENTIFIER_CATALOGUE, memCachedDataset, _download_callback, params); } } } diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/packages/JSONUtils.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/packages/JSONUtils.java index e7aca31936..1f93ea8282 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/packages/JSONUtils.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/packages/JSONUtils.java @@ -121,8 +121,8 @@ public class JSONUtils { /** * Iterate through a JSONArray to determine if a language/keyboard/model ID exists. - * @param {a} JSONArray to search - * @param {id} String of the language/keyboard ID + * @param a JSONArray to search + * @param id String of the language/keyboard ID * @return int - Index if the ID is found (starting with 0). -1 if the ID doesn't exist */ public static int findID(JSONArray a, String id) { @@ -171,7 +171,7 @@ public class JSONUtils { /** * Mirror options information that comes from keyboard cloud catalog - * @param String deviceType + * @param deviceType * @return JSONObject */ public static JSONObject defaultOptions(String deviceType) { diff --git a/android/history.md b/android/history.md index 9d80655bec..b231893425 100644 --- a/android/history.md +++ b/android/history.md @@ -3,7 +3,7 @@ ## 13.0 alpha * Start version 13.0 * New Features: - * Adding a download manager to execute downloads in background (#2247,#2275) + * Adding a download manager to execute downloads in background and cleanup the existing implementation (#2247, #2275, #2308) * Improve custom package installation: Show readme.htm before starting installation process (#2286) * Update target Android SDK version to 29 (#2279) * Add linting to Debug builds and resolve lint errors (#2305)