mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 12:05:22 +00:00
Support for populating contacts DB with TS account type.
// FREEBIE
This commit is contained in:
parent
8d9ae731ef
commit
d1940fe0f9
@ -148,6 +148,8 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
|
||||
|
||||
</activity-alias>
|
||||
|
||||
<activity android:name=".ConversationActivity"
|
||||
@ -278,6 +280,11 @@
|
||||
<data android:scheme="mms" />
|
||||
<data android:scheme="mmsto" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".RecipientPreferenceActivity"
|
||||
@ -308,6 +315,20 @@
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<service android:name=".service.AccountAuthenticatorService" android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.accounts.AccountAuthenticator" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator" />
|
||||
</service>
|
||||
|
||||
<service android:name=".service.ContactsSyncAdapterService" android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.SyncAdapter"/>
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.content.SyncAdapter" android:resource="@xml/syncadapter" />
|
||||
<meta-data android:name="android.provider.CONTACTS_STRUCTURE" android:resource="@xml/contactsformat" />
|
||||
</service>
|
||||
|
||||
<receiver android:name=".gcm.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
|
||||
<intent-filter>
|
||||
|
6
res/xml/authenticator.xml
Normal file
6
res/xml/authenticator.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:accountType="org.thoughtcrime.securesms"
|
||||
android:icon="@drawable/icon"
|
||||
android:smallIcon="@drawable/icon"
|
||||
android:label="@string/app_name"/>
|
||||
|
9
res/xml/contactsformat.xml
Normal file
9
res/xml/contactsformat.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ContactsSource xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<ContactsDataKind
|
||||
android:icon="@drawable/icon"
|
||||
android:mimeType="vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact"
|
||||
android:summaryColumn="data2"
|
||||
android:detailColumn="data3"
|
||||
android:detailSocialSummary="true"/>
|
||||
</ContactsSource>
|
8
res/xml/syncadapter.xml
Normal file
8
res/xml/syncadapter.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:contentAuthority="com.android.contacts"
|
||||
android:accountType="org.thoughtcrime.securesms"
|
||||
android:userVisible="true"
|
||||
android:supportsUploading="false"
|
||||
android:allowParallelSyncs="false"
|
||||
android:isAlwaysSyncable="true"/>
|
@ -2,7 +2,10 @@ package org.thoughtcrime.securesms;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.provider.ContactsContract;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
@ -25,36 +28,79 @@ public class SmsSendtoActivity extends Activity {
|
||||
}
|
||||
|
||||
private Intent getNextIntent(Intent original) {
|
||||
String body = "";
|
||||
String data = "";
|
||||
DestinationAndBody destination;
|
||||
|
||||
if (original.getAction().equals(Intent.ACTION_SENDTO)) {
|
||||
body = original.getStringExtra("sms_body");
|
||||
data = original.getData().getSchemeSpecificPart();
|
||||
destination = getDestinationForSendTo(original);
|
||||
} else if (original.getData() != null && "content".equals(original.getData().getScheme())) {
|
||||
destination = getDestinationForSyncAdapter(original);
|
||||
} else {
|
||||
try {
|
||||
Rfc5724Uri smsUri = new Rfc5724Uri(original.getData().toString());
|
||||
body = smsUri.getQueryParams().get("body");
|
||||
data = smsUri.getPath();
|
||||
} catch (URISyntaxException e) {
|
||||
Log.w(TAG, "unable to parse RFC5724 URI from intent", e);
|
||||
}
|
||||
destination = getDestinationForView(original);
|
||||
}
|
||||
|
||||
Recipients recipients = RecipientFactory.getRecipientsFromString(this, data, false);
|
||||
Recipients recipients = RecipientFactory.getRecipientsFromString(this, destination.getDestination(), false);
|
||||
long threadId = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipients);
|
||||
|
||||
final Intent nextIntent;
|
||||
if (recipients == null || recipients.isEmpty()) {
|
||||
nextIntent = new Intent(this, NewConversationActivity.class);
|
||||
nextIntent.putExtra(ConversationActivity.DRAFT_TEXT_EXTRA, body);
|
||||
nextIntent.putExtra(ConversationActivity.DRAFT_TEXT_EXTRA, destination.getBody());
|
||||
Toast.makeText(this, R.string.ConversationActivity_specify_recipient, Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
nextIntent = new Intent(this, ConversationActivity.class);
|
||||
nextIntent.putExtra(ConversationActivity.DRAFT_TEXT_EXTRA, body);
|
||||
nextIntent.putExtra(ConversationActivity.DRAFT_TEXT_EXTRA, destination.getBody());
|
||||
nextIntent.putExtra(ConversationActivity.THREAD_ID_EXTRA, threadId);
|
||||
nextIntent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients.getIds());
|
||||
}
|
||||
return nextIntent;
|
||||
}
|
||||
|
||||
private @NonNull DestinationAndBody getDestinationForSendTo(Intent intent) {
|
||||
return new DestinationAndBody(intent.getData().getSchemeSpecificPart(),
|
||||
intent.getStringExtra("sms_body"));
|
||||
}
|
||||
|
||||
private @NonNull DestinationAndBody getDestinationForView(Intent intent) {
|
||||
try {
|
||||
Rfc5724Uri smsUri = new Rfc5724Uri(intent.getData().toString());
|
||||
return new DestinationAndBody(smsUri.getPath(), smsUri.getQueryParams().get("body"));
|
||||
} catch (URISyntaxException e) {
|
||||
Log.w(TAG, "unable to parse RFC5724 URI from intent", e);
|
||||
return new DestinationAndBody("", "");
|
||||
}
|
||||
}
|
||||
|
||||
private @NonNull DestinationAndBody getDestinationForSyncAdapter(Intent intent) {
|
||||
Cursor cursor = null;
|
||||
|
||||
try {
|
||||
cursor = getContentResolver().query(intent.getData(), null, null, null, null);
|
||||
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
return new DestinationAndBody(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.RawContacts.Data.DATA1)), "");
|
||||
}
|
||||
|
||||
return new DestinationAndBody("", "");
|
||||
} finally {
|
||||
if (cursor != null) cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static class DestinationAndBody {
|
||||
private final String destination;
|
||||
private final String body;
|
||||
|
||||
private DestinationAndBody(String destination, String body) {
|
||||
this.destination = destination;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public String getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,11 @@
|
||||
*/
|
||||
package org.thoughtcrime.securesms.contacts;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.ContentProviderOperation;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.OperationApplicationException;
|
||||
import android.database.Cursor;
|
||||
import android.database.CursorWrapper;
|
||||
import android.database.MatrixCursor;
|
||||
@ -25,7 +28,10 @@ import android.database.MergeCursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.BaseColumns;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.ContactsContract.RawContacts;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
@ -36,7 +42,12 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Database to supply all types of contacts that TextSecure needs to know about
|
||||
@ -84,6 +95,88 @@ public class ContactsDatabase {
|
||||
dbHelper.close();
|
||||
}
|
||||
|
||||
public synchronized void setRegisteredUsers(Account account, List<String> e164numbers)
|
||||
throws RemoteException, OperationApplicationException
|
||||
{
|
||||
Map<String, Long> currentContacts = new HashMap<>();
|
||||
Set<String> registeredNumbers = new HashSet<>(e164numbers);
|
||||
ArrayList<ContentProviderOperation> operations = new ArrayList<>();
|
||||
Uri currentContactsUri = RawContacts.CONTENT_URI.buildUpon()
|
||||
.appendQueryParameter(RawContacts.ACCOUNT_NAME, account.name)
|
||||
.appendQueryParameter(RawContacts.ACCOUNT_TYPE, account.type).build();
|
||||
|
||||
Cursor cursor = null;
|
||||
|
||||
try {
|
||||
cursor = context.getContentResolver().query(currentContactsUri, new String[] {BaseColumns._ID, RawContacts.SYNC1}, null, null, null);
|
||||
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
currentContacts.put(cursor.getString(1), cursor.getLong(0));
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
for (String number : e164numbers) {
|
||||
if (!currentContacts.containsKey(number)) {
|
||||
addTextSecureRawContact(operations, account, number);
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Long> currentContactEntry : currentContacts.entrySet()) {
|
||||
if (!registeredNumbers.contains(currentContactEntry.getKey())) {
|
||||
removeTextSecureRawContact(operations, account, currentContactEntry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (!operations.isEmpty()) {
|
||||
context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);
|
||||
}
|
||||
}
|
||||
|
||||
private void addTextSecureRawContact(List<ContentProviderOperation> operations,
|
||||
Account account, String e164number)
|
||||
{
|
||||
int index = operations.size();
|
||||
Uri dataUri = ContactsContract.Data.CONTENT_URI.buildUpon()
|
||||
.appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
|
||||
.build();
|
||||
|
||||
operations.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
|
||||
.withValue(RawContacts.ACCOUNT_NAME, account.name)
|
||||
.withValue(RawContacts.ACCOUNT_TYPE, account.type)
|
||||
.withValue(RawContacts.SYNC1, e164number)
|
||||
.build());
|
||||
|
||||
operations.add(ContentProviderOperation.newInsert(dataUri)
|
||||
.withValueBackReference(ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID, index)
|
||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
|
||||
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, e164number)
|
||||
.build());
|
||||
|
||||
operations.add(ContentProviderOperation.newInsert(dataUri)
|
||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, index)
|
||||
.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact")
|
||||
.withValue(ContactsContract.Data.DATA1, e164number)
|
||||
.withValue(ContactsContract.Data.DATA2, context.getString(R.string.app_name))
|
||||
.withValue(ContactsContract.Data.DATA3, String.format("Message %s", e164number))
|
||||
.withYieldAllowed(true)
|
||||
.build());
|
||||
}
|
||||
|
||||
private void removeTextSecureRawContact(List<ContentProviderOperation> operations,
|
||||
Account account, long rowId)
|
||||
{
|
||||
operations.add(ContentProviderOperation.newDelete(RawContacts.CONTENT_URI.buildUpon()
|
||||
.appendQueryParameter(RawContacts.ACCOUNT_NAME, account.name)
|
||||
.appendQueryParameter(RawContacts.ACCOUNT_TYPE, account.type)
|
||||
.appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").build())
|
||||
.withYieldAllowed(true)
|
||||
.withSelection(BaseColumns._ID + " = ?", new String[] {String.valueOf(rowId)})
|
||||
.build());
|
||||
}
|
||||
|
||||
public Cursor query(String filter, boolean pushOnly) {
|
||||
// FIXME: This doesn't make sense to me. You pass in pushOnly, but then
|
||||
// conditionally check to see whether other contacts should be included
|
||||
|
@ -0,0 +1,34 @@
|
||||
package org.thoughtcrime.securesms.contacts;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.AbstractThreadedSyncAdapter;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.Context;
|
||||
import android.content.SyncResult;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ContactsSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||
|
||||
private static final String TAG = ContactsSyncAdapter.class.getSimpleName();
|
||||
|
||||
public ContactsSyncAdapter(Context context, boolean autoInitialize) {
|
||||
super(context, autoInitialize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPerformSync(Account account, Bundle extras, String authority,
|
||||
ContentProviderClient provider, SyncResult syncResult)
|
||||
{
|
||||
try {
|
||||
DirectoryHelper.refreshDirectory(getContext());
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -24,20 +24,18 @@ public class TextSecureDirectory {
|
||||
private static final int INTRODUCED_CHANGE_FROM_TOKEN_TO_E164_NUMBER = 2;
|
||||
|
||||
private static final String DATABASE_NAME = "whisper_directory.db";
|
||||
private static final int DATABASE_VERSION = 2;
|
||||
private static final int DATABASE_VERSION = 3;
|
||||
|
||||
private static final String TABLE_NAME = "directory";
|
||||
private static final String ID = "_id";
|
||||
private static final String NUMBER = "number";
|
||||
private static final String REGISTERED = "registered";
|
||||
private static final String RELAY = "relay";
|
||||
private static final String SUPPORTS_SMS = "supports_sms";
|
||||
private static final String TIMESTAMP = "timestamp";
|
||||
private static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + ID + " INTEGER PRIMARY KEY, " +
|
||||
NUMBER + " TEXT UNIQUE, " +
|
||||
REGISTERED + " INTEGER, " +
|
||||
RELAY + " TEXT, " +
|
||||
SUPPORTS_SMS + " INTEGER, " +
|
||||
TIMESTAMP + " INTEGER);";
|
||||
|
||||
private static final Object instanceLock = new Object();
|
||||
@ -63,25 +61,6 @@ public class TextSecureDirectory {
|
||||
this.databaseHelper = new DatabaseHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
public boolean isSmsFallbackSupported(String e164number) {
|
||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||
Cursor cursor = null;
|
||||
|
||||
try {
|
||||
cursor = db.query(TABLE_NAME, new String[] {SUPPORTS_SMS}, NUMBER + " = ?",
|
||||
new String[]{e164number}, null, null, null);
|
||||
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
return cursor.getInt(0) == 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isActiveNumber(String e164number) throws NotInDirectoryException {
|
||||
if (e164number == null || e164number.length() == 0) {
|
||||
return false;
|
||||
@ -131,7 +110,6 @@ public class TextSecureDirectory {
|
||||
values.put(NUMBER, token.getNumber());
|
||||
values.put(RELAY, token.getRelay());
|
||||
values.put(REGISTERED, active ? 1 : 0);
|
||||
values.put(SUPPORTS_SMS, token.isSupportsSms() ? 1 : 0);
|
||||
values.put(TIMESTAMP, System.currentTimeMillis());
|
||||
db.replace(TABLE_NAME, null, values);
|
||||
}
|
||||
@ -149,7 +127,6 @@ public class TextSecureDirectory {
|
||||
values.put(REGISTERED, 1);
|
||||
values.put(TIMESTAMP, timestamp);
|
||||
values.put(RELAY, token.getRelay());
|
||||
values.put(SUPPORTS_SMS, token.isSupportsSms() ? 1 : 0);
|
||||
db.replace(TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
@ -169,7 +146,7 @@ public class TextSecureDirectory {
|
||||
|
||||
public Set<String> getPushEligibleContactNumbers(String localNumber) {
|
||||
final Uri uri = Phone.CONTENT_URI;
|
||||
final Set<String> results = new HashSet<String>();
|
||||
final Set<String> results = new HashSet<>();
|
||||
Cursor cursor = null;
|
||||
|
||||
try {
|
||||
@ -208,7 +185,7 @@ public class TextSecureDirectory {
|
||||
}
|
||||
|
||||
public List<String> getActiveNumbers() {
|
||||
final List<String> results = new ArrayList<String>();
|
||||
final List<String> results = new ArrayList<>();
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[]{NUMBER},
|
||||
|
@ -0,0 +1,80 @@
|
||||
package org.thoughtcrime.securesms.service;
|
||||
|
||||
import android.accounts.AbstractAccountAuthenticator;
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountAuthenticatorResponse;
|
||||
import android.accounts.NetworkErrorException;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
|
||||
public class AccountAuthenticatorService extends Service {
|
||||
|
||||
private static AccountAuthenticatorImpl accountAuthenticator = null;
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
if (intent.getAction().equals(android.accounts.AccountManager.ACTION_AUTHENTICATOR_INTENT)) {
|
||||
return getAuthenticator().getIBinder();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized AccountAuthenticatorImpl getAuthenticator() {
|
||||
if (accountAuthenticator == null) {
|
||||
accountAuthenticator = new AccountAuthenticatorImpl(this);
|
||||
}
|
||||
|
||||
return accountAuthenticator;
|
||||
}
|
||||
|
||||
private static class AccountAuthenticatorImpl extends AbstractAccountAuthenticator {
|
||||
|
||||
public AccountAuthenticatorImpl(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType,
|
||||
String[] requiredFeatures, Bundle options)
|
||||
throws NetworkErrorException
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType,
|
||||
Bundle options) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthTokenLabel(String authTokenType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features)
|
||||
throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType,
|
||||
Bundle options) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.thoughtcrime.securesms.service;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.contacts.ContactsSyncAdapter;
|
||||
|
||||
public class ContactsSyncAdapterService extends Service {
|
||||
|
||||
private static ContactsSyncAdapter syncAdapter;
|
||||
|
||||
@Override
|
||||
public synchronized void onCreate() {
|
||||
if (syncAdapter == null) {
|
||||
syncAdapter = new ContactsSyncAdapter(this, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return syncAdapter.getSyncAdapterBinder();
|
||||
}
|
||||
}
|
@ -1,19 +1,28 @@
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.OperationApplicationException;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.ContactsContract;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.contacts.ContactsDatabase;
|
||||
import org.thoughtcrime.securesms.database.NotInDirectoryException;
|
||||
import org.thoughtcrime.securesms.database.TextSecureDirectory;
|
||||
import org.thoughtcrime.securesms.push.TextSecureCommunicationFactory;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.whispersystems.libaxolotl.util.guava.Optional;
|
||||
import org.whispersystems.textsecure.api.TextSecureAccountManager;
|
||||
import org.whispersystems.textsecure.api.push.ContactTokenDetails;
|
||||
import org.whispersystems.textsecure.api.util.InvalidNumberException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@ -65,6 +74,7 @@ public class DirectoryHelper {
|
||||
throws IOException
|
||||
{
|
||||
TextSecureDirectory directory = TextSecureDirectory.getInstance(context);
|
||||
Optional<Account> account = getOrCreateAccount(context);
|
||||
Set<String> eligibleContactNumbers = directory.getPushEligibleContactNumbers(localNumber);
|
||||
List<ContactTokenDetails> activeTokens = accountManager.getContacts(eligibleContactNumbers);
|
||||
|
||||
@ -75,6 +85,20 @@ public class DirectoryHelper {
|
||||
}
|
||||
|
||||
directory.setNumbers(activeTokens, eligibleContactNumbers);
|
||||
|
||||
if (account.isPresent()) {
|
||||
List<String> e164numbers = new LinkedList<>();
|
||||
|
||||
for (ContactTokenDetails contactTokenDetails : activeTokens) {
|
||||
e164numbers.add(contactTokenDetails.getNumber());
|
||||
}
|
||||
|
||||
try {
|
||||
new ContactsDatabase(context).setRegisteredUsers(account.get(), e164numbers);
|
||||
} catch (RemoteException | OperationApplicationException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,24 +137,25 @@ public class DirectoryHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isSmsFallbackAllowed(Context context, Recipients recipients) {
|
||||
try {
|
||||
if (recipients == null || !recipients.isSingleRecipient() || recipients.isGroupRecipient()) {
|
||||
return false;
|
||||
private static Optional<Account> getOrCreateAccount(Context context) {
|
||||
AccountManager accountManager = AccountManager.get(context);
|
||||
Account[] accounts = accountManager.getAccountsByType("org.thoughtcrime.securesms");
|
||||
|
||||
if (accounts.length == 0) return createAccount(context);
|
||||
else return Optional.of(accounts[0]);
|
||||
}
|
||||
|
||||
final String number = recipients.getPrimaryRecipient().getNumber();
|
||||
private static Optional<Account> createAccount(Context context) {
|
||||
AccountManager accountManager = AccountManager.get(context);
|
||||
Account account = new Account(context.getString(R.string.app_name), "org.thoughtcrime.securesms");
|
||||
|
||||
if (number == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final String e164number = Util.canonicalizeNumber(context, number);
|
||||
|
||||
return TextSecureDirectory.getInstance(context).isSmsFallbackSupported(e164number);
|
||||
} catch (InvalidNumberException e) {
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
if (accountManager.addAccountExplicitly(account, null, null)) {
|
||||
Log.w(TAG, "Created new account...");
|
||||
ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 1);
|
||||
return Optional.of(account);
|
||||
} else {
|
||||
Log.w(TAG, "Failed to create account!");
|
||||
return Optional.absent();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user