From 13086cfba468c98d66c285a20dc8c13d92b39a85 Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Mon, 21 Sep 2015 17:31:38 -0700 Subject: [PATCH] Support for syncing voice support indicators // FREEBIE --- .../api/TextSecureAccountManager.java | 28 ++++++++++++++++--- .../api/push/ContactTokenDetails.java | 17 ++++++++--- .../internal/push/AccountAttributes.java | 9 +++++- .../push/ContactTokenDetailsList.java | 3 ++ .../internal/push/PushServiceSocket.java | 14 +++++++--- 5 files changed, 58 insertions(+), 13 deletions(-) diff --git a/java/src/main/java/org/whispersystems/textsecure/api/TextSecureAccountManager.java b/java/src/main/java/org/whispersystems/textsecure/api/TextSecureAccountManager.java index e2e713402d..bce04ef6c4 100644 --- a/java/src/main/java/org/whispersystems/textsecure/api/TextSecureAccountManager.java +++ b/java/src/main/java/org/whispersystems/textsecure/api/TextSecureAccountManager.java @@ -123,14 +123,15 @@ public class TextSecureAccountManager { * This value should remain consistent across registrations for the * same install, but probabilistically differ across registrations * for separate installs. + * @param voice A boolean that indicates whether the client supports secure voice (RedPhone) calls. * * @throws IOException */ - public void verifyAccountWithCode(String verificationCode, String signalingKey, int axolotlRegistrationId) + public void verifyAccountWithCode(String verificationCode, String signalingKey, int axolotlRegistrationId, boolean voice) throws IOException { this.pushServiceSocket.verifyAccountCode(verificationCode, signalingKey, - axolotlRegistrationId); + axolotlRegistrationId, voice); } /** @@ -144,13 +145,32 @@ public class TextSecureAccountManager { * This value should remain consistent across registrations for the * same install, but probabilistically differ across registrations * for separate installs. + * @param voice A boolean that indicates whether the client supports secure voice (RedPhone) calls. * * @throws IOException */ - public void verifyAccountWithToken(String verificationToken, String signalingKey, int axolotlRegistrationId) + public void verifyAccountWithToken(String verificationToken, String signalingKey, int axolotlRegistrationId, boolean voice) throws IOException { - this.pushServiceSocket.verifyAccountToken(verificationToken, signalingKey, axolotlRegistrationId); + this.pushServiceSocket.verifyAccountToken(verificationToken, signalingKey, axolotlRegistrationId, voice); + } + + /** + * Refresh account attributes with server. + * + * @param signalingKey 52 random bytes. A 32 byte AES key and a 20 byte Hmac256 key, concatenated. + * @param axolotlRegistrationId A random 14-bit number that identifies this TextSecure install. + * This value should remain consistent across registrations for the same + * install, but probabilistically differ across registrations for + * separate installs. + * @param voice A boolean that indicates whether the client supports secure voice (RedPhone) + * + * @throws IOException + */ + public void setAccountAttributes(String signalingKey, int axolotlRegistrationId, boolean voice) + throws IOException + { + this.pushServiceSocket.setAccountAttributes(signalingKey, axolotlRegistrationId, voice); } /** diff --git a/java/src/main/java/org/whispersystems/textsecure/api/push/ContactTokenDetails.java b/java/src/main/java/org/whispersystems/textsecure/api/push/ContactTokenDetails.java index 3012492446..3140e7d7a8 100644 --- a/java/src/main/java/org/whispersystems/textsecure/api/push/ContactTokenDetails.java +++ b/java/src/main/java/org/whispersystems/textsecure/api/push/ContactTokenDetails.java @@ -16,15 +16,24 @@ */ package org.whispersystems.textsecure.api.push; +import com.fasterxml.jackson.annotation.JsonProperty; + /** * A class that represents a contact's registration state. */ public class ContactTokenDetails { + @JsonProperty private String token; + + @JsonProperty private String relay; + + @JsonProperty private String number; - private boolean supportsSms; + + @JsonProperty + private boolean voice; public ContactTokenDetails() {} @@ -43,10 +52,10 @@ public class ContactTokenDetails { } /** - * @return Whether this contact supports receiving encrypted SMS. + * @return Whether this contact supports secure voice calls. */ - public boolean isSupportsSms() { - return supportsSms; + public boolean isVoice() { + return voice; } public void setNumber(String number) { diff --git a/java/src/main/java/org/whispersystems/textsecure/internal/push/AccountAttributes.java b/java/src/main/java/org/whispersystems/textsecure/internal/push/AccountAttributes.java index f92f9a60a8..ada7aad212 100644 --- a/java/src/main/java/org/whispersystems/textsecure/internal/push/AccountAttributes.java +++ b/java/src/main/java/org/whispersystems/textsecure/internal/push/AccountAttributes.java @@ -26,9 +26,13 @@ public class AccountAttributes { @JsonProperty private int registrationId; - public AccountAttributes(String signalingKey, int registrationId) { + @JsonProperty + private boolean voice; + + public AccountAttributes(String signalingKey, int registrationId, boolean voice) { this.signalingKey = signalingKey; this.registrationId = registrationId; + this.voice = voice; } public AccountAttributes() {} @@ -41,4 +45,7 @@ public class AccountAttributes { return registrationId; } + public boolean isVoice() { + return voice; + } } diff --git a/java/src/main/java/org/whispersystems/textsecure/internal/push/ContactTokenDetailsList.java b/java/src/main/java/org/whispersystems/textsecure/internal/push/ContactTokenDetailsList.java index 79fd91a4ed..730b23f530 100644 --- a/java/src/main/java/org/whispersystems/textsecure/internal/push/ContactTokenDetailsList.java +++ b/java/src/main/java/org/whispersystems/textsecure/internal/push/ContactTokenDetailsList.java @@ -16,12 +16,15 @@ */ package org.whispersystems.textsecure.internal.push; +import com.fasterxml.jackson.annotation.JsonProperty; + import org.whispersystems.textsecure.api.push.ContactTokenDetails; import java.util.List; public class ContactTokenDetailsList { + @JsonProperty private List contacts; public ContactTokenDetailsList() {} diff --git a/java/src/main/java/org/whispersystems/textsecure/internal/push/PushServiceSocket.java b/java/src/main/java/org/whispersystems/textsecure/internal/push/PushServiceSocket.java index a6c60efadf..34160d892f 100644 --- a/java/src/main/java/org/whispersystems/textsecure/internal/push/PushServiceSocket.java +++ b/java/src/main/java/org/whispersystems/textsecure/internal/push/PushServiceSocket.java @@ -83,6 +83,7 @@ public class PushServiceSocket { private static final String VERIFY_ACCOUNT_TOKEN_PATH = "/v1/accounts/token/%s"; private static final String REGISTER_GCM_PATH = "/v1/accounts/gcm/"; private static final String REQUEST_TOKEN_PATH = "/v1/accounts/token"; + private static final String SET_ACCOUNT_ATTRIBUTES = "/v1/acccounts/attributes"; private static final String PREKEY_METADATA_PATH = "/v2/keys/"; private static final String PREKEY_PATH = "/v2/keys/%s"; @@ -120,22 +121,27 @@ public class PushServiceSocket { makeRequest(String.format(path, credentialsProvider.getUser()), "GET", null); } - public void verifyAccountCode(String verificationCode, String signalingKey, int registrationId) + public void verifyAccountCode(String verificationCode, String signalingKey, int registrationId, boolean voice) throws IOException { - AccountAttributes signalingKeyEntity = new AccountAttributes(signalingKey, registrationId); + AccountAttributes signalingKeyEntity = new AccountAttributes(signalingKey, registrationId, voice); makeRequest(String.format(VERIFY_ACCOUNT_CODE_PATH, verificationCode), "PUT", JsonUtil.toJson(signalingKeyEntity)); } - public void verifyAccountToken(String verificationToken, String signalingKey, int registrationId) + public void verifyAccountToken(String verificationToken, String signalingKey, int registrationId, boolean voice) throws IOException { - AccountAttributes signalingKeyEntity = new AccountAttributes(signalingKey, registrationId); + AccountAttributes signalingKeyEntity = new AccountAttributes(signalingKey, registrationId, voice); makeRequest(String.format(VERIFY_ACCOUNT_TOKEN_PATH, verificationToken), "PUT", JsonUtil.toJson(signalingKeyEntity)); } + public void setAccountAttributes(String signalingKey, int registrationId, boolean voice) throws IOException { + AccountAttributes accountAttributes = new AccountAttributes(signalingKey, registrationId, voice); + makeRequest(SET_ACCOUNT_ATTRIBUTES, "PUT", JsonUtil.toJson(accountAttributes)); + } + public String getAccountVerificationToken() throws IOException { String responseText = makeRequest(REQUEST_TOKEN_PATH, "GET", null); return JsonUtil.fromJson(responseText, AuthorizationToken.class).getToken();