diff --git a/src/org/thoughtcrime/securesms/DeviceListActivity.java b/src/org/thoughtcrime/securesms/DeviceListActivity.java index 70605144e3..9e8138c685 100644 --- a/src/org/thoughtcrime/securesms/DeviceListActivity.java +++ b/src/org/thoughtcrime/securesms/DeviceListActivity.java @@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.dependencies.InjectableType; import org.thoughtcrime.securesms.util.DynamicLanguage; import org.thoughtcrime.securesms.util.DynamicTheme; import org.thoughtcrime.securesms.util.ProgressDialogAsyncTask; +import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.textsecure.api.TextSecureAccountManager; import org.whispersystems.textsecure.api.messages.multidevice.DeviceInfo; @@ -122,8 +123,12 @@ public class DeviceListActivity extends PassphraseRequiredActionBarActivity { setListAdapter(new DeviceListAdapter(getActivity(), R.layout.device_list_item_view, data)); - if (data.isEmpty()) empty.setVisibility(View.VISIBLE); - else empty.setVisibility(View.GONE); + if (data.isEmpty()) { + empty.setVisibility(View.VISIBLE); + TextSecurePreferences.setMultiDevice(getActivity(), false); + } else { + empty.setVisibility(View.GONE); + } } @Override diff --git a/src/org/thoughtcrime/securesms/DeviceProvisioningActivity.java b/src/org/thoughtcrime/securesms/DeviceProvisioningActivity.java index 2d5799da3e..77c5aec2de 100644 --- a/src/org/thoughtcrime/securesms/DeviceProvisioningActivity.java +++ b/src/org/thoughtcrime/securesms/DeviceProvisioningActivity.java @@ -20,6 +20,7 @@ import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.push.TextSecureCommunicationFactory; import org.thoughtcrime.securesms.util.Base64; import org.thoughtcrime.securesms.util.ProgressDialogAsyncTask; +import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.libaxolotl.IdentityKeyPair; import org.whispersystems.libaxolotl.InvalidKeyException; import org.whispersystems.libaxolotl.ecc.Curve; @@ -111,6 +112,7 @@ public class DeviceProvisioningActivity extends PassphraseRequiredActionBarActiv IdentityKeyPair identityKeyPair = IdentityKeyUtil.getIdentityKeyPair(context); accountManager.addDevice(ephemeralId, publicKey, identityKeyPair, verificationCode); + TextSecurePreferences.setMultiDevice(context, true); return SUCCESS; diff --git a/src/org/thoughtcrime/securesms/contacts/ContactsDatabase.java b/src/org/thoughtcrime/securesms/contacts/ContactsDatabase.java index 28f8ee7b07..24b59ef62f 100644 --- a/src/org/thoughtcrime/securesms/contacts/ContactsDatabase.java +++ b/src/org/thoughtcrime/securesms/contacts/ContactsDatabase.java @@ -70,7 +70,7 @@ public class ContactsDatabase { this.context = context; } - public synchronized void setRegisteredUsers(Account account, List e164numbers) + public synchronized boolean setRegisteredUsers(Account account, List e164numbers) throws RemoteException, OperationApplicationException { Map currentContacts = new HashMap<>(); @@ -111,6 +111,9 @@ public class ContactsDatabase { if (!operations.isEmpty()) { context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations); + return true; + } else { + return false; } } diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java index 35011f7879..f0a9dffb99 100644 --- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java +++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java @@ -101,17 +101,19 @@ public class MultiDeviceContactUpdateJob extends MasterSecretJob implements Inje private void sendUpdate(TextSecureMessageSender messageSender, File contactsFile) throws IOException, UntrustedIdentityException, NetworkException { - FileInputStream contactsFileStream = new FileInputStream(contactsFile); - TextSecureAttachmentStream attachmentStream = TextSecureAttachment.newStreamBuilder() - .withStream(contactsFileStream) - .withContentType("application/octet-stream") - .withLength(contactsFile.length()) - .build(); + if (contactsFile.length() > 0) { + FileInputStream contactsFileStream = new FileInputStream(contactsFile); + TextSecureAttachmentStream attachmentStream = TextSecureAttachment.newStreamBuilder() + .withStream(contactsFileStream) + .withContentType("application/octet-stream") + .withLength(contactsFile.length()) + .build(); - try { - messageSender.sendMessage(TextSecureSyncMessage.forContacts(attachmentStream)); - } catch (IOException ioe) { - throw new NetworkException(ioe); + try { + messageSender.sendMessage(TextSecureSyncMessage.forContacts(attachmentStream)); + } catch (IOException ioe) { + throw new NetworkException(ioe); + } } } diff --git a/src/org/thoughtcrime/securesms/util/DirectoryHelper.java b/src/org/thoughtcrime/securesms/util/DirectoryHelper.java index e8a09b2567..496415d73a 100644 --- a/src/org/thoughtcrime/securesms/util/DirectoryHelper.java +++ b/src/org/thoughtcrime/securesms/util/DirectoryHelper.java @@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.NotInDirectoryException; import org.thoughtcrime.securesms.database.TextSecureDirectory; import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob; +import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob; import org.thoughtcrime.securesms.push.TextSecureCommunicationFactory; import org.thoughtcrime.securesms.recipients.Recipients; import org.thoughtcrime.securesms.util.DirectoryHelper.UserCapabilities.Capability; @@ -59,13 +60,9 @@ public class DirectoryHelper { private static final String TAG = DirectoryHelper.class.getSimpleName(); public static void refreshDirectory(final Context context) throws IOException { - refreshDirectory(context, TextSecureCommunicationFactory.createManager(context)); - } - - public static void refreshDirectory(final Context context, final TextSecureAccountManager accountManager) - throws IOException - { - refreshDirectory(context, accountManager, TextSecurePreferences.getLocalNumber(context)); + refreshDirectory(context, + TextSecureCommunicationFactory.createManager(context), + TextSecurePreferences.getLocalNumber(context)); } public static void refreshDirectory(final Context context, final TextSecureAccountManager accountManager, final String localNumber) @@ -92,7 +89,14 @@ public class DirectoryHelper { } try { - DatabaseFactory.getContactsDatabase(context).setRegisteredUsers(account.get(), e164numbers); + boolean modified = DatabaseFactory.getContactsDatabase(context) + .setRegisteredUsers(account.get(), e164numbers); + + if (modified && TextSecurePreferences.isMultiDevice(context)) { + ApplicationContext.getInstance(context) + .getJobManager() + .add(new MultiDeviceContactUpdateJob(context)); + } } catch (RemoteException | OperationApplicationException e) { Log.w(TAG, e); } diff --git a/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java index 7d4d62b01b..e6b05ce628 100644 --- a/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java +++ b/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java @@ -90,6 +90,15 @@ public class TextSecurePreferences { public static final String MEDIA_DOWNLOAD_ROAMING_PREF = "pref_media_download_roaming"; public static final String SYSTEM_EMOJI_PREF = "pref_system_emoji"; + private static final String MULTI_DEVICE_PROVISIONED_PREF = "pref_multi_device"; + + public static void setMultiDevice(Context context, boolean value) { + setBooleanPreference(context, MULTI_DEVICE_PROVISIONED_PREF, value); + } + + public static boolean isMultiDevice(Context context) { + return getBooleanPreference(context, MULTI_DEVICE_PROVISIONED_PREF, false); + } public static NotificationPrivacyPreference getNotificationPrivacy(Context context) { return new NotificationPrivacyPreference(getStringPreference(context, NOTIFICATION_PRIVACY_PREF, "all"));