Merge branch 'dev' of github.com:loki-project/loki-messenger-android into bug-fixes

# Conflicts:
#	src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java
This commit is contained in:
Niels Andriesse 2019-09-12 09:46:12 +10:00
commit 3b242e7435
6 changed files with 63 additions and 32 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="@color/loki_darkest_gray"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -26,7 +26,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/welcome_terms_button"
app:layout_constraintBottom_toTopOf="@id/beta_terms_label"
android:orientation="vertical"
android:gravity="center">
@ -37,6 +37,21 @@
</LinearLayout>
<TextView
android:id="@+id/beta_terms_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="24dp"
style="@style/Signal.Text.Body"
android:text="@string/activity_landing_beta_terms"
android:textColor="@color/white"
android:textAlignment="center"
app:layout_constraintBottom_toTopOf="@+id/welcome_terms_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/welcome_terms_button"
android:layout_width="wrap_content"
@ -45,6 +60,7 @@
style="@style/Signal.Text.Body"
android:text="@string/activity_landing_privacy_policy_button_title"
android:textColor="@color/signal_primary"
android:textAlignment="center"
app:layout_constraintBottom_toTopOf="@+id/welcome_continue_button"
app:layout_constraintEnd_toEndOf="@+id/welcome_continue_button"
app:layout_constraintStart_toStartOf="@+id/welcome_continue_button" />

View File

@ -1547,6 +1547,7 @@
<!-- Landing activity -->
<string name="activity_landing_title">Loki Messenger</string>
<string name="activity_landing_permission_dialog_message">Some features of Loki Messenger (such as automatic message backup) require storage access to work.</string>
<string name="activity_landing_beta_terms">"Loki Messenger is currently in beta. For development purposes the beta version collects basic usage statistics and crash logs. In addition, the beta version doesn't provide full privacy and shouldn\'t be used to transmit sensitive information."</string>
<string name="activity_landing_privacy_policy_button_title">Privacy Policy</string>
<!-- Account details activity -->
<string name="activity_account_details_title">Create Your Loki Messenger Account</string>

View File

