mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-22 03:18:26 +00:00
parent
434ce4f9c9
commit
8d82033855
BIN
res/drawable-hdpi/ic_favorite_grey600_24dp.png
Normal file
BIN
res/drawable-hdpi/ic_favorite_grey600_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 483 B |
BIN
res/drawable-mdpi/ic_favorite_grey600_24dp.png
Normal file
BIN
res/drawable-mdpi/ic_favorite_grey600_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 344 B |
BIN
res/drawable-xhdpi/ic_favorite_grey600_24dp.png
Normal file
BIN
res/drawable-xhdpi/ic_favorite_grey600_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 575 B |
BIN
res/drawable-xxhdpi/ic_favorite_grey600_24dp.png
Normal file
BIN
res/drawable-xxhdpi/ic_favorite_grey600_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 834 B |
BIN
res/drawable-xxxhdpi/ic_favorite_grey600_24dp.png
Normal file
BIN
res/drawable-xxxhdpi/ic_favorite_grey600_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
@ -291,6 +291,7 @@
|
|||||||
<string name="MessageRecord_s_called_you">%s called you</string>
|
<string name="MessageRecord_s_called_you">%s called you</string>
|
||||||
<string name="MessageRecord_called_s">Called %s</string>
|
<string name="MessageRecord_called_s">Called %s</string>
|
||||||
<string name="MessageRecord_missed_call_from">Missed call from %s</string>
|
<string name="MessageRecord_missed_call_from">Missed call from %s</string>
|
||||||
|
<string name="MessageRecord_s_is_on_signal_say_hey">%s is on Signal, say hey!</string>
|
||||||
|
|
||||||
|
|
||||||
<!-- PassphraseChangeActivity -->
|
<!-- PassphraseChangeActivity -->
|
||||||
@ -447,6 +448,7 @@
|
|||||||
<string name="ThreadRecord_called_you">Called you</string>
|
<string name="ThreadRecord_called_you">Called you</string>
|
||||||
<string name="ThreadRecord_missed_call">Missed call</string>
|
<string name="ThreadRecord_missed_call">Missed call</string>
|
||||||
<string name="ThreadRecord_media_message">Media message</string>
|
<string name="ThreadRecord_media_message">Media message</string>
|
||||||
|
<string name="ThreadRecord_s_is_on_signal_say_hey">%s is on Signal, say hey!</string>
|
||||||
|
|
||||||
<!-- VerifyIdentityActivity -->
|
<!-- VerifyIdentityActivity -->
|
||||||
<string name="VerifyIdentityActivity_you_do_not_have_an_identity_key">You do not have an identity key.</string>
|
<string name="VerifyIdentityActivity_you_do_not_have_an_identity_key">You do not have an identity key.</string>
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
android:contentAuthority="com.android.contacts"
|
android:contentAuthority="com.android.contacts"
|
||||||
android:accountType="org.thoughtcrime.securesms"
|
android:accountType="org.thoughtcrime.securesms"
|
||||||
android:userVisible="true"
|
android:userVisible="true"
|
||||||
android:supportsUploading="false"
|
android:supportsUploading="true"
|
||||||
android:allowParallelSyncs="false"
|
android:allowParallelSyncs="false"
|
||||||
android:isAlwaysSyncable="true"/>
|
android:isAlwaysSyncable="true"/>
|
@ -61,6 +61,7 @@ public abstract class ContactSelectionActivity extends PassphraseRequiredActionB
|
|||||||
|
|
||||||
protected ContactSelectionListFragment contactsFragment;
|
protected ContactSelectionListFragment contactsFragment;
|
||||||
|
|
||||||
|
private MasterSecret masterSecret;
|
||||||
private Toolbar toolbar;
|
private Toolbar toolbar;
|
||||||
private EditText searchText;
|
private EditText searchText;
|
||||||
private AnimatingToggle toggle;
|
private AnimatingToggle toggle;
|
||||||
@ -79,6 +80,7 @@ public abstract class ContactSelectionActivity extends PassphraseRequiredActionB
|
|||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle icicle, MasterSecret masterSecret) {
|
protected void onCreate(Bundle icicle, MasterSecret masterSecret) {
|
||||||
setContentView(R.layout.contact_selection_activity);
|
setContentView(R.layout.contact_selection_activity);
|
||||||
|
this.masterSecret = masterSecret;
|
||||||
|
|
||||||
initializeToolbar();
|
initializeToolbar();
|
||||||
initializeResources();
|
initializeResources();
|
||||||
@ -216,16 +218,19 @@ public abstract class ContactSelectionActivity extends PassphraseRequiredActionB
|
|||||||
private static class RefreshDirectoryTask extends AsyncTask<Context, Void, Void> {
|
private static class RefreshDirectoryTask extends AsyncTask<Context, Void, Void> {
|
||||||
|
|
||||||
private final WeakReference<ContactSelectionActivity> activity;
|
private final WeakReference<ContactSelectionActivity> activity;
|
||||||
|
private final MasterSecret masterSecret;
|
||||||
|
|
||||||
private RefreshDirectoryTask(ContactSelectionActivity activity) {
|
private RefreshDirectoryTask(ContactSelectionActivity activity) {
|
||||||
this.activity = new WeakReference<>(activity);
|
this.activity = new WeakReference<>(activity);
|
||||||
|
this.masterSecret = activity.masterSecret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Context... params) {
|
protected Void doInBackground(Context... params) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DirectoryHelper.refreshDirectory(params[0]);
|
DirectoryHelper.refreshDirectory(params[0], masterSecret);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
}
|
}
|
||||||
|
@ -158,13 +158,17 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemViewType(@NonNull Cursor cursor) {
|
public int getItemViewType(@NonNull Cursor cursor) {
|
||||||
long id = cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsColumns.ID));
|
long id = cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsColumns.ID));
|
||||||
String type = cursor.getString(cursor.getColumnIndexOrThrow(MmsSmsDatabase.TRANSPORT));
|
String type = cursor.getString(cursor.getColumnIndexOrThrow(MmsSmsDatabase.TRANSPORT));
|
||||||
MessageRecord messageRecord = getMessageRecord(id, cursor, type);
|
MessageRecord messageRecord = getMessageRecord(id, cursor, type);
|
||||||
|
|
||||||
if (messageRecord.isGroupAction() || messageRecord.isCallLog()) return MESSAGE_TYPE_UPDATE;
|
if (messageRecord.isGroupAction() || messageRecord.isCallLog() || messageRecord.isJoined()) {
|
||||||
else if (messageRecord.isOutgoing()) return MESSAGE_TYPE_OUTGOING;
|
return MESSAGE_TYPE_UPDATE;
|
||||||
else return MESSAGE_TYPE_INCOMING;
|
} else if (messageRecord.isOutgoing()) {
|
||||||
|
return MESSAGE_TYPE_OUTGOING;
|
||||||
|
} else {
|
||||||
|
return MESSAGE_TYPE_INCOMING;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private MessageRecord getMessageRecord(long messageId, Cursor cursor, String type) {
|
private MessageRecord getMessageRecord(long messageId, Cursor cursor, String type) {
|
||||||
|
@ -70,7 +70,8 @@ public class ConversationUpdateItem extends LinearLayout
|
|||||||
|
|
||||||
if (messageRecord.isGroupAction()) setGroupRecord(messageRecord);
|
if (messageRecord.isGroupAction()) setGroupRecord(messageRecord);
|
||||||
else if (messageRecord.isCallLog()) setCallRecord(messageRecord);
|
else if (messageRecord.isCallLog()) setCallRecord(messageRecord);
|
||||||
else throw new AssertionError("Neither group no log.");
|
else if (messageRecord.isJoined()) setJoinedRecord(messageRecord);
|
||||||
|
else throw new AssertionError("Neither group nor log nor joined.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setCallRecord(MessageRecord messageRecord) {
|
private void setCallRecord(MessageRecord messageRecord) {
|
||||||
@ -99,6 +100,12 @@ public class ConversationUpdateItem extends LinearLayout
|
|||||||
date.setVisibility(View.GONE);
|
date.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setJoinedRecord(MessageRecord messageRecord) {
|
||||||
|
icon.setImageResource(R.drawable.ic_favorite_grey600_24dp);
|
||||||
|
body.setText(messageRecord.getDisplayBody());
|
||||||
|
date.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onModified(Recipients recipients) {
|
public void onModified(Recipients recipients) {
|
||||||
onModified(recipients.getPrimaryRecipient());
|
onModified(recipients.getPrimaryRecipient());
|
||||||
|
@ -32,14 +32,18 @@ import android.provider.ContactsContract.RawContacts;
|
|||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.whispersystems.libaxolotl.util.guava.Optional;
|
import org.whispersystems.libaxolotl.util.guava.Optional;
|
||||||
|
import org.whispersystems.textsecure.api.util.InvalidNumberException;
|
||||||
|
import org.whispersystems.textsecure.api.util.PhoneNumberFormatter;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -70,11 +74,14 @@ public class ContactsDatabase {
|
|||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean setRegisteredUsers(Account account, List<String> e164numbers)
|
public synchronized @NonNull List<String> setRegisteredUsers(@NonNull Account account,
|
||||||
|
@NonNull String localNumber,
|
||||||
|
@NonNull List<String> e164numbers)
|
||||||
throws RemoteException, OperationApplicationException
|
throws RemoteException, OperationApplicationException
|
||||||
{
|
{
|
||||||
Map<String, Long> currentContacts = new HashMap<>();
|
Map<String, Long> currentContacts = new HashMap<>();
|
||||||
Set<String> registeredNumbers = new HashSet<>(e164numbers);
|
Set<String> registeredNumbers = new HashSet<>(e164numbers);
|
||||||
|
List<String> addedNumbers = new LinkedList<>();
|
||||||
ArrayList<ContentProviderOperation> operations = new ArrayList<>();
|
ArrayList<ContentProviderOperation> operations = new ArrayList<>();
|
||||||
Uri currentContactsUri = RawContacts.CONTENT_URI.buildUpon()
|
Uri currentContactsUri = RawContacts.CONTENT_URI.buildUpon()
|
||||||
.appendQueryParameter(RawContacts.ACCOUNT_NAME, account.name)
|
.appendQueryParameter(RawContacts.ACCOUNT_NAME, account.name)
|
||||||
@ -86,7 +93,16 @@ public class ContactsDatabase {
|
|||||||
cursor = context.getContentResolver().query(currentContactsUri, new String[] {BaseColumns._ID, RawContacts.SYNC1}, null, null, null);
|
cursor = context.getContentResolver().query(currentContactsUri, new String[] {BaseColumns._ID, RawContacts.SYNC1}, null, null, null);
|
||||||
|
|
||||||
while (cursor != null && cursor.moveToNext()) {
|
while (cursor != null && cursor.moveToNext()) {
|
||||||
currentContacts.put(cursor.getString(1), cursor.getLong(0));
|
String currentNumber;
|
||||||
|
|
||||||
|
try {
|
||||||
|
currentNumber = PhoneNumberFormatter.formatNumber(cursor.getString(1), localNumber);
|
||||||
|
} catch (InvalidNumberException e) {
|
||||||
|
Log.w(TAG, e);
|
||||||
|
currentNumber = cursor.getString(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentContacts.put(currentNumber, cursor.getLong(0));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (cursor != null)
|
if (cursor != null)
|
||||||
@ -95,10 +111,11 @@ public class ContactsDatabase {
|
|||||||
|
|
||||||
for (String number : e164numbers) {
|
for (String number : e164numbers) {
|
||||||
if (!currentContacts.containsKey(number)) {
|
if (!currentContacts.containsKey(number)) {
|
||||||
Optional<Pair<String, Long>> systemContactInfo = getSystemContactInfo(number);
|
Optional<SystemContactInfo> systemContactInfo = getSystemContactInfo(number);
|
||||||
|
|
||||||
if (systemContactInfo.isPresent()) {
|
if (systemContactInfo.isPresent()) {
|
||||||
addTextSecureRawContact(operations, account, systemContactInfo.get().first, systemContactInfo.get().second);
|
addedNumbers.add(number);
|
||||||
|
addTextSecureRawContact(operations, account, systemContactInfo.get().number, systemContactInfo.get().id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,14 +128,15 @@ public class ContactsDatabase {
|
|||||||
|
|
||||||
if (!operations.isEmpty()) {
|
if (!operations.isEmpty()) {
|
||||||
context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);
|
context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return addedNumbers;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addTextSecureRawContact(List<ContentProviderOperation> operations,
|
private void addTextSecureRawContact(List<ContentProviderOperation> operations,
|
||||||
Account account, String e164number, long aggregateId)
|
Account account,
|
||||||
|
String e164number,
|
||||||
|
long aggregateId)
|
||||||
{
|
{
|
||||||
int index = operations.size();
|
int index = operations.size();
|
||||||
Uri dataUri = ContactsContract.Data.CONTENT_URI.buildUpon()
|
Uri dataUri = ContactsContract.Data.CONTENT_URI.buildUpon()
|
||||||
@ -254,10 +272,11 @@ public class ContactsDatabase {
|
|||||||
return newNumberCursor;
|
return newNumberCursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<Pair<String, Long>> getSystemContactInfo(String e164number) {
|
private Optional<SystemContactInfo> getSystemContactInfo(String e164number) {
|
||||||
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(e164number));
|
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(e164number));
|
||||||
String[] projection = {ContactsContract.PhoneLookup.NUMBER,
|
String[] projection = {ContactsContract.PhoneLookup.NUMBER,
|
||||||
ContactsContract.PhoneLookup._ID};
|
ContactsContract.PhoneLookup._ID,
|
||||||
|
ContactsContract.PhoneLookup.DISPLAY_NAME};
|
||||||
Cursor numberCursor = null;
|
Cursor numberCursor = null;
|
||||||
Cursor idCursor = null;
|
Cursor idCursor = null;
|
||||||
|
|
||||||
@ -272,7 +291,9 @@ public class ContactsDatabase {
|
|||||||
null);
|
null);
|
||||||
|
|
||||||
if (idCursor != null && idCursor.moveToNext()) {
|
if (idCursor != null && idCursor.moveToNext()) {
|
||||||
return Optional.of(new Pair<>(numberCursor.getString(0), idCursor.getLong(0)));
|
return Optional.of(new SystemContactInfo(numberCursor.getString(2),
|
||||||
|
numberCursor.getString(0),
|
||||||
|
idCursor.getLong(0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@ -381,4 +402,16 @@ public class ContactsDatabase {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class SystemContactInfo {
|
||||||
|
private final String name;
|
||||||
|
private final String number;
|
||||||
|
private final long id;
|
||||||
|
|
||||||
|
private SystemContactInfo(String name, String number, long id) {
|
||||||
|
this.name = name;
|
||||||
|
this.number = number;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import android.content.SyncResult;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||||
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -25,7 +26,7 @@ public class ContactsSyncAdapter extends AbstractThreadedSyncAdapter {
|
|||||||
ContentProviderClient provider, SyncResult syncResult)
|
ContentProviderClient provider, SyncResult syncResult)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
DirectoryHelper.refreshDirectory(getContext());
|
DirectoryHelper.refreshDirectory(getContext(), KeyCachingService.getMasterSecret(getContext()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ public interface MmsSmsColumns {
|
|||||||
protected static final long INCOMING_CALL_TYPE = 1;
|
protected static final long INCOMING_CALL_TYPE = 1;
|
||||||
protected static final long OUTGOING_CALL_TYPE = 2;
|
protected static final long OUTGOING_CALL_TYPE = 2;
|
||||||
protected static final long MISSED_CALL_TYPE = 3;
|
protected static final long MISSED_CALL_TYPE = 3;
|
||||||
|
protected static final long JOINED_TYPE = 4;
|
||||||
|
|
||||||
protected static final long BASE_INBOX_TYPE = 20;
|
protected static final long BASE_INBOX_TYPE = 20;
|
||||||
protected static final long BASE_OUTBOX_TYPE = 21;
|
protected static final long BASE_OUTBOX_TYPE = 21;
|
||||||
@ -114,6 +115,10 @@ public interface MmsSmsColumns {
|
|||||||
return (type & BASE_TYPE_MASK) == BASE_INBOX_TYPE;
|
return (type & BASE_TYPE_MASK) == BASE_INBOX_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isJoinedType(long type) {
|
||||||
|
return (type & BASE_TYPE_MASK) == JOINED_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isSecureType(long type) {
|
public static boolean isSecureType(long type) {
|
||||||
return (type & SECURE_MESSAGE_BIT) != 0;
|
return (type & SECURE_MESSAGE_BIT) != 0;
|
||||||
}
|
}
|
||||||
|
@ -384,7 +384,9 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Pair<Long, Long> insertMessageInbox(IncomingTextMessage message, long type) {
|
protected Pair<Long, Long> insertMessageInbox(IncomingTextMessage message, long type) {
|
||||||
if (message.isPreKeyBundle()) {
|
if (message.isJoined()) {
|
||||||
|
type = (type & (Types.TOTAL_MASK - Types.BASE_TYPE_MASK)) | Types.JOINED_TYPE;
|
||||||
|
} else if (message.isPreKeyBundle()) {
|
||||||
type |= Types.KEY_EXCHANGE_BIT | Types.KEY_EXCHANGE_BUNDLE_BIT;
|
type |= Types.KEY_EXCHANGE_BIT | Types.KEY_EXCHANGE_BUNDLE_BIT;
|
||||||
} else if (message.isSecureMessage()) {
|
} else if (message.isSecureMessage()) {
|
||||||
type |= Types.SECURE_MESSAGE_BIT;
|
type |= Types.SECURE_MESSAGE_BIT;
|
||||||
|
@ -99,6 +99,10 @@ public abstract class DisplayRecord {
|
|||||||
return SmsDatabase.Types.isCallLog(type);
|
return SmsDatabase.Types.isCallLog(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isJoined() {
|
||||||
|
return SmsDatabase.Types.isJoinedType(type);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isIncomingCall() {
|
public boolean isIncomingCall() {
|
||||||
return SmsDatabase.Types.isIncomingCall(type);
|
return SmsDatabase.Types.isIncomingCall(type);
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,8 @@ public abstract class MessageRecord extends DisplayRecord {
|
|||||||
return emphasisAdded(context.getString(R.string.MessageRecord_called_s, getIndividualRecipient().toShortString()));
|
return emphasisAdded(context.getString(R.string.MessageRecord_called_s, getIndividualRecipient().toShortString()));
|
||||||
} else if (isMissedCall()) {
|
} else if (isMissedCall()) {
|
||||||
return emphasisAdded(context.getString(R.string.MessageRecord_missed_call_from, getIndividualRecipient().toShortString()));
|
return emphasisAdded(context.getString(R.string.MessageRecord_missed_call_from, getIndividualRecipient().toShortString()));
|
||||||
|
} else if (isJoined()) {
|
||||||
|
return emphasisAdded(context.getString(R.string.MessageRecord_s_is_on_signal_say_hey, getIndividualRecipient().toShortString()));
|
||||||
} else if (getBody().getBody().length() > MAX_DISPLAY_LENGTH) {
|
} else if (getBody().getBody().length() > MAX_DISPLAY_LENGTH) {
|
||||||
return new SpannableString(getBody().getBody().substring(0, MAX_DISPLAY_LENGTH));
|
return new SpannableString(getBody().getBody().substring(0, MAX_DISPLAY_LENGTH));
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,8 @@ public class ThreadRecord extends DisplayRecord {
|
|||||||
return emphasisAdded(context.getString(org.thoughtcrime.securesms.R.string.ThreadRecord_called_you));
|
return emphasisAdded(context.getString(org.thoughtcrime.securesms.R.string.ThreadRecord_called_you));
|
||||||
} else if (SmsDatabase.Types.isMissedCall(type)) {
|
} else if (SmsDatabase.Types.isMissedCall(type)) {
|
||||||
return emphasisAdded(context.getString(org.thoughtcrime.securesms.R.string.ThreadRecord_missed_call));
|
return emphasisAdded(context.getString(org.thoughtcrime.securesms.R.string.ThreadRecord_missed_call));
|
||||||
|
} else if (SmsDatabase.Types.isJoinedType(type)) {
|
||||||
|
return emphasisAdded(context.getString(R.string.ThreadRecord_s_is_on_signal_say_hey, getRecipients().getPrimaryRecipient().toShortString()));
|
||||||
} else {
|
} else {
|
||||||
if (TextUtils.isEmpty(getBody().getBody())) {
|
if (TextUtils.isEmpty(getBody().getBody())) {
|
||||||
return new SpannableString(emphasisAdded(context.getString(R.string.ThreadRecord_media_message)));
|
return new SpannableString(emphasisAdded(context.getString(R.string.ThreadRecord_media_message)));
|
||||||
|
@ -4,6 +4,7 @@ import android.content.Context;
|
|||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.crypto.SecurityEvent;
|
import org.thoughtcrime.securesms.crypto.SecurityEvent;
|
||||||
|
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||||
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
||||||
import org.whispersystems.jobqueue.JobParameters;
|
import org.whispersystems.jobqueue.JobParameters;
|
||||||
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
|
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
|
||||||
@ -30,7 +31,7 @@ public class DirectoryRefreshJob extends ContextJob {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
wakeLock.acquire();
|
wakeLock.acquire();
|
||||||
DirectoryHelper.refreshDirectory(context);
|
DirectoryHelper.refreshDirectory(context, KeyCachingService.getMasterSecret(context));
|
||||||
SecurityEvent.broadcastSecurityUpdateEvent(context);
|
SecurityEvent.broadcastSecurityUpdateEvent(context);
|
||||||
} finally {
|
} finally {
|
||||||
if (wakeLock.isHeld()) wakeLock.release();
|
if (wakeLock.isHeld()) wakeLock.release();
|
||||||
|
@ -14,6 +14,8 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
|||||||
|
|
||||||
public class DirectoryRefreshListener extends BroadcastReceiver {
|
public class DirectoryRefreshListener extends BroadcastReceiver {
|
||||||
|
|
||||||
|
private static final String TAG = DirectoryRefreshListener.class.getSimpleName();
|
||||||
|
|
||||||
private static final String REFRESH_EVENT = "org.whispersystems.whisperpush.DIRECTORY_REFRESH";
|
private static final String REFRESH_EVENT = "org.whispersystems.whisperpush.DIRECTORY_REFRESH";
|
||||||
private static final String BOOT_EVENT = "android.intent.action.BOOT_COMPLETED";
|
private static final String BOOT_EVENT = "android.intent.action.BOOT_COMPLETED";
|
||||||
|
|
||||||
@ -51,7 +53,7 @@ public class DirectoryRefreshListener extends BroadcastReceiver {
|
|||||||
time = System.currentTimeMillis() + INTERVAL;
|
time = System.currentTimeMillis() + INTERVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.w("DirectoryRefreshListener", "Scheduling for: " + time);
|
Log.w(TAG, "Scheduling for: " + time);
|
||||||
|
|
||||||
alarmManager.cancel(pendingIntent);
|
alarmManager.cancel(pendingIntent);
|
||||||
alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);
|
alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package org.thoughtcrime.securesms.sms;
|
||||||
|
|
||||||
|
import org.whispersystems.libaxolotl.util.guava.Optional;
|
||||||
|
import org.whispersystems.textsecure.api.messages.TextSecureGroup;
|
||||||
|
|
||||||
|
public class IncomingJoinedMessage extends IncomingTextMessage {
|
||||||
|
|
||||||
|
public IncomingJoinedMessage(String sender) {
|
||||||
|
super(sender, 1, System.currentTimeMillis(), null, Optional.<TextSecureGroup>absent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isJoined() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSecureMessage() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -188,6 +188,10 @@ public class IncomingTextMessage implements Parcelable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isJoined() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int describeContents() {
|
public int describeContents() {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -7,17 +7,25 @@ import android.content.Context;
|
|||||||
import android.content.OperationApplicationException;
|
import android.content.OperationApplicationException;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.provider.ContactsContract;
|
import android.provider.ContactsContract;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.ApplicationContext;
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.NotInDirectoryException;
|
import org.thoughtcrime.securesms.database.NotInDirectoryException;
|
||||||
import org.thoughtcrime.securesms.database.TextSecureDirectory;
|
import org.thoughtcrime.securesms.database.TextSecureDirectory;
|
||||||
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
|
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
|
||||||
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
|
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
|
||||||
|
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||||
import org.thoughtcrime.securesms.push.TextSecureCommunicationFactory;
|
import org.thoughtcrime.securesms.push.TextSecureCommunicationFactory;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||||
|
import org.thoughtcrime.securesms.sms.IncomingGroupMessage;
|
||||||
|
import org.thoughtcrime.securesms.sms.IncomingJoinedMessage;
|
||||||
|
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||||
import org.thoughtcrime.securesms.util.DirectoryHelper.UserCapabilities.Capability;
|
import org.thoughtcrime.securesms.util.DirectoryHelper.UserCapabilities.Capability;
|
||||||
import org.whispersystems.libaxolotl.util.guava.Optional;
|
import org.whispersystems.libaxolotl.util.guava.Optional;
|
||||||
import org.whispersystems.textsecure.api.TextSecureAccountManager;
|
import org.whispersystems.textsecure.api.TextSecureAccountManager;
|
||||||
@ -59,13 +67,29 @@ public class DirectoryHelper {
|
|||||||
|
|
||||||
private static final String TAG = DirectoryHelper.class.getSimpleName();
|
private static final String TAG = DirectoryHelper.class.getSimpleName();
|
||||||
|
|
||||||
public static void refreshDirectory(final Context context) throws IOException {
|
public static void refreshDirectory(@NonNull Context context, @Nullable MasterSecret masterSecret)
|
||||||
refreshDirectory(context,
|
throws IOException
|
||||||
TextSecureCommunicationFactory.createManager(context),
|
{
|
||||||
TextSecurePreferences.getLocalNumber(context));
|
List<String> newUsers = refreshDirectory(context,
|
||||||
|
TextSecureCommunicationFactory.createManager(context),
|
||||||
|
TextSecurePreferences.getLocalNumber(context));
|
||||||
|
|
||||||
|
if (!newUsers.isEmpty() && TextSecurePreferences.isMultiDevice(context)) {
|
||||||
|
ApplicationContext.getInstance(context)
|
||||||
|
.getJobManager()
|
||||||
|
.add(new MultiDeviceContactUpdateJob(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String newUser : newUsers) {
|
||||||
|
IncomingJoinedMessage message = new IncomingJoinedMessage(newUser);
|
||||||
|
Pair<Long, Long> smsAndThreadId = DatabaseFactory.getSmsDatabase(context).insertMessageInbox(message);
|
||||||
|
MessageNotifier.updateNotification(context, masterSecret, smsAndThreadId.second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void refreshDirectory(final Context context, final TextSecureAccountManager accountManager, final String localNumber)
|
public static @NonNull List<String> refreshDirectory(@NonNull Context context,
|
||||||
|
@NonNull TextSecureAccountManager accountManager,
|
||||||
|
@NonNull String localNumber)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
TextSecureDirectory directory = TextSecureDirectory.getInstance(context);
|
TextSecureDirectory directory = TextSecureDirectory.getInstance(context);
|
||||||
@ -89,19 +113,15 @@ public class DirectoryHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
boolean modified = DatabaseFactory.getContactsDatabase(context)
|
return DatabaseFactory.getContactsDatabase(context)
|
||||||
.setRegisteredUsers(account.get(), e164numbers);
|
.setRegisteredUsers(account.get(), localNumber, e164numbers);
|
||||||
|
|
||||||
if (modified && TextSecurePreferences.isMultiDevice(context)) {
|
|
||||||
ApplicationContext.getInstance(context)
|
|
||||||
.getJobManager()
|
|
||||||
.add(new MultiDeviceContactUpdateJob(context));
|
|
||||||
}
|
|
||||||
} catch (RemoteException | OperationApplicationException e) {
|
} catch (RemoteException | OperationApplicationException e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return new LinkedList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UserCapabilities refreshDirectoryFor(Context context, Recipients recipients)
|
public static UserCapabilities refreshDirectoryFor(Context context, Recipients recipients)
|
||||||
@ -173,8 +193,16 @@ public class DirectoryHelper {
|
|||||||
AccountManager accountManager = AccountManager.get(context);
|
AccountManager accountManager = AccountManager.get(context);
|
||||||
Account[] accounts = accountManager.getAccountsByType("org.thoughtcrime.securesms");
|
Account[] accounts = accountManager.getAccountsByType("org.thoughtcrime.securesms");
|
||||||
|
|
||||||
if (accounts.length == 0) return createAccount(context);
|
Optional<Account> account;
|
||||||
else return Optional.of(accounts[0]);
|
|
||||||
|
if (accounts.length == 0) account = createAccount(context);
|
||||||
|
else account = Optional.of(accounts[0]);
|
||||||
|
|
||||||
|
if (account.isPresent() && !ContentResolver.getSyncAutomatically(account.get(), ContactsContract.AUTHORITY)) {
|
||||||
|
ContentResolver.setSyncAutomatically(account.get(), ContactsContract.AUTHORITY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Optional<Account> createAccount(Context context) {
|
private static Optional<Account> createAccount(Context context) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user