Beta support for webrtc video and voice calling

// FREEBIE
This commit is contained in:
Moxie Marlinspike
2016-11-09 09:37:40 -08:00
parent a9651e2e9c
commit ea0945d406
96 changed files with 6098 additions and 130 deletions

View File

@@ -40,8 +40,8 @@ public class DirectoryHelper {
public static class UserCapabilities {
public static final UserCapabilities UNKNOWN = new UserCapabilities(Capability.UNKNOWN, Capability.UNKNOWN);
public static final UserCapabilities UNSUPPORTED = new UserCapabilities(Capability.UNSUPPORTED, Capability.UNSUPPORTED);
public static final UserCapabilities UNKNOWN = new UserCapabilities(Capability.UNKNOWN, Capability.UNKNOWN, Capability.UNKNOWN);
public static final UserCapabilities UNSUPPORTED = new UserCapabilities(Capability.UNSUPPORTED, Capability.UNSUPPORTED, Capability.UNSUPPORTED);
public enum Capability {
UNKNOWN, SUPPORTED, UNSUPPORTED
@@ -49,10 +49,12 @@ public class DirectoryHelper {
private final Capability text;
private final Capability voice;
private final Capability video;
public UserCapabilities(Capability text, Capability voice) {
public UserCapabilities(Capability text, Capability voice, Capability video) {
this.text = text;
this.voice = voice;
this.video = video;
}
public Capability getTextCapability() {
@@ -62,6 +64,10 @@ public class DirectoryHelper {
public Capability getVoiceCapability() {
return voice;
}
public Capability getVideoCapability() {
return video;
}
}
private static final String TAG = DirectoryHelper.class.getSimpleName();
@@ -131,7 +137,9 @@ public class DirectoryHelper {
notifyNewUsers(context, masterSecret, result.getNewUsers());
}
return new UserCapabilities(Capability.SUPPORTED, details.get().isVoice() ? Capability.SUPPORTED : Capability.UNSUPPORTED);
return new UserCapabilities(Capability.SUPPORTED,
details.get().isVoice() ? Capability.SUPPORTED : Capability.UNSUPPORTED,
details.get().isVideo() ? Capability.SUPPORTED : Capability.UNSUPPORTED);
} else {
ContactTokenDetails absent = new ContactTokenDetails();
absent.setNumber(number);
@@ -161,7 +169,7 @@ public class DirectoryHelper {
}
if (recipients.isGroupRecipient()) {
return new UserCapabilities(Capability.SUPPORTED, Capability.UNSUPPORTED);
return new UserCapabilities(Capability.SUPPORTED, Capability.UNSUPPORTED, Capability.UNSUPPORTED);
}
final String number = recipients.getPrimaryRecipient().getNumber();
@@ -173,9 +181,11 @@ public class DirectoryHelper {
String e164number = Util.canonicalizeNumber(context, number);
boolean secureText = TextSecureDirectory.getInstance(context).isSecureTextSupported(e164number);
boolean secureVoice = TextSecureDirectory.getInstance(context).isSecureVoiceSupported(e164number);
boolean secureVideo = TextSecureDirectory.getInstance(context).isSecureVideoSupported(e164number);
return new UserCapabilities(secureText ? Capability.SUPPORTED : Capability.UNSUPPORTED,
secureVoice ? Capability.SUPPORTED : Capability.UNSUPPORTED);
secureVoice ? Capability.SUPPORTED : Capability.UNSUPPORTED,
secureVideo ? Capability.SUPPORTED : Capability.UNSUPPORTED);
} catch (InvalidNumberException e) {
Log.w(TAG, e);

View File

@@ -16,7 +16,9 @@
*/
package org.thoughtcrime.securesms.util;
import java.util.concurrent.ExecutionException;
public interface FutureTaskListener<V> {
public void onSuccess(V result);
public void onFailure(Throwable error);
public void onFailure(ExecutionException exception);
}

View File

@@ -22,6 +22,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.FutureTask;
public class ListenableFutureTask<V> extends FutureTask<V> {
@@ -31,15 +32,24 @@ public class ListenableFutureTask<V> extends FutureTask<V> {
@Nullable
private final Object identifier;
@Nullable
private final Executor callbackExecutor;
public ListenableFutureTask(Callable<V> callable) {
this(callable, null);
}
public ListenableFutureTask(Callable<V> callable, @Nullable Object identifier) {
super(callable);
this.identifier = identifier;
this(callable, identifier, null);
}
public ListenableFutureTask(Callable<V> callable, @Nullable Object identifier, @Nullable Executor callbackExecutor) {
super(callable);
this.identifier = identifier;
this.callbackExecutor = callbackExecutor;
}
public ListenableFutureTask(final V result) {
this(result, null);
}
@@ -51,7 +61,8 @@ public class ListenableFutureTask<V> extends FutureTask<V> {
return result;
}
});
this.identifier = identifier;
this.identifier = identifier;
this.callbackExecutor = null;
this.run();
}
@@ -73,9 +84,17 @@ public class ListenableFutureTask<V> extends FutureTask<V> {
}
private void callback() {
for (FutureTaskListener<V> listener : listeners) {
callback(listener);
}
Runnable callbackRunnable = new Runnable() {
@Override
public void run() {
for (FutureTaskListener<V> listener : listeners) {
callback(listener);
}
}
};
if (callbackExecutor == null) callbackRunnable.run();
else callbackExecutor.execute(callbackRunnable);
}
private void callback(FutureTaskListener<V> listener) {

View File

@@ -90,6 +90,7 @@ public class TextSecurePreferences {
public static final String REPEAT_ALERTS_PREF = "pref_repeat_alerts";
public static final String NOTIFICATION_PRIVACY_PREF = "pref_notification_privacy";
public static final String NEW_CONTACTS_NOTIFICATIONS = "pref_enable_new_contacts_notifications";
public static final String WEBRTC_CALLING_PREF = "pref_webrtc_calling";
public static final String MEDIA_DOWNLOAD_MOBILE_PREF = "pref_media_download_mobile";
public static final String MEDIA_DOWNLOAD_WIFI_PREF = "pref_media_download_wifi";
@@ -99,6 +100,14 @@ public class TextSecurePreferences {
private static final String MULTI_DEVICE_PROVISIONED_PREF = "pref_multi_device";
public static final String DIRECT_CAPTURE_CAMERA_ID = "pref_direct_capture_camera_id";
public static boolean isWebrtcCallingEnabled(Context context) {
return getBooleanPreference(context, WEBRTC_CALLING_PREF, false);
}
public static void setWebrtcCallingEnabled(Context context, boolean enabled) {
setBooleanPreference(context, WEBRTC_CALLING_PREF, enabled);
}
public static void setDirectCaptureCameraId(Context context, int value) {
setIntegerPrefrence(context, DIRECT_CAPTURE_CAMERA_ID, value);
}

View File

@@ -459,4 +459,8 @@ public class Util {
if (first == null) return second == null;
return first.equals(second);
}
public static boolean isEquals(@Nullable Long first, long second) {
return first != null && first == second;
}
}

View File

@@ -0,0 +1,39 @@
package org.thoughtcrime.securesms.util;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.text.style.ClickableSpan;
import android.view.View;
import org.thoughtcrime.securesms.VerifyIdentityActivity;
import org.thoughtcrime.securesms.crypto.IdentityKeyParcelable;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.whispersystems.libsignal.IdentityKey;
public class VerifySpan extends ClickableSpan {
private final Context context;
private final long recipientId;
private final IdentityKey identityKey;
public VerifySpan(@NonNull Context context, @NonNull IdentityKeyMismatch mismatch) {
this.context = context;
this.recipientId = mismatch.getRecipientId();
this.identityKey = mismatch.getIdentityKey();
}
public VerifySpan(@NonNull Context context, long recipientId, @NonNull IdentityKey identityKey) {
this.context = context;
this.recipientId = recipientId;
this.identityKey = identityKey;
}
@Override
public void onClick(View widget) {
Intent intent = new Intent(context, VerifyIdentityActivity.class);
intent.putExtra(VerifyIdentityActivity.RECIPIENT_ID, recipientId);
intent.putExtra(VerifyIdentityActivity.RECIPIENT_IDENTITY, new IdentityKeyParcelable(identityKey));
context.startActivity(intent);
}
}

View File

@@ -42,6 +42,7 @@ public class SettableFuture<T> implements ListenableFuture<T> {
this.result = result;
this.completed = true;
notifyAll();
}
@@ -55,6 +56,7 @@ public class SettableFuture<T> implements ListenableFuture<T> {
this.exception = throwable;
this.completed = true;
notifyAll();
}