Refresh attributes to signal voice support on update.

// FREEBIE
This commit is contained in:
Moxie Marlinspike 2015-09-30 16:19:50 -07:00
parent 5a73884b0b
commit 0b20e99cd2
9 changed files with 95 additions and 16 deletions

View file

@ -75,10 +75,10 @@ dependencies {
compile 'com.commonsware.cwac:camera:0.6.12'
provided 'com.squareup.dagger:dagger-compiler:1.2.2'
compile 'org.whispersystems:jobmanager:0.11.0'
compile 'org.whispersystems:jobmanager:1.0.2'
compile 'org.whispersystems:libpastelog:1.0.6'
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
compile 'org.whispersystems:textsecure-android:1.8.0'
compile 'org.whispersystems:textsecure-android:1.8.1'
compile 'com.h6ah4i.android.compat:mulsellistprefcompat:1.0.0'
testCompile 'junit:junit:4.12'
@ -126,15 +126,12 @@ dependencyVerification {
'com.doomonafireball.betterpickers:library:132ecd685c95a99e7377c4e27bfadbb2d7ed0bea995944060cd62d4369fdaf3d',
'com.madgag.spongycastle:prov:b8c3fec3a59aac1aa04ccf4dad7179351e54ef7672f53f508151b614c131398a',
'com.commonsware.cwac:camera:dcc93ddbb2f0393114fa1f31a13fe9e6edfcf5dbe96b22bc4b66c7b15e179054',
'org.whispersystems:jobmanager:ea9cb943c4892fb90c1eea1be30efeb85cefca213d52c788419553b58d0ed70d',
'org.whispersystems:libpastelog:550d33c565380d90f4c671e7b8ed5f3a6da55a9fda468373177106b2eb5220b2',
'com.amulyakhare:com.amulyakhare.textdrawable:54c92b5fba38cfd316a07e5a30528068f45ce8515a6890f1297df4c401af5dcb',
'org.whispersystems:textsecure-android:226214454003de852d856509ce9ca90a0865f7ad85a45f7a769916c6362fd4d7',
'com.h6ah4i.android.compat:mulsellistprefcompat:47167c5cb796de1a854788e9ff318358e36c8fb88123baaa6e38fb78511dfabe',
'com.nineoldandroids:library:68025a14e3e7673d6ad2f95e4b46d78d7d068343aa99256b686fe59de1b3163a',
'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f',
'org.whispersystems:textsecure-java:97ef37e2ad88c6d7a896680bbab051ea894dc45409bc9b4683f75b55718fbeb5',
'org.whispersystems:axolotl-android:40d3db5004a84749a73f68d2f0d01b2ae35a73c54df96d8c6c6723b96efb6fc0',
'com.googlecode.libphonenumber:libphonenumber:eba17eae81dd622ea89a00a3a8c025b2f25d342e0d9644c5b62e16f15687c3ab',
'com.google.protobuf:protobuf-java:e0c1c64575c005601725e7c6a02cebf9e1285e888f756b2a1d73ffa8d725cc74',

View file

@ -60,6 +60,10 @@ public class RedPhoneAccountManager {
Response response = client.newCall(builder.build()).execute();
if (response.code() == 401 || response.code() == 403) {
throw new UnauthorizedException("Failed to perform GCM operation: " + response.code());
}
if (!response.isSuccessful()) {
throw new IOException("Failed to perform GCM operation: " + response.code());
}

View file

@ -0,0 +1,9 @@
package org.thoughtcrime.redphone.signaling;
import java.io.IOException;
public class UnauthorizedException extends IOException {
public UnauthorizedException(String s) {
super(s);
}
}

View file

@ -25,8 +25,10 @@ import android.os.StrictMode.VmPolicy;
import org.thoughtcrime.securesms.crypto.PRNGFixes;
import org.thoughtcrime.securesms.dependencies.AxolotlStorageModule;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.dependencies.RedPhoneCommunicationModule;
import org.thoughtcrime.securesms.dependencies.TextSecureCommunicationModule;
import org.thoughtcrime.securesms.jobs.GcmRefreshJob;
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
import org.thoughtcrime.securesms.jobs.persistence.EncryptingJobSerializer;
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirementProvider;
import org.thoughtcrime.securesms.jobs.requirements.MediaNetworkRequirementProvider;
@ -118,6 +120,7 @@ public class ApplicationContext extends Application implements DependencyInjecto
private void initializeDependencyInjection() {
this.objectGraph = ObjectGraph.create(new TextSecureCommunicationModule(this),
new RedPhoneCommunicationModule(this),
new AxolotlStorageModule(this));
}

View file

@ -41,6 +41,7 @@ import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob;
import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
import org.thoughtcrime.securesms.jobs.PushDecryptJob;
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.VersionTracker;
@ -67,6 +68,7 @@ public class DatabaseUpgradeActivity extends BaseActivity {
public static final int MIGRATE_SESSION_PLAINTEXT = 136;
public static final int CONTACTS_ACCOUNT_VERSION = 136;
public static final int MEDIA_DOWNLOAD_CONTROLS_VERSION = 151;
public static final int REDPHONE_SUPPORT_VERSION = 157;
private static final SortedSet<Integer> UPGRADE_VERSIONS = new TreeSet<Integer>() {{
add(NO_MORE_KEY_EXCHANGE_PREFIX_VERSION);
@ -79,6 +81,7 @@ public class DatabaseUpgradeActivity extends BaseActivity {
add(PUSH_DECRYPT_SERIAL_ID_VERSION);
add(MIGRATE_SESSION_PLAINTEXT);
add(MEDIA_DOWNLOAD_CONTROLS_VERSION);
add(REDPHONE_SUPPORT_VERSION);
}};
private MasterSecret masterSecret;
@ -220,6 +223,12 @@ public class DatabaseUpgradeActivity extends BaseActivity {
schedulePendingIncomingParts(context);
}
if (params[0] < REDPHONE_SUPPORT_VERSION) {
ApplicationContext.getInstance(getApplicationContext())
.getJobManager()
.add(new RefreshAttributesJob(getApplicationContext()));
}
return null;
}

View file

@ -0,0 +1,32 @@
package org.thoughtcrime.securesms.dependencies;
import android.content.Context;
import org.thoughtcrime.redphone.signaling.RedPhoneAccountManager;
import org.thoughtcrime.redphone.signaling.RedPhoneTrustStore;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.jobs.GcmRefreshJob;
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import dagger.Module;
import dagger.Provides;
@Module(complete = false, injects = {GcmRefreshJob.class,
RefreshAttributesJob.class})
public class RedPhoneCommunicationModule {
private final Context context;
public RedPhoneCommunicationModule(Context context) {
this.context = context;
}
@Provides RedPhoneAccountManager provideRedPhoneAccountManager() {
return new RedPhoneAccountManager(BuildConfig.REDPHONE_MASTER_URL,
new RedPhoneTrustStore(context),
TextSecurePreferences.getLocalNumber(context),
TextSecurePreferences.getPushServerPassword(context));
}
}

View file

@ -9,6 +9,7 @@ import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob;
import org.thoughtcrime.securesms.jobs.CleanPreKeysJob;
import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
import org.thoughtcrime.securesms.jobs.DeliveryReceiptJob;
import org.thoughtcrime.securesms.jobs.GcmRefreshJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceGroupUpdateJob;
import org.thoughtcrime.securesms.jobs.PushGroupSendJob;
@ -43,7 +44,8 @@ import dagger.Provides;
MultiDeviceContactUpdateJob.class,
MultiDeviceGroupUpdateJob.class,
DeviceListActivity.DeviceListFragment.class,
RefreshAttributesJob.class})
RefreshAttributesJob.class,
GcmRefreshJob.class})
public class TextSecureCommunicationModule {
private final Context context;

View file

@ -28,9 +28,11 @@ import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import org.thoughtcrime.redphone.signaling.RedPhoneAccountManager;
import org.thoughtcrime.redphone.signaling.UnauthorizedException;
import org.thoughtcrime.securesms.PlayServicesProblemActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.push.TextSecureCommunicationFactory;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
@ -38,12 +40,17 @@ import org.whispersystems.libaxolotl.util.guava.Optional;
import org.whispersystems.textsecure.api.TextSecureAccountManager;
import org.whispersystems.textsecure.api.push.exceptions.NonSuccessfulResponseCodeException;
public class GcmRefreshJob extends ContextJob {
import javax.inject.Inject;
public class GcmRefreshJob extends ContextJob implements InjectableType {
private static final String TAG = GcmRefreshJob.class.getSimpleName();
public static final String REGISTRATION_ID = "312334754206";
@Inject transient TextSecureAccountManager textSecureAccountManager;
@Inject transient RedPhoneAccountManager redPhoneAccountManager;
public GcmRefreshJob(Context context) {
super(context, JobParameters.newBuilder().withRequirement(new NetworkRequirement(context)).create());
}
@ -53,8 +60,7 @@ public class GcmRefreshJob extends ContextJob {
@Override
public void onRun() throws Exception {
TextSecureAccountManager accountManager = TextSecureCommunicationFactory.createManager(context);
String registrationId = TextSecurePreferences.getGcmRegistrationId(context);
String registrationId = TextSecurePreferences.getGcmRegistrationId(context);
if (registrationId == null) {
Log.w(TAG, "GCM registrationId expired, reregistering...");
@ -64,7 +70,14 @@ public class GcmRefreshJob extends ContextJob {
notifyGcmFailure();
} else {
String gcmId = GoogleCloudMessaging.getInstance(context).register(REGISTRATION_ID);
accountManager.setGcmId(Optional.of(gcmId));
textSecureAccountManager.setGcmId(Optional.of(gcmId));
try {
redPhoneAccountManager.setGcmId(Optional.of(gcmId));
} catch (UnauthorizedException e) {
Log.w(TAG, e);
}
TextSecurePreferences.setGcmRegistrationId(context, gcmId);
TextSecurePreferences.setWebsocketRegistered(context, true);
}

View file

@ -3,6 +3,9 @@ package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.util.Log;
import org.thoughtcrime.redphone.signaling.RedPhoneAccountAttributes;
import org.thoughtcrime.redphone.signaling.RedPhoneAccountManager;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
@ -13,11 +16,14 @@ import java.io.IOException;
import javax.inject.Inject;
public class RefreshAttributesJob extends ContextJob {
public class RefreshAttributesJob extends ContextJob implements InjectableType {
public static final long serialVersionUID = 1L;
private static final String TAG = RefreshAttributesJob.class.getSimpleName();
@Inject TextSecureAccountManager accountManager;
@Inject transient TextSecureAccountManager textSecureAccountManager;
@Inject transient RedPhoneAccountManager redPhoneAccountManager;
public RefreshAttributesJob(Context context) {
super(context, JobParameters.newBuilder()
@ -32,10 +38,14 @@ public class RefreshAttributesJob extends ContextJob {
@Override
public void onRun() throws IOException {
String signalingKey = TextSecurePreferences.getSignalingKey(context);
int registrationId = TextSecurePreferences.getLocalRegistrationId(context);
String signalingKey = TextSecurePreferences.getSignalingKey(context);
String gcmRegistrationId = TextSecurePreferences.getGcmRegistrationId(context);
int registrationId = TextSecurePreferences.getLocalRegistrationId(context);
accountManager.setAccountAttributes(signalingKey, registrationId, true);
String token = textSecureAccountManager.getAccountVerificationToken();
redPhoneAccountManager.createAccount(token, new RedPhoneAccountAttributes(signalingKey, gcmRegistrationId));
textSecureAccountManager.setAccountAttributes(signalingKey, registrationId, true);
}
@Override