mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-24 19:00:26 +01:00
Handle GV2 addresses.
This commit is contained in:
committed by
Greyson Parrelli
parent
06eadd0c15
commit
e4456bb236
@@ -0,0 +1,38 @@
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.whispersystems.util.Base64;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class Base64UrlSafe {
|
||||
|
||||
private Base64UrlSafe() {
|
||||
}
|
||||
|
||||
public static @NonNull byte[] decode(@NonNull String s) throws IOException {
|
||||
return Base64.decode(s, Base64.URL_SAFE);
|
||||
}
|
||||
|
||||
public static @NonNull byte[] decodePaddingAgnostic(@NonNull String s) throws IOException {
|
||||
switch (s.length() % 4) {
|
||||
case 1:
|
||||
case 3: s = s + "="; break;
|
||||
case 2: s = s + "=="; break;
|
||||
}
|
||||
return decode(s);
|
||||
}
|
||||
|
||||
public static @NonNull String encodeBytes(@NonNull byte[] source) {
|
||||
try {
|
||||
return Base64.encodeBytes(source, Base64.URL_SAFE);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static @NonNull String encodeBytesWithoutPadding(@NonNull byte[] source) {
|
||||
return encodeBytes(source).replace("=", "");
|
||||
}
|
||||
}
|
||||
@@ -24,12 +24,17 @@ import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.WebRtcCallActivity;
|
||||
import org.thoughtcrime.securesms.conversation.ConversationActivity;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.ui.invitesandrequests.joining.GroupJoinUpdateRequiredBottomSheetDialogFragment;
|
||||
import org.thoughtcrime.securesms.groups.v2.GroupInviteLinkUrl;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
||||
import org.thoughtcrime.securesms.service.WebRtcCallService;
|
||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
|
||||
|
||||
public class CommunicationActions {
|
||||
@@ -162,6 +167,47 @@ public class CommunicationActions {
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the url is a group link it will handle it.
|
||||
* If the url is a malformed group link, it will assume Signal needs to update.
|
||||
* Otherwise returns false, indicating was not a group link.
|
||||
*/
|
||||
public static boolean handlePotentialGroupLinkUrl(@NonNull FragmentActivity activity, @NonNull String potentialGroupLinkUrl) {
|
||||
try {
|
||||
GroupInviteLinkUrl groupInviteLinkUrl = GroupInviteLinkUrl.fromUrl(potentialGroupLinkUrl);
|
||||
|
||||
if (groupInviteLinkUrl == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
handleGroupLinkUrl(activity, groupInviteLinkUrl);
|
||||
return true;
|
||||
} catch (GroupInviteLinkUrl.InvalidGroupLinkException | GroupInviteLinkUrl.UnknownGroupLinkVersionException e) {
|
||||
Log.w(TAG, "Could not parse group URL", e);
|
||||
GroupJoinUpdateRequiredBottomSheetDialogFragment.show(activity.getSupportFragmentManager());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleGroupLinkUrl(@NonNull FragmentActivity activity,
|
||||
@NonNull GroupInviteLinkUrl groupInviteLinkUrl)
|
||||
{
|
||||
GroupId.V2 groupId = GroupId.v2(groupInviteLinkUrl.getGroupMasterKey());
|
||||
|
||||
SimpleTask.run(SignalExecutors.BOUNDED, () ->
|
||||
DatabaseFactory.getGroupDatabase(activity)
|
||||
.getGroup(groupId)
|
||||
.transform(groupRecord -> Recipient.resolved(groupRecord.getRecipientId()))
|
||||
.orNull(),
|
||||
recipient -> {
|
||||
if (recipient != null) {
|
||||
CommunicationActions.startConversation(activity, recipient, null);
|
||||
Toast.makeText(activity, R.string.GroupJoinBottomSheetDialogFragment_you_are_already_a_member, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
GroupJoinUpdateRequiredBottomSheetDialogFragment.show(activity.getSupportFragmentManager());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void startInsecureCallInternal(@NonNull Activity activity, @NonNull Recipient recipient) {
|
||||
try {
|
||||
|
||||
@@ -75,6 +75,14 @@ public class Hex {
|
||||
return out;
|
||||
}
|
||||
|
||||
public static byte[] fromStringOrThrow(String encoded) {
|
||||
try {
|
||||
return fromStringCondensed(encoded);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String dump(byte[] bytes) {
|
||||
return dump(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.groups.v2.GroupInviteLinkUrl;
|
||||
|
||||
/**
|
||||
* Passes clicked Urls to the supplied {@link UrlClickHandler}.
|
||||
*/
|
||||
public final class InterceptableLongClickCopyLinkSpan extends LongClickCopySpan {
|
||||
|
||||
private final UrlClickHandler onClickListener;
|
||||
|
||||
public InterceptableLongClickCopyLinkSpan(@NonNull String url,
|
||||
@NonNull UrlClickHandler onClickListener)
|
||||
{
|
||||
super(url);
|
||||
this.onClickListener = onClickListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View widget) {
|
||||
if (!onClickListener.handleOnClick(getURL())) {
|
||||
super.onClick(widget);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.BuildConfig;
|
||||
|
||||
public final class PlayStoreUtil {
|
||||
|
||||
private PlayStoreUtil() {
|
||||
}
|
||||
|
||||
public static void openPlayStoreOrOurApkDownloadPage(@NonNull Context context) {
|
||||
if (BuildConfig.PLAY_STORE_DISABLED) {
|
||||
CommunicationActions.openBrowserLink(context, "https://signal.org/android/apk");
|
||||
} else {
|
||||
openPlayStore(context);
|
||||
}
|
||||
}
|
||||
|
||||
private static void openPlayStore(@NonNull Context context) {
|
||||
String packageName = context.getPackageName();
|
||||
|
||||
try {
|
||||
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + packageName)));
|
||||
} catch (ActivityNotFoundException e) {
|
||||
CommunicationActions.openBrowserLink(context, "https://play.google.com/store/apps/details?id=" + packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public interface UrlClickHandler {
|
||||
|
||||
/**
|
||||
* @return true if you have handled it, false if you want to allow the standard Url handling.
|
||||
*/
|
||||
boolean handleOnClick(@NonNull String url);
|
||||
}
|
||||
Reference in New Issue
Block a user