diff --git a/android/.gitignore b/android/.gitignore
index a502ae727d..25aee8957a 100644
--- a/android/.gitignore
+++ b/android/.gitignore
@@ -31,8 +31,15 @@ gradle_models.ser
**/keyman-engine.aar
# keymanweb dependencies
-KMEA/app/src/main/assets/
-KMAPro/assets/keyman.js
+KMEA/**/assets/ajax-loader.gif
+KMEA/**/assets/keymanandroid.js
+KMEA/**/assets/keyman.js.map
+KMEA/**/assets/keyman-sentry.js
+KMEA/**/assets/kmwosk.css
+KMEA/**/assets/resources
+
+# keymanweb OSK font
+KMEA/**/assets/keymanweb-osk.*
# KMAPRo default packages
KMAPro/**/assets/*.kmp
diff --git a/android/KMAPro/build.gradle b/android/KMAPro/build.gradle
index afcdfe36c0..c4bd1bb49a 100644
--- a/android/KMAPro/build.gradle
+++ b/android/KMAPro/build.gradle
@@ -7,7 +7,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.2'
- classpath 'io.sentry:sentry-android-gradle-plugin:1.7.35'
+ classpath 'io.sentry:sentry-android-gradle-plugin:1.7.36'
classpath 'name.remal:gradle-plugins:1.0.157'
classpath 'com.stepstone.stepper:material-stepper:4.3.1'
}
diff --git a/android/KMAPro/build.sh b/android/KMAPro/build.sh
index 18982a7c10..6a46d2f399 100755
--- a/android/KMAPro/build.sh
+++ b/android/KMAPro/build.sh
@@ -29,15 +29,27 @@ display_usage ( ) {
echo
echo "Build Keyman for Android"
echo " -no-daemon Don't start the Gradle daemon. Use for CI"
+ echo " -upload-sentry Uploads debug symbols, etc, to Sentry"
echo " -debug Compile only Debug variant"
echo " -download-resources Download sil_euro_latin.kmp and nrc.en.mtnt.model.kmp from downloads.keyman.com"
exit 1
}
+function makeLocalSentryRelease() {
+ local SENTRY_RELEASE_VERSION="release-$VERSION_WITH_TAG"
+ echo "Making a Sentry release for tag $SENTRY_RELEASE_VERSION"
+ sentry-cli upload-dif -p keyman-android --include-sources
+ sentry-cli releases -p keyman-android files $SENTRY_RELEASE_VERSION upload-sourcemaps ./
+
+ echo "Finalizing release tag $SENTRY_RELEASE_VERSION"
+ sentry-cli releases finalize "$SENTRY_RELEASE_VERSION"
+}
+
NO_DAEMON=false
ONLY_DEBUG=false
DO_KEYBOARDS_DOWNLOAD=false
DO_MODELS_DOWNLOAD=false
+DO_SENTRY_LOCAL_UPLOAD=false
# Parse args
while [[ $# -gt 0 ]] ; do
@@ -46,6 +58,10 @@ while [[ $# -gt 0 ]] ; do
-no-daemon)
NO_DAEMON=true
;;
+ -upload-sentry)
+ # Overrides default set by build-utils.sh
+ UPLOAD_SENTRY=true
+ ;;
-debug)
ONLY_DEBUG=true
;;
@@ -76,11 +92,17 @@ if [[ ! -f "$MODELS_TARGET" ]]; then
DO_MODELS_DOWNLOAD=true
fi
+# Local development optimization to upload local symbols to Sentry
+if [[ $VERSION_ENVIRONMENT == "local" && $ONLY_DEBUG == true && $UPLOAD_SENTRY == true ]]; then
+ DO_SENTRY_LOCAL_UPLOAD=true
+fi
+
echo
echo "NO_DAEMON: $NO_DAEMON"
echo "ONLY_DEBUG: $ONLY_DEBUG"
echo "DO_KEYBOARDS_DOWNLOAD: $DO_KEYBOARDS_DOWNLOAD"
echo "DO_MODELS_DOWNLOAD: $DO_MODELS_DOWNLOAD"
+echo "DO_SENTRY_LOCAL_UPLOAD: $DO_SENTRY_LOCAL_UPLOAD"
echo
if [ "$NO_DAEMON" = true ]; then
@@ -108,3 +130,7 @@ fi
echo "BUILD_FLAGS $BUILD_FLAGS"
./gradlew $DAEMON_FLAG clean $BUILD_FLAGS
+
+if [ "$DO_SENTRY_LOCAL_UPLOAD" = true ]; then
+ makeLocalSentryRelease
+fi
\ No newline at end of file
diff --git a/android/KMAPro/kMAPro/build.gradle b/android/KMAPro/kMAPro/build.gradle
index 07db128246..30a19cf94d 100644
--- a/android/KMAPro/kMAPro/build.gradle
+++ b/android/KMAPro/kMAPro/build.gradle
@@ -123,7 +123,7 @@ dependencies {
implementation 'com.google.android.material:material:1.2.1'
implementation 'com.stepstone.stepper:material-stepper:4.3.1'
api(name: 'keyman-engine', ext: 'aar')
- implementation 'io.sentry:sentry-android:2.3.0'
+ implementation 'io.sentry:sentry-android:3.1.0'
implementation 'androidx.preference:preference:1.1.1'
// Add dependency for generating QR Codes
diff --git a/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java b/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java
index 1f0e0ed694..4a3dbd843a 100644
--- a/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java
+++ b/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java
@@ -29,7 +29,7 @@ import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import io.sentry.android.core.SentryAndroid;
-import io.sentry.core.Sentry;
+import io.sentry.Sentry;
public class SystemKeyboard extends InputMethodService implements OnKeyboardEventListener {
diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KeymanSettingsActivity.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KeymanSettingsActivity.java
index e7d4543059..b681fff7e0 100644
--- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KeymanSettingsActivity.java
+++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KeymanSettingsActivity.java
@@ -9,6 +9,7 @@ public class KeymanSettingsActivity extends AppCompatActivity {
protected static final String installedLanguagesKey = "InstalledLanguages";
protected static final String installKeyboardOrDictionaryKey = "InstallKeyboardOrDictionary";
protected static final String showBannerKey = "ShowBanner";
+ protected static final String sendCrashReport = "SendCrashReport";
protected KeymanSettingsFragment innerFragment;
diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KeymanSettingsFragment.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KeymanSettingsFragment.java
index c08b4cd85a..fa15d4c1b9 100644
--- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KeymanSettingsFragment.java
+++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KeymanSettingsFragment.java
@@ -61,9 +61,15 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
SwitchPreference getStartedPreference = new SwitchPreference(context);
getStartedPreference.setKey(GetStartedActivity.showGetStartedKey);
getStartedPreference.setTitle(String.format(getString(R.string.show_get_started), getString(R.string.get_started)));
-
getStartedPreference.setDefaultValue(true);
+ SwitchPreference sendCrashReportPreference = new SwitchPreference(context);
+ sendCrashReportPreference.setKey(KeymanSettingsActivity.sendCrashReport);
+ sendCrashReportPreference.setTitle(getString(R.string.show_send_crash_report));
+ sendCrashReportPreference.setSummaryOn(getString(R.string.show_send_crash_report_on));
+ sendCrashReportPreference.setSummaryOff(getString(R.string.show_send_crash_report_off));
+ sendCrashReportPreference.setDefaultValue(true);
+
// Blocks the default checkmark interaction; we want to control the checkmark's state separately
// from within update() based on if the user has taken the appropriate actions with the OS.
final Preference.OnPreferenceChangeListener checkBlocker = new Preference.OnPreferenceChangeListener() {
@@ -106,6 +112,7 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
screen.addPreference(bannerPreference);
screen.addPreference(getStartedPreference);
+ screen.addPreference(sendCrashReportPreference);
setPreferenceScreen(screen);
}
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 e7220b41b4..22ef98e40f 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
@@ -91,7 +91,6 @@ import android.widget.TextView;
import android.widget.Toast;
import io.sentry.android.core.SentryAndroid;
-import io.sentry.core.Sentry;
public class MainActivity extends AppCompatActivity implements OnKeyboardEventListener, OnKeyboardDownloadEventListener,
ActivityCompat.OnRequestPermissionsResultCallback {
@@ -127,10 +126,13 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
super.onCreate(savedInstanceState);
context = this;
- SentryAndroid.init(context, options -> {
- options.setRelease("release-"+com.tavultesoft.kmapro.BuildConfig.VERSION_NAME);
- options.setEnvironment(com.tavultesoft.kmapro.BuildConfig.VERSION_ENVIRONMENT);
- });
+ checkSendCrashReport();
+ if (KMManager.getMaySendCrashReport()) {
+ SentryAndroid.init(context, options -> {
+ options.setRelease("release-" + com.tavultesoft.kmapro.BuildConfig.VERSION_NAME);
+ options.setEnvironment(com.tavultesoft.kmapro.BuildConfig.VERSION_ENVIRONMENT);
+ });
+ }
checkStoragePermission(null);
resultReceiver = new DownloadResultReceiver(new Handler(), context);
@@ -744,6 +746,12 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
}
}
+ private void checkSendCrashReport() {
+ SharedPreferences prefs = getSharedPreferences(getString(R.string.kma_prefs_name), Context.MODE_PRIVATE);
+ boolean maySendCrashReport = prefs.getBoolean(KeymanSettingsActivity.sendCrashReport, true);
+ KMManager.setMaySendCrashReport(maySendCrashReport);
+ }
+
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
diff --git a/android/KMAPro/kMAPro/src/main/res/values/strings.xml b/android/KMAPro/kMAPro/src/main/res/values/strings.xml
index 06edc95a94..5bf53e6b65 100644
--- a/android/KMAPro/kMAPro/src/main/res/values/strings.xml
+++ b/android/KMAPro/kMAPro/src/main/res/values/strings.xml
@@ -96,6 +96,14 @@