MANAGE_EXTERNAL_STORAGE is for non-Google Play builds.
Google won't let us have the permission, but there's no reason
other stores + users have to suffer this decision.
This allows a Google Play user to restore their data if they uninstall
(uninstall, then download the APK and data is available again)
* Remove MANAGE_EXTERNAL_STORAGE from the manifest if targeting `play`
Version Codes & Outcomes:
1 < Q - force storage permissions as done previously (incl. Play Store)
2 Q - Users are unsafe and need a storage migration
* MANAGE_EXTERNAL_STORAGE is unavailable
* READ/WRITE_EXTERNAL_STORAGE is unavailable
3 > Q - Non-Play-Store users need MANAGE_EXTERNAL_STORAGE (*)
4 > Q - Play Store users are unsafe and need a storage migration
If a user is starting out and may request 'safe' permissions (1) (3)
Then we keep `deckPath` as a legacy path.
1) & 3) We do not allow access to the app until they give permission
----
Storage can be re-enabled after this change via:
```
adb shell am compat disable DEFAULT_SCOPED_STORAGE com.ichi2.anki.debug
adb shell am compat disable FORCE_ENABLE_SCOPED_STORAGE com.ichi2.anki.debug
adb shell pm grant com.ichi2.anki.debug android.permission.READ_EXTERNAL_STORAGE
adb shell pm grant com.ichi2.anki.debug android.permission.WRITE_EXTERNAL_STORAGE
```
on an API 30 emulator (or a non-AOSP emulator)
Related: Issue 5304
Fixes 13051 - targetSdkVersion 30 fixes this
* Bump org.jlleitschuh.gradle:ktlint-gradle from 11.1.0 to 11.2.0 (#13265)
* Bump org.jlleitschuh.gradle:ktlint-gradle from 11.1.0 to 11.2.0
Bumps org.jlleitschuh.gradle:ktlint-gradle from 11.1.0 to 11.2.0.
---
updated-dependencies:
- dependency-name: org.jlleitschuh.gradle:ktlint-gradle
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): move ktlint rules to .editorconfig
With new syntax
----
An individual property can be enabled or disabled with a rule property.
The name of the rule property consists of the ktlint_ prefix followed
by the rule set id followed by a _ and the rule id.
> https://pinterest.github.io/ktlint/faq/#why-is-editorconfig-property-disabled_rules-deprecated-and-how-do-i-resolve-this
----
disabled_rules is deprecated:
https://pinterest.github.io/ktlint/faq/#why-is-editorconfig-property-disabled_rules-deprecated-and-how-do-i-resolve-this
ktlint-gradle v11.2.0 resolves a few issues around this
> Fixed disabled_rules set only in editorconfig in ktlint 0.46+
> Fixed disabled_rules warning when using new editorconfig syntax in ktlint 0.48+
https://github.com/JLLeitschuh/ktlint-gradle/releases/tag/v11.2.0
* lint: fix new ktlint errors
Caused when we remove the version specifier in ktlint-gradle
* Argument should be on a separate line (unless all arguments can fit a single line)
* File annotations should be separated from file contents with a blank line
* Declarations and declarations with comments should have an empty space between.
* Multiple annotations should not be placed on the same line as the annotated construct
Removed unused `KotlinCleanup` class rather than fixing lint errors
* build(deps): depend on ktlint-gradle's ktlint
Some lint indentation was reduced due to this.
Fixed it manually as I didn't like the change
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: David Allison <62114487+david-allison@users.noreply.github.com>
* autoformat squash
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: David Allison <62114487+david-allison@users.noreply.github.com>
* Bump kotlin_version from 1.7.22 to 1.8.10 (#13196)
* Bump kotlin_version from 1.7.22 to 1.8.10
Bumps `kotlin_version` from 1.7.22 to 1.8.10.
Updates `org.jetbrains.kotlin:kotlin-gradle-plugin` from 1.7.22 to 1.8.10
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.8.10/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.22...v1.8.10)
Updates `org.jetbrains.kotlin:kotlin-stdlib` from 1.7.22 to 1.8.10
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.8.10/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.22...v1.8.10)
Updates `org.jetbrains.kotlin:kotlin-test` from 1.7.22 to 1.8.10
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.8.10/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.22...v1.8.10)
Updates `org.jetbrains.kotlin:kotlin-reflect` from 1.7.22 to 1.8.10
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.8.10/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.22...v1.8.10)
Updates `org.jetbrains.kotlin:kotlin-test-junit5` from 1.7.22 to 1.8.10
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.8.10/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.22...v1.8.10)
Updates `org.jetbrains.kotlin:kotlin-test-junit` from 1.7.22 to 1.8.10
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.8.10/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.22...v1.8.10)
---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-gradle-plugin
dependency-type: direct:production
update-type: version-update:semver-minor
- dependency-name: org.jetbrains.kotlin:kotlin-stdlib
dependency-type: direct:production
update-type: version-update:semver-minor
- dependency-name: org.jetbrains.kotlin:kotlin-test
dependency-type: direct:production
update-type: version-update:semver-minor
- dependency-name: org.jetbrains.kotlin:kotlin-reflect
dependency-type: direct:production
update-type: version-update:semver-minor
- dependency-name: org.jetbrains.kotlin:kotlin-test-junit5
dependency-type: direct:production
update-type: version-update:semver-minor
- dependency-name: org.jetbrains.kotlin:kotlin-test-junit
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* Enable OptIn(ExperimentalCoroutinesApi) for project
This will eliminate all warnings related to experimental coroutines api usages in the project, with the exception of
the "api" module which was ignored. The reason for this is that the module doesn't currently use coroutines so the library(
and the annotation) isn't available which results in a warning(and a crash as all warnings are fatal) when building.
See: https://youtrack.jetbrains.com/issue/KT-28777/Using-experimental-coroutines-api-causes-unresolved-dependency
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: lukstbit <52494258+lukstbit@users.noreply.github.com>
* Bump androidx.exifinterface:exifinterface from 1.3.5 to 1.3.6
Bumps androidx.exifinterface:exifinterface from 1.3.5 to 1.3.6.
---
updated-dependencies:
- dependency-name: androidx.exifinterface:exifinterface
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* Bump androidx.browser:browser from 1.4.0 to 1.5.0
Bumps androidx.browser:browser from 1.4.0 to 1.5.0.
---
updated-dependencies:
- dependency-name: androidx.browser:browser
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* Bump sqlite-framework from 2.2.0 to 2.3.0 (#13104)
Bumps sqlite-framework from 2.2.0 to 2.3.0.
---
updated-dependencies:
- dependency-name: androidx.sqlite:sqlite-framework
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* Update database related code to match the new release parameter types
Changes in this PR:
- DatabaseChangeDecorator: update of the methods signatures according to the library types changes, safe because we went from non nullable parameter types to more permisive nullable types
- DB: went from nullable query/bindArgs parameters to non null types. Reviewed all usages of the changed methods and verified that the changes are ok. One of the methods was changed
to remove the bindArgs param(which was set to null) because they weren't used and they were breaking the type system.
- Anki2Importer: remove the null bindArgs parameter as it wasn't used and it was breaking the type system.
- Finder: replaced bindArgs parameter value with an emptyArray() if it is null to conform to the new type system(I assumed that a null value represented no bindARgs parameters).
This SHOULD be ok but is difficult to say for sure as the code building the query is complex.
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: lukstbit <52494258+lukstbit@users.noreply.github.com>
* Bump androidx.appcompat:appcompat from 1.6.0-rc01 to 1.7.0-alpha02
Bumps androidx.appcompat:appcompat from 1.6.0-rc01 to 1.7.0-alpha02.
---
updated-dependencies:
- dependency-name: androidx.appcompat:appcompat
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* fix kotlin/java compile target harmony issues
```
* What went wrong:
Execution failed for task ':lint-rules:compileTestKotlin'.
'compileTestJava' task (current target is 11) and 'compileTestKotlin' task (current target is 18) jvm target compatibility should be set to the same Java version.
Consider using JVM toolchain: https://kotl.in/gradle/jvm/toolchain
```
https://issuetracker.google.com/issues/260059413https://kotlinlang.org/docs/gradle-configure-project.html#gradle-java-toolchains-support
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: lukstbit <52494258+lukstbit@users.noreply.github.com>
Since we're moving to scoped storage, uninstalling the app will very likely
delete user data.
In Debug/Dev, we want this to impact the dev's workflow as little as possible
So we change the applicationId. This relays the expectation that a 'stable'
anki should be using 'com.ichi2.anki' and an 'unstable/dev' AnkiDroid should be
'com.ichi2.anki.debug'. A developer should have two copies of the app, each with
their own storage location.
API:
As previously, define the API permissions/authority using the applicationId:
permission: 'com.ichi2.anki.debug.permission'
authority: 'com.ichi2.anki.debug.flashcards'
androidTest needs to access 'com.ichi2.anki.debug.flashcards' and have
'com.ichi2.anki.debug.permission'.
To resolve this, if the API is built in debug mode, the constants are modified:
(api/build.gradle)
* AUTHORITY = "com.ichi2.anki.debug.flashcards"
* READ_WRITE_PERMISSION = "com.ichi2.anki.debug.permission.READ_WRITE_DATABASE"
Implementation:
High level:
* Define variables in build.gradle
* Handle modifying them via parallel-package-name.sh
Low level:
* Use 'applicationIdSuffix' for this
* Modifies '<provider android:authorities>' in AndroidManifest.xml
* Required for installation on device
* Use 'applicationId'
* Modifies '<permission android:name' in AndroidManifest.xml
* Not required - cleanup on parallel-package-name.sh
* Modifies preferences_sync.xml
* via resValue in build.gradle
* Fixes crash
Source for both: https://developer.android.com/studio/build/build-variants#build-types
applicationIdSuffix:
https://developer.android.com/reference/tools/gradle-api/7.3/com/android/build/api/dsl/ApplicationVariantDimension#applicationIdSuffix()
@string/applicationId
* syntax ref: https://stackoverflow.com/questions/27954215/changing-resvalue-in-variant
manifestPlaceholders/${applicationId}
https://developer.android.com/studio/build/manage-manifests
Learning:
> By default, the build tools also provide your app's application ID in the ${applicationId} placeholder. The value always matches the final application ID for the current build, including changes by build variants. This is useful when you want to use a unique namespace for identifiers such as an intent action, even between your build variants.
https://developer.android.com/studio/build/manage-manifests
* Fix nullability for Note.getTags()
The returned property from this method is of type Array<String>, also the property is initialiazed with non null strings.
* Fix nullability for AddContentApi.addNote()
Changed the type of tags parameter from Set<String?>? to Set<String>? because:
- it doesn't make sense to have a null tag(what would that mean)
- the method addNotes() below uses a List<Set<String>?>? so either this method is incorrect or that one
- our current code would crash with a null tag string as Utils.joinTags() uses !! to reference the string tags when
doing its work
As a future todo maybe we can change parameter to a default one seeing that the database structure for notes specifies
this column as not null(use an empty String?).
* Fix nullability for AddContentApi.addNotes()
Changed the type of parameter fieldsList from List<Array<String>?> to List<Array<String>> because:
- it doesn't make sense to have null fields for a note(it is possible?)
- it would crash as with a null fields array, Utils.joinFields would return null and we would insert null in a
non null declared column flds
* Fix nullability for AddContentApi.updateNoteTags()
Changed the type of parameter tags from Set<String?>? to Set<String> because:
- same issue with null tag strings which doesn't make sense and it would crash our code in Utils.joinTags
- the tags parameter was made non null, this is an update call so using null(which would result in no tags update)
doesn't make sense
* Fix nullability for AddContentApi.updateNoteFields()
Made the parameter type non null because this is an update call and using null would do no update so the call would be
useless(why do it?).
* Fix nullability for AddContentApi.addNewBasicModel()
Made the name non null, can the model have a null name?
* Fix nullability for AddContentApi.addNewBasic2Model()
Made name non null(can the model have null as name?)
* Fix nullability for AddContentApi.addNewCustomModel()
Made name non null (can the model have null as name?)
Also silenced a silly IDE reported issue.
* Fix nullability for AddContentApi.addNewDeck()
Made the name parameter as non null, does it make sense to have adeck with null for name?!
* Fix nullability for AddContentApi.findDuplicateNotes()
Made the keys parameter as List<String> from List<String?>. What duplicates to find for a null key?
* Remove todo about nullability in AddContentApi
This cleanup includes:
- fixing ide lint issues
- adding extra @JvmField annotations to replicate the initial static fields in java, the targets were Uris and the
projection arrays(without the annotations these would have ended in the final bytecode as private static field + getter
method)
- enabled the explicit api mode as this is a library project and I think would be a good addition going forward. I made
the violations as warnings for now( to be able to suppress them for the other api classes) and fixed them for
FlashCardContract. When we finish cleaning up the api module we should move from warning to strict.
See https://kotlinlang.org/docs/whatsnew14.html#explicit-api-mode-for-library-authors
This included specifying the visibility modifiers and the actual properties types(nothing to note here as we have only
strings, not null Uris and not null arrays of not null strings)
- adding some @ Suppress annotations for naming(_ID) and properties not being used(but part of the default projection)
This PR also adds two return types in AddContentApi which I missed in the cleanup of that file.
This is required before enabling explicitApi() mode in the build file of the api module.
Also adds the @JvmStatic annotation for one of the methods to follow the original method signature.
The original todos pointed at using @JvmField but this is not applicable as there's no backing field to use.
Also the changes in this commit replicate the java api(visibility and appearance(they were functions)). See last commit
as java file in f39b7fa10f
We're no longer in Java, so only a few annotations are still necessary.
These are mostly test methods (`@Parameter/@Rule`),
This is a potentially flaky commit, hopefully the reduction in code causes a reduction in compile times
It did not modify the API project public classes
We're no longer in Java, so only a few annotations are still necessary.
These are mostly test methods (`@Parameters/@MethodSource`),
a few which are useful for mocks, and a small number which cause tests
to fail if they're removed for no reasonable reason
This is a potentially flaky commit, hopefully the reduction in
code causes a reduction in compile times
This was a mostly automated process, adding comments manually
if removing the annotation failed tests
It did not modify the API project public classes
com.ichi2.anki.api.AddContentApi
The conversion caused breaking changes WRT nullability of parameters
AND changing `fun` to `val`
This is NOT the final nullability which we desire, we perform the conversion
in a single commit to reduce the chance of bugs being introduced
Changes from a 'pure' conversion':
- addNotes:
- fieldsList: changed to List<Array<String>?>
- tagsList: changed to List<Set<String>?>?
- addNewCustomModel changed from auto conversion:
- fields: -> Array<String>
- cards -> Array<String>
- qfmt -> Array<String>
- afmt -> Array<String>
- splitFields(flds).length -> splitFields(flds).size
suppress lint for name shadowing:
- `var preferredName = preferredName`
add `!!`
- `val fname = File(returnUri!!.path).toString()`
- `val fname = File(returnUri!!.path!!).toString()`
remove `private`:
- `private get() = if (apiHostSpecVersion < 2) CompatV1() else CompatV2()`
- `get() = if (apiHostSpecVersion < 2) CompatV1() else CompatV2()`
remove imports:
- NoteInfo.Companion.buildFromCursor
- Utils.fieldChecksum
- Utils.joinFields
- Utils.joinTags
- Utils.splitFields
add imports: FlashCardsContract
- Card
- CardTemplate
- Deck
- Model
- Note
many spacing changes:
- sample: values.put(Note.TAGS, Utils.joinTags(tagsList[i]))
- moved back to a single line
Moved api docs from <pre> to ```
----
Converted with disabled git hooks + tested manually
com.ichi2.anki.api.ApiUtilsTest
Git hooks were disabled for this commit due to the extra commit for the
java -> kt rename
(irrelevant) Issue with conversion file was listed: 12209
added kotlin-test for null-safe: `assertNull` required for lint
com.ichi2.anki.api.ApiUtilsTest
Git hooks were disabled for this commit due to the extra commit for the
java -> kt rename
Tested manually
(irrelevant) Issue with conversion file was listed: 12209
This method do not take nullable value anymore. And it seems that even from
java's code, it can't be called with nullable value, since it's only called from
either literals or result of Cursor. I.e. strings that are not null by
assumption about the database.
This method do not take nullable value anymore. And it seems that even from
java's code, it can't be called with nullable value, since it's only called from
result of Cursor. I.e. strings that are not null by assumption about the database.