This commit is contained in:
nielsandriesse 2020-05-22 09:53:04 +10:00
parent 373dfc264f
commit 06883cc3ef
28 changed files with 198 additions and 207 deletions

View File

@ -345,16 +345,16 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
}
String seed = new MnemonicCodec(languageFileDirectory).encode(hexEncodedSeed, MnemonicCodec.Language.Configuration.Companion.getEnglish());
new AlertDialog.Builder(getContext())
.setTitle(R.string.activity_settings_seed_dialog_title)
.setMessage(seed)
.setPositiveButton(R.string.activity_settings_seed_dialog_copy_button_title, (DialogInterface.OnClickListener) (dialog, which) -> {
ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("seed", seed);
clipboard.setPrimaryClip(clip);
Toast.makeText(getContext(), R.string.activity_settings_seed_copied_message, Toast.LENGTH_SHORT).show();
})
.setNeutralButton(R.string.activity_settings_seed_dialog_ok_button_title, null)
.show();
.setTitle(R.string.activity_settings_seed_dialog_title)
.setMessage(seed)
.setPositiveButton(R.string.activity_settings_seed_dialog_copy_button_title, (DialogInterface.OnClickListener) (dialog, which) -> {
ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("seed", seed);
clipboard.setPrimaryClip(clip);
Toast.makeText(getContext(), R.string.activity_settings_seed_copied_message, Toast.LENGTH_SHORT).show();
})
.setNeutralButton(R.string.activity_settings_seed_dialog_ok_button_title, null)
.show();
} catch (Exception e) {
Log.d("Loki", e.getMessage());
}

View File

@ -80,7 +80,7 @@ public class AvatarImageView extends AppCompatImageView {
setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setOval(0, 0, view.getWidth(), view.getHeight());
outline.setOval(0, 0, view.getWidth(), view.getHeight());
}
});
setClipToOutline(true);
@ -132,11 +132,11 @@ public class AvatarImageView extends AppCompatImageView {
if (photo.contactPhoto != null) {
requestManager.load(photo.contactPhoto)
.fallback(fallbackContactPhotoDrawable)
.error(fallbackContactPhotoDrawable)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.circleCrop()
.into(this);
.fallback(fallbackContactPhotoDrawable)
.error(fallbackContactPhotoDrawable)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.circleCrop()
.into(this);
} else {
setImageDrawable(fallbackContactPhotoDrawable);
}
@ -184,9 +184,9 @@ public class AvatarImageView extends AppCompatImageView {
if (other == null) return false;
return other.recipient.equals(recipient) &&
other.recipient.getColor().equals(recipient.getColor()) &&
other.ready == ready &&
Objects.equals(other.contactPhoto, contactPhoto);
other.recipient.getColor().equals(recipient.getColor()) &&
other.ready == ready &&
Objects.equals(other.contactPhoto, contactPhoto);
}
}
}

View File

@ -661,9 +661,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
*/
case PICK_GIF:
setMedia(data.getData(),
MediaType.GIF,
data.getIntExtra(GiphyActivity.EXTRA_WIDTH, 0),
data.getIntExtra(GiphyActivity.EXTRA_HEIGHT, 0));
MediaType.GIF,
data.getIntExtra(GiphyActivity.EXTRA_WIDTH, 0),
data.getIntExtra(GiphyActivity.EXTRA_HEIGHT, 0));
break;
case SMS_DEFAULT:
initializeSecurity(isSecureText, isDefaultSms);
@ -2932,12 +2932,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
inputPanel.setQuote(GlideApp.with(this),
messageRecord.getDateSent(),
author,
body,
slideDeck,
recipient,
threadId);
messageRecord.getDateSent(),
author,
body,
slideDeck,
recipient,
threadId);
} else if (messageRecord.isMms() && !((MmsMessageRecord) messageRecord).getLinkPreviews().isEmpty()) {
LinkPreview linkPreview = ((MmsMessageRecord) messageRecord).getLinkPreviews().get(0);
@ -2948,20 +2948,20 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
inputPanel.setQuote(GlideApp.with(this),
messageRecord.getDateSent(),
author,
messageRecord.getBody(),
slideDeck,
recipient,
threadId);
messageRecord.getDateSent(),
author,
messageRecord.getBody(),
slideDeck,
recipient,
threadId);
} else {
inputPanel.setQuote(GlideApp.with(this),
messageRecord.getDateSent(),
author,
messageRecord.getBody(),
messageRecord.isMms() ? ((MmsMessageRecord) messageRecord).getSlideDeck() : new SlideDeck(),
recipient,
threadId);
messageRecord.getDateSent(),
author,
messageRecord.getBody(),
messageRecord.isMms() ? ((MmsMessageRecord) messageRecord).getSlideDeck() : new SlideDeck(),
recipient,
threadId);
}
}
@ -3209,6 +3209,5 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
FriendRequestProtocol.rejectFriendRequest(this, recipient);
updateInputPanel();
}
// endregion
}

View File

@ -105,16 +105,16 @@ public class ConversationUpdateItem extends LinearLayout
this.sender.addListener(this);
if (messageRecord.isGroupAction()) setGroupRecord(messageRecord);
else if (messageRecord.isCallLog()) setCallRecord(messageRecord);
else if (messageRecord.isJoined()) setJoinedRecord(messageRecord);
else if (messageRecord.isExpirationTimerUpdate()) setTimerRecord(messageRecord);
else if (messageRecord.isEndSession()) setEndSessionRecord(messageRecord);
else if (messageRecord.isIdentityUpdate()) setIdentityRecord(messageRecord);
if (messageRecord.isGroupAction()) setGroupRecord(messageRecord);
else if (messageRecord.isCallLog()) setCallRecord(messageRecord);
else if (messageRecord.isJoined()) setJoinedRecord(messageRecord);
else if (messageRecord.isExpirationTimerUpdate()) setTimerRecord(messageRecord);
else if (messageRecord.isEndSession()) setEndSessionRecord(messageRecord);
else if (messageRecord.isIdentityUpdate()) setIdentityRecord(messageRecord);
else if (messageRecord.isIdentityVerified() ||
messageRecord.isIdentityDefault()) setIdentityVerifyUpdate(messageRecord);
messageRecord.isIdentityDefault()) setIdentityVerifyUpdate(messageRecord);
else if (messageRecord.isLokiSessionRestoreSent()) setTextMessageRecord(messageRecord);
else throw new AssertionError("Neither group nor log nor joined.");
else throw new AssertionError("Neither group nor log nor joined.");
if (batchSelected.contains(messageRecord)) setSelected(true);
else setSelected(false);

View File

@ -9,22 +9,15 @@ import android.support.annotation.WorkerThread;
import org.signal.libsignal.metadata.SignalProtos;
import org.signal.libsignal.metadata.certificate.CertificateValidator;
import org.signal.libsignal.metadata.certificate.InvalidCertificateException;
import network.loki.messenger.BuildConfig;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.libsignal.InvalidKeyException;
import org.whispersystems.libsignal.ecc.Curve;
import org.whispersystems.libsignal.ecc.ECPublicKey;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import java.io.IOException;
public class UnidentifiedAccessUtil {
private static final String TAG = UnidentifiedAccessUtil.class.getSimpleName();
@ -116,9 +109,9 @@ public class UnidentifiedAccessUtil {
String ourNumber = TextSecurePreferences.getLocalNumber(context);
if (ourNumber != null) {
SignalProtos.SenderCertificate certificate = SignalProtos.SenderCertificate.newBuilder()
.setSender(ourNumber)
.setSenderDevice(SignalServiceAddress.DEFAULT_DEVICE_ID)
.build();
.setSender(ourNumber)
.setSenderDevice(SignalServiceAddress.DEFAULT_DEVICE_ID)
.build();
return certificate.toByteArray();
}

View File

@ -168,7 +168,7 @@ public class GroupDatabase extends Database {
GroupRecord record;
while ((record = reader.getNext()) != null) {
if (record.isClosedGroup() && record.members.contains(address)) {
return true;
return true;
}
}
@ -293,8 +293,7 @@ public class GroupDatabase extends Database {
contents.put(ADMINS, Address.toSerializedList(admins, ','));
contents.put(ACTIVE, 1);
databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?",
new String[] {groupId});
databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?", new String[] {groupId});
}
public void remove(String groupId, Address source) {

View File

@ -341,12 +341,12 @@ public class SmsDatabase extends MessagingDatabase {
try {
cursor = database.query(TABLE_NAME, new String[] { ID, THREAD_ID, ADDRESS, TYPE },
DATE_SENT + " = ?", new String[] { String.valueOf(timestamp) },
null, null, null, null);
DATE_SENT + " = ?", new String[] { String.valueOf(timestamp) },
null, null, null, null);
while (cursor.moveToNext()) {
if (Types.isOutgoingMessageType(cursor.getLong(cursor.getColumnIndexOrThrow(TYPE)))) {
isOutgoing = true;
isOutgoing = true;
}
}
} finally {

View File

@ -544,7 +544,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
if (publicChat != null) {
byte[] groupId = publicChat.getId().getBytes();
String oldId = GroupUtil.getEncodedId(groupId, false);
String newId = GroupUtil.getEncodedPublicChatId(groupId);
String newId = GroupUtil.getEncodedOpenGroupId(groupId);
ContentValues threadUpdate = new ContentValues();
threadUpdate.put("recipient_ids", newId);
db.update("thread", threadUpdate, "recipient_ids = ?", new String[]{ oldId });

View File

@ -21,7 +21,6 @@ import android.content.Context;
import android.support.annotation.NonNull;
import android.text.SpannableString;
import network.loki.messenger.R;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
@ -30,6 +29,8 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import java.util.LinkedList;
import java.util.List;
import network.loki.messenger.R;
/**
* The message record model which represents standard SMS messages.
*
@ -67,9 +68,9 @@ public class SmsMessageRecord extends MessageRecord {
int readReceiptCount, boolean unidentified, boolean isFriendRequest)
{
super(id, body, recipient, individualRecipient, recipientDeviceId,
dateSent, dateReceived, threadId, status, deliveryReceiptCount, type,
mismatches, new LinkedList<>(), subscriptionId,
expiresIn, expireStarted, readReceiptCount, unidentified);
dateSent, dateReceived, threadId, status, deliveryReceiptCount, type,
mismatches, new LinkedList<>(), subscriptionId,
expiresIn, expireStarted, readReceiptCount, unidentified);
this.isFriendRequest = isFriendRequest;
}

View File

@ -37,7 +37,7 @@ import java.util.Set;
public class GroupManager {
public static long getOpenGroupThreadID(String id, @NonNull Context context) {
final String groupID = GroupUtil.getEncodedPublicChatId(id.getBytes());
final String groupID = GroupUtil.getEncodedOpenGroupId(id.getBytes());
return getThreadIDFromGroupID(groupID, context);
}
@ -47,7 +47,7 @@ public class GroupManager {
}
public static long getThreadIDFromGroupID(String groupID, @NonNull Context context) {
final Recipient groupRecipient = Recipient.from(context, Address.fromSerialized(groupID), false);
final Recipient groupRecipient = Recipient.from(context, Address.fromSerialized(groupID), false);
return DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(groupRecipient);
}
@ -78,10 +78,10 @@ public class GroupManager {
final Set<Address> memberAddresses = getMemberAddresses(members);
final Set<Address> adminAddresses = getMemberAddresses(admins);
String masterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
String publicKeyToUse = masterPublicKey != null ? masterPublicKey : TextSecurePreferences.getLocalNumber(context);
String masterPublicKeyOrNull = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
String masterPublicKey = masterPublicKeyOrNull != null ? masterPublicKeyOrNull : TextSecurePreferences.getLocalNumber(context);
memberAddresses.add(Address.fromSerialized(publicKeyToUse));
memberAddresses.add(Address.fromSerialized(masterPublicKey));
groupDatabase.create(groupId, name, new LinkedList<>(memberAddresses), null, null, new LinkedList<>(adminAddresses));
if (!mms) {
@ -94,28 +94,28 @@ public class GroupManager {
}
}
public static @NonNull GroupActionResult createOpenGroup(@NonNull String id,
@NonNull Context context,
@Nullable Bitmap avatar,
@Nullable String name)
public static @NonNull GroupActionResult createOpenGroup(@NonNull String id,
@NonNull Context context,
@Nullable Bitmap avatar,
@Nullable String name)
{
final String groupID = GroupUtil.getEncodedPublicChatId(id.getBytes());
final String groupID = GroupUtil.getEncodedOpenGroupId(id.getBytes());
return createLokiGroup(groupID, context, avatar, name);
}
public static @NonNull GroupActionResult createRSSFeed(@NonNull String id,
@NonNull Context context,
@Nullable Bitmap avatar,
@Nullable String name)
public static @NonNull GroupActionResult createRSSFeed(@NonNull String id,
@NonNull Context context,
@Nullable Bitmap avatar,
@Nullable String name)
{
final String groupID = GroupUtil.getEncodedRSSFeedId(id.getBytes());
return createLokiGroup(groupID, context, avatar, name);
}
private static @NonNull GroupActionResult createLokiGroup(@NonNull String groupId,
@NonNull Context context,
@Nullable Bitmap avatar,
@Nullable String name)
private static @NonNull GroupActionResult createLokiGroup(@NonNull String groupId,
@NonNull Context context,
@Nullable Bitmap avatar,
@Nullable String name)
{
final byte[] avatarBytes = BitmapUtil.toByteArray(avatar);
final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);

View File

@ -143,7 +143,7 @@ public class GroupMessageProcessor {
// Loki - Only process update messages if we're part of the group
Address userMasterDeviceAddress = Address.fromSerialized(userMasterDevice);
if (!groupRecord.getMembers().contains(userMasterDeviceAddress) &&
!group.getMembers().or(Collections.emptyList()).contains(userMasterDevice)) {
!group.getMembers().or(Collections.emptyList()).contains(userMasterDevice)) {
Log.d("Loki", "Received a group update message from a group we're not a member of: " + id + "; ignoring.");
database.setActive(id, false);
return null;

View File

@ -196,15 +196,17 @@ public class AttachmentDownloadJob extends BaseJob implements InjectableType {
try {
long id = Long.parseLong(attachment.getLocation());
if (isPublicAttachment) {
return new SignalServiceAttachmentPointer(id, null, new byte[0],
Optional.of(Util.toIntExact(attachment.getSize())),
Optional.absent(),
0,
0,
Optional.fromNullable(attachment.getDigest()),
Optional.fromNullable(attachment.getFileName()),
attachment.isVoiceNote(),
Optional.absent(), attachment.getUrl());
return new SignalServiceAttachmentPointer(id,
null,
new byte[0],
Optional.of(Util.toIntExact(attachment.getSize())),
Optional.absent(),
0,
0,
Optional.fromNullable(attachment.getDigest()),
Optional.fromNullable(attachment.getFileName()),
attachment.isVoiceNote(),
Optional.absent(), attachment.getUrl());
}
byte[] key = Base64.decode(attachment.getKey());

View File

@ -142,15 +142,13 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy
// Loki - Only sync contacts we are friends with
if (SyncMessagesProtocol.shouldSyncContact(context, address)) {
out.write(new DeviceContact(address.toPhoneString(),
Optional.fromNullable(recipient.getName()),
getAvatar(recipient.getContactUri()),
Optional.fromNullable(recipient.getColor().serialize()),
verifiedMessage,
Optional.fromNullable(recipient.getProfileKey()),
recipient.isBlocked(),
recipient.getExpireMessages() > 0 ?
Optional.of(recipient.getExpireMessages()) :
Optional.absent()));
Optional.fromNullable(recipient.getName()),
getAvatar(recipient.getContactUri()),
Optional.fromNullable(recipient.getColor().serialize()),
verifiedMessage,
Optional.fromNullable(recipient.getProfileKey()),
recipient.isBlocked(),
recipient.getExpireMessages() > 0 ? Optional.of(recipient.getExpireMessages()) : Optional.absent()));
}
out.close();

View File

@ -124,7 +124,7 @@ public class MultiDeviceGroupUpdateJob extends BaseJob implements InjectableType
@Override
public boolean onShouldRetry(@NonNull Exception exception) {
// Loki - Disabled because we have our own retrying
// Loki - Disabled since we have our own retrying
return false;
}

View File

@ -128,6 +128,7 @@ import org.whispersystems.signalservice.loki.api.fileserver.LokiFileServerAPI;
import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher;
import org.whispersystems.signalservice.loki.protocol.mentions.MentionsManager;
import org.whispersystems.signalservice.loki.protocol.meta.LokiServiceMessage;
import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation;
import java.security.MessageDigest;
import java.security.SecureRandom;
@ -762,8 +763,8 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
}
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(masterAddress, message.getTimestamp(), -1,
message.getExpiresInSeconds() * 1000L, false, content.isNeedsReceipt(), message.getBody(), message.getGroupInfo(), message.getAttachments(),
quote, sharedContacts, linkPreviews, sticker);
message.getExpiresInSeconds() * 1000L, false, content.isNeedsReceipt(), message.getBody(), message.getGroupInfo(), message.getAttachments(),
quote, sharedContacts, linkPreviews, sticker);
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
database.beginTransaction();
@ -824,7 +825,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
private long handleSynchronizeSentExpirationUpdate(@NonNull SentTranscriptMessage message) throws MmsException {
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
Recipient recipient = getSyncMessageMasterDestination(message.getDestination().get());
Recipient recipient = getSyncMessageMasterDestination(message);
OutgoingExpirationUpdateMessage expirationUpdateMessage = new OutgoingExpirationUpdateMessage(recipient,
message.getTimestamp(),
@ -844,7 +845,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
throws MmsException
{
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
Recipient recipients = getSyncMessageMasterDestination(message.getDestination().get());
Recipient recipients = getSyncMessageMasterDestination(message);
Optional<QuoteModel> quote = getValidatedQuote(message.getMessage().getQuote());
Optional<Attachment> sticker = getStickerAttachment(message.getMessage().getSticker());
Optional<List<Contact>> sharedContacts = getContacts(message.getMessage().getSharedContacts());
@ -1007,7 +1008,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
throws MmsException
{
Recipient recipient = getSyncMessageMasterDestination(message.getDestination().get());
Recipient recipient = getSyncMessageMasterDestination(message);
String body = message.getMessage().getBody().or("");
long expiresInMillis = message.getMessage().getExpiresInSeconds() * 1000L;
@ -1394,10 +1395,42 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
}
}
private Recipient getSyncMessageMasterDestination(String publicKey) {
Recipient recipient = Recipient.from(context, Address.fromSerialized(publicKey), false);
if (recipient.isGroupRecipient()) {
return recipient;
private Recipient getSyncMessageMasterDestination(SentTranscriptMessage message) {
if (message.getMessage().isGroupMessage()) {
return Recipient.from(context, Address.fromSerialized(GroupUtil.getEncodedId(message.getMessage().getGroupInfo().get())), false);
} else {
String publicKey = message.getDestination().get();
String userPublicKey = TextSecurePreferences.getLocalNumber(context);
Set<String> allUserDevices = org.whispersystems.signalservice.loki.protocol.multidevice.MultiDeviceProtocol.shared.getAllLinkedDevices(userPublicKey);
if (allUserDevices.contains(publicKey)) {
return Recipient.from(context, Address.fromSerialized(userPublicKey), false);
} else {
try {
// TODO: Burn this with fire when we can
PromiseUtilities.timeout(LokiFileServerAPI.shared.getDeviceLinks(publicKey, false), 4000).get();
String masterPublicKey = org.whispersystems.signalservice.loki.protocol.multidevice.MultiDeviceProtocol.shared.getMasterDevice(publicKey);
if (masterPublicKey == null) {
masterPublicKey = publicKey;
}
return Recipient.from(context, Address.fromSerialized(masterPublicKey), false);
} catch (Exception e) {
return Recipient.from(context, Address.fromSerialized(publicKey), false);
}
}
}
}
private Recipient getMessageDestination(SignalServiceContent content, SignalServiceDataMessage message) {
if (message.getGroupInfo().isPresent()) {
return Recipient.from(context, Address.fromExternal(context, GroupUtil.getEncodedId(message.getGroupInfo().get().getGroupId(), false)), false);
} else {
return Recipient.from(context, Address.fromExternal(context, content.getSender()), false);
}
}
private Recipient getMessageMasterDestination(String publicKey) {
if (!PublicKeyValidation.isValid(publicKey)) {
return Recipient.from(context, Address.fromSerialized(publicKey), false);
} else {
String userPublicKey = TextSecurePreferences.getLocalNumber(context);
Set<String> allUserDevices = org.whispersystems.signalservice.loki.protocol.multidevice.MultiDeviceProtocol.shared.getAllLinkedDevices(userPublicKey);
@ -1413,39 +1446,12 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
}
return Recipient.from(context, Address.fromSerialized(masterPublicKey), false);
} catch (Exception e) {
return recipient;
return Recipient.from(context, Address.fromSerialized(publicKey), false);
}
}
}
}
private Recipient getMessageDestination(SignalServiceContent content, SignalServiceDataMessage message) {
if (message.getGroupInfo().isPresent()) {
return Recipient.from(context, Address.fromExternal(context, GroupUtil.getEncodedId(message.getGroupInfo().get().getGroupId(), false)), false);
} else {
return Recipient.from(context, Address.fromExternal(context, content.getSender()), false);
}
}
private Recipient getMessageMasterDestination(String publicKey) {
Recipient recipient = Recipient.from(context, Address.fromSerialized(publicKey), false);
if (recipient.isGroupRecipient()) {
return recipient;
} else {
try {
// TODO: Burn this with fire when we can
PromiseUtilities.timeout(LokiFileServerAPI.shared.getDeviceLinks(publicKey, false), 4000).get();
String masterPublicKey = org.whispersystems.signalservice.loki.protocol.multidevice.MultiDeviceProtocol.shared.getMasterDevice(publicKey);
if (masterPublicKey == null) {
masterPublicKey = publicKey;
}
return Recipient.from(context, Address.fromSerialized(masterPublicKey), false);
} catch (Exception e) {
return recipient;
}
}
}
private void notifyTypingStoppedFromIncomingMessage(@NonNull Recipient conversationRecipient, @NonNull String sender, int device) {
Recipient author = Recipient.from(context, Address.fromSerialized(sender), false);
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(conversationRecipient);

View File

@ -145,10 +145,10 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
@Override
public @NonNull Data serialize() {
Data.Builder builder = new Data.Builder()
.putLong(KEY_TEMPLATE_MESSAGE_ID, templateMessageId)
.putLong(KEY_MESSAGE_ID, messageId)
.putString(KEY_DESTINATION, destination.serialize())
.putBoolean(KEY_IS_LOKI_PRE_KEY_BUNDLE_MESSAGE, isLokiPreKeyBundleMessage);
.putLong(KEY_TEMPLATE_MESSAGE_ID, templateMessageId)
.putLong(KEY_MESSAGE_ID, messageId)
.putString(KEY_DESTINATION, destination.serialize())
.putBoolean(KEY_IS_LOKI_PRE_KEY_BUNDLE_MESSAGE, isLokiPreKeyBundleMessage);
if (customFriendRequestMessage != null) { builder.putString(KEY_CUSTOM_FR_MESSAGE, customFriendRequestMessage); }
return builder.build();

View File

@ -85,10 +85,10 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
@Override
public @NonNull Data serialize() {
Data.Builder builder = new Data.Builder()
.putLong(KEY_TEMPLATE_MESSAGE_ID, templateMessageId)
.putLong(KEY_MESSAGE_ID, messageId)
.putString(KEY_DESTINATION, destination.serialize())
.putBoolean(KEY_IS_LOKI_PRE_KEY_BUNDLE_MESSAGE, isLokiPreKeyBundleMessage);
.putLong(KEY_TEMPLATE_MESSAGE_ID, templateMessageId)
.putLong(KEY_MESSAGE_ID, messageId)
.putString(KEY_DESTINATION, destination.serialize())
.putBoolean(KEY_IS_LOKI_PRE_KEY_BUNDLE_MESSAGE, isLokiPreKeyBundleMessage);
if (customFriendRequestMessage != null) { builder.putString(KEY_CUSTOM_FR_MESSAGE, customFriendRequestMessage); }
return builder.build();

View File

@ -99,8 +99,8 @@ public class RetrieveProfileAvatarJob extends BaseJob implements InjectableType
File downloadDestination = File.createTempFile("avatar", "jpg", context.getCacheDir());
try {
InputStream avatarStream = receiver.retrieveProfileAvatar(profileAvatar, downloadDestination, profileKey, MAX_PROFILE_SIZE_BYTES);
File decryptDestination = File.createTempFile("avatar", "jpg", context.getCacheDir());
InputStream avatarStream = receiver.retrieveProfileAvatar(profileAvatar, downloadDestination, profileKey, MAX_PROFILE_SIZE_BYTES);
File decryptDestination = File.createTempFile("avatar", "jpg", context.getCacheDir());
Util.copy(avatarStream, new FileOutputStream(decryptDestination));
decryptDestination.renameTo(AvatarHelper.getAvatarFile(context, recipient.getAddress()));

View File

@ -84,8 +84,8 @@ public class TypingSendJob extends BaseJob implements InjectableType {
throw new IllegalStateException("Tried to send a typing indicator to a non-existent thread.");
}
List<Recipient> recipients = Collections.singletonList(recipient);
Optional<byte[]> groupId = Optional.absent();
List<Recipient> recipients = Collections.singletonList(recipient);
Optional<byte[]> groupId = Optional.absent();
if (recipient.isGroupRecipient()) {
recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(recipient.getAddress().toGroupString(), false);

View File

@ -99,8 +99,8 @@ public class MarkReadReceiver extends BroadcastReceiver {
for (String device : linkedDevices) {
Address deviceAsAddress = Address.fromExternal(context, device);
ApplicationContext.getInstance(context)
.getJobManager()
.add(new SendReadReceiptJob(deviceAsAddress, timestamps));
.getJobManager()
.add(new SendReadReceiptJob(deviceAsAddress, timestamps));
}
}
}

View File

@ -332,8 +332,8 @@ public class MessageNotifier {
if (canReply) {
builder.addAndroidAutoAction(notificationState.getAndroidAutoReplyIntent(context, recipient),
notificationState.getAndroidAutoHeardIntent(context, notificationId),
notifications.get(0).getTimestamp());
notificationState.getAndroidAutoHeardIntent(context, notificationId),
notifications.get(0).getTimestamp());
}
ListIterator<NotificationItem> iterator = notifications.listIterator(notifications.size());

View File

@ -247,10 +247,8 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
}
private Bitmap getCircularBitmap(Bitmap bitmap) {
final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(output);
final int color = Color.RED;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
@ -260,7 +258,6 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawOval(rectF, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);

View File

@ -37,11 +37,11 @@ public class NotificationsPreferenceFragment extends ListSummaryPreferenceFragme
String fcmKey = "pref_key_use_fcm";
((SwitchPreferenceCompat)findPreference(fcmKey)).setChecked(TextSecurePreferences.isUsingFCM(getContext()));
this.findPreference(fcmKey)
.setOnPreferenceChangeListener((preference, newValue) -> {
TextSecurePreferences.setIsUsingFCM(getContext(), (boolean) newValue);
ApplicationContext.getInstance(getContext()).registerForFCMIfNeeded(true);
return true;
});
.setOnPreferenceChangeListener((preference, newValue) -> {
TextSecurePreferences.setIsUsingFCM(getContext(), (boolean) newValue);
ApplicationContext.getInstance(getContext()).registerForFCMIfNeeded(true);
return true;
});
Preference ledBlinkPref = this.findPreference(TextSecurePreferences.LED_BLINK_PREF);

View File

@ -36,7 +36,7 @@ public class ProfilePreference extends Preference {
private TextView profileNameView;
private TextView profileNumberView;
private TextView profileTagView;
private String ourDeviceWords;
private String shortDeviceMnemonic;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public ProfilePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
@ -81,8 +81,8 @@ public class ProfilePreference extends Preference {
Context context = getContext();
String userPublicKey = TextSecurePreferences.getLocalNumber(context);
String masterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
String publicKeyToUse = masterPublicKey != null ? masterPublicKey : userPublicKey;
String userMasterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
String publicKeyToUse = userMasterPublicKey != null ? userMasterPublicKey : userPublicKey;
final Address address = Address.fromSerialized(publicKeyToUse);
final Recipient recipient = Recipient.from(context, address, false);
final String displayName = TextSecurePreferences.getProfileName(context);
@ -121,13 +121,14 @@ public class ProfilePreference extends Preference {
profileNameView.setVisibility(TextUtils.isEmpty(displayName) ? View.GONE : View.VISIBLE);
profileNumberView.setText(address.toPhoneString());
profileTagView.setVisibility(masterPublicKey == null ? View.GONE : View.VISIBLE);
if (masterPublicKey != null && ourDeviceWords == null) {
profileTagView.setVisibility(userMasterPublicKey == null ? View.GONE : View.VISIBLE);
if (userMasterPublicKey != null && shortDeviceMnemonic == null) {
MnemonicCodec codec = new MnemonicCodec(MnemonicUtilities.getLanguageFileDirectory(context));
ourDeviceWords = MnemonicUtilities.getFirst3Words(codec, userPublicKey);
shortDeviceMnemonic = MnemonicUtilities.getFirst3Words(codec, userPublicKey);
}
String tag = context.getResources().getString(R.string.activity_settings_linked_device_tag);
profileTagView.setText(String.format(tag, ourDeviceWords != null ? ourDeviceWords : "-"));
profileTagView.setText(String.format(tag, shortDeviceMnemonic != null ? shortDeviceMnemonic : "-"));
}
}

View File

@ -8,9 +8,6 @@ import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
public class MessageSenderEventListener implements SignalServiceMessageSender.EventListener {
private static final String TAG = MessageSenderEventListener.class.getSimpleName();
private final Context context;
public MessageSenderEventListener(Context context) {
@ -22,15 +19,18 @@ public class MessageSenderEventListener implements SignalServiceMessageSender.Ev
SecurityEvent.broadcastSecurityUpdateEvent(context);
}
@Override public void onFriendRequestSending(long messageID, long threadID) {
@Override
public void onFriendRequestSending(long messageID, long threadID) {
FriendRequestProtocol.setFriendRequestStatusToSendingIfNeeded(context, messageID, threadID);
}
@Override public void onFriendRequestSent(long messageID, long threadID) {
@Override
public void onFriendRequestSent(long messageID, long threadID) {
FriendRequestProtocol.setFriendRequestStatusToSentIfNeeded(context, messageID, threadID);
}
@Override public void onFriendRequestSendingFailed(long messageID, long threadID) {
@Override
public void onFriendRequestSendingFailed(long messageID, long threadID) {
FriendRequestProtocol.setFriendRequestStatusToFailedIfNeeded(context, messageID, threadID);
}
}

View File

@ -456,7 +456,7 @@ public class Recipient implements RecipientModifiedListener {
public synchronized String toShortString() {
String name = getName();
return (name == null ? address.serialize() : name);
return (name != null ? name : address.serialize());
}
public synchronized @NonNull Drawable getFallbackContactPhotoDrawable(Context context, boolean inverted) {
@ -469,8 +469,8 @@ public class Recipient implements RecipientModifiedListener {
else {
String userPublicKey = TextSecurePreferences.getLocalNumber(context);
String publicKey = address.serialize();
String masterDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
String publicKeyToUse = (publicKey.equalsIgnoreCase(userPublicKey) && masterDevice != null) ? masterDevice : publicKey;
String userMasterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
String publicKeyToUse = (publicKey.equalsIgnoreCase(userPublicKey) && userMasterPublicKey != null) ? userMasterPublicKey : publicKey;
return new JazzIdenticonContactPhoto(publicKeyToUse);
}
}

View File

@ -1,16 +1,13 @@
package org.thoughtcrime.securesms.search;
import android.Manifest;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.MergeCursor;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import com.annimon.stream.Stream;
import org.thoughtcrime.securesms.contacts.ContactAccessor;
import org.thoughtcrime.securesms.contacts.ContactsDatabase;
import org.thoughtcrime.securesms.database.Address;
@ -20,13 +17,11 @@ import org.thoughtcrime.securesms.database.SearchDatabase;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.database.model.ThreadRecord;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.search.model.MessageResult;
import org.thoughtcrime.securesms.search.model.SearchResult;
import org.thoughtcrime.securesms.util.Stopwatch;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -122,7 +117,7 @@ public class SearchRepository {
private CursorList<Recipient> queryContacts(String query) {
return CursorList.emptyList();
/* Loki - Don't need contact permissions
/* Loki - We don't need contacts permission
if (!Permissions.hasAny(context, Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS)) {
return CursorList.emptyList();
}

View File

@ -28,16 +28,16 @@ import static org.whispersystems.signalservice.internal.push.SignalServiceProtos
public class GroupUtil {
private static final String ENCODED_SIGNAL_GROUP_PREFIX = "__textsecure_group__!";
private static final String ENCODED_MMS_GROUP_PREFIX = "__signal_mms_group__!";
private static final String ENCODED_PUBLIC_CHAT_GROUP_PREFIX = "__loki_public_chat_group__!";
private static final String ENCODED_RSS_FEED_GROUP_PREFIX = "__loki_rss_feed_group__!";
private static final String TAG = GroupUtil.class.getSimpleName();
private static final String ENCODED_CLOSED_GROUP_PREFIX = "__textsecure_group__!";
private static final String ENCODED_MMS_GROUP_PREFIX = "__signal_mms_group__!";
private static final String ENCODED_OPEN_GROUP_PREFIX = "__loki_public_chat_group__!";
private static final String ENCODED_RSS_FEED_GROUP_PREFIX = "__loki_rss_feed_group__!";
private static final String TAG = GroupUtil.class.getSimpleName();
public static String getEncodedId(SignalServiceGroup group) {
byte[] groupId = group.getGroupId();
if (group.getGroupType() == SignalServiceGroup.GroupType.PUBLIC_CHAT) {
return getEncodedPublicChatId(groupId);
return getEncodedOpenGroupId(groupId);
} else if (group.getGroupType() == SignalServiceGroup.GroupType.RSS_FEED) {
return getEncodedRSSFeedId(groupId);
}
@ -45,11 +45,11 @@ public class GroupUtil {
}
public static String getEncodedId(byte[] groupId, boolean mms) {
return (mms ? ENCODED_MMS_GROUP_PREFIX : ENCODED_SIGNAL_GROUP_PREFIX) + Hex.toStringCondensed(groupId);
return (mms ? ENCODED_MMS_GROUP_PREFIX : ENCODED_CLOSED_GROUP_PREFIX) + Hex.toStringCondensed(groupId);
}
public static String getEncodedPublicChatId(byte[] groupId) {
return ENCODED_PUBLIC_CHAT_GROUP_PREFIX + Hex.toStringCondensed(groupId);
public static String getEncodedOpenGroupId(byte[] groupId) {
return ENCODED_OPEN_GROUP_PREFIX + Hex.toStringCondensed(groupId);
}
public static String getEncodedRSSFeedId(byte[] groupId) {
@ -70,7 +70,7 @@ public class GroupUtil {
}
public static boolean isEncodedGroup(@NonNull String groupId) {
return groupId.startsWith(ENCODED_SIGNAL_GROUP_PREFIX) || groupId.startsWith(ENCODED_MMS_GROUP_PREFIX) || groupId.startsWith(ENCODED_PUBLIC_CHAT_GROUP_PREFIX) || groupId.startsWith(ENCODED_RSS_FEED_GROUP_PREFIX);
return groupId.startsWith(ENCODED_CLOSED_GROUP_PREFIX) || groupId.startsWith(ENCODED_MMS_GROUP_PREFIX) || groupId.startsWith(ENCODED_OPEN_GROUP_PREFIX) || groupId.startsWith(ENCODED_RSS_FEED_GROUP_PREFIX);
}
public static boolean isMmsGroup(@NonNull String groupId) {
@ -78,7 +78,7 @@ public class GroupUtil {
}
public static boolean isOpenGroup(@NonNull String groupId) {
return groupId.startsWith(ENCODED_PUBLIC_CHAT_GROUP_PREFIX);
return groupId.startsWith(ENCODED_OPEN_GROUP_PREFIX);
}
public static boolean isRSSFeed(@NonNull String groupId) {
@ -86,7 +86,7 @@ public class GroupUtil {
}
public static boolean isClosedGroup(@NonNull String groupId) {
return groupId.startsWith(ENCODED_SIGNAL_GROUP_PREFIX);
return groupId.startsWith(ENCODED_CLOSED_GROUP_PREFIX);
}
@WorkerThread
@ -159,9 +159,9 @@ public class GroupUtil {
// If we were the one that quit then we need to leave the group (only relevant for slave
// devices in a multi device context)
if (!removedMembers.isEmpty()) {
String masterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
String userPublicKey = masterPublicKey != null ? masterPublicKey : TextSecurePreferences.getLocalNumber(context);
wasCurrentUserRemoved = removedMembers.contains(userPublicKey);
String masterPublicKeyOrNull = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
String masterPublicKey = masterPublicKeyOrNull != null ? masterPublicKeyOrNull : TextSecurePreferences.getLocalNumber(context);
wasCurrentUserRemoved = removedMembers.contains(masterPublicKey);
}
}
}