Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(android/engine): Parse keyboards.json for FirstVoices app #11943

Merged
merged 7 commits into from
Aug 8, 2024

Conversation

darcywong00
Copy link
Contributor

@darcywong00 darcywong00 commented Jul 9, 2024

Relates to #2036

This PR migrates the FirstVoices for Android app from using keyboards.csv to using the keyboards.json metadata file published within fv_all.kmp (as of keymanapp/keyboards#2872)

All the keyboard info along with region names are included in keyboards.json, so startup is just a matter of populating the keyboard info from it.

Note: I'm leaving keyboards.csv in the repo because the FirstVoices app for iOS still uses it.

User Testing

Setup - Install the PR build of FirstVoices for Android on an Android device/emulator

  • TEST_FV_ANDROID - Verifies the FirstVoices for Android app runs
  1. Launch the FirstVoices for Android app
  2. From the main FV Setup menu
  • Select keyboards --> Select a region --> select a keyboard --> Enable the keyboard
  • Setup --> enable FirstVoices and set as the current input method
  1. Launch Chrome browser and select a text area
  2. Select FirstVoices as system keyboard
  3. Verify the installed keyboard displays and functions

@keymanapp-test-bot keymanapp-test-bot bot added has-user-test user-test-required User tests have not been completed labels Jul 9, 2024
@keymanapp-test-bot
Copy link

keymanapp-test-bot bot commented Jul 9, 2024

User Test Results

Test specification and instructions

  • TEST_FV_ANDROID (PASSED): I tested this issue with the attached "FirstVoices-18.0.81-alpha-test-11943" build on the Android 14(Physical Device) environment: Here is my observation. (notes)

Test Artifacts

@darcywong00
Copy link
Contributor Author

I note the keyboard names now come straight from the individual keyboard kmn store(&NAME), so they'll vary slightly from existing keyboard names in the keyboards.csv column.

@dinakaranr
Copy link

Test Results

  • TEST_FV_ANDROID (Passed): I tested this issue with the attached "FirstVoices-18.0.71-alpha-test-11943" build on the Android 12(emulator) and 14(Physical Device) environment: Here is my observation.
  1. Install the FirstVoices for Android app
  2. Open the FirstVoice app.
  3. Select keyboards --> Select a region --> Select a keyboard --> Enable the keyboard
  4. Setup --> Enable FirstVoices and set as the current input method
  5. Launch the Chrome browser.
  6. Open the Google Docs or Google search box.
  7. Select FirstVoices as the system keyboard
  8. Type some text sentences using the FirstVoice keyboard.
    Actual Results: The first Voice keyboard was installed successfully and performed with any text area in the Chrome browser.

@keymanapp-test-bot keymanapp-test-bot bot removed the user-test-required User tests have not been completed label Jul 10, 2024
@darcywong00 darcywong00 modified the milestones: A18S6, A18S7 Jul 19, 2024
Copy link
Member

@mcdurdin mcdurdin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the way this is going. But I think we need to have better error handling and a unit test for the new function.

https://keyman.sentry.io/issues/?project=5983532&statsPeriod=90d shows that we are collecting Sentry data for FV Keyboards (this report needs auditing by the way), so let's leverage that in this function as well -- let exceptions propagate to Sentry.

Comment on lines 137 to 139
if (!jsonFile.exists()) {
return list;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it should be fatal because if this cannot be loaded, we don't get any data for the keyboards, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to throw fatal Error if keyboards.json doesn't exist

Comment on lines 145 to 148
if (keyboardsArray == null) {
Log.d("loadRegionList", "unable to load keyboards.json");
return list;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Malformed data should at the very least be reporting to sentry, or killing the app so we know that there is something wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the following to use KMLog to sentry.

Are you wanting to throw fatal errors for all of them?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you wanting to throw fatal errors for all of them?

I think so -- if our keyboards.json is invalid, we should reject the build at startup.

Comment on lines 152 to 160
if (keyboardObj == null) {
Log.d("loadRegionList", "keyboard Obj is null");
continue;
}
JSONArray languageArray = keyboardObj.getJSONArray("languages");
if (languageArray == null) {
Log.d("loadRegionList", "language Array is null");
continue;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Comment on lines 133 to 134
File resourceRoot = new File(getResourceRoot());
PackageProcessor kmpProcessor = new PackageProcessor(resourceRoot);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to be used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch. removed

File resourceRoot = new File(getResourceRoot());
PackageProcessor kmpProcessor = new PackageProcessor(resourceRoot);
JSONParser parser = new JSONParser();
File jsonFile = new File(getPackagesDir() + FVDefault_PackageID + File.separator + FVKeyboards_JSON);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we pass this path in as a parameter, then we could add a unit test for this quite easily I think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could add the keyboards.json path as a parameter to loadRegionList().

I don't think the FV project is running any unit tests, so I'd have to add some plumbing for that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could add the keyboards.json path as a parameter to loadRegionList().

Good stuff.

I don't think the FV project is running any unit tests, so I'd have to add some plumbing for that.

Yep, future project :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, future project :)

Tracked as #12098

Comment on lines 195 to 198
} catch (Exception e) {
Log.e("createKeyboardList", "Error: " + e);
// We'll return a malformed list for now in this situation
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be crashing the app so we can detect this -- a malformed list will make the app unusable anyway, won't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block was pre-existing.
I've updated to throw fatal error

Comment on lines +52 to -61
if (BuildConfig.DEBUG) {
KMManager.setDebugMode(true);
}
KMManager.initialize(getApplicationContext(), KMManager.KeyboardType.KEYBOARD_TYPE_INAPP);

FVShared.getInstance().initialize(this);

FVShared.getInstance().upgradeTo12();
FVShared.getInstance().upgradeTo14();
FVShared.getInstance().preloadPackages();

if (BuildConfig.DEBUG) {
KMManager.setDebugMode(true);
}
KMManager.initialize(getApplicationContext(), KMManager.KeyboardType.KEYBOARD_TYPE_INAPP);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this change in initialization order cause problems for upgrade scenarios?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure - atm I don't have a clear way to test upgrade scenarios.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the purpose of changing the order? Was it needed for the load?

Re testing upgrade scenarios, can't we just get user testers to install an old version of say 12.x or 14.x and then upgrade it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously, KMManager.initialize() hasn't happened yet, so the fv_all.kmp file hasn't been extracted.
This is why we've been copying keyboards.csv into the assets folder during the build.sh process (at the same folder as fv_all.kmp).

@github-actions github-actions bot added android/ and removed android/ labels Aug 2, 2024
@darcywong00 darcywong00 modified the milestones: A18S7, A18S8 Aug 2, 2024
@github-actions github-actions bot added android/ and removed android/ labels Aug 5, 2024
Copy link
Member

@mcdurdin mcdurdin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small change requested but apart from that LGTM

String errorMsg = "loadRegionList had malformed keyboard list";
KMLog.LogException(TAG, errorMsg, e);
// Crash the app
throw new Error(errorMsg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an antipattern -- masking the original error in the thrown exception. Should re-throw e.

@github-actions github-actions bot added android/ and removed android/ labels Aug 6, 2024
@darcywong00
Copy link
Contributor Author

After cleanup, ready for re-testing
@keymanapp-test-bot retest

@keymanapp-test-bot keymanapp-test-bot bot added the user-test-required User tests have not been completed label Aug 6, 2024
@dinakaranr
Copy link

Test Results

  • TEST_FV_ANDROID (Passed): I tested this issue with the attached "FirstVoices-18.0.81-alpha-test-11943" build on the Android 14(Physical Device) environment: Here is my observation.
  1. Install the FirstVoices for Android app.
  2. Open the FirstVoice app.
  3. Select keyboards --> Select a region --> Select a keyboard --> Enable the keyboard.
  4. Setup --> Enable FirstVoices and set as the current input method.
  5. Launch the Chrome browser.
  6. Open the Google Docs or Google search box.
  7. FirstVoices appears as the system keyboard.
  8. Type some text sentences using the FirstVoice keyboard.
    Actual Results: The first voice keyboard was installed successfully. Text appears in the search box using the firstvoice/keyboard. Online editor(editpad.org): Text appears using the firstvoice/keyboard.
    It works well. Thank you.

@keymanapp-test-bot keymanapp-test-bot bot removed the user-test-required User tests have not been completed label Aug 7, 2024
@darcywong00 darcywong00 merged commit 464c6f9 into master Aug 8, 2024
5 checks passed
@darcywong00 darcywong00 deleted the fv-all/keyboards-json branch August 8, 2024 00:44
@keyman-server
Copy link
Collaborator

Changes in this pull request will be available for download in Keyman version 18.0.85-alpha

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants