Merge pull request #6720 from vector-im/feature/adm/modularisation-app-module
Modularisation - vector-app module
4
.github/workflows/build.yml
vendored
@ -40,7 +40,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: vector-${{ matrix.target }}-debug
|
name: vector-${{ matrix.target }}-debug
|
||||||
path: |
|
path: |
|
||||||
vector/build/outputs/apk/*/debug/*.apk
|
vector-app/build/outputs/apk/*/debug/*.apk
|
||||||
|
|
||||||
release:
|
release:
|
||||||
name: Build unsigned GPlay APKs
|
name: Build unsigned GPlay APKs
|
||||||
@ -65,7 +65,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: vector-gplay-release-unsigned
|
name: vector-gplay-release-unsigned
|
||||||
path: |
|
path: |
|
||||||
vector/build/outputs/apk/*/release/*.apk
|
vector-app/build/outputs/apk/*/release/*.apk
|
||||||
|
|
||||||
exodus:
|
exodus:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
10
.github/workflows/quality.yml
vendored
@ -7,7 +7,7 @@ on:
|
|||||||
|
|
||||||
# Enrich gradle.properties for CI/CD
|
# Enrich gradle.properties for CI/CD
|
||||||
env:
|
env:
|
||||||
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options="-Xmx2560m" -Dkotlin.incremental=false
|
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -XX:MaxPermSize=512m -Dkotlin.daemon.jvm.options="-Xmx2g" -Dkotlin.incremental=false
|
||||||
CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
|
CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@ -27,7 +27,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Run knit
|
- name: Run knit
|
||||||
run: |
|
run: |
|
||||||
./gradlew knitCheck
|
./gradlew knitCheck $CI_GRADLE_ARG_PROPERTIES
|
||||||
|
|
||||||
# Check the project: ktlint, detekt, lint
|
# Check the project: ktlint, detekt, lint
|
||||||
lint:
|
lint:
|
||||||
@ -41,7 +41,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Run ktlint
|
- name: Run ktlint
|
||||||
run: |
|
run: |
|
||||||
./gradlew ktlintCheck --continue
|
./gradlew ktlintCheck $CI_GRADLE_ARG_PROPERTIES --continue
|
||||||
- name: Run detekt
|
- name: Run detekt
|
||||||
if: always()
|
if: always()
|
||||||
run: |
|
run: |
|
||||||
@ -49,8 +49,8 @@ jobs:
|
|||||||
- name: Run lint
|
- name: Run lint
|
||||||
# Not always, if ktlint or detekt fail, avoid running the long lint check.
|
# Not always, if ktlint or detekt fail, avoid running the long lint check.
|
||||||
run: |
|
run: |
|
||||||
./gradlew lintGplayRelease $CI_GRADLE_ARG_PROPERTIES
|
./gradlew vector-app:lintGplayRelease $CI_GRADLE_ARG_PROPERTIES
|
||||||
./gradlew lintFdroidRelease $CI_GRADLE_ARG_PROPERTIES
|
./gradlew vector-app:lintFdroidRelease $CI_GRADLE_ARG_PROPERTIES
|
||||||
- name: Upload reports
|
- name: Upload reports
|
||||||
if: always()
|
if: always()
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
|
2
.github/workflows/tests.yml
vendored
@ -49,6 +49,7 @@ jobs:
|
|||||||
disable-animations: true
|
disable-animations: true
|
||||||
emulator-build: 7425822
|
emulator-build: 7425822
|
||||||
script: |
|
script: |
|
||||||
|
./gradlew gatherGplayDebugStringTemplates $CI_GRADLE_ARG_PROPERTIES
|
||||||
./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
||||||
./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
||||||
./gradlew generateCoverageReport $CI_GRADLE_ARG_PROPERTIES
|
./gradlew generateCoverageReport $CI_GRADLE_ARG_PROPERTIES
|
||||||
@ -65,6 +66,7 @@ jobs:
|
|||||||
disable-animations: true
|
disable-animations: true
|
||||||
emulator-build: 7425822
|
emulator-build: 7425822
|
||||||
script: |
|
script: |
|
||||||
|
./gradlew gatherGplayDebugStringTemplates $CI_GRADLE_ARG_PROPERTIES
|
||||||
./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
||||||
./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
||||||
./gradlew generateCoverageReport $CI_GRADLE_ARG_PROPERTIES
|
./gradlew generateCoverageReport $CI_GRADLE_ARG_PROPERTIES
|
||||||
|
@ -32,6 +32,7 @@ buildscript {
|
|||||||
classpath 'org.owasp:dependency-check-gradle:7.1.2'
|
classpath 'org.owasp:dependency-check-gradle:7.1.2'
|
||||||
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.7.10"
|
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.7.10"
|
||||||
classpath "org.jetbrains.kotlinx:kotlinx-knit:0.4.0"
|
classpath "org.jetbrains.kotlinx:kotlinx-knit:0.4.0"
|
||||||
|
classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3'
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
}
|
}
|
||||||
|
1
changelog.d/6407.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Converts the vector module to a library with a parent vector-app application module
|
@ -74,7 +74,7 @@ def collectProjects(predicate) {
|
|||||||
task generateCoverageReport(type: JacocoReport) {
|
task generateCoverageReport(type: JacocoReport) {
|
||||||
outputs.upToDateWhen { false }
|
outputs.upToDateWhen { false }
|
||||||
rootProject.apply plugin: 'jacoco'
|
rootProject.apply plugin: 'jacoco'
|
||||||
def projects = collectProjects { ['vector', 'matrix-sdk-android'].contains(it.name) }
|
def projects = collectProjects { ['vector-app', 'vector', 'matrix-sdk-android'].contains(it.name) }
|
||||||
initializeReport(it, projects, excludes)
|
initializeReport(it, projects, excludes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,5 +87,5 @@ task unitTestsWithCoverage(type: GradleBuild) {
|
|||||||
task instrumentationTestsWithCoverage(type: GradleBuild) {
|
task instrumentationTestsWithCoverage(type: GradleBuild) {
|
||||||
startParameter.projectProperties.coverage = [enableTestCoverage: true]
|
startParameter.projectProperties.coverage = [enableTestCoverage: true]
|
||||||
startParameter.projectProperties['android.testInstrumentationRunnerArguments.notPackage'] = 'im.vector.app.ui'
|
startParameter.projectProperties['android.testInstrumentationRunnerArguments.notPackage'] = 'im.vector.app.ui'
|
||||||
tasks = [':vector:connectedGplayDebugAndroidTest', 'matrix-sdk-android:connectedDebugAndroidTest']
|
tasks = [':vector-app:connectedGplayDebugAndroidTest', ':vector:connectedGplayDebugAndroidTest', 'matrix-sdk-android:connectedDebugAndroidTest']
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,8 @@ ext.libs = [
|
|||||||
'material' : "com.google.android.material:material:1.6.1",
|
'material' : "com.google.android.material:material:1.6.1",
|
||||||
'appdistributionApi' : "com.google.firebase:firebase-appdistribution-api-ktx:$appDistribution",
|
'appdistributionApi' : "com.google.firebase:firebase-appdistribution-api-ktx:$appDistribution",
|
||||||
'appdistribution' : "com.google.firebase:firebase-appdistribution:$appDistribution",
|
'appdistribution' : "com.google.firebase:firebase-appdistribution:$appDistribution",
|
||||||
|
// Phone number https://github.com/google/libphonenumber
|
||||||
|
'phonenumber' : "com.googlecode.libphonenumber:libphonenumber:8.12.54"
|
||||||
],
|
],
|
||||||
dagger : [
|
dagger : [
|
||||||
'dagger' : "com.google.dagger:dagger:$dagger",
|
'dagger' : "com.google.dagger:dagger:$dagger",
|
||||||
|
@ -199,8 +199,7 @@ dependencies {
|
|||||||
// Exif data handling
|
// Exif data handling
|
||||||
implementation libs.apache.commonsImaging
|
implementation libs.apache.commonsImaging
|
||||||
|
|
||||||
// Phone number https://github.com/google/libphonenumber
|
implementation libs.google.phonenumber
|
||||||
implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.54'
|
|
||||||
|
|
||||||
testImplementation libs.tests.junit
|
testImplementation libs.tests.junit
|
||||||
// Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281
|
// Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
include ':vector-app'
|
||||||
include ':vector'
|
include ':vector'
|
||||||
include ':vector-config'
|
include ':vector-config'
|
||||||
include ':matrix-sdk-android'
|
include ':matrix-sdk-android'
|
||||||
|
@ -74,7 +74,9 @@ ${searchForbiddenStringsScript} ./tools/check/forbidden_strings_in_code.txt \
|
|||||||
./vector/src/debug/java \
|
./vector/src/debug/java \
|
||||||
./vector/src/release/java \
|
./vector/src/release/java \
|
||||||
./vector/src/fdroid/java \
|
./vector/src/fdroid/java \
|
||||||
./vector/src/gplay/java
|
./vector/src/gplay/java \
|
||||||
|
./vector-app/src/gplay/java \
|
||||||
|
./vector-app/src/main/java
|
||||||
|
|
||||||
resultForbiddenStringInCode=$?
|
resultForbiddenStringInCode=$?
|
||||||
|
|
||||||
@ -95,7 +97,9 @@ ${searchForbiddenStringsScript} ./tools/check/forbidden_strings_in_code_app.txt
|
|||||||
./vector/src/debug/java \
|
./vector/src/debug/java \
|
||||||
./vector/src/release/java \
|
./vector/src/release/java \
|
||||||
./vector/src/fdroid/java \
|
./vector/src/fdroid/java \
|
||||||
./vector/src/gplay/java
|
./vector/src/gplay/java \
|
||||||
|
./vector-app/src/gplay/java \
|
||||||
|
./vector-app/src/main/java
|
||||||
|
|
||||||
resultForbiddenStringInCodeApp=$?
|
resultForbiddenStringInCodeApp=$?
|
||||||
|
|
||||||
@ -107,7 +111,8 @@ ${searchForbiddenStringsScript} ./tools/check/forbidden_strings_in_resources.txt
|
|||||||
./vector/src/main/res/color \
|
./vector/src/main/res/color \
|
||||||
./vector/src/main/res/layout \
|
./vector/src/main/res/layout \
|
||||||
./vector/src/main/res/values \
|
./vector/src/main/res/values \
|
||||||
./vector/src/main/res/xml
|
./vector/src/main/res/xml \
|
||||||
|
./vector-app/src/main/res/values
|
||||||
|
|
||||||
resultForbiddenStringInResource=$?
|
resultForbiddenStringInResource=$?
|
||||||
|
|
||||||
@ -115,7 +120,8 @@ echo
|
|||||||
echo "Search for forbidden patterns in layouts..."
|
echo "Search for forbidden patterns in layouts..."
|
||||||
|
|
||||||
${searchForbiddenStringsScript} ./tools/check/forbidden_strings_in_layout.txt \
|
${searchForbiddenStringsScript} ./tools/check/forbidden_strings_in_layout.txt \
|
||||||
./vector/src/main/res/layout
|
./vector/src/main/res/layout \
|
||||||
|
./vector-app/src/main/res/layout
|
||||||
|
|
||||||
resultForbiddenStringInLayout=$?
|
resultForbiddenStringInLayout=$?
|
||||||
|
|
||||||
@ -155,7 +161,11 @@ ${checkLongFilesScript} ${maxLines} \
|
|||||||
./vector/src/main/java \
|
./vector/src/main/java \
|
||||||
./vector/src/release/java \
|
./vector/src/release/java \
|
||||||
./vector/src/sharedTest/java \
|
./vector/src/sharedTest/java \
|
||||||
./vector/src/test/java
|
./vector/src/test/java \
|
||||||
|
./vector/src/androidTest/java \
|
||||||
|
./vector/src/gplay/java \
|
||||||
|
./vector/src/main/java
|
||||||
|
|
||||||
|
|
||||||
resultLongFiles=$?
|
resultLongFiles=$?
|
||||||
|
|
||||||
|
380
vector-app/build.gradle
Normal file
@ -0,0 +1,380 @@
|
|||||||
|
import com.android.build.OutputFile
|
||||||
|
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'com.google.firebase.appdistribution'
|
||||||
|
apply plugin: 'com.google.android.gms.oss-licenses-plugin'
|
||||||
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlin-parcelize'
|
||||||
|
apply plugin: 'kotlin-kapt'
|
||||||
|
apply plugin: 'dagger.hilt.android.plugin'
|
||||||
|
apply plugin: 'kotlinx-knit'
|
||||||
|
apply plugin: 'com.likethesalad.stem'
|
||||||
|
|
||||||
|
if (project.hasProperty("coverage")) {
|
||||||
|
apply plugin: 'jacoco'
|
||||||
|
}
|
||||||
|
|
||||||
|
kapt {
|
||||||
|
correctErrorTypes = true
|
||||||
|
}
|
||||||
|
|
||||||
|
knit {
|
||||||
|
files = fileTree(project.rootDir) {
|
||||||
|
include '**/*.md'
|
||||||
|
include '**/*.kt'
|
||||||
|
include '**/*.kts'
|
||||||
|
exclude '**/build/**'
|
||||||
|
exclude '**/.gradle/**'
|
||||||
|
exclude '**/towncrier/template.md'
|
||||||
|
exclude '**/CHANGES.md'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: 2 digits max for each value
|
||||||
|
ext.versionMajor = 1
|
||||||
|
ext.versionMinor = 4
|
||||||
|
// Note: even values are reserved for regular release, odd values for hotfix release.
|
||||||
|
// When creating a hotfix, you should decrease the value, since the current value
|
||||||
|
// is the value for the next regular release.
|
||||||
|
ext.versionPatch = 36
|
||||||
|
|
||||||
|
static def getGitTimestamp() {
|
||||||
|
def cmd = 'git show -s --format=%ct'
|
||||||
|
return cmd.execute().text.trim() as Long
|
||||||
|
}
|
||||||
|
|
||||||
|
static def generateVersionCodeFromTimestamp() {
|
||||||
|
// It's unix timestamp, minus timestamp of October 3rd 2018 (first commit date) divided by 100: It's incremented by one every 100 seconds.
|
||||||
|
// plus 20_000_000 for compatibility reason with the previous way the Version Code was computed
|
||||||
|
// Note that the result will be multiplied by 10 when adding the digit for the arch
|
||||||
|
return ((getGitTimestamp() - 1_538_524_800) / 100).toInteger() + 20_000_000
|
||||||
|
}
|
||||||
|
|
||||||
|
def generateVersionCodeFromVersionName() {
|
||||||
|
// plus 4_000_000 for compatibility reason with the previous way the Version Code was computed
|
||||||
|
// Note that the result will be multiplied by 10 when adding the digit for the arch
|
||||||
|
return (versionMajor * 1_00_00 + versionMinor * 1_00 + versionPatch) + 4_000_000
|
||||||
|
}
|
||||||
|
|
||||||
|
def getVersionCode() {
|
||||||
|
if (gitBranchName() == "develop") {
|
||||||
|
return generateVersionCodeFromTimestamp()
|
||||||
|
} else {
|
||||||
|
return generateVersionCodeFromVersionName()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static def gitRevision() {
|
||||||
|
def cmd = "git rev-parse --short=8 HEAD"
|
||||||
|
return cmd.execute().text.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
static def gitRevisionDate() {
|
||||||
|
def cmd = "git show -s --format=%ci HEAD^{commit}"
|
||||||
|
return cmd.execute().text.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
static def gitBranchName() {
|
||||||
|
def fromEnv = System.env.BUILDKITE_BRANCH as String ?: ""
|
||||||
|
|
||||||
|
if (!fromEnv.isEmpty()) {
|
||||||
|
return fromEnv
|
||||||
|
} else {
|
||||||
|
// Note: this command return "HEAD" on Buildkite, so use the system env 'BUILDKITE_BRANCH' content first
|
||||||
|
def cmd = "git rev-parse --abbrev-ref HEAD"
|
||||||
|
return cmd.execute().text.trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For Google Play build, build on any other branch than main will have a "-dev" suffix
|
||||||
|
static def getGplayVersionSuffix() {
|
||||||
|
if (gitBranchName() == "main") {
|
||||||
|
return ""
|
||||||
|
} else {
|
||||||
|
return "-dev"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static def gitTag() {
|
||||||
|
def cmd = "git describe --exact-match --tags"
|
||||||
|
return cmd.execute().text.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
// For F-Droid build, build on a not tagged commit will have a "-dev" suffix
|
||||||
|
static def getFdroidVersionSuffix() {
|
||||||
|
if (gitTag() == "") {
|
||||||
|
return "-dev"
|
||||||
|
} else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.android.buildTypes.all { buildType ->
|
||||||
|
buildType.javaCompileOptions.annotationProcessorOptions.arguments =
|
||||||
|
[
|
||||||
|
validateEpoxyModelUsage: String.valueOf(buildType.name == 'debug')
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// map for the version codes last digit
|
||||||
|
// x86 must have greater values than arm
|
||||||
|
// 64 bits have greater value than 32 bits
|
||||||
|
ext.abiVersionCodes = ["armeabi-v7a": 1, "arm64-v8a": 2, "x86": 3, "x86_64": 4].withDefault { 0 }
|
||||||
|
|
||||||
|
def buildNumber = System.env.BUILDKITE_BUILD_NUMBER as Integer ?: 0
|
||||||
|
|
||||||
|
android {
|
||||||
|
// Due to a bug introduced in Android gradle plugin 3.6.0, we have to specify the ndk version to use
|
||||||
|
// Ref: https://issuetracker.google.com/issues/144111441
|
||||||
|
ndkVersion "21.3.6528147"
|
||||||
|
|
||||||
|
compileSdk versions.compileSdk
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "im.vector.app"
|
||||||
|
// Set to API 21: see #405
|
||||||
|
minSdk versions.minSdk
|
||||||
|
targetSdk versions.targetSdk
|
||||||
|
multiDexEnabled true
|
||||||
|
|
||||||
|
renderscriptTargetApi 24
|
||||||
|
renderscriptSupportModeEnabled true
|
||||||
|
|
||||||
|
// `develop` branch will have version code from timestamp, to ensure each build from CI has a incremented versionCode.
|
||||||
|
// Other branches (main, features, etc.) will have version code based on application version.
|
||||||
|
versionCode project.getVersionCode()
|
||||||
|
|
||||||
|
// Required for sonar analysis
|
||||||
|
versionName "${versionMajor}.${versionMinor}.${versionPatch}-sonar"
|
||||||
|
|
||||||
|
// Generate a random app task affinity
|
||||||
|
manifestPlaceholders = [appTaskAffinitySuffix: "H_${gitRevision()}"]
|
||||||
|
|
||||||
|
buildConfigField "String", "GIT_REVISION", "\"${gitRevision()}\""
|
||||||
|
buildConfigField "String", "GIT_REVISION_DATE", "\"${gitRevisionDate()}\""
|
||||||
|
buildConfigField "String", "GIT_BRANCH_NAME", "\"${gitBranchName()}\""
|
||||||
|
buildConfigField "String", "BUILD_NUMBER", "\"${buildNumber}\""
|
||||||
|
|
||||||
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
|
// Keep abiFilter for the universalApk
|
||||||
|
ndk {
|
||||||
|
abiFilters "armeabi-v7a", "x86", 'arm64-v8a', 'x86_64'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ref: https://developer.android.com/studio/build/configure-apk-splits.html
|
||||||
|
splits {
|
||||||
|
// Configures multiple APKs based on ABI.
|
||||||
|
abi {
|
||||||
|
// Enables building multiple APKs per ABI.
|
||||||
|
enable true
|
||||||
|
|
||||||
|
// By default all ABIs are included, so use reset() and include to specify that we only
|
||||||
|
// want APKs for armeabi-v7a, x86, arm64-v8a and x86_64.
|
||||||
|
|
||||||
|
// Resets the list of ABIs that Gradle should create APKs for to none.
|
||||||
|
reset()
|
||||||
|
|
||||||
|
// Specifies a list of ABIs that Gradle should create APKs for.
|
||||||
|
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||||
|
|
||||||
|
// Generate a universal APK that includes all ABIs, so user who install from CI tool can use this one by default.
|
||||||
|
universalApk true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applicationVariants.all { variant ->
|
||||||
|
// assign different version code for each output
|
||||||
|
def baseVariantVersion = variant.versionCode * 10
|
||||||
|
variant.outputs.each { output ->
|
||||||
|
def baseAbiVersionCode = project.ext.abiVersionCodes.get(output.getFilter(OutputFile.ABI))
|
||||||
|
// Known limitation: it does not modify the value in the BuildConfig.java generated file
|
||||||
|
// See https://issuetracker.google.com/issues/171133218
|
||||||
|
output.versionCodeOverride = baseVariantVersion + baseAbiVersionCode
|
||||||
|
print "ABI " + output.getFilter(OutputFile.ABI) + " \t-> VersionCode = " + output.versionCodeOverride + "\n"
|
||||||
|
output.outputFileName = output.outputFileName.replace("vector-app", "vector")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following argument makes the Android Test Orchestrator run its
|
||||||
|
// "pm clear" command after each test invocation. This command ensures
|
||||||
|
// that the app's state is completely cleared between tests.
|
||||||
|
testInstrumentationRunnerArguments clearPackageData: 'true'
|
||||||
|
}
|
||||||
|
|
||||||
|
testOptions {
|
||||||
|
// Disables animations during instrumented tests you run from the command line…
|
||||||
|
// This property does not affect tests that you run using Android Studio.”
|
||||||
|
animationsDisabled = true
|
||||||
|
|
||||||
|
// Comment to run on Android 12
|
||||||
|
// execution 'ANDROIDX_TEST_ORCHESTRATOR'
|
||||||
|
}
|
||||||
|
|
||||||
|
signingConfigs {
|
||||||
|
debug {
|
||||||
|
keyAlias 'androiddebugkey'
|
||||||
|
keyPassword 'android'
|
||||||
|
storeFile file('./signature/debug.keystore')
|
||||||
|
storePassword 'android'
|
||||||
|
}
|
||||||
|
nightly {
|
||||||
|
keyAlias System.env.ELEMENT_ANDROID_NIGHTLY_KEYID ?: project.property("signing.element.nightly.keyId")
|
||||||
|
keyPassword System.env.ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD ?: project.property("signing.element.nightly.keyPassword")
|
||||||
|
storeFile file('./signature/nightly.keystore')
|
||||||
|
storePassword System.env.ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD ?: project.property("signing.element.nightly.storePassword")
|
||||||
|
}
|
||||||
|
release {
|
||||||
|
keyAlias project.property("signing.element.keyId")
|
||||||
|
keyPassword project.property("signing.element.keyPassword")
|
||||||
|
storeFile file(project.property("signing.element.storePath"))
|
||||||
|
storePassword project.property("signing.element.storePassword")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
debug {
|
||||||
|
applicationIdSuffix ".debug"
|
||||||
|
signingConfig signingConfigs.debug
|
||||||
|
resValue "color", "launcher_background", "#0DBD8B"
|
||||||
|
|
||||||
|
if (project.hasProperty("coverage")) {
|
||||||
|
testCoverageEnabled = coverage.enableTestCoverage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
release {
|
||||||
|
resValue "color", "launcher_background", "#0DBD8B"
|
||||||
|
postprocessing {
|
||||||
|
removeUnusedCode true
|
||||||
|
removeUnusedResources true
|
||||||
|
// We do not activate obfuscation as it makes it hard then to read crash reports, and it's a bit useless on an open source project :)
|
||||||
|
obfuscate false
|
||||||
|
optimizeCode true
|
||||||
|
proguardFiles 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
// signingConfig signingConfigs.release
|
||||||
|
}
|
||||||
|
|
||||||
|
nightly {
|
||||||
|
initWith release
|
||||||
|
applicationIdSuffix ".nightly"
|
||||||
|
versionNameSuffix "-nightly"
|
||||||
|
resValue "color", "launcher_background", "#07007E"
|
||||||
|
|
||||||
|
// We need to copy paste this block, this is not done automatically by `initWith release`
|
||||||
|
postprocessing {
|
||||||
|
removeUnusedCode true
|
||||||
|
removeUnusedResources true
|
||||||
|
// We do not activate obfuscation as it makes it hard then to read crash reports, and it's a bit useless on an open source project :)
|
||||||
|
obfuscate false
|
||||||
|
optimizeCode true
|
||||||
|
proguardFiles 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
matchingFallbacks = ['release']
|
||||||
|
signingConfig signingConfigs.nightly
|
||||||
|
firebaseAppDistribution {
|
||||||
|
artifactType = "APK"
|
||||||
|
// We upload the universal APK to fix this error:
|
||||||
|
// "App Distribution found more than 1 output file for this variant.
|
||||||
|
// Please contact firebase-support@google.com for help using APK splits with App Distribution."
|
||||||
|
artifactPath = "$rootDir/vector-app/build/outputs/apk/gplay/nightly/vector-gplay-universal-nightly.apk"
|
||||||
|
// This file will be generated by the GitHub action
|
||||||
|
releaseNotesFile = "CHANGES_NIGHTLY.md"
|
||||||
|
groups = "external-testers"
|
||||||
|
// This should not be required, but if I do not add the appId, I get this error:
|
||||||
|
// "App Distribution halted because it had a problem uploading the APK: [404] Requested entity was not found."
|
||||||
|
appId = "1:912726360885:android:efd8545af52a9f9300427c"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flavorDimensions "store"
|
||||||
|
|
||||||
|
productFlavors {
|
||||||
|
gplay {
|
||||||
|
apply plugin: 'com.google.gms.google-services'
|
||||||
|
afterEvaluate {
|
||||||
|
tasks.matching { it.name.contains("GoogleServices") && !it.name.contains("Gplay") }*.enabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
dimension "store"
|
||||||
|
isDefault = true
|
||||||
|
versionName "${versionMajor}.${versionMinor}.${versionPatch}${getGplayVersionSuffix()}"
|
||||||
|
buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"G\""
|
||||||
|
buildConfigField "String", "FLAVOR_DESCRIPTION", "\"GooglePlay\""
|
||||||
|
}
|
||||||
|
|
||||||
|
fdroid {
|
||||||
|
dimension "store"
|
||||||
|
versionName "${versionMajor}.${versionMinor}.${versionPatch}${getFdroidVersionSuffix()}"
|
||||||
|
buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"F\""
|
||||||
|
buildConfigField "String", "FLAVOR_DESCRIPTION", "\"FDroid\""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lintOptions {
|
||||||
|
lintConfig file("../tools/lint/lint.xml")
|
||||||
|
|
||||||
|
checkDependencies true
|
||||||
|
abortOnError true
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility versions.sourceCompat
|
||||||
|
targetCompatibility versions.targetCompat
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "11"
|
||||||
|
freeCompilerArgs += [
|
||||||
|
"-opt-in=kotlin.RequiresOptIn",
|
||||||
|
// Fixes false positive "This is an internal Mavericks API. It is not intended for external use."
|
||||||
|
// of MvRx `by viewModel()` calls. Maybe due to the inlining of code... This is a temporary fix...
|
||||||
|
"-opt-in=com.airbnb.mvrx.InternalMavericksApi",
|
||||||
|
// Opt in for kotlinx.coroutines.FlowPreview too
|
||||||
|
"-opt-in=kotlinx.coroutines.FlowPreview",
|
||||||
|
// Opt in for kotlinx.coroutines.ExperimentalCoroutinesApi too
|
||||||
|
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
buildFeatures {
|
||||||
|
viewBinding true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':vector')
|
||||||
|
implementation project(':vector-config')
|
||||||
|
implementation libs.dagger.hilt
|
||||||
|
implementation 'androidx.multidex:multidex:2.0.1'
|
||||||
|
implementation "androidx.sharetarget:sharetarget:1.1.0"
|
||||||
|
|
||||||
|
kapt libs.dagger.hiltCompiler
|
||||||
|
|
||||||
|
androidTestImplementation libs.androidx.testCore
|
||||||
|
androidTestImplementation libs.androidx.testRunner
|
||||||
|
androidTestImplementation libs.androidx.testRules
|
||||||
|
androidTestImplementation libs.androidx.junit
|
||||||
|
androidTestImplementation libs.androidx.espressoCore
|
||||||
|
androidTestImplementation libs.androidx.espressoContrib
|
||||||
|
androidTestImplementation libs.androidx.espressoIntents
|
||||||
|
androidTestImplementation libs.tests.kluent
|
||||||
|
androidTestImplementation libs.androidx.coreTesting
|
||||||
|
androidTestImplementation(libs.jetbrains.coroutinesTest) {
|
||||||
|
exclude group: "org.jetbrains.kotlinx", module: "kotlinx-coroutines-debug"
|
||||||
|
}
|
||||||
|
// Plant Timber tree for test
|
||||||
|
androidTestImplementation libs.tests.timberJunitRule
|
||||||
|
// "The one who serves a great Espresso"
|
||||||
|
androidTestImplementation('com.adevinta.android:barista:4.2.0') {
|
||||||
|
exclude group: 'org.jetbrains.kotlin'
|
||||||
|
}
|
||||||
|
androidTestImplementation libs.mockk.mockkAndroid
|
||||||
|
androidTestUtil libs.androidx.orchestrator
|
||||||
|
androidTestImplementation libs.androidx.fragmentTesting
|
||||||
|
androidTestImplementation "org.jetbrains.kotlin:kotlin-reflect:1.7.10"
|
||||||
|
debugImplementation libs.androidx.fragmentTesting
|
||||||
|
}
|
||||||
|
|
@ -23,6 +23,7 @@ import androidx.test.espresso.matcher.ViewMatchers
|
|||||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.filters.LargeTest
|
import androidx.test.filters.LargeTest
|
||||||
|
import com.adevinta.android.barista.internal.viewaction.SleepViewAction
|
||||||
import im.vector.app.features.MainActivity
|
import im.vector.app.features.MainActivity
|
||||||
import im.vector.app.ui.robot.ElementRobot
|
import im.vector.app.ui.robot.ElementRobot
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
@ -33,7 +34,7 @@ import java.util.UUID
|
|||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
@LargeTest
|
@LargeTest
|
||||||
class CantVerifyTest : VerificationTestBase() {
|
class CantVerifyTest {
|
||||||
|
|
||||||
@get:Rule
|
@get:Rule
|
||||||
val testRule = RuleChain
|
val testRule = RuleChain
|
@ -21,6 +21,8 @@ import androidx.datastore.core.DataStore
|
|||||||
import androidx.datastore.preferences.core.Preferences
|
import androidx.datastore.preferences.core.Preferences
|
||||||
import androidx.datastore.preferences.core.edit
|
import androidx.datastore.preferences.core.edit
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import dagger.hilt.EntryPoints
|
||||||
|
import im.vector.app.core.di.SingletonEntryPoint
|
||||||
import im.vector.app.features.analytics.store.AnalyticsStore
|
import im.vector.app.features.analytics.store.AnalyticsStore
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.rules.TestWatcher
|
import org.junit.rules.TestWatcher
|
||||||
@ -39,10 +41,11 @@ class ClearCurrentSessionRule : TestWatcher() {
|
|||||||
runBlocking {
|
runBlocking {
|
||||||
reflectAnalyticDatastore(context).edit { it.clear() }
|
reflectAnalyticDatastore(context).edit { it.clear() }
|
||||||
runCatching {
|
runCatching {
|
||||||
val holder = (context.applicationContext as VectorApplication).activeSessionHolder
|
val entryPoint = EntryPoints.get(context.applicationContext, SingletonEntryPoint::class.java)
|
||||||
holder.getSafeActiveSession()?.signOutService()?.signOut(true)
|
val sessionHolder = entryPoint.activeSessionHolder()
|
||||||
(context.applicationContext as VectorApplication).vectorPreferences.clearPreferences()
|
sessionHolder.getSafeActiveSession()?.signOutService()?.signOut(true)
|
||||||
holder.clearActiveSession()
|
entryPoint.vectorPreferences().clearPreferences()
|
||||||
|
sessionHolder.clearActiveSession()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return super.apply(base, description)
|
return super.apply(base, description)
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2020 New Vector Ltd
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2020 New Vector Ltd
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2020 New Vector Ltd
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -33,6 +33,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
|
|||||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.filters.LargeTest
|
import androidx.test.filters.LargeTest
|
||||||
|
import com.adevinta.android.barista.internal.viewaction.SleepViewAction
|
||||||
import im.vector.app.core.utils.getMatrixInstance
|
import im.vector.app.core.utils.getMatrixInstance
|
||||||
import im.vector.app.features.MainActivity
|
import im.vector.app.features.MainActivity
|
||||||
import im.vector.app.features.home.HomeActivity
|
import im.vector.app.features.home.HomeActivity
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2020 New Vector Ltd
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -33,6 +33,7 @@ import androidx.test.ext.junit.rules.ActivityScenarioRule
|
|||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.filters.LargeTest
|
import androidx.test.filters.LargeTest
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import com.adevinta.android.barista.internal.viewaction.SleepViewAction
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.core.utils.getMatrixInstance
|
import im.vector.app.core.utils.getMatrixInstance
|
||||||
import im.vector.app.features.MainActivity
|
import im.vector.app.features.MainActivity
|
@ -1,8 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
package="im.vector.app">
|
|
||||||
|
|
||||||
<application>
|
<application android:name="im.vector.app.VectorApplication">
|
||||||
|
|
||||||
<!-- Firebase components -->
|
<!-- Firebase components -->
|
||||||
<meta-data
|
<meta-data
|
||||||
@ -10,8 +9,8 @@
|
|||||||
android:value="true" />
|
android:value="true" />
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
|
android:name="im.vector.app.push.fcm.EmbeddedFCMDistributor"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:name=".push.fcm.EmbeddedFCMDistributor"
|
|
||||||
android:exported="false">
|
android:exported="false">
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
58
vector-app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
package="im.vector.application">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="false"
|
||||||
|
android:hasFragileUserData="true"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:networkSecurityConfig="@xml/network_security_config"
|
||||||
|
android:resizeableActivity="true"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:taskAffinity="${applicationId}.${appTaskAffinitySuffix}"
|
||||||
|
android:theme="@style/Theme.Vector.Light"
|
||||||
|
tools:ignore="UnusedAttribute"
|
||||||
|
tools:replace="android:allowBackup">
|
||||||
|
|
||||||
|
<!-- Providers -->
|
||||||
|
|
||||||
|
<!-- Remove WorkManagerInitializer Provider because we are using on-demand initialization of WorkManager-->
|
||||||
|
<provider
|
||||||
|
android:name="androidx.startup.InitializationProvider"
|
||||||
|
android:authorities="${applicationId}.androidx-startup"
|
||||||
|
android:exported="false"
|
||||||
|
tools:node="merge">
|
||||||
|
<meta-data
|
||||||
|
android:name="androidx.work.WorkManagerInitializer"
|
||||||
|
android:value="androidx.startup"
|
||||||
|
tools:node="remove" />
|
||||||
|
<!-- We init the lib ourself in EmojiCompatWrapper -->
|
||||||
|
<meta-data
|
||||||
|
android:name="androidx.emoji2.text.EmojiCompatInitializer"
|
||||||
|
tools:node="remove" />
|
||||||
|
</provider>
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
android:authorities="${applicationId}.fileProvider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/sdk_provider_paths" />
|
||||||
|
</provider>
|
||||||
|
|
||||||
|
<!-- Temporary fix for Android 12. android:exported has to be explicitly set when targeting Android 12
|
||||||
|
Do it for services coming from dependencies - BEGIN -->
|
||||||
|
<service
|
||||||
|
android:name="androidx.sharetarget.ChooserTargetServiceCompat"
|
||||||
|
android:exported="false"
|
||||||
|
tools:node="merge" />
|
||||||
|
<!-- Temporary fix for Android 12 change - END -->
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019 New Vector Ltd
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -66,6 +66,7 @@ import im.vector.app.features.settings.VectorLocale
|
|||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import im.vector.app.features.themes.ThemeUtils
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
import im.vector.app.features.version.VersionProvider
|
import im.vector.app.features.version.VersionProvider
|
||||||
|
import im.vector.application.R
|
||||||
import org.jitsi.meet.sdk.log.JitsiMeetDefaultLogHandler
|
import org.jitsi.meet.sdk.log.JitsiMeetDefaultLogHandler
|
||||||
import org.matrix.android.sdk.api.Matrix
|
import org.matrix.android.sdk.api.Matrix
|
||||||
import org.matrix.android.sdk.api.auth.AuthenticationService
|
import org.matrix.android.sdk.api.auth.AuthenticationService
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019 New Vector Ltd
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -28,7 +28,6 @@ import dagger.Module
|
|||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.EmojiCompatWrapper
|
import im.vector.app.EmojiCompatWrapper
|
||||||
import im.vector.app.EmojiSpanify
|
import im.vector.app.EmojiSpanify
|
||||||
import im.vector.app.SpaceStateHandler
|
import im.vector.app.SpaceStateHandler
|
||||||
@ -58,6 +57,7 @@ import im.vector.app.features.settings.FontScalePreferencesImpl
|
|||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import im.vector.app.features.ui.SharedPreferencesUiStateRepository
|
import im.vector.app.features.ui.SharedPreferencesUiStateRepository
|
||||||
import im.vector.app.features.ui.UiStateRepository
|
import im.vector.app.features.ui.UiStateRepository
|
||||||
|
import im.vector.application.BuildConfig
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
5
vector-app/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
<!-- The https://github.com/LikeTheSalad/android-stem requires a non empty strings.xml -->
|
||||||
|
<string name="ignored_placeholder" tools:ignore="UnusedResources">ignored</string>
|
||||||
|
</resources>
|
@ -1,14 +1,9 @@
|
|||||||
import com.android.build.OutputFile
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
|
||||||
apply plugin: 'com.google.firebase.appdistribution'
|
|
||||||
apply plugin: 'com.google.android.gms.oss-licenses-plugin'
|
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply plugin: 'kotlin-parcelize'
|
apply plugin: 'kotlin-parcelize'
|
||||||
apply plugin: 'kotlin-kapt'
|
apply plugin: 'kotlin-kapt'
|
||||||
apply plugin: 'com.likethesalad.stem'
|
|
||||||
apply plugin: 'dagger.hilt.android.plugin'
|
apply plugin: 'dagger.hilt.android.plugin'
|
||||||
apply plugin: 'kotlinx-knit'
|
apply plugin: 'com.likethesalad.stem-library'
|
||||||
|
|
||||||
if (project.hasProperty("coverage")) {
|
if (project.hasProperty("coverage")) {
|
||||||
apply plugin: 'jacoco'
|
apply plugin: 'jacoco'
|
||||||
@ -18,98 +13,11 @@ kapt {
|
|||||||
correctErrorTypes = true
|
correctErrorTypes = true
|
||||||
}
|
}
|
||||||
|
|
||||||
knit {
|
|
||||||
files = fileTree(project.rootDir) {
|
|
||||||
include '**/*.md'
|
|
||||||
include '**/*.kt'
|
|
||||||
include '**/*.kts'
|
|
||||||
exclude '**/build/**'
|
|
||||||
exclude '**/.gradle/**'
|
|
||||||
exclude '**/towncrier/template.md'
|
|
||||||
exclude '**/CHANGES.md'
|
|
||||||
exclude '/node_modules'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: 2 digits max for each value
|
|
||||||
ext.versionMajor = 1
|
|
||||||
ext.versionMinor = 4
|
|
||||||
// Note: even values are reserved for regular release, odd values for hotfix release.
|
|
||||||
// When creating a hotfix, you should decrease the value, since the current value
|
|
||||||
// is the value for the next regular release.
|
|
||||||
ext.versionPatch = 36
|
|
||||||
|
|
||||||
static def getGitTimestamp() {
|
|
||||||
def cmd = 'git show -s --format=%ct'
|
|
||||||
return cmd.execute().text.trim() as Long
|
|
||||||
}
|
|
||||||
|
|
||||||
static def generateVersionCodeFromTimestamp() {
|
|
||||||
// It's unix timestamp, minus timestamp of October 3rd 2018 (first commit date) divided by 100: It's incremented by one every 100 seconds.
|
|
||||||
// plus 20_000_000 for compatibility reason with the previous way the Version Code was computed
|
|
||||||
// Note that the result will be multiplied by 10 when adding the digit for the arch
|
|
||||||
return ((getGitTimestamp() - 1_538_524_800) / 100).toInteger() + 20_000_000
|
|
||||||
}
|
|
||||||
|
|
||||||
def generateVersionCodeFromVersionName() {
|
|
||||||
// plus 4_000_000 for compatibility reason with the previous way the Version Code was computed
|
|
||||||
// Note that the result will be multiplied by 10 when adding the digit for the arch
|
|
||||||
return (versionMajor * 1_00_00 + versionMinor * 1_00 + versionPatch) + 4_000_000
|
|
||||||
}
|
|
||||||
|
|
||||||
def getVersionCode() {
|
|
||||||
if (gitBranchName() == "develop") {
|
|
||||||
return generateVersionCodeFromTimestamp()
|
|
||||||
} else {
|
|
||||||
return generateVersionCodeFromVersionName()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static def gitRevision() {
|
static def gitRevision() {
|
||||||
def cmd = "git rev-parse --short=8 HEAD"
|
def cmd = "git rev-parse --short=8 HEAD"
|
||||||
return cmd.execute().text.trim()
|
return cmd.execute().text.trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
static def gitRevisionDate() {
|
|
||||||
def cmd = "git show -s --format=%ci HEAD^{commit}"
|
|
||||||
return cmd.execute().text.trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
static def gitBranchName() {
|
|
||||||
def fromEnv = System.env.BUILDKITE_BRANCH as String ?: ""
|
|
||||||
|
|
||||||
if (!fromEnv.isEmpty()) {
|
|
||||||
return fromEnv
|
|
||||||
} else {
|
|
||||||
// Note: this command return "HEAD" on Buildkite, so use the system env 'BUILDKITE_BRANCH' content first
|
|
||||||
def cmd = "git rev-parse --abbrev-ref HEAD"
|
|
||||||
return cmd.execute().text.trim()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For Google Play build, build on any other branch than main will have a "-dev" suffix
|
|
||||||
static def getGplayVersionSuffix() {
|
|
||||||
if (gitBranchName() == "main") {
|
|
||||||
return ""
|
|
||||||
} else {
|
|
||||||
return "-dev"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static def gitTag() {
|
|
||||||
def cmd = "git describe --exact-match --tags"
|
|
||||||
return cmd.execute().text.trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
// For F-Droid build, build on a not tagged commit will have a "-dev" suffix
|
|
||||||
static def getFdroidVersionSuffix() {
|
|
||||||
if (gitTag() == "") {
|
|
||||||
return "-dev"
|
|
||||||
} else {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
project.android.buildTypes.all { buildType ->
|
project.android.buildTypes.all { buildType ->
|
||||||
buildType.javaCompileOptions.annotationProcessorOptions.arguments =
|
buildType.javaCompileOptions.annotationProcessorOptions.arguments =
|
||||||
[
|
[
|
||||||
@ -117,13 +25,6 @@ project.android.buildTypes.all { buildType ->
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
// map for the version codes last digit
|
|
||||||
// x86 must have greater values than arm
|
|
||||||
// 64 bits have greater value than 32 bits
|
|
||||||
ext.abiVersionCodes = ["armeabi-v7a": 1, "arm64-v8a": 2, "x86": 3, "x86_64": 4].withDefault { 0 }
|
|
||||||
|
|
||||||
def buildNumber = System.env.BUILDKITE_BUILD_NUMBER as Integer ?: 0
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
// Due to a bug introduced in Android gradle plugin 3.6.0, we have to specify the ndk version to use
|
// Due to a bug introduced in Android gradle plugin 3.6.0, we have to specify the ndk version to use
|
||||||
// Ref: https://issuetracker.google.com/issues/144111441
|
// Ref: https://issuetracker.google.com/issues/144111441
|
||||||
@ -132,29 +33,9 @@ android {
|
|||||||
compileSdk versions.compileSdk
|
compileSdk versions.compileSdk
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "im.vector.app"
|
|
||||||
// Set to API 21: see #405
|
// Set to API 21: see #405
|
||||||
minSdk versions.minSdk
|
minSdk versions.minSdk
|
||||||
targetSdk versions.targetSdk
|
targetSdk versions.targetSdk
|
||||||
multiDexEnabled true
|
|
||||||
|
|
||||||
renderscriptTargetApi 24
|
|
||||||
renderscriptSupportModeEnabled true
|
|
||||||
|
|
||||||
// `develop` branch will have version code from timestamp, to ensure each build from CI has a incremented versionCode.
|
|
||||||
// Other branches (main, features, etc.) will have version code based on application version.
|
|
||||||
versionCode project.getVersionCode()
|
|
||||||
|
|
||||||
// Required for sonar analysis
|
|
||||||
versionName "${versionMajor}.${versionMinor}.${versionPatch}-sonar"
|
|
||||||
|
|
||||||
// Generate a random app task affinity
|
|
||||||
manifestPlaceholders = [appTaskAffinitySuffix: "H_${gitRevision()}"]
|
|
||||||
|
|
||||||
buildConfigField "String", "GIT_REVISION", "\"${gitRevision()}\""
|
|
||||||
buildConfigField "String", "GIT_REVISION_DATE", "\"${gitRevisionDate()}\""
|
|
||||||
buildConfigField "String", "GIT_BRANCH_NAME", "\"${gitBranchName()}\""
|
|
||||||
buildConfigField "String", "BUILD_NUMBER", "\"${buildNumber}\""
|
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
@ -163,38 +44,8 @@ android {
|
|||||||
abiFilters "armeabi-v7a", "x86", 'arm64-v8a', 'x86_64'
|
abiFilters "armeabi-v7a", "x86", 'arm64-v8a', 'x86_64'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ref: https://developer.android.com/studio/build/configure-apk-splits.html
|
// Generate a random app task affinity
|
||||||
splits {
|
manifestPlaceholders = [appTaskAffinitySuffix: "H_${gitRevision()}"]
|
||||||
// Configures multiple APKs based on ABI.
|
|
||||||
abi {
|
|
||||||
// Enables building multiple APKs per ABI.
|
|
||||||
enable true
|
|
||||||
|
|
||||||
// By default all ABIs are included, so use reset() and include to specify that we only
|
|
||||||
// want APKs for armeabi-v7a, x86, arm64-v8a and x86_64.
|
|
||||||
|
|
||||||
// Resets the list of ABIs that Gradle should create APKs for to none.
|
|
||||||
reset()
|
|
||||||
|
|
||||||
// Specifies a list of ABIs that Gradle should create APKs for.
|
|
||||||
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
|
||||||
|
|
||||||
// Generate a universal APK that includes all ABIs, so user who install from CI tool can use this one by default.
|
|
||||||
universalApk true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
applicationVariants.all { variant ->
|
|
||||||
// assign different version code for each output
|
|
||||||
def baseVariantVersion = variant.versionCode * 10
|
|
||||||
variant.outputs.each { output ->
|
|
||||||
def baseAbiVersionCode = project.ext.abiVersionCodes.get(output.getFilter(OutputFile.ABI))
|
|
||||||
// Known limitation: it does not modify the value in the BuildConfig.java generated file
|
|
||||||
// See https://issuetracker.google.com/issues/171133218
|
|
||||||
output.versionCodeOverride = baseVariantVersion + baseAbiVersionCode
|
|
||||||
print "ABI " + output.getFilter(OutputFile.ABI) + " \t-> VersionCode = " + output.versionCodeOverride + "\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The following argument makes the Android Test Orchestrator run its
|
// The following argument makes the Android Test Orchestrator run its
|
||||||
// "pm clear" command after each test invocation. This command ensures
|
// "pm clear" command after each test invocation. This command ensures
|
||||||
@ -210,87 +61,20 @@ android {
|
|||||||
// Comment to run on Android 12
|
// Comment to run on Android 12
|
||||||
// execution 'ANDROIDX_TEST_ORCHESTRATOR'
|
// execution 'ANDROIDX_TEST_ORCHESTRATOR'
|
||||||
}
|
}
|
||||||
signingConfigs {
|
|
||||||
debug {
|
|
||||||
keyAlias 'androiddebugkey'
|
|
||||||
keyPassword 'android'
|
|
||||||
storeFile file('./signature/debug.keystore')
|
|
||||||
storePassword 'android'
|
|
||||||
}
|
|
||||||
nightly {
|
|
||||||
keyAlias System.env.ELEMENT_ANDROID_NIGHTLY_KEYID ?: project.property("signing.element.nightly.keyId")
|
|
||||||
keyPassword System.env.ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD ?: project.property("signing.element.nightly.keyPassword")
|
|
||||||
storeFile file('./signature/nightly.keystore')
|
|
||||||
storePassword System.env.ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD ?: project.property("signing.element.nightly.storePassword")
|
|
||||||
}
|
|
||||||
release {
|
|
||||||
keyAlias project.property("signing.element.keyId")
|
|
||||||
keyPassword project.property("signing.element.keyPassword")
|
|
||||||
storeFile file(project.property("signing.element.storePath"))
|
|
||||||
storePassword project.property("signing.element.storePassword")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
debug {
|
debug {
|
||||||
applicationIdSuffix ".debug"
|
|
||||||
resValue "string", "app_name", "Element dbg"
|
resValue "string", "app_name", "Element dbg"
|
||||||
resValue "color", "launcher_background", "#0DBD8B"
|
|
||||||
|
|
||||||
signingConfig signingConfigs.debug
|
|
||||||
|
|
||||||
if (project.hasProperty("coverage")) {
|
if (project.hasProperty("coverage")) {
|
||||||
testCoverageEnabled = coverage.enableTestCoverage
|
testCoverageEnabled = coverage.enableTestCoverage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
release {
|
|
||||||
resValue "string", "app_name", "Element"
|
|
||||||
resValue "color", "launcher_background", "#0DBD8B"
|
|
||||||
|
|
||||||
postprocessing {
|
|
||||||
removeUnusedCode true
|
|
||||||
removeUnusedResources true
|
|
||||||
// We do not activate obfuscation as it makes it hard then to read crash reports, and it's a bit useless on an open source project :)
|
|
||||||
obfuscate false
|
|
||||||
optimizeCode true
|
|
||||||
proguardFiles 'proguard-rules.pro'
|
|
||||||
}
|
|
||||||
// signingConfig signingConfigs.release
|
|
||||||
}
|
|
||||||
|
|
||||||
nightly {
|
nightly {
|
||||||
initWith release
|
initWith release
|
||||||
applicationIdSuffix ".nightly"
|
resValue "string", "app_name", "Element"
|
||||||
versionNameSuffix "-nightly"
|
|
||||||
|
|
||||||
// Just override the background color of the launcher icon for the nightly build.
|
|
||||||
resValue "color", "launcher_background", "#07007E"
|
|
||||||
|
|
||||||
// We need to copy paste this block, this is not done automatically by `initWith release`
|
|
||||||
postprocessing {
|
|
||||||
removeUnusedCode true
|
|
||||||
removeUnusedResources true
|
|
||||||
// We do not activate obfuscation as it makes it hard then to read crash reports, and it's a bit useless on an open source project :)
|
|
||||||
obfuscate false
|
|
||||||
optimizeCode true
|
|
||||||
proguardFiles 'proguard-rules.pro'
|
|
||||||
}
|
|
||||||
matchingFallbacks = ['release']
|
matchingFallbacks = ['release']
|
||||||
signingConfig signingConfigs.nightly
|
|
||||||
firebaseAppDistribution {
|
|
||||||
artifactType = "APK"
|
|
||||||
// We upload the universal APK to fix this error:
|
|
||||||
// "App Distribution found more than 1 output file for this variant.
|
|
||||||
// Please contact firebase-support@google.com for help using APK splits with App Distribution."
|
|
||||||
artifactPath = "$rootDir/vector/build/outputs/apk/gplay/nightly/vector-gplay-universal-nightly.apk"
|
|
||||||
// This file will be generated by the GitHub action
|
|
||||||
releaseNotesFile = "CHANGES_NIGHTLY.md"
|
|
||||||
groups = "external-testers"
|
|
||||||
// This should not be required, but if I do not add the appId, I get this error:
|
|
||||||
// "App Distribution halted because it had a problem uploading the APK: [404] Requested entity was not found."
|
|
||||||
appId = "1:912726360885:android:efd8545af52a9f9300427c"
|
|
||||||
}
|
}
|
||||||
|
release {
|
||||||
|
resValue "string", "app_name", "Element"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,14 +82,8 @@ android {
|
|||||||
|
|
||||||
productFlavors {
|
productFlavors {
|
||||||
gplay {
|
gplay {
|
||||||
apply plugin: 'com.google.gms.google-services'
|
|
||||||
afterEvaluate {
|
|
||||||
tasks.matching { it.name.contains("GoogleServices") && !it.name.contains("Gplay") }*.enabled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
dimension "store"
|
dimension "store"
|
||||||
isDefault = true
|
isDefault = true
|
||||||
versionName "${versionMajor}.${versionMinor}.${versionPatch}${getGplayVersionSuffix()}"
|
|
||||||
|
|
||||||
buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"G\""
|
buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"G\""
|
||||||
buildConfigField "String", "FLAVOR_DESCRIPTION", "\"GooglePlay\""
|
buildConfigField "String", "FLAVOR_DESCRIPTION", "\"GooglePlay\""
|
||||||
@ -314,20 +92,11 @@ android {
|
|||||||
fdroid {
|
fdroid {
|
||||||
dimension "store"
|
dimension "store"
|
||||||
|
|
||||||
versionName "${versionMajor}.${versionMinor}.${versionPatch}${getFdroidVersionSuffix()}"
|
|
||||||
|
|
||||||
buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"F\""
|
buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"F\""
|
||||||
buildConfigField "String", "FLAVOR_DESCRIPTION", "\"FDroid\""
|
buildConfigField "String", "FLAVOR_DESCRIPTION", "\"FDroid\""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lintOptions {
|
|
||||||
lintConfig file("lint.xml")
|
|
||||||
|
|
||||||
checkDependencies true
|
|
||||||
abortOnError true
|
|
||||||
}
|
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility versions.sourceCompat
|
sourceCompatibility versions.sourceCompat
|
||||||
targetCompatibility versions.targetCompat
|
targetCompatibility versions.targetCompat
|
||||||
@ -367,7 +136,7 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(":vector-config")
|
implementation project(":vector-config")
|
||||||
implementation project(":matrix-sdk-android")
|
api project(":matrix-sdk-android")
|
||||||
implementation project(":matrix-sdk-android-flow")
|
implementation project(":matrix-sdk-android-flow")
|
||||||
implementation project(":library:jsonviewer")
|
implementation project(":library:jsonviewer")
|
||||||
implementation project(":library:ui-styles")
|
implementation project(":library:ui-styles")
|
||||||
@ -375,7 +144,6 @@ dependencies {
|
|||||||
implementation project(":library:attachment-viewer")
|
implementation project(":library:attachment-viewer")
|
||||||
implementation project(":library:diff-match-patch")
|
implementation project(":library:diff-match-patch")
|
||||||
implementation project(":library:multipicker")
|
implementation project(":library:multipicker")
|
||||||
implementation 'androidx.multidex:multidex:2.0.1'
|
|
||||||
|
|
||||||
implementation libs.jetbrains.coroutinesCore
|
implementation libs.jetbrains.coroutinesCore
|
||||||
implementation libs.jetbrains.coroutinesAndroid
|
implementation libs.jetbrains.coroutinesAndroid
|
||||||
@ -384,49 +152,47 @@ dependencies {
|
|||||||
implementation libs.androidx.appCompat
|
implementation libs.androidx.appCompat
|
||||||
implementation libs.androidx.fragmentKtx
|
implementation libs.androidx.fragmentKtx
|
||||||
implementation libs.androidx.constraintLayout
|
implementation libs.androidx.constraintLayout
|
||||||
implementation "androidx.sharetarget:sharetarget:1.1.0"
|
|
||||||
implementation libs.androidx.core
|
implementation libs.androidx.core
|
||||||
implementation "androidx.media:media:1.6.0"
|
implementation "androidx.media:media:1.6.0"
|
||||||
implementation "androidx.transition:transition:1.4.1"
|
implementation "androidx.transition:transition:1.4.1"
|
||||||
implementation libs.androidx.biometric
|
implementation libs.androidx.biometric
|
||||||
|
|
||||||
implementation "org.threeten:threetenbp:1.4.0:no-tzdb"
|
api "org.threeten:threetenbp:1.4.0:no-tzdb"
|
||||||
implementation "com.gabrielittner.threetenbp:lazythreetenbp:0.11.0"
|
api "com.gabrielittner.threetenbp:lazythreetenbp:0.11.0"
|
||||||
|
|
||||||
implementation libs.squareup.moshi
|
implementation libs.squareup.moshi
|
||||||
kapt libs.squareup.moshiKotlin
|
kapt libs.squareup.moshiKotlin
|
||||||
|
|
||||||
// Lifecycle
|
// Lifecycle
|
||||||
implementation libs.androidx.lifecycleLivedata
|
implementation libs.androidx.lifecycleLivedata
|
||||||
implementation libs.androidx.lifecycleProcess
|
api libs.androidx.lifecycleProcess
|
||||||
implementation libs.androidx.lifecycleRuntimeKtx
|
implementation libs.androidx.lifecycleRuntimeKtx
|
||||||
|
|
||||||
implementation libs.androidx.datastorepreferences
|
api libs.androidx.datastorepreferences
|
||||||
|
|
||||||
// Opus Encoder
|
// Opus Encoder
|
||||||
implementation libs.element.opusencoder
|
implementation libs.element.opusencoder
|
||||||
|
|
||||||
// Log
|
// Log
|
||||||
implementation libs.jakewharton.timber
|
api libs.jakewharton.timber
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
implementation 'com.facebook.stetho:stetho:1.6.0'
|
api 'com.facebook.stetho:stetho:1.6.0'
|
||||||
|
|
||||||
// Phone number https://github.com/google/libphonenumber
|
api libs.google.phonenumber
|
||||||
implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.54'
|
|
||||||
|
|
||||||
// FlowBinding
|
// FlowBinding
|
||||||
implementation libs.github.flowBinding
|
implementation libs.github.flowBinding
|
||||||
implementation libs.github.flowBindingAppcompat
|
implementation libs.github.flowBindingAppcompat
|
||||||
|
|
||||||
implementation libs.airbnb.epoxy
|
api libs.airbnb.epoxy
|
||||||
implementation libs.airbnb.epoxyGlide
|
implementation libs.airbnb.epoxyGlide
|
||||||
kapt libs.airbnb.epoxyProcessor
|
kapt libs.airbnb.epoxyProcessor
|
||||||
implementation libs.airbnb.epoxyPaging
|
implementation libs.airbnb.epoxyPaging
|
||||||
implementation libs.airbnb.mavericks
|
api libs.airbnb.mavericks
|
||||||
|
|
||||||
// Snap Helper https://github.com/rubensousa/GravitySnapHelper
|
// Snap Helper https://github.com/rubensousa/GravitySnapHelper
|
||||||
implementation 'com.github.rubensousa:gravitysnaphelper:2.2.2'
|
api 'com.github.rubensousa:gravitysnaphelper:2.2.2'
|
||||||
|
|
||||||
// Nightly
|
// Nightly
|
||||||
// API-only library
|
// API-only library
|
||||||
@ -435,7 +201,7 @@ dependencies {
|
|||||||
gplayImplementation libs.google.appdistribution
|
gplayImplementation libs.google.appdistribution
|
||||||
|
|
||||||
// Work
|
// Work
|
||||||
implementation libs.androidx.work
|
api libs.androidx.work
|
||||||
|
|
||||||
// Paging
|
// Paging
|
||||||
implementation libs.androidx.pagingRuntimeKtx
|
implementation libs.androidx.pagingRuntimeKtx
|
||||||
@ -444,7 +210,7 @@ dependencies {
|
|||||||
implementation libs.arrow.core
|
implementation libs.arrow.core
|
||||||
|
|
||||||
// Pref
|
// Pref
|
||||||
implementation libs.androidx.preferenceKtx
|
api libs.androidx.preferenceKtx
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
|
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
|
||||||
@ -519,7 +285,7 @@ dependencies {
|
|||||||
implementation('com.facebook.react:react-native-webrtc:1.94.2-jitsi-10227332@aar')
|
implementation('com.facebook.react:react-native-webrtc:1.94.2-jitsi-10227332@aar')
|
||||||
|
|
||||||
// Jitsi
|
// Jitsi
|
||||||
implementation('org.jitsi.react:jitsi-meet-sdk:5.0.2') {
|
api('org.jitsi.react:jitsi-meet-sdk:5.0.2') {
|
||||||
exclude group: 'com.google.firebase'
|
exclude group: 'com.google.firebase'
|
||||||
exclude group: 'com.google.android.gms'
|
exclude group: 'com.google.android.gms'
|
||||||
exclude group: 'com.android.installreferrer'
|
exclude group: 'com.android.installreferrer'
|
||||||
@ -531,8 +297,8 @@ dependencies {
|
|||||||
implementation 'me.dm7.barcodescanner:zxing:1.9.13'
|
implementation 'me.dm7.barcodescanner:zxing:1.9.13'
|
||||||
|
|
||||||
// Emoji Keyboard
|
// Emoji Keyboard
|
||||||
implementation libs.vanniktech.emojiMaterial
|
api libs.vanniktech.emojiMaterial
|
||||||
implementation libs.vanniktech.emojiGoogle
|
api libs.vanniktech.emojiGoogle
|
||||||
|
|
||||||
implementation 'im.dlg:android-dialer:1.2.5'
|
implementation 'im.dlg:android-dialer:1.2.5'
|
||||||
|
|
||||||
@ -545,14 +311,14 @@ dependencies {
|
|||||||
implementation 'commons-codec:commons-codec:1.15'
|
implementation 'commons-codec:commons-codec:1.15'
|
||||||
|
|
||||||
// MapTiler
|
// MapTiler
|
||||||
fdroidImplementation(libs.maplibre.androidSdk) {
|
fdroidApi(libs.maplibre.androidSdk) {
|
||||||
exclude group: 'com.google.android.gms', module: 'play-services-location'
|
exclude group: 'com.google.android.gms', module: 'play-services-location'
|
||||||
}
|
}
|
||||||
fdroidImplementation(libs.maplibre.pluginAnnotation) {
|
fdroidApi(libs.maplibre.pluginAnnotation) {
|
||||||
exclude group: 'com.google.android.gms', module: 'play-services-location'
|
exclude group: 'com.google.android.gms', module: 'play-services-location'
|
||||||
}
|
}
|
||||||
gplayImplementation libs.maplibre.androidSdk
|
gplayApi libs.maplibre.androidSdk
|
||||||
gplayImplementation libs.maplibre.pluginAnnotation
|
gplayApi libs.maplibre.pluginAnnotation
|
||||||
|
|
||||||
// TESTS
|
// TESTS
|
||||||
testImplementation libs.tests.junit
|
testImplementation libs.tests.junit
|
||||||
|
@ -20,8 +20,8 @@ import android.content.SharedPreferences
|
|||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import com.google.firebase.appdistribution.FirebaseAppDistribution
|
import com.google.firebase.appdistribution.FirebaseAppDistribution
|
||||||
import com.google.firebase.appdistribution.FirebaseAppDistributionException
|
import com.google.firebase.appdistribution.FirebaseAppDistributionException
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.core.di.DefaultPreferences
|
import im.vector.app.core.di.DefaultPreferences
|
||||||
|
import im.vector.app.core.resources.BuildMeta
|
||||||
import im.vector.app.core.time.Clock
|
import im.vector.app.core.time.Clock
|
||||||
import im.vector.app.features.home.NightlyProxy
|
import im.vector.app.features.home.NightlyProxy
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -31,6 +31,7 @@ class FirebaseNightlyProxy @Inject constructor(
|
|||||||
private val clock: Clock,
|
private val clock: Clock,
|
||||||
@DefaultPreferences
|
@DefaultPreferences
|
||||||
private val sharedPreferences: SharedPreferences,
|
private val sharedPreferences: SharedPreferences,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
) : NightlyProxy {
|
) : NightlyProxy {
|
||||||
|
|
||||||
override fun onHomeResumed() {
|
override fun onHomeResumed() {
|
||||||
@ -58,7 +59,7 @@ class FirebaseNightlyProxy @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun canDisplayPopup(): Boolean {
|
private fun canDisplayPopup(): Boolean {
|
||||||
if (BuildConfig.APPLICATION_ID != "im.vector.app.nightly") return false
|
if (buildMeta.applicationId != "im.vector.app.nightly") return false
|
||||||
val today = clock.epochMillis() / A_DAY_IN_MILLIS
|
val today = clock.epochMillis() / A_DAY_IN_MILLIS
|
||||||
val lastDisplayPopupDay = sharedPreferences.getLong(SHARED_PREF_KEY, 0)
|
val lastDisplayPopupDay = sharedPreferences.getLong(SHARED_PREF_KEY, 0)
|
||||||
return (today > lastDisplayPopupDay)
|
return (today > lastDisplayPopupDay)
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
|
||||||
<!-- Call feature -->
|
<!-- Call feature -->
|
||||||
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
|
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
|
||||||
@ -74,20 +75,7 @@
|
|||||||
</intent>
|
</intent>
|
||||||
</queries>
|
</queries>
|
||||||
|
|
||||||
<application
|
<application android:supportsRtl="true">
|
||||||
android:name=".VectorApplication"
|
|
||||||
android:allowBackup="false"
|
|
||||||
android:hasFragileUserData="true"
|
|
||||||
android:icon="@mipmap/ic_launcher"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:networkSecurityConfig="@xml/network_security_config"
|
|
||||||
android:resizeableActivity="true"
|
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
|
||||||
android:supportsRtl="true"
|
|
||||||
android:taskAffinity="${applicationId}.${appTaskAffinitySuffix}"
|
|
||||||
android:theme="@style/Theme.Vector.Light"
|
|
||||||
tools:ignore="UnusedAttribute"
|
|
||||||
tools:replace="android:allowBackup">
|
|
||||||
|
|
||||||
<!-- No limit for screen ratio: avoid black strips -->
|
<!-- No limit for screen ratio: avoid black strips -->
|
||||||
<meta-data
|
<meta-data
|
||||||
@ -434,42 +422,6 @@
|
|||||||
<action android:name="org.unifiedpush.android.connector.REGISTRATION_REFUSED" />
|
<action android:name="org.unifiedpush.android.connector.REGISTRATION_REFUSED" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<!-- Providers -->
|
|
||||||
|
|
||||||
<!-- Remove WorkManagerInitializer Provider because we are using on-demand initialization of WorkManager-->
|
|
||||||
<provider
|
|
||||||
android:name="androidx.startup.InitializationProvider"
|
|
||||||
android:authorities="${applicationId}.androidx-startup"
|
|
||||||
android:exported="false"
|
|
||||||
tools:node="merge">
|
|
||||||
<meta-data
|
|
||||||
android:name="androidx.work.WorkManagerInitializer"
|
|
||||||
android:value="androidx.startup"
|
|
||||||
tools:node="remove" />
|
|
||||||
<!-- We init the lib ourself in EmojiCompatWrapper -->
|
|
||||||
<meta-data
|
|
||||||
android:name="androidx.emoji2.text.EmojiCompatInitializer"
|
|
||||||
tools:node="remove" />
|
|
||||||
</provider>
|
|
||||||
|
|
||||||
<provider
|
|
||||||
android:name="androidx.core.content.FileProvider"
|
|
||||||
android:authorities="${applicationId}.fileProvider"
|
|
||||||
android:exported="false"
|
|
||||||
android:grantUriPermissions="true">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
|
||||||
android:resource="@xml/sdk_provider_paths" />
|
|
||||||
</provider>
|
|
||||||
|
|
||||||
<!-- Temporary fix for Android 12. android:exported has to be explicitly set when targeting Android 12
|
|
||||||
Do it for services coming from dependencies - BEGIN -->
|
|
||||||
<service
|
|
||||||
android:name="androidx.sharetarget.ChooserTargetServiceCompat"
|
|
||||||
android:exported="false"
|
|
||||||
tools:node="merge" />
|
|
||||||
<!-- Temporary fix for Android 12 change - END -->
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@ -246,7 +246,7 @@ abstract class CallTileTimelineItem : AbsBaseMessageItem<CallTileTimelineItem.Ho
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageCallStub
|
private val STUB_ID = R.id.messageCallStub
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Attributes(
|
data class Attributes(
|
||||||
|
@ -61,6 +61,6 @@ abstract class DefaultItem : BaseEventItem<DefaultItem.Holder>(R.layout.item_tim
|
|||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentDefaultStub
|
private val STUB_ID = R.id.messageContentDefaultStub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ abstract class MergedRoomCreationItem : BasedMergedItem<MergedRoomCreationItem.H
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentMergedCreationStub
|
private val STUB_ID = R.id.messageContentMergedCreationStub
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Attributes(
|
data class Attributes(
|
||||||
|
@ -63,7 +63,7 @@ abstract class MergedSimilarEventsItem : BasedMergedItem<MergedSimilarEventsItem
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentMergedHeaderStub
|
private val STUB_ID = R.id.messageContentMergedHeaderStub
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Attributes(
|
data class Attributes(
|
||||||
|
@ -210,6 +210,6 @@ abstract class MessageAudioItem : AbsMessageItem<MessageAudioItem.Holder>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentAudioStub
|
private val STUB_ID = R.id.messageContentAudioStub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,6 +118,6 @@ abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentFileStub
|
private val STUB_ID = R.id.messageContentFileStub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,6 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentMediaStub
|
private val STUB_ID = R.id.messageContentMediaStub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,6 @@ abstract class MessageLiveLocationInactiveItem :
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentLiveLocationInactiveStub
|
private val STUB_ID = R.id.messageContentLiveLocationInactiveStub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,6 @@ abstract class MessageLiveLocationItem : AbsMessageLocationItem<MessageLiveLocat
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentLiveLocationStub
|
private val STUB_ID = R.id.messageContentLiveLocationStub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,6 @@ abstract class MessageLiveLocationStartItem :
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentLiveLocationStartStub
|
private val STUB_ID = R.id.messageContentLiveLocationStartStub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,6 @@ abstract class MessageLocationItem : AbsMessageLocationItem<MessageLocationItem.
|
|||||||
class Holder : AbsMessageLocationItem.Holder(STUB_ID)
|
class Holder : AbsMessageLocationItem.Holder(STUB_ID)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentLocationStub
|
private val STUB_ID = R.id.messageContentLocationStub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,6 +144,6 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentTextStub
|
private val STUB_ID = R.id.messageContentTextStub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,6 +179,6 @@ abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentVoiceStub
|
private val STUB_ID = R.id.messageContentVoiceStub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,6 @@ abstract class NoticeItem : BaseEventItem<NoticeItem.Holder>(R.layout.item_timel
|
|||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentNoticeStub
|
private val STUB_ID = R.id.messageContentNoticeStub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,6 @@ abstract class PollItem : AbsMessageItem<PollItem.Holder>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentPollStub
|
private val STUB_ID = R.id.messageContentPollStub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,6 @@ abstract class RedactedMessageItem : AbsMessageItem<RedactedMessageItem.Holder>(
|
|||||||
class Holder : AbsMessageItem.Holder(STUB_ID)
|
class Holder : AbsMessageItem.Holder(STUB_ID)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageContentRedactedStub
|
private val STUB_ID = R.id.messageContentRedactedStub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ abstract class StatusTileTimelineItem : AbsBaseMessageItem<StatusTileTimelineIte
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageVerificationDoneStub
|
private val STUB_ID = R.id.messageVerificationDoneStub
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -137,7 +137,7 @@ abstract class VerificationRequestItem : AbsBaseMessageItem<VerificationRequestI
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageVerificationRequestStub
|
private val STUB_ID = R.id.messageVerificationRequestStub
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,7 +66,7 @@ abstract class WidgetTileTimelineItem : AbsBaseMessageItem<WidgetTileTimelineIte
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val STUB_ID = R.id.messageWidgetStub
|
private val STUB_ID = R.id.messageWidgetStub
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|