Enable auto-updates for nightly builds.
This commit is contained in:
parent
c4f5110148
commit
b8d229e58e
9 changed files with 91 additions and 20 deletions
|
@ -320,22 +320,26 @@ android {
|
|||
dimension 'distribution'
|
||||
isDefault true
|
||||
buildConfigField "boolean", "MANAGES_APP_UPDATES", "false"
|
||||
buildConfigField "String", "APK_UPDATE_URL", "null"
|
||||
buildConfigField "String", "APK_UPDATE_MANIFEST_URL", "null"
|
||||
buildConfigField "String", "BUILD_DISTRIBUTION_TYPE", "\"play\""
|
||||
}
|
||||
|
||||
website {
|
||||
dimension 'distribution'
|
||||
buildConfigField "boolean", "MANAGES_APP_UPDATES", "true"
|
||||
buildConfigField "String", "APK_UPDATE_URL", "\"https://updates.signal.org/android\""
|
||||
buildConfigField "String", "APK_UPDATE_MANIFEST_URL", "\"https://updates.signal.org/android/latest.json\""
|
||||
buildConfigField "String", "BUILD_DISTRIBUTION_TYPE", "\"website\""
|
||||
}
|
||||
|
||||
nightly {
|
||||
def apkUpdateManifestUrl = "<unset>"
|
||||
if (project.hasProperty('nightlyApkUpdateManifestUrl')) {
|
||||
apkUpdateManifestUrl = project.getProperty('nightlyApkUpdateManifestUrl')
|
||||
}
|
||||
dimension 'distribution'
|
||||
versionNameSuffix "-nightly-untagged-${getDateSuffix()}"
|
||||
buildConfigField "boolean", "MANAGES_APP_UPDATES", "false"
|
||||
buildConfigField "String", "APK_UPDATE_URL", "null"
|
||||
buildConfigField "boolean", "MANAGES_APP_UPDATES", "true"
|
||||
buildConfigField "String", "APK_UPDATE_MANIFEST_URL", "\"${apkUpdateManifestUrl}\""
|
||||
buildConfigField "String", "BUILD_DISTRIBUTION_TYPE", "\"nightly\""
|
||||
}
|
||||
|
||||
|
@ -400,6 +404,9 @@ android {
|
|||
tag = tag.substring(1)
|
||||
}
|
||||
output.versionNameOverride = tag
|
||||
output.outputFileName = output.outputFileName.replace(".apk", "-${versionNameOverride}.apk")
|
||||
} else {
|
||||
output.outputFileName = output.outputFileName.replace(".apk", "-${variant.versionName}.apk")
|
||||
}
|
||||
} else {
|
||||
output.outputFileName = output.outputFileName.replace(".apk", "-${variant.versionName}.apk")
|
||||
|
@ -659,6 +666,23 @@ tasks.withType(Test) {
|
|||
}
|
||||
}
|
||||
|
||||
project.tasks.configureEach { task ->
|
||||
if (task.name.toLowerCase().contains("nightly") && task.name != 'checkNightlyParams') {
|
||||
task.dependsOn checkNightlyParams
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register('checkNightlyParams') {
|
||||
doFirst {
|
||||
if (project.gradle.startParameter.taskNames.any { it.toLowerCase().contains("nightly") }) {
|
||||
if (!project.hasProperty('nightlyApkUpdateManifestUrl')) {
|
||||
throw new GradleException("Required command-line parameter 'nightlyApkUpdateManifestUrl' not found for nightly build!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def loadKeystoreProperties(filename) {
|
||||
def keystorePropertiesFile = file("${project.rootDir}/${filename}")
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.signal.core.util.getDownloadManager
|
|||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.util.Environment
|
||||
import org.thoughtcrime.securesms.util.FileUtils
|
||||
import java.io.FileInputStream
|
||||
import java.io.IOException
|
||||
|
@ -86,17 +87,6 @@ object ApkUpdateInstaller {
|
|||
Log.d(TAG, "Beginning APK install...")
|
||||
val packageInstaller: PackageInstaller = context.packageManager.packageInstaller
|
||||
|
||||
Log.d(TAG, "Clearing inactive sessions...")
|
||||
packageInstaller.mySessions
|
||||
.filter { session -> !session.isActive }
|
||||
.forEach { session ->
|
||||
try {
|
||||
packageInstaller.abandonSession(session.sessionId)
|
||||
} catch (e: SecurityException) {
|
||||
Log.w(TAG, "Failed to abandon inactive session!", e)
|
||||
}
|
||||
}
|
||||
|
||||
val sessionParams = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL).apply {
|
||||
// At this point, we always want to set this if possible, since we've already prompted the user with our own notification when necessary.
|
||||
// This lets us skip the system-generated notification.
|
||||
|
@ -151,8 +141,7 @@ object ApkUpdateInstaller {
|
|||
}
|
||||
|
||||
private fun shouldAutoUpdate(): Boolean {
|
||||
// TODO Auto-updates temporarily disabled. Once we have designs for allowing users to opt-out of auto-updates, we can re-enable this
|
||||
return false
|
||||
// return Build.VERSION.SDK_INT >= 31 && SignalStore.apkUpdate().autoUpdate && !ApplicationDependencies.getAppForegroundObserver().isForegrounded
|
||||
// TODO Auto-updates temporarily restricted to nightlies. Once we have designs for allowing users to opt-out of auto-updates, we can re-enable this
|
||||
return Environment.IS_NIGHTLY && Build.VERSION.SDK_INT >= 31 && SignalStore.apkUpdate().autoUpdate && !ApplicationDependencies.getAppForegroundObserver().isForegrounded
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,11 +66,34 @@ object ApkUpdateNotifications {
|
|||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setColor(ContextCompat.getColor(context, R.color.core_ultramarine))
|
||||
.setContentIntent(pendingIntent)
|
||||
.setAutoCancel(true)
|
||||
.build()
|
||||
|
||||
ServiceUtil.getNotificationManager(context).notify(NotificationIds.APK_UPDATE_FAILED_INSTALL, notification)
|
||||
}
|
||||
|
||||
fun showAutoUpdateSuccess(context: Context) {
|
||||
val pendingIntent = PendingIntent.getActivity(
|
||||
context,
|
||||
0,
|
||||
Intent(context, MainActivity::class.java),
|
||||
PendingIntentFlags.immutable()
|
||||
)
|
||||
|
||||
val appVersionName = context.packageManager.getPackageInfo(context.packageName, 0).versionName
|
||||
|
||||
val notification = NotificationCompat.Builder(context, NotificationChannels.getInstance().APP_UPDATES)
|
||||
.setContentTitle(context.getString(R.string.ApkUpdateNotifications_auto_update_success_title))
|
||||
.setContentText(context.getString(R.string.ApkUpdateNotifications_auto_update_success_body, appVersionName))
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setColor(ContextCompat.getColor(context, R.color.core_ultramarine))
|
||||
.setContentIntent(pendingIntent)
|
||||
.setAutoCancel(true)
|
||||
.build()
|
||||
|
||||
ServiceUtil.getNotificationManager(context).notify(NotificationIds.APK_UPDATE_SUCCESSFUL_INSTALL, notification)
|
||||
}
|
||||
|
||||
enum class FailureReason {
|
||||
UNKNOWN,
|
||||
ABORTED,
|
||||
|
|
|
@ -34,8 +34,11 @@ class ApkUpdatePackageInstallerReceiver : BroadcastReceiver() {
|
|||
Log.w(TAG, "[onReceive] Status: $statusCode, Message: $statusMessage")
|
||||
|
||||
when (statusCode) {
|
||||
PackageInstaller.STATUS_SUCCESS -> {
|
||||
Log.i(TAG, "Update installed successfully!")
|
||||
ApkUpdateNotifications.showAutoUpdateSuccess(context)
|
||||
}
|
||||
PackageInstaller.STATUS_PENDING_USER_ACTION -> handlePendingUserAction(context, userInitiated, intent!!)
|
||||
PackageInstaller.STATUS_SUCCESS -> Log.w(TAG, "Update installed successfully!")
|
||||
PackageInstaller.STATUS_FAILURE_ABORTED -> ApkUpdateNotifications.showInstallFailed(context, FailureReason.ABORTED)
|
||||
PackageInstaller.STATUS_FAILURE_BLOCKED -> ApkUpdateNotifications.showInstallFailed(context, FailureReason.BLOCKED)
|
||||
PackageInstaller.STATUS_FAILURE_INCOMPATIBLE -> ApkUpdateNotifications.showInstallFailed(context, FailureReason.INCOMPATIBLE)
|
||||
|
|
|
@ -63,7 +63,7 @@ class ApkUpdateJob private constructor(parameters: Parameters) : BaseJob(paramet
|
|||
Log.i(TAG, "Checking for APK update...")
|
||||
|
||||
val client = OkHttpClient()
|
||||
val request = Request.Builder().url("${BuildConfig.APK_UPDATE_URL}/latest.json").build()
|
||||
val request = Request.Builder().url(BuildConfig.APK_UPDATE_MANIFEST_URL).build()
|
||||
|
||||
val rawUpdateDescriptor: String = client.newCall(request).execute().use { response ->
|
||||
if (!response.isSuccessful || response.body() == null) {
|
||||
|
|
|
@ -9,6 +9,7 @@ public final class NotificationIds {
|
|||
public static final int FCM_FAILURE = 12;
|
||||
public static final int APK_UPDATE_PROMPT_INSTALL = 666;
|
||||
public static final int APK_UPDATE_FAILED_INSTALL = 667;
|
||||
public static final int APK_UPDATE_SUCCESSFUL_INSTALL = 668;
|
||||
public static final int PENDING_MESSAGES = 1111;
|
||||
public static final int MESSAGE_SUMMARY = 1338;
|
||||
public static final int APPLICATION_MIGRATION = 4242;
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.thoughtcrime.securesms.BuildConfig
|
|||
object Environment {
|
||||
const val IS_STAGING: Boolean = BuildConfig.BUILD_ENVIRONMENT_TYPE == "Staging"
|
||||
const val IS_PNP: Boolean = BuildConfig.BUILD_ENVIRONMENT_TYPE == "Pnp"
|
||||
const val IS_NIGHTLY: Boolean = BuildConfig.BUILD_DISTRIBUTION_TYPE == "nightly"
|
||||
|
||||
object Donations {
|
||||
@JvmStatic
|
||||
|
|
|
@ -2105,6 +2105,8 @@
|
|||
<string name="ApkUpdateNotifications_prompt_install_body">A new version of Signal is available. Tap to update.</string>
|
||||
<string name="ApkUpdateNotifications_failed_general_title">Signal failed to update</string>
|
||||
<string name="ApkUpdateNotifications_failed_general_body">We will try again later.</string>
|
||||
<string name="ApkUpdateNotifications_auto_update_success_title">Signal successfully updated</string>
|
||||
<string name="ApkUpdateNotifications_auto_update_success_body">You were automatically updated to version %1$s.</string>
|
||||
|
||||
<!-- UntrustedSendDialog -->
|
||||
<string name="UntrustedSendDialog_send_message">Send message?</string>
|
||||
|
|
28
app/src/nightly/AndroidManifest.xml
Normal file
28
app/src/nightly/AndroidManifest.xml
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"/>
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
|
||||
<uses-permission android:name="android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION"/>
|
||||
|
||||
<application>
|
||||
<receiver android:name=".apkupdate.ApkUpdateRefreshListener" android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".apkupdate.ApkUpdateDownloadManagerReceiver" android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver
|
||||
android:name=".apkupdate.ApkUpdatePackageInstallerReceiver"
|
||||
android:exported="true" />
|
||||
|
||||
<receiver
|
||||
android:name=".apkupdate.ApkUpdateNotificationReceiver"
|
||||
android:exported="false" />
|
||||
</application>
|
||||
</manifest>
|
Loading…
Add table
Reference in a new issue