@ -20,8 +20,8 @@ import android.widget.TextView;
import com.annimon.stream.Stream;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import network.loki.messenger.R;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.mms.Slide;
@ -30,9 +30,12 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
import org.thoughtcrime.securesms.util.ThemeUtil;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI;
import java.util.List;
import network.loki.messenger.R;
public class QuoteView extends FrameLayout implements RecipientModifiedListener {
private static final String TAG = QuoteView.class.getSimpleName();
@ -186,8 +189,11 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener
boolean outgoing = messageType != MESSAGE_TYPE_INCOMING;
boolean isOwnNumber = Util.isOwnNumber(getContext(), author.getAddress());
authorView.setText(isOwnNumber ? getContext().getString(R.string.QuoteView_you)
: author.toShortString());
String quoteeDisplayName = author.toShortString();
if (quoteeDisplayName.equals(author.getAddress().toString())) {
quoteeDisplayName = DatabaseFactory.getLokiUserDatabase(getContext()).getServerDisplayName(LokiGroupChatAPI.getPublicChatServer() + "." + LokiGroupChatAPI.getPublicChatServerID(), author.getAddress().toString());
}
authorView.setText(isOwnNumber ? getContext().getString(R.string.QuoteView_you) : quoteeDisplayName);
// We use the raw color resource because Android 4.x was struggling with tints here
quoteBarView.setImageResource(author.getColor().toQuoteBarColorResource(getContext(), outgoing));

View File

@ -408,10 +408,10 @@ public class ConversationFragment extends Fragment
boolean isGroupChat = recipient.isGroupRecipient();
if (isGroupChat) {
menu.findItem(R.id.menu_context_reply).setVisible(false);
LokiAPIDatabase lokiAPIDatabase = DatabaseFactory.getLokiAPIDatabase(getContext());
boolean isLokiPublicChat = recipient.getName().equals("Loki Public Chat");
boolean isLokiPublicChat = recipient.getName() != null && recipient.getName().equals("Loki Public Chat");
int selectedMessageCount = messageRecords.size();
menu.findItem(R.id.menu_context_reply).setVisible(isLokiPublicChat && selectedMessageCount == 1);
LokiAPIDatabase lokiAPIDatabase = DatabaseFactory.getLokiAPIDatabase(getContext());
boolean isSentByUser = ((MessageRecord)messageRecords.toArray()[0]).isOutgoing();
boolean userCanModerate = lokiAPIDatabase.isModerator(LokiGroupChatAPI.getPublicChatServerID(), LokiGroupChatAPI.getPublicChatServer());
boolean isDeleteOptionVisible = isLokiPublicChat && selectedMessageCount == 1 && (isSentByUser || userCanModerate);

View File

@ -305,7 +305,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
if (message.isEndSession()) handleEndSessionMessage(content, smsMessageId);
else if (message.isGroupUpdate()) handleGroupMessage(content, message, smsMessageId);
else if (message.isExpirationUpdate()) handleExpirationUpdate(content, message, smsMessageId);
else if (isMediaMessage) handleMediaMessage(content, message, smsMessageId);
else if (isMediaMessage) handleMediaMessage(content, message, smsMessageId, Optional.absent());
else if (message.getBody().isPresent()) handleTextMessage(content, message, smsMessageId, Optional.absent());
if (message.getGroupInfo().isPresent() && groupDatabase.isUnknownGroup(GroupUtil.getEncodedId(message.getGroupInfo().get().getGroupId(), false))) {
@ -733,9 +733,10 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
MessageNotifier.updateNotification(context);
}
private void handleMediaMessage(@NonNull SignalServiceContent content,
@NonNull SignalServiceDataMessage message,
@NonNull Optional<Long> smsMessageId)
public void handleMediaMessage(@NonNull SignalServiceContent content,
@NonNull SignalServiceDataMessage message,
@NonNull Optional<Long> smsMessageId,
@NonNull Optional<Long> messageServerIDOrNull)
throws StorageFailedException
{
notifyTypingStoppedFromIncomingMessage(getMessageDestination(content, message), content.getSender(), content.getSenderDevice());
@ -764,7 +765,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
}
if (c == linkPreviewCount) {
try {
handleMediaMessage(content, mediaMessage, smsMessageId);
handleMediaMessage(content, mediaMessage, smsMessageId, messageServerIDOrNull);
} catch (Exception e) {
// TODO: Handle
}
@ -772,17 +773,13 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
}));
}
} else {
handleMediaMessage(content, mediaMessage, smsMessageId);
handleMediaMessage(content, mediaMessage, smsMessageId, messageServerIDOrNull);
}
} else {
handleMediaMessage(content, mediaMessage, smsMessageId);
handleMediaMessage(content, mediaMessage, smsMessageId, messageServerIDOrNull);
}
}
private void handleMediaMessage(@NonNull SignalServiceContent content, @NonNull IncomingMediaMessage mediaMessage, @NonNull Optional<Long> smsMessageID) throws StorageFailedException {
handleMediaMessage(content, mediaMessage, smsMessageID, null);
}
private void handleMediaMessage(@NonNull SignalServiceContent content, @NonNull IncomingMediaMessage mediaMessage, @NonNull Optional<Long> smsMessageID, @Nullable Optional<Long> messageServerIDOrNull) throws StorageFailedException {
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
database.beginTransaction();
@ -927,7 +924,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
public void handleTextMessage(@NonNull SignalServiceContent content,
@NonNull SignalServiceDataMessage message,
@NonNull Optional<Long> smsMessageId,
@Nullable Optional<Long> messageServerIDOrNull)
@NonNull Optional<Long> messageServerIDOrNull)
throws StorageFailedException
{
SmsDatabase database = DatabaseFactory.getSmsDatabase(context);
@ -996,7 +993,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
}
}
private void updatePublicChatMessageWithServerID(@Nullable Optional<Long> messageServerIDOrNull, Optional<InsertResult> databaseInsert) {
private void updatePublicChatMessageWithServerID(Optional<Long> messageServerIDOrNull, Optional<InsertResult> databaseInsert) {
if (messageServerIDOrNull == null) { return; }
if (databaseInsert.isPresent() && messageServerIDOrNull.isPresent()) {
long messageID = databaseInsert.get().getMessageId();

View File

@ -3,19 +3,15 @@ package org.thoughtcrime.securesms.loki
import android.content.Context
import android.os.Handler
import android.util.Log
import org.thoughtcrime.securesms.attachments.Attachment
import org.thoughtcrime.securesms.contactshare.Contact
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch
import org.thoughtcrime.securesms.database.documents.NetworkFailure
import org.thoughtcrime.securesms.jobs.PushDecryptJob
import org.thoughtcrime.securesms.linkpreview.LinkPreview
import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage
import org.thoughtcrime.securesms.mms.QuoteModel
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.GroupUtil
import org.thoughtcrime.securesms.util.TextSecurePreferences
@ -28,7 +24,6 @@ import org.whispersystems.signalservice.api.push.SignalServiceAddress
import org.whispersystems.signalservice.loki.api.LokiGroupChat
import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI
import org.whispersystems.signalservice.loki.api.LokiGroupMessage
import java.util.*
class LokiGroupChatPoller(private val context: Context, private val group: LokiGroupChat) {
private val handler = Handler()
@ -102,11 +97,21 @@ class LokiGroupChatPoller(private val context: Context, private val group: LokiG
fun processIncomingMessage(message: LokiGroupMessage) {
val id = group.id.toByteArray()
val x1 = SignalServiceGroup(SignalServiceGroup.Type.UPDATE, id, null, null, null)
val x2 = SignalServiceDataMessage(message.timestamp, x1, null, message.body)
val quote: SignalServiceDataMessage.Quote?
if (message.quote != null) {
quote = SignalServiceDataMessage.Quote(message.quote!!.quotedMessageTimestamp, SignalServiceAddress(message.quote!!.quoteeHexEncodedPublicKey), message.quote!!.quotedMessageBody, listOf())
} else {
quote = null
}
val x2 = SignalServiceDataMessage(message.timestamp, x1, listOf(), message.body, false, 0, false, null, false, quote, null, null, null)
val x3 = SignalServiceContent(x2, message.hexEncodedPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.timestamp, false)
val senderDisplayName = "${message.displayName} (...${message.hexEncodedPublicKey.takeLast(8)})"
DatabaseFactory.getLokiUserDatabase(context).setServerDisplayName(group.id, message.hexEncodedPublicKey, senderDisplayName)
PushDecryptJob(context).handleTextMessage(x3, x2, Optional.absent(), Optional.of(message.serverID))
if (quote != null) {
PushDecryptJob(context).handleMediaMessage(x3, x2, Optional.absent(), Optional.of(message.serverID))
} else {
PushDecryptJob(context).handleTextMessage(x3, x2, Optional.absent(), Optional.of(message.serverID))
}
}
fun processOutgoingMessage(message: LokiGroupMessage) {
val messageServerID = message.serverID ?: return
@ -116,8 +121,14 @@ class LokiGroupChatPoller(private val context: Context, private val group: LokiG
val id = group.id.toByteArray()
val mmsDatabase = DatabaseFactory.getMmsDatabase(context)
val recipient = Recipient.from(context, Address.fromSerialized(GroupUtil.getEncodedId(id, false)), false)
val signalMessage = OutgoingMediaMessage(recipient, message.body, ArrayList<Attachment>(), message.timestamp, 0, 0, ThreadDatabase.DistributionTypes.DEFAULT,
null, ArrayList<Contact>(), ArrayList<LinkPreview>(), ArrayList<NetworkFailure>(), ArrayList<IdentityKeyMismatch>())
val quote: QuoteModel?
if (message.quote != null) {
quote = QuoteModel(message.quote!!.quotedMessageTimestamp, Address.fromSerialized(message.quote!!.quoteeHexEncodedPublicKey), message.quote!!.quotedMessageBody, false, listOf())
} else {
quote = null
}
val signalMessage = OutgoingMediaMessage(recipient, message.body, listOf(), message.timestamp, 0, 0,
ThreadDatabase.DistributionTypes.DEFAULT, quote, listOf(), listOf(), listOf(), listOf())
val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient)
fun finalize() {
val messageID = mmsDatabase.insertMessageOutbox(signalMessage, threadID, false, null)