Skip to content

Commit

Permalink
Merge tag 'v7.0.2' into molly-7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
valldrac committed Feb 28, 2024
2 parents 66b254d + 940cee0 commit 51b3e88
Show file tree
Hide file tree
Showing 105 changed files with 602 additions and 211 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ apply {
from("fix-profm.gradle")
}

val canonicalVersionCode = 1395
val canonicalVersionName = "7.0.1"
val canonicalVersionCode = 1396
val canonicalVersionName = "7.0.2"
val mollyRevision = 1

val postFixSize = 100
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,17 @@ class RecipientTableTest_getAndPossiblyMerge {
expectChangeNumberEvent()
}

test("merge, e164 follows pni+aci") {
given(E164_A, PNI_A, null)
given(null, null, ACI_A)

process(null, PNI_A, ACI_A, pniVerified = true)

expect(E164_A, PNI_A, ACI_A)
expectThreadMergeEvent(E164_A)
expectPniVerified()
}

test("local user, local e164 and aci provided, changeSelf=false, leave e164 alone") {
given(E164_SELF, null, ACI_SELF)
given(null, null, ACI_A)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class AliceClient(val serviceId: ServiceId, val e164: String, val trustRoot: ECK
ApplicationDependencies.getIncomingMessageObserver()
.processEnvelope(bufferedStore, envelope, serverDeliveredTimestamp)
?.mapNotNull { it.run() }
?.forEach { ApplicationDependencies.getJobManager().add(it) }
?.forEach { it.enqueue() }

bufferedStore.flushToDisk()
val end = System.currentTimeMillis()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,6 @@ class AppSettingsActivity : DSLSettingsActivity() {
override fun onWillFinish() {
if (wasConfigurationUpdated) {
setResult(MainActivity.RESULT_CONFIG_CHANGED)
} else {
setResult(RESULT_OK)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,48 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter
}
)

clickPref(
title = DSLSettingsText.from("Log dump PreKey ServiceId-KeyIds"),
onClick = {
logPreKeyIds()
}
)

clickPref(
title = DSLSettingsText.from("Retry all jobs now"),
summary = DSLSettingsText.from("Clear backoff intervals, app will restart"),
onClick = {
SimpleTask.run({
JobDatabase.getInstance(ApplicationDependencies.getApplication()).debugResetBackoffInterval()
}) {
AppUtil.restart(requireContext())
}
}
)

clickPref(
title = DSLSettingsText.from("Delete all prekeys"),
summary = DSLSettingsText.from("Deletes all signed/last-resort/one-time prekeys for both ACI and PNI accounts. WILL cause problems."),
onClick = {
MaterialAlertDialogBuilder(requireContext())
.setTitle("Delete all prekeys?")
.setMessage("Are you sure? This will delete all prekeys for both ACI and PNI accounts. This WILL cause problems.")
.setPositiveButton(android.R.string.ok) { _, _ ->
SignalDatabase.signedPreKeys.debugDeleteAll()
SignalDatabase.oneTimePreKeys.debugDeleteAll()
SignalDatabase.kyberPreKeys.debugDeleteAll()

Toast.makeText(requireContext(), "All prekeys deleted!", Toast.LENGTH_SHORT).show()
}
.setNegativeButton(android.R.string.cancel, null)
.show()
}
)

dividerPref()

sectionHeaderPref(DSLSettingsText.from("Logging"))

clickPref(
title = DSLSettingsText.from("Clear all logs"),
onClick = {
Expand Down Expand Up @@ -215,21 +257,10 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter
)

clickPref(
title = DSLSettingsText.from("Log dump PreKey ServiceId-KeyIds"),
onClick = {
logPreKeyIds()
}
)

clickPref(
title = DSLSettingsText.from("Retry all jobs now"),
summary = DSLSettingsText.from("Clear backoff intervals, app will restart"),
title = DSLSettingsText.from("Clear local metrics"),
summary = DSLSettingsText.from("Click to clear all local metrics state."),
onClick = {
SimpleTask.run({
JobDatabase.getInstance(ApplicationDependencies.getApplication()).debugResetBackoffInterval()
}) {
AppUtil.restart(requireContext())
}
clearAllLocalMetricsState()
}
)

Expand Down Expand Up @@ -424,18 +455,6 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter

dividerPref()

sectionHeaderPref(DSLSettingsText.from("Local Metrics"))

clickPref(
title = DSLSettingsText.from("Clear local metrics"),
summary = DSLSettingsText.from("Click to clear all local metrics state."),
onClick = {
clearAllLocalMetricsState()
}
)

dividerPref()

sectionHeaderPref(DSLSettingsText.from("Group call server"))

radioPref(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ class UsernameLinkSettingsViewModel : ViewModel() {
}

// Draw the username
val usernamePaint = Paint().apply {
val usernamePaint = TextPaint().apply {
color = state.qrCodeColorScheme.textColor.toArgb()
textSize = usernameTextSize
typeface = if (Build.VERSION.SDK_INT < 26) {
Expand All @@ -316,10 +316,18 @@ class UsernameLinkSettingsViewModel : ViewModel() {
.build()
}
}
val usernameBounds = Rect()
usernamePaint.getTextBounds(state.username, 0, state.username.length, usernameBounds)

androidCanvas.drawText(state.username, (width / 2f) - (usernameBounds.width() / 2f), usernameVerticalPad + usernameBounds.height(), usernamePaint)
val usernameMaxWidth = qrBorderWidth - borderSizeX * 2f
val usernameLayout = StaticLayout(state.username, usernamePaint, usernameMaxWidth.toInt(), Layout.Alignment.ALIGN_CENTER, 1f, 0f, true)
val usernameVerticalOffset = when (usernameLayout.lineCount) {
1 -> 0f
2 -> usernameTextSize / 2f
else -> usernameTextSize
}

androidCanvas.withTranslation(x = backgroundPadHorizontal + borderSizeX, y = usernameVerticalPad - usernameVerticalOffset) {
usernameLayout.draw(this)
}

// Draw the help text
val helpTextPaint = TextPaint().apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.PathEffect
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.Fill
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
Expand Down Expand Up @@ -46,24 +45,30 @@ fun UsernameQrScanScreen(
onQrResultHandled: () -> Unit,
modifier: Modifier = Modifier
) {
val path = remember { Path() }

when (qrScanResult) {
QrScanResult.InvalidData -> {
QrScanResultDialog(stringResource(R.string.UsernameLinkSettings_qr_result_invalid), onDismiss = onQrResultHandled)
}

QrScanResult.NetworkError -> {
QrScanResultDialog(stringResource(R.string.UsernameLinkSettings_qr_result_network_error), onDismiss = onQrResultHandled)
}

is QrScanResult.NotFound -> {
if (qrScanResult.username != null) {
QrScanResultDialog(stringResource(R.string.UsernameLinkSettings_qr_result_not_found, qrScanResult.username), onDismiss = onQrResultHandled)
} else {
QrScanResultDialog(stringResource(R.string.UsernameLinkSettings_qr_result_not_found_no_username), onDismiss = onQrResultHandled)
}
}

is QrScanResult.Success -> {
CommunicationActions.startConversation(LocalContext.current, qrScanResult.recipient, null)
onQrResultHandled()
}

null -> {}
}

Expand All @@ -88,7 +93,7 @@ fun UsernameQrScanScreen(
.weight(1f, true)
.drawWithContent {
drawContent()
drawQrCrosshair()
drawQrCrosshair(path)
}
)

Expand Down Expand Up @@ -117,33 +122,39 @@ private fun QrScanResultDialog(message: String, onDismiss: () -> Unit) {
)
}

private fun DrawScope.drawQrCrosshair() {
private fun DrawScope.drawQrCrosshair(path: Path) {
val crosshairWidth: Float = size.minDimension * 0.6f
val clearWidth: Float = crosshairWidth * 0.75f
val crosshairLineLength = crosshairWidth * 0.125f

// Draw a full white rounded rect...
drawRoundRect(
color = Color.White,
topLeft = center - Offset(crosshairWidth / 2, crosshairWidth / 2),
style = Stroke(width = 3.dp.toPx()),
size = Size(crosshairWidth, crosshairWidth),
cornerRadius = CornerRadius(10.dp.toPx(), 10.dp.toPx())
)
val topLeft = center - Offset(crosshairWidth / 2, crosshairWidth / 2)
val topRight = center + Offset(crosshairWidth / 2, -crosshairWidth / 2)
val bottomRight = center + Offset(crosshairWidth / 2, crosshairWidth / 2)
val bottomLeft = center + Offset(-crosshairWidth / 2, crosshairWidth / 2)

// ...then cut out the middle parts with BlendMode.Clear to leave us with just the corners
drawRect(
color = Color.White,
topLeft = Offset(center.x - clearWidth / 2, 0f),
style = Fill,
size = Size(clearWidth, size.height),
blendMode = BlendMode.Clear
)
path.reset()

drawPath(
path = path.apply {
moveTo(topLeft.x, topLeft.y + crosshairLineLength)
lineTo(topLeft.x, topLeft.y)
lineTo(topLeft.x + crosshairLineLength, topLeft.y)

drawRect(
moveTo(topRight.x - crosshairLineLength, topRight.y)
lineTo(topRight.x, topRight.y)
lineTo(topRight.x, topRight.y + crosshairLineLength)

moveTo(bottomRight.x, bottomRight.y - crosshairLineLength)
lineTo(bottomRight.x, bottomRight.y)
lineTo(bottomRight.x - crosshairLineLength, bottomRight.y)

moveTo(bottomLeft.x + crosshairLineLength, bottomLeft.y)
lineTo(bottomLeft.x, bottomLeft.y)
lineTo(bottomLeft.x, bottomLeft.y - crosshairLineLength)
},
color = Color.White,
topLeft = Offset(0f, center.y - clearWidth / 2),
style = Fill,
size = Size(size.width, clearWidth),
blendMode = BlendMode.Clear
style = Stroke(
width = 3.dp.toPx(),
pathEffect = PathEffect.cornerPathEffect(10.dp.toPx())
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.database

import android.content.Context
import org.signal.core.util.delete
import org.signal.core.util.deleteAll
import org.signal.core.util.exists
import org.signal.core.util.insertInto
import org.signal.core.util.logging.Log
Expand Down Expand Up @@ -171,6 +172,10 @@ class KyberPreKeyTable(context: Context, databaseHelper: SignalDatabase) : Datab
Log.i(TAG, "Deleted $count stale one-time EC prekeys.")
}

fun debugDeleteAll() {
writableDatabase.deleteAll(OneTimePreKeyTable.TABLE_NAME)
}

data class KyberPreKey(
val record: KyberPreKeyRecord,
val lastResort: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.core.content.contentValuesOf
import org.signal.core.util.Base64
import org.signal.core.util.SqlUtil
import org.signal.core.util.delete
import org.signal.core.util.deleteAll
import org.signal.core.util.logging.Log
import org.signal.core.util.requireNonNullString
import org.signal.core.util.update
Expand Down Expand Up @@ -115,6 +116,10 @@ class OneTimePreKeyTable(context: Context, databaseHelper: SignalDatabase) : Dat
Log.i(TAG, "Deleted $count stale one-time EC prekeys.")
}

fun debugDeleteAll() {
writableDatabase.deleteAll(TABLE_NAME)
}

private fun ServiceId.toAccountId(): String {
return when (this) {
is ServiceId.ACI -> this.toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2942,10 +2942,10 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
primaryId = data.byAci,
secondaryId = data.byPni
)
} else if (data.pniRecord.aci == null && data.pniRecord.e164 == data.e164) {
} else if (data.pniRecord.aci == null && (data.e164 == null || data.pniRecord.e164 == data.e164)) {
// The PNI record also has the E164 on it with no ACI. We're going to be stealing all of it's fields,
// so this is basically a merge with a little bit of extra prep.
breadCrumbs += "PniRecordHasMatchingE164AndNoAci"
breadCrumbs += "PniRecordHasNoAci"

if (data.aciRecord.pni != null) {
operations += PnpOperation.RemovePni(data.byAci)
Expand All @@ -2970,10 +2970,10 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
secondaryId = data.byPni
)
} else {
// The PNI record either has an ACI or a non-matching e164, meaning we need to steal what we need and leave the rest behind
// The PNI record has a different ACI, meaning we need to steal what we need and leave the rest behind

breadCrumbs += if (data.pniRecord.aci != null && data.pniRecord.e164 != data.e164) {
"PniRecordHasAciAndNonMatchingE164"
"PniRecordHasAci"
} else if (data.pniRecord.aci != null) {
"PniRecordHasAci"
} else {
Expand Down Expand Up @@ -4054,7 +4054,8 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
PROFILE_FAMILY_NAME to null,
PROFILE_JOINED_NAME to null,
LAST_PROFILE_FETCH to 0,
PROFILE_AVATAR to null
PROFILE_AVATAR to null,
PROFILE_SHARING to 0
)
.run {
if (recipientId == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Context
import androidx.core.content.contentValuesOf
import org.signal.core.util.Base64
import org.signal.core.util.SqlUtil
import org.signal.core.util.deleteAll
import org.signal.core.util.logging.Log
import org.signal.core.util.requireInt
import org.signal.core.util.requireLong
Expand Down Expand Up @@ -103,6 +104,10 @@ class SignedPreKeyTable(context: Context, databaseHelper: SignalDatabase) : Data
writableDatabase.delete(TABLE_NAME, "$ACCOUNT_ID = ? AND $KEY_ID = ?", SqlUtil.buildArgs(serviceId.toAccountId(), keyId))
}

fun debugDeleteAll() {
writableDatabase.deleteAll(OneTimePreKeyTable.TABLE_NAME)
}

private fun ServiceId.toAccountId(): String {
return when (this) {
is ServiceId.ACI -> this.toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1541,7 +1541,7 @@ private UpdateDescription updateDescription(@PluralsRes int stringRes,
String beforeChunk = template.substring(startIndex, nearestPosition);

builder.append(beforeChunk);
builder.append(SpanUtil.clickable(Recipient.resolved(recipientId).getDisplayName(context), ContextCompat.getColor(context, R.color.conversation_item_update_text_color), v -> {
builder.append(SpanUtil.clickable(Recipient.resolved(recipientId).getDisplayNameOrUsername(context), ContextCompat.getColor(context, R.color.conversation_item_update_text_color), v -> {
if (!recipientId.isUnknown() && clickHandler != null) {
clickHandler.accept(recipientId);
}
Expand Down
Loading

0 comments on commit 51b3e88

Please sign in to comment.