diff --git a/app/acra.properties.sample b/app/acra.properties.sample deleted file mode 100644 index c0c912f..0000000 --- a/app/acra.properties.sample +++ /dev/null @@ -1,3 +0,0 @@ -url=ACRA_URL -user=ACRA_USER -pass=ACRA_PASS diff --git a/app/build.gradle b/app/build.gradle index 118bfd2..4bec8d0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,17 +16,6 @@ try { keystoreProperties['storePassword'] = "" } -def acraProperties = new Properties() -try { - def acraPropertiesFile = project.file("acra.properties") - acraProperties.load(new FileInputStream(acraPropertiesFile)) -} catch (FileNotFoundException ignored) { - logger.warn("Unable to load ACRA properties. Error reporting won't be available") - acraProperties['url'] = "" - acraProperties['user'] = "" - acraProperties['pass'] = "" -} - android { configurations.all { resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1' @@ -38,7 +27,7 @@ android { exclude 'META-INF/LICENSE' exclude 'META-INF/DEPENDENCIES' } - compileSdkVersion 29 + compileSdkVersion 30 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 @@ -54,9 +43,6 @@ android { versionName "0.8.6" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" buildConfigField "boolean", "ENABLE_CUSTOM_CSS", "false" - buildConfigField "String", "ACRA_URL", "\"${acraProperties['url']}\"" - buildConfigField "String", "ACRA_USER", "\"${acraProperties['user']}\"" - buildConfigField "String", "ACRA_PASS", "\"${acraProperties['pass']}\"" } signingConfigs { release { @@ -120,7 +106,7 @@ dependencies { implementation 'androidx.preference:preference:1.1.1' implementation "androidx.fragment:fragment-ktx:1.2.5" implementation 'androidx.constraintlayout:constraintlayout:2.0.1' - implementation 'com.google.android.material:material:1.2.0' + implementation 'com.google.android.material:material:1.2.1' implementation 'androidx.legacy:legacy-support-v13:1.0.0' implementation 'com.commonsware.cwac:anddown:0.3.0' playImplementation 'com.android.billingclient:billing:3.0.0' @@ -136,10 +122,6 @@ dependencies { implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" kapt "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" implementation 'eu.crydee:syllable-counter:4.0.2' - - def acraVersion = '5.7.0' - implementation "ch.acra:acra-http:$acraVersion" - implementation "ch.acra:acra-advanced-scheduler:$acraVersion" } android.productFlavors.each { flavor -> diff --git a/app/src/free/java/com/wbrawner/simplemarkdown/utility/ReviewHelper.kt b/app/src/free/java/com/wbrawner/simplemarkdown/utility/ReviewHelper.kt index 32bf984..86bc6f5 100644 --- a/app/src/free/java/com/wbrawner/simplemarkdown/utility/ReviewHelper.kt +++ b/app/src/free/java/com/wbrawner/simplemarkdown/utility/ReviewHelper.kt @@ -1,15 +1,11 @@ package com.wbrawner.simplemarkdown.utility -import android.app.Activity -import android.content.Context -import androidx.preference.PreferenceManager -import com.google.android.play.core.review.ReviewManagerFactory -import kotlin.coroutines.resume -import kotlin.coroutines.suspendCoroutine +import android.app.Application +import android.util.Log object ReviewHelper { // No review library for F-droid, so this is a no-op - fun init(application: Application, errorHandler: ErrorHandler) { + fun init(application: Application) { Log.w("ReviewHelper", "ReviewHelper not enabled for free builds") } } \ No newline at end of file diff --git a/app/src/main/assets/Privacy Policy.md b/app/src/main/assets/Privacy Policy.md deleted file mode 100644 index aa9fb79..0000000 --- a/app/src/main/assets/Privacy Policy.md +++ /dev/null @@ -1,70 +0,0 @@ -## Privacy Policy - -First and foremost, Simple Markdown DOES NOT collect any personally identifiable information. The -internet access permission is requested primarily for retrieving images from the internet in case -you embed them in your markdown, but it also allows me to send automated error and crash reports -to myself whenever the app runs into an issue. These error reports are powered by [ACRA](https://github.com/ACRA/acra), which is -an open source error reporting solution, and are sent to a private server that only I have access -to, where it is stored for up to 90 days before being permanently deleted. These error reports are -used exclusively for fixing problems that occur while you're using the app, and contain only the -bare minimum information that I need to be able to resolve the issue. The information sent may -include: - -- the version of Android your device is running (e.g. 7.1) -- details about the version of SimpleMarkdown that you are using (Google Play version, Samsung Galaxy Apps version, FDroid version, version number, etc) -- any logs that SimpleMarkdown (but not other apps) might have created during execution -- the app identifier (com.wbrawner.simplemarkdown) -- your device's manufacturer (Samsung, Huawei, LG, etc) -- your device's model (Galaxy S8, Mate 10 pro, G7, etc) -- your device's configuration at app start and at the moment of the crash (the configuration tells me things like if you had the keyboard open, and if you were using the app in landscape or portrait mode. See the end of this privacy policy for a sample of that this might look like.) -- an estimation of the amount of available memory your device has (7353192448) -- an estimation of the amount of total memory your device has (55540875264) -- a stacktrace of the error (a stacktrace tells me which part of my code caused the error, what kind of error it was, and which parts of the code ran up to that error. See the end of this privacy policy for a sample of what this might look like.) -- any custom settings you have set within SimpleMarkdown (your default launch screen, default file directory, etc. Note that this does NOT include settings specific to your device, like whether or not you have WiFi enabled for example) -- details about which thread the crash occurred on (e.g. main, file handling, network) -- the time and date you started the app -- the time and date the crash occurred - -This information is the only information that I collect, and it's strictly used for finding and fixing issues in the code as quickly as possible. If you don't feel comfortable with this however, you are able to opt-out from the settings menu. Should you choose to opt-out of automated crash reports, I would very much appreciate it if you could contact me when you run into an issue either by email: [support@wbrawner.com](mailto:support@wbrawner.com) or by submitting an issue via the [GitHub page](https://github.com/wbrawner/SimpleMarkdown). - -### Sample data - -A sample configuration: - -``` -locale=fr_FR -hardKeyboardHidden=HARDKEYBOARDHIDDEN_YES -keyboard=KEYBOARD_NOKEYS -keyboardHidden=KEYBOARDHIDDEN_NO -fontScale=1.0 -mcc=208 -mnc=10 -navigation=NAVIGATION_TRACKBALL -navigationHidden=NAVIGATIONHIDDEN_NO -orientation=ORIENTATION_PORTRAIT -screenLayout=SCREENLAYOUT_SIZE_NORMAL+SCREENLAYOUT_LONG_YES -seq=117 -touchscreen=TOUCHSCREEN_FINGER -uiMode=UI_MODE_TYPE_NORMAL+UI_MODE_NIGHT_NO -userSetLocale=false -``` - -A sample stacktrace: - -``` -java.io.IOException: No such file or directory - at java.io.UnixFileSystem.createFileExclusively0(UnixFileSystem.java) - at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:280) - at java.io.File.createNewFile(File.java:948) - at com.wbrawner.simplemarkdown.model.MarkdownFile.save(MarkdownFile.java:152) - at com.wbrawner.simplemarkdown.presentation.MarkdownPresenterImpl.saveMarkdown(MarkdownPresenterImpl.java:120) - at com.wbrawner.simplemarkdown.presentation.MarkdownPresenterImpl.lambda$saveMarkdown$2$MarkdownPresenterImpl(MarkdownPresenterImpl.java:120) - at com.wbrawner.simplemarkdown.presentation.MarkdownPresenterImpl$$Lambda$2.run(MarkdownPresenterImpl.java) - at android.os.Handler.handleCallback(Handler.java:751) - at android.os.Handler.dispatchMessage(Handler.java:95) - at android.os.Looper.loop(Looper.java:154) - at android.app.ActivityThread.main(ActivityThread.java:6121) - at java.lang.reflect.Method.invoke(Method.java) - at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889) - at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779) -``` diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.kt b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.kt index bd4e15b..f12e4de 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/MarkdownApplication.kt @@ -1,17 +1,10 @@ package com.wbrawner.simplemarkdown import android.app.Application -import android.content.Context import android.os.StrictMode -import com.wbrawner.simplemarkdown.utility.AcraErrorHandler -import com.wbrawner.simplemarkdown.utility.ErrorHandler import com.wbrawner.simplemarkdown.utility.ReviewHelper class MarkdownApplication : Application() { - val errorHandler: ErrorHandler by lazy { - AcraErrorHandler() - } - override fun onCreate() { if (BuildConfig.DEBUG) { StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder() @@ -24,11 +17,6 @@ class MarkdownApplication : Application() { .build()) } super.onCreate() - ReviewHelper.init(this, errorHandler) - } - - override fun attachBaseContext(base: Context?) { - super.attachBaseContext(base) - errorHandler.init(this) + ReviewHelper.init(this) } } diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/utility/ErrorHandler.kt b/app/src/main/java/com/wbrawner/simplemarkdown/utility/ErrorHandler.kt deleted file mode 100644 index c91a5d1..0000000 --- a/app/src/main/java/com/wbrawner/simplemarkdown/utility/ErrorHandler.kt +++ /dev/null @@ -1,72 +0,0 @@ -package com.wbrawner.simplemarkdown.utility - -import android.app.Application -import android.app.job.JobInfo -import android.util.Log -import com.wbrawner.simplemarkdown.BuildConfig -import org.acra.ACRA -import org.acra.ReportField -import org.acra.config.CoreConfigurationBuilder -import org.acra.config.HttpSenderConfigurationBuilder -import org.acra.config.SchedulerConfigurationBuilder -import org.acra.data.StringFormat -import org.acra.sender.HttpSender - -interface ErrorHandler { - fun init(application: Application) - fun reportException(t: Throwable, message: String? = null) -} - -class AcraErrorHandler : ErrorHandler { - - override fun init(application: Application) { - if (BuildConfig.ACRA_URL.isBlank() - || BuildConfig.ACRA_USER.isBlank() - || BuildConfig.ACRA_PASS.isBlank()) { - return - } - val builder = CoreConfigurationBuilder(application) - .setBuildConfigClass(BuildConfig::class.java) - .setReportFormat(StringFormat.JSON) - .setReportContent( - ReportField.ANDROID_VERSION, - ReportField.APP_VERSION_CODE, - ReportField.APP_VERSION_NAME, - ReportField.APPLICATION_LOG, - ReportField.AVAILABLE_MEM_SIZE, - ReportField.BRAND, - ReportField.BUILD_CONFIG, - ReportField.CRASH_CONFIGURATION, - ReportField.CUSTOM_DATA, // Not currently used, but might be useful in the future - ReportField.INITIAL_CONFIGURATION, - ReportField.PACKAGE_NAME, - ReportField.PHONE_MODEL, - ReportField.SHARED_PREFERENCES, - ReportField.STACK_TRACE, - ReportField.STACK_TRACE_HASH, - ReportField.THREAD_DETAILS, - ReportField.TOTAL_MEM_SIZE, - ReportField.USER_APP_START_DATE, - ReportField.USER_CRASH_DATE - ) - builder.getPluginConfigurationBuilder(HttpSenderConfigurationBuilder::class.java) - .setUri(BuildConfig.ACRA_URL) - .setHttpMethod(HttpSender.Method.POST) - .setBasicAuthLogin(BuildConfig.ACRA_USER) - .setBasicAuthPassword(BuildConfig.ACRA_PASS) - .setEnabled(true) - builder.getPluginConfigurationBuilder(SchedulerConfigurationBuilder::class.java) - .setRequiresNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) - .setRequiresBatteryNotLow(true) - .setEnabled(true) - ACRA.init(application, builder) - } - - override fun reportException(t: Throwable, message: String?) { - @Suppress("ConstantConditionIf") - if (BuildConfig.DEBUG) { - Log.e("AcraErrorHandler", "Caught exception: $message", t) - } - ACRA.getErrorReporter().handleException(t) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/MarkdownInfoFragment.kt b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/MarkdownInfoFragment.kt index 25c888a..ef68e66 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/MarkdownInfoFragment.kt +++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/MarkdownInfoFragment.kt @@ -11,7 +11,6 @@ import androidx.appcompat.app.AppCompatDelegate import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController import androidx.navigation.ui.setupWithNavController -import com.wbrawner.simplemarkdown.MarkdownApplication import com.wbrawner.simplemarkdown.R import com.wbrawner.simplemarkdown.utility.readAssetToString import com.wbrawner.simplemarkdown.utility.toHtml @@ -61,7 +60,6 @@ class MarkdownInfoFragment : Fragment(), CoroutineScope { "UTF-8", null ) } catch (e: Exception) { - (requireActivity().application as MarkdownApplication).errorHandler.reportException(e) Toast.makeText(view.context, R.string.file_load_error, Toast.LENGTH_SHORT).show() findNavController().navigateUp() } diff --git a/app/src/play/java/com/wbrawner/simplemarkdown/utility/ReviewHelper.kt b/app/src/play/java/com/wbrawner/simplemarkdown/utility/ReviewHelper.kt index cb99524..fae79e7 100644 --- a/app/src/play/java/com/wbrawner/simplemarkdown/utility/ReviewHelper.kt +++ b/app/src/play/java/com/wbrawner/simplemarkdown/utility/ReviewHelper.kt @@ -27,7 +27,6 @@ object ReviewHelper : Application.ActivityLifecycleCallbacks { private lateinit var application: Application private lateinit var reviewManager: ReviewManager private lateinit var sharedPreferences: SharedPreferences - private lateinit var errorHandler: ErrorHandler private var currentActivity: Activity? = null private var activityCount = 0 set(value) { @@ -41,12 +40,10 @@ object ReviewHelper : Application.ActivityLifecycleCallbacks { fun init( application: Application, - errorHandler: ErrorHandler, sharedPreferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(application), reviewManager: ReviewManager = ReviewManagerFactory.create(application) ) { this.application = application - this.errorHandler = errorHandler this.sharedPreferences = sharedPreferences this.reviewManager = reviewManager if (sharedPreferences.getLong(KEY_TIME_IN_APP, 0L) == -1L) { @@ -77,7 +74,6 @@ object ReviewHelper : Application.ActivityLifecycleCallbacks { val exception = request.exception ?: RuntimeException("Failed to request review") Log.e("ReviewHelper", "Failed to prompt user for review", exception) - errorHandler.reportException(exception) return@addOnCompleteListener }