Merge pull request #469 from vector-im/feature/versionCode_auto

Ensure versionCode is the wanted one for GPlay and F-Droid build
This commit is contained in:
Benoit Marty 2019-08-08 16:32:10 +02:00 committed by GitHub
commit 37fde374b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 128 additions and 77 deletions

View File

@ -71,9 +71,7 @@ android {
targetSdkVersion 28 targetSdkVersion 28
multiDexEnabled true multiDexEnabled true


// For release, use generateVersionCodeFromVersionName() // Note: versionCode is depending on the build variant
versionCode generateVersionCodeFromTimestamp()
//versionCode generateVersionCodeFromVersionName()


versionName "${versionMajor}.${versionMinor}.${versionPatch}-dev" versionName "${versionMajor}.${versionMinor}.${versionPatch}-dev"


@ -117,9 +115,10 @@ android {
} }
} }


android.applicationVariants.all { variant -> applicationVariants.all { variant ->
variant.outputs.each { output -> variant.outputs.each { output ->
def baseAbiVersionCode = project.ext.abiVersionCodes.get(output.getFilter(OutputFile.ABI)) def baseAbiVersionCode = project.ext.abiVersionCodes.get(output.getFilter(OutputFile.ABI))
// Known limitation: it does not modify the value in the BuildConfig.java generated file
output.versionCodeOverride = baseAbiVersionCode * 10_000_000 + variant.versionCode output.versionCodeOverride = baseAbiVersionCode * 10_000_000 + variant.versionCode
} }
} }
@ -162,6 +161,8 @@ android {
gplay { gplay {
dimension "store" dimension "store"


versionCode = generateVersionCodeFromVersionName()

buildConfigField "boolean", "ALLOW_FCM_USE", "true" buildConfigField "boolean", "ALLOW_FCM_USE", "true"
buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"G\"" buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"G\""
buildConfigField "String", "FLAVOR_DESCRIPTION", "\"GooglePlay\"" buildConfigField "String", "FLAVOR_DESCRIPTION", "\"GooglePlay\""
@ -170,6 +171,8 @@ android {
fdroid { fdroid {
dimension "store" dimension "store"


versionCode = generateVersionCodeFromTimestamp()

buildConfigField "boolean", "ALLOW_FCM_USE", "false" buildConfigField "boolean", "ALLOW_FCM_USE", "false"
buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"F\"" buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"F\""
buildConfigField "String", "FLAVOR_DESCRIPTION", "\"FDroid\"" buildConfigField "String", "FLAVOR_DESCRIPTION", "\"FDroid\""

View File

@ -51,7 +51,7 @@ import im.vector.riotx.features.notifications.PushRuleTriggerListener
import im.vector.riotx.features.rageshake.VectorFileLogger import im.vector.riotx.features.rageshake.VectorFileLogger
import im.vector.riotx.features.rageshake.VectorUncaughtExceptionHandler import im.vector.riotx.features.rageshake.VectorUncaughtExceptionHandler
import im.vector.riotx.features.settings.VectorPreferences import im.vector.riotx.features.settings.VectorPreferences
import im.vector.riotx.features.version.getVersion import im.vector.riotx.features.version.VersionProvider
import im.vector.riotx.push.fcm.FcmHelper import im.vector.riotx.push.fcm.FcmHelper
import timber.log.Timber import timber.log.Timber
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -71,6 +71,7 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration.
@Inject lateinit var notificationDrawerManager: NotificationDrawerManager @Inject lateinit var notificationDrawerManager: NotificationDrawerManager
@Inject lateinit var pushRuleTriggerListener: PushRuleTriggerListener @Inject lateinit var pushRuleTriggerListener: PushRuleTriggerListener
@Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var vectorPreferences: VectorPreferences
@Inject lateinit var versionProvider: VersionProvider
lateinit var vectorComponent: VectorComponent lateinit var vectorComponent: VectorComponent
private var fontThreadHandler: Handler? = null private var fontThreadHandler: Handler? = null


@ -140,7 +141,7 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration.
} }


private fun logInfo() { private fun logInfo() {
val appVersion = getVersion(longFormat = true, useBuildNumber = true) val appVersion = versionProvider.getVersion(longFormat = true, useBuildNumber = true)
val sdkVersion = Matrix.getSdkVersion() val sdkVersion = Matrix.getSdkVersion()
val date = SimpleDateFormat("MM-dd HH:mm:ss.SSSZ", Locale.US).format(Date()) val date = SimpleDateFormat("MM-dd HH:mm:ss.SSSZ", Locale.US).format(Date())



View File

@ -154,6 +154,8 @@ interface ScreenComponent {


fun inject(vectorSettingsSecurityPrivacyFragment: VectorSettingsSecurityPrivacyFragment) fun inject(vectorSettingsSecurityPrivacyFragment: VectorSettingsSecurityPrivacyFragment)


fun inject(vectorSettingsHelpAboutFragment: VectorSettingsHelpAboutFragment)

fun inject(userAvatarPreference: UserAvatarPreference) fun inject(userAvatarPreference: UserAvatarPreference)


fun inject(vectorSettingsNotificationsTroubleshootFragment: VectorSettingsNotificationsTroubleshootFragment) fun inject(vectorSettingsNotificationsTroubleshootFragment: VectorSettingsNotificationsTroubleshootFragment)

View File

@ -0,0 +1,40 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.riotx.core.resources

import android.content.Context
import android.os.Build
import androidx.annotation.NonNull
import javax.inject.Inject

class VersionCodeProvider @Inject constructor(private val context: Context) {

/**
* Returns the version code, read from the Manifest. It is not the same than BuildConfig.VERSION_CODE due to versionCodeOverride
*/
@NonNull
fun getVersionCode(): Long {
val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0)

return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
packageInfo.longVersionCode
} else {
@Suppress("DEPRECATION")
packageInfo.versionCode.toLong()
}
}
}

View File

@ -35,7 +35,7 @@ import im.vector.riotx.core.extensions.toOnOff
import im.vector.riotx.core.utils.getDeviceLocale import im.vector.riotx.core.utils.getDeviceLocale
import im.vector.riotx.features.settings.VectorLocale import im.vector.riotx.features.settings.VectorLocale
import im.vector.riotx.features.themes.ThemeUtils import im.vector.riotx.features.themes.ThemeUtils
import im.vector.riotx.features.version.getVersion import im.vector.riotx.features.version.VersionProvider
import okhttp3.* import okhttp3.*
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
@ -51,7 +51,8 @@ import javax.inject.Singleton
* BugReporter creates and sends the bug reports. * BugReporter creates and sends the bug reports.
*/ */
@Singleton @Singleton
class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSessionHolder) { class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSessionHolder,
private val versionProvider: VersionProvider) {
var inMultiWindowMode = false var inMultiWindowMode = false


companion object { companion object {
@ -225,7 +226,7 @@ class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSes
.addFormDataPart("user_agent", Matrix.getInstance(context).getUserAgent()) .addFormDataPart("user_agent", Matrix.getInstance(context).getUserAgent())
.addFormDataPart("user_id", userId) .addFormDataPart("user_id", userId)
.addFormDataPart("device_id", deviceId) .addFormDataPart("device_id", deviceId)
.addFormDataPart("version", getVersion(longFormat = true, useBuildNumber = false)) .addFormDataPart("version", versionProvider.getVersion(longFormat = true, useBuildNumber = false))
.addFormDataPart("branch_name", context.getString(R.string.git_branch_name)) .addFormDataPart("branch_name", context.getString(R.string.git_branch_name))
.addFormDataPart("matrix_sdk_version", Matrix.getSdkVersion()) .addFormDataPart("matrix_sdk_version", Matrix.getSdkVersion())
.addFormDataPart("olm_version", olmVersion) .addFormDataPart("olm_version", olmVersion)

View File

@ -21,8 +21,8 @@ import android.os.Build
import androidx.core.content.edit import androidx.core.content.edit
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.Matrix
import im.vector.riotx.BuildConfig import im.vector.riotx.core.resources.VersionCodeProvider
import im.vector.riotx.features.version.getVersion import im.vector.riotx.features.version.VersionProvider
import timber.log.Timber import timber.log.Timber
import java.io.PrintWriter import java.io.PrintWriter
import java.io.StringWriter import java.io.StringWriter
@ -30,16 +30,15 @@ import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton


@Singleton @Singleton
class VectorUncaughtExceptionHandler @Inject constructor(private val bugReporter: BugReporter) : Thread.UncaughtExceptionHandler { class VectorUncaughtExceptionHandler @Inject constructor(private val bugReporter: BugReporter,
private val versionProvider: VersionProvider,
private val versionCodeProvider: VersionCodeProvider) : Thread.UncaughtExceptionHandler {


// key to save the crash status // key to save the crash status
companion object { companion object {
private const val PREFS_CRASH_KEY = "PREFS_CRASH_KEY" private const val PREFS_CRASH_KEY = "PREFS_CRASH_KEY"
} }


private val vectorVersion = getVersion(longFormat = true, useBuildNumber = true)
private val matrixSdkVersion = Matrix.getSdkVersion()

private var previousHandler: Thread.UncaughtExceptionHandler? = null private var previousHandler: Thread.UncaughtExceptionHandler? = null


private lateinit var context: Context private lateinit var context: Context
@ -68,9 +67,9 @@ class VectorUncaughtExceptionHandler @Inject constructor(private val bugReporter
val b = StringBuilder() val b = StringBuilder()
val appName = "RiotX" // TODO Matrix.getApplicationName() val appName = "RiotX" // TODO Matrix.getApplicationName()


b.append(appName + " Build : " + BuildConfig.VERSION_CODE + "\n") b.append(appName + " Build : " + versionCodeProvider.getVersionCode() + "\n")
b.append("$appName Version : $vectorVersion\n") b.append("$appName Version : ${versionProvider.getVersion(longFormat = true, useBuildNumber = true)}\n")
b.append("SDK Version : $matrixSdkVersion\n") b.append("SDK Version : ${Matrix.getSdkVersion()}\n")
b.append("Phone : " + Build.MODEL.trim() + " (" + Build.VERSION.INCREMENTAL + " " + Build.VERSION.RELEASE + " " + Build.VERSION.CODENAME + ")\n") b.append("Phone : " + Build.MODEL.trim() + " (" + Build.VERSION.INCREMENTAL + " " + Build.VERSION.RELEASE + " " + Build.VERSION.CODENAME + ")\n")


b.append("Memory statuses \n") b.append("Memory statuses \n")
@ -94,14 +93,6 @@ class VectorUncaughtExceptionHandler @Inject constructor(private val bugReporter
b.append("Thread: ") b.append("Thread: ")
b.append(thread.name) b.append(thread.name)


/*
val a = VectorApp.getCurrentActivity()
if (a != null) {
b.append(", Activity:")
b.append(a.localClassName)
}
*/

b.append(", Exception: ") b.append(", Exception: ")


val sw = StringWriter() val sw = StringWriter()

View File

@ -23,15 +23,23 @@ import androidx.preference.Preference
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.Matrix
import im.vector.riotx.R import im.vector.riotx.R
import im.vector.riotx.core.di.ScreenComponent
import im.vector.riotx.core.utils.copyToClipboard import im.vector.riotx.core.utils.copyToClipboard
import im.vector.riotx.core.utils.displayInWebView import im.vector.riotx.core.utils.displayInWebView
import im.vector.riotx.features.version.getVersion import im.vector.riotx.features.version.VersionProvider
import javax.inject.Inject


class VectorSettingsHelpAboutFragment : VectorSettingsBaseFragment() { class VectorSettingsHelpAboutFragment : VectorSettingsBaseFragment() {


override var titleRes = R.string.preference_root_help_about override var titleRes = R.string.preference_root_help_about
override val preferenceXmlRes = R.xml.vector_settings_help_about override val preferenceXmlRes = R.xml.vector_settings_help_about


@Inject lateinit var versionProvider: VersionProvider

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun bindPref() { override fun bindPref() {
// preference to start the App info screen, to facilitate App permissions access // preference to start the App info screen, to facilitate App permissions access
findPreference(APP_INFO_LINK_PREFERENCE_KEY) findPreference(APP_INFO_LINK_PREFERENCE_KEY)
@ -54,7 +62,7 @@ class VectorSettingsHelpAboutFragment : VectorSettingsBaseFragment() {


// application version // application version
(findPreference(VectorPreferences.SETTINGS_VERSION_PREFERENCE_KEY)).let { (findPreference(VectorPreferences.SETTINGS_VERSION_PREFERENCE_KEY)).let {
it.summary = getVersion(longFormat = false, useBuildNumber = true) it.summary = versionProvider.getVersion(longFormat = false, useBuildNumber = true)


it.setOnPreferenceClickListener { pref -> it.setOnPreferenceClickListener { pref ->
copyToClipboard(requireContext(), pref.summary) copyToClipboard(requireContext(), pref.summary)

View File

@ -1,49 +0,0 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.riotx.features.version

import im.vector.riotx.BuildConfig

fun getVersion(longFormat: Boolean, useBuildNumber: Boolean): String {
var result = "${BuildConfig.VERSION_NAME} [${BuildConfig.VERSION_CODE}]"

var flavor = BuildConfig.SHORT_FLAVOR_DESCRIPTION

if (flavor.isNotBlank()) {
flavor += "-"
}

var gitVersion = BuildConfig.GIT_REVISION
val gitRevisionDate = BuildConfig.GIT_REVISION_DATE
val buildNumber = BuildConfig.BUILD_NUMBER

var useLongFormat = longFormat

if (useBuildNumber && buildNumber != "0") {
// It's a build from CI
gitVersion = "b$buildNumber"
useLongFormat = false
}

result += if (useLongFormat) {
" ($flavor$gitVersion-$gitRevisionDate)"
} else {
" ($flavor$gitVersion)"
}

return result
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.riotx.features.version

import im.vector.riotx.BuildConfig
import im.vector.riotx.core.resources.VersionCodeProvider
import javax.inject.Inject

class VersionProvider @Inject constructor(private val versionCodeProvider: VersionCodeProvider) {

fun getVersion(longFormat: Boolean, useBuildNumber: Boolean): String {
var result = "${BuildConfig.VERSION_NAME} [${versionCodeProvider.getVersionCode()}]"

var flavor = BuildConfig.SHORT_FLAVOR_DESCRIPTION

if (flavor.isNotBlank()) {
flavor += "-"
}

var gitVersion = BuildConfig.GIT_REVISION
val gitRevisionDate = BuildConfig.GIT_REVISION_DATE
val buildNumber = BuildConfig.BUILD_NUMBER

var useLongFormat = longFormat

if (useBuildNumber && buildNumber != "0") {
// It's a build from CI
gitVersion = "b$buildNumber"
useLongFormat = false
}

result += if (useLongFormat) {
" ($flavor$gitVersion-$gitRevisionDate)"
} else {
" ($flavor$gitVersion)"
}

return result
}
}