mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
Merge branch 'main' into r10s/remove-email-from-account-switcher
This commit is contained in:
@@ -62,9 +62,9 @@ public class ApplicationContext extends MultiDexApplication {
|
||||
private Rpc rpc;
|
||||
private DcContext dcContext;
|
||||
|
||||
public DcLocationManager dcLocationManager;
|
||||
public DcEventCenter eventCenter;
|
||||
public NotificationCenter notificationCenter;
|
||||
private DcLocationManager dcLocationManager;
|
||||
private DcEventCenter eventCenter;
|
||||
private NotificationCenter notificationCenter;
|
||||
private JobManager jobManager;
|
||||
|
||||
private int debugOnAvailableCount;
|
||||
@@ -127,6 +127,33 @@ public class ApplicationContext extends MultiDexApplication {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get DcLocationManager instance, waiting for initialization if necessary.
|
||||
* This method is thread-safe and will block until initialization is complete.
|
||||
*/
|
||||
public DcLocationManager getLocationManager() {
|
||||
ensureInitialized();
|
||||
return dcLocationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get DcEventCenter instance, waiting for initialization if necessary.
|
||||
* This method is thread-safe and will block until initialization is complete.
|
||||
*/
|
||||
public DcEventCenter getEventCenter() {
|
||||
ensureInitialized();
|
||||
return eventCenter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get NotificationCenter instance, waiting for initialization if necessary.
|
||||
* This method is thread-safe and will block until initialization is complete.
|
||||
*/
|
||||
public NotificationCenter getNotificationCenter() {
|
||||
ensureInitialized();
|
||||
return notificationCenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
@@ -187,14 +214,13 @@ public class ApplicationContext extends MultiDexApplication {
|
||||
dcContext = dcAccounts.getSelectedAccount();
|
||||
notificationCenter = new NotificationCenter(this);
|
||||
eventCenter = new DcEventCenter(this);
|
||||
dcLocationManager = new DcLocationManager(this, dcContext);
|
||||
|
||||
// Mark as initialized before starting threads that depend on it
|
||||
isInitialized = true;
|
||||
initLock.notifyAll();
|
||||
Log.i(TAG, "DcAccounts initialization complete");
|
||||
|
||||
dcLocationManager = new DcLocationManager(this); // depends on dcContext
|
||||
|
||||
new Thread(() -> {
|
||||
Log.i(TAG, "Starting event loop");
|
||||
DcEventEmitter emitter = dcAccounts.getEventEmitter();
|
||||
|
||||
@@ -74,6 +74,7 @@ import org.thoughtcrime.securesms.search.SearchFragment;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.Prefs;
|
||||
import org.thoughtcrime.securesms.util.ScreenLockUtil;
|
||||
import org.thoughtcrime.securesms.util.ShareUtil;
|
||||
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
|
||||
import org.thoughtcrime.securesms.util.SendRelayedMessageUtil;
|
||||
@@ -95,6 +96,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
||||
public static final String CLEAR_NOTIFICATIONS = "clear_notifications";
|
||||
public static final String ACCOUNT_ID_EXTRA = "account_id";
|
||||
public static final String FROM_WELCOME = "from_welcome";
|
||||
private static final int REQUEST_CODE_CONFIRM_CREDENTIALS_DELETE_PROFILE = ScreenLockUtil.REQUEST_CODE_CONFIRM_CREDENTIALS+1;
|
||||
|
||||
private ConversationListFragment conversationListFragment;
|
||||
public TextView title;
|
||||
@@ -106,6 +108,11 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
||||
private ViewGroup fragmentContainer;
|
||||
private ViewGroup selfAvatarContainer;
|
||||
|
||||
/** used to store temporarily scanned QR to pass it back to QrCodeHandler when ScreenLockUtil is used */
|
||||
private String qrData = null;
|
||||
/** used to store temporarily profile ID to delete after authorization is granted via ScreenLockUtil */
|
||||
private int deleteProfileId = 0;
|
||||
|
||||
@Override
|
||||
protected void onPreCreate() {
|
||||
dynamicTheme = new DynamicNoActionBarTheme();
|
||||
@@ -491,7 +498,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
||||
|
||||
if (uri.getScheme().equalsIgnoreCase(OPENPGP4FPR) || Util.isInviteURL(uri)) {
|
||||
QrCodeHandler qrCodeHandler = new QrCodeHandler(this);
|
||||
qrCodeHandler.handleQrData(uri.toString(), SecurejoinSource.ExternalLink, null);
|
||||
qrCodeHandler.handleOnlySecureJoinQr(uri.toString(), SecurejoinSource.ExternalLink, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -566,14 +573,55 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
||||
startActivity(Intent.createChooser(intent, getString(R.string.chat_share_with_title)));
|
||||
}
|
||||
|
||||
public void onDeleteProfile(int profileId) {
|
||||
deleteProfileId = profileId;
|
||||
boolean result = ScreenLockUtil.applyScreenLock(this, getString(R.string.delete_account), getString(R.string.enter_system_secret_to_continue), REQUEST_CODE_CONFIRM_CREDENTIALS_DELETE_PROFILE);
|
||||
if (!result) {
|
||||
deleteProfile(profileId);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteProfile(int profileId) {
|
||||
DcAccounts accounts = DcHelper.getAccounts(this);
|
||||
boolean selected = profileId == accounts.getSelectedAccount().getAccountId();
|
||||
DcHelper.getNotificationCenter(this).removeAllNotifications(profileId);
|
||||
accounts.removeAccount(profileId);
|
||||
if (selected) {
|
||||
DcContext selAcc = accounts.getSelectedAccount();
|
||||
AccountManager.getInstance().switchAccountAndStartActivity(this, selAcc.isOk()? selAcc.getAccountId() : 0);
|
||||
} else {
|
||||
AccountManager.getInstance().showSwitchAccountMenu(this);
|
||||
}
|
||||
|
||||
// title update needed to show "Delta Chat" in case there is only one profile left
|
||||
refreshTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode != RESULT_OK) return;
|
||||
|
||||
QrCodeHandler qrCodeHandler = new QrCodeHandler(this);
|
||||
switch (requestCode) {
|
||||
case IntentIntegrator.REQUEST_CODE:
|
||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
|
||||
QrCodeHandler qrCodeHandler = new QrCodeHandler(this);
|
||||
qrCodeHandler.onScanPerformed(scanResult, SecurejoinUiPath.QrIcon);
|
||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(resultCode, data);
|
||||
qrData = scanResult.getContents();
|
||||
qrCodeHandler.handleQrData(qrData, SecurejoinSource.Scan, SecurejoinUiPath.QrIcon);
|
||||
break;
|
||||
case ScreenLockUtil.REQUEST_CODE_CONFIRM_CREDENTIALS:
|
||||
// QrCodeHandler requested user authorization before adding a relay
|
||||
// and it was granted, so proceed to add the relay
|
||||
if (qrData != null) {
|
||||
qrCodeHandler.addRelay(qrData);
|
||||
qrData = null;
|
||||
}
|
||||
break;
|
||||
case REQUEST_CODE_CONFIRM_CREDENTIALS_DELETE_PROFILE:
|
||||
if (deleteProfileId != 0) {
|
||||
deleteProfile(deleteProfileId);
|
||||
deleteProfileId = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -208,10 +208,8 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
|
||||
case IntentIntegrator.REQUEST_CODE:
|
||||
String qrRaw = data.getStringExtra(RegistrationQrActivity.QRDATA_EXTRA);
|
||||
if (qrRaw == null) {
|
||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
|
||||
if (scanResult != null && scanResult.getFormatName() != null) {
|
||||
qrRaw = scanResult.getContents();
|
||||
}
|
||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(resultCode, data);
|
||||
qrRaw = scanResult.getContents();
|
||||
}
|
||||
if (qrRaw != null) {
|
||||
setProviderFromQr(qrRaw);
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.thoughtcrime.securesms.qr.QrActivity;
|
||||
import org.thoughtcrime.securesms.qr.QrCodeHandler;
|
||||
import org.thoughtcrime.securesms.util.MailtoUtil;
|
||||
|
||||
import chat.delta.rpc.types.SecurejoinSource;
|
||||
import chat.delta.rpc.types.SecurejoinUiPath;
|
||||
|
||||
/**
|
||||
@@ -135,11 +136,13 @@ public class NewConversationActivity extends ContactSelectionActivity {
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode != RESULT_OK) return;
|
||||
|
||||
switch (requestCode) {
|
||||
case IntentIntegrator.REQUEST_CODE:
|
||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
|
||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(resultCode, data);
|
||||
QrCodeHandler qrCodeHandler = new QrCodeHandler(this);
|
||||
qrCodeHandler.onScanPerformed(scanResult, SecurejoinUiPath.NewContact);
|
||||
qrCodeHandler.handleOnlySecureJoinQr(scanResult.getContents(), SecurejoinSource.Scan, SecurejoinUiPath.NewContact);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -304,7 +304,7 @@ public class WebViewActivity extends PassphraseRequiredActionBarActivity
|
||||
// invite-links should be handled directly
|
||||
String schema = url.split(":")[0].toLowerCase();
|
||||
if (schema.equals("openpgp4fpr") || url.startsWith("https://" + Util.INVITE_DOMAIN + "/")) {
|
||||
new QrCodeHandler(this).handleQrData(url, SecurejoinSource.InternalLink, null);
|
||||
new QrCodeHandler(this).handleOnlySecureJoinQr(url, SecurejoinSource.InternalLink, null);
|
||||
return true; // abort internal loading
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.b44t.messenger.DcContext;
|
||||
import com.b44t.messenger.DcEvent;
|
||||
import com.b44t.messenger.DcLot;
|
||||
import com.google.zxing.integration.android.IntentIntegrator;
|
||||
import com.google.zxing.integration.android.IntentResult;
|
||||
|
||||
@@ -32,6 +31,7 @@ import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentManager;
|
||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
import org.thoughtcrime.securesms.qr.BackupTransferActivity;
|
||||
import org.thoughtcrime.securesms.qr.QrCodeHandler;
|
||||
import org.thoughtcrime.securesms.qr.RegistrationQrActivity;
|
||||
import org.thoughtcrime.securesms.service.GenericForegroundService;
|
||||
import org.thoughtcrime.securesms.service.NotificationController;
|
||||
@@ -336,39 +336,14 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
|
||||
if (requestCode==IntentIntegrator.REQUEST_CODE) {
|
||||
String qrRaw = data.getStringExtra(RegistrationQrActivity.QRDATA_EXTRA);
|
||||
if (qrRaw == null) {
|
||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
|
||||
if (scanResult == null || scanResult.getFormatName() == null) {
|
||||
return; // aborted
|
||||
}
|
||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(resultCode, data);
|
||||
qrRaw = scanResult.getContents();
|
||||
}
|
||||
DcLot qrParsed = dcContext.checkQr(qrRaw);
|
||||
switch (qrParsed.getState()) {
|
||||
case DcContext.DC_QR_BACKUP2:
|
||||
final String finalQrRaw = qrRaw;
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.multidevice_receiver_title)
|
||||
.setMessage(R.string.multidevice_receiver_scanning_ask)
|
||||
.setPositiveButton(R.string.perm_continue, (dialog, which) -> startBackupTransfer(finalQrRaw))
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setCancelable(false)
|
||||
.show();
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_BACKUP_TOO_NEW:
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.multidevice_receiver_title)
|
||||
.setMessage(R.string.multidevice_receiver_needs_update)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show();
|
||||
break;
|
||||
|
||||
default:
|
||||
new AlertDialog.Builder(this)
|
||||
.setMessage(R.string.qraccount_qr_code_cannot_be_used)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show();
|
||||
break;
|
||||
if (!new QrCodeHandler(this).handleBackupQr(qrRaw)) {
|
||||
new AlertDialog.Builder(this)
|
||||
.setMessage(R.string.qraccount_qr_code_cannot_be_used)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show();
|
||||
}
|
||||
} else if (requestCode == PICK_BACKUP) {
|
||||
Uri uri = (data != null ? data.getData() : null);
|
||||
|
||||
+9
-22
@@ -47,9 +47,15 @@ import chat.delta.rpc.RpcException;
|
||||
public class AccountSelectionListFragment extends DialogFragment implements DcEventCenter.DcEventDelegate
|
||||
{
|
||||
private static final String TAG = AccountSelectionListFragment.class.getSimpleName();
|
||||
private final ConversationListActivity activity;
|
||||
private RecyclerView recyclerView;
|
||||
private AccountSelectionListAdapter adapter;
|
||||
|
||||
public AccountSelectionListFragment(ConversationListActivity activity) {
|
||||
super();
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
@@ -132,7 +138,7 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv
|
||||
private void onContextItemSelected(MenuItem item, int accountId) {
|
||||
int itemId = item.getItemId();
|
||||
if (itemId == R.id.delete) {
|
||||
onDeleteAccount(accountId);
|
||||
onDeleteProfile(accountId);
|
||||
} else if (itemId == R.id.menu_mute_notifications) {
|
||||
onToggleMute(accountId);
|
||||
} else if (itemId == R.id.menu_set_tag) {
|
||||
@@ -167,8 +173,6 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv
|
||||
}
|
||||
|
||||
private void onSetTag(int accountId) {
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) return;
|
||||
AccountSelectionListFragment.this.dismiss();
|
||||
|
||||
DcContext dcContext = DcHelper.getAccounts(activity).getAccount(accountId);
|
||||
@@ -190,10 +194,8 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv
|
||||
.show();
|
||||
}
|
||||
|
||||
private void onDeleteAccount(int accountId) {
|
||||
Activity activity = getActivity();
|
||||
private void onDeleteProfile(int accountId) {
|
||||
AccountSelectionListFragment.this.dismiss();
|
||||
if (activity == null) return;
|
||||
DcAccounts accounts = DcHelper.getAccounts(activity);
|
||||
Rpc rpc = DcHelper.getRpc(activity);
|
||||
|
||||
@@ -229,22 +231,7 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv
|
||||
.setTitle(R.string.delete_account)
|
||||
.setView(dialogView)
|
||||
.setNegativeButton(R.string.cancel, (d, which) -> AccountManager.getInstance().showSwitchAccountMenu(activity))
|
||||
.setPositiveButton(R.string.delete, (d2, which2) -> {
|
||||
boolean selected = accountId == accounts.getSelectedAccount().getAccountId();
|
||||
DcHelper.getNotificationCenter(activity).removeAllNotifications(accountId);
|
||||
accounts.removeAccount(accountId);
|
||||
if (selected) {
|
||||
DcContext selAcc = accounts.getSelectedAccount();
|
||||
AccountManager.getInstance().switchAccountAndStartActivity(activity, selAcc.isOk()? selAcc.getAccountId() : 0);
|
||||
} else {
|
||||
AccountManager.getInstance().showSwitchAccountMenu(activity);
|
||||
}
|
||||
|
||||
// title update needed to show "Delta Chat" in case there is only one profile left
|
||||
if (activity instanceof ConversationListActivity) {
|
||||
((ConversationListActivity)activity).refreshTitle();
|
||||
}
|
||||
})
|
||||
.setPositiveButton(R.string.delete, (d2, w2) -> activity.onDeleteProfile(accountId))
|
||||
.show();
|
||||
Util.redPositiveButton(dialog);
|
||||
}
|
||||
|
||||
@@ -147,8 +147,8 @@ public class AccountManager {
|
||||
|
||||
// ui
|
||||
|
||||
public void showSwitchAccountMenu(Activity activity) {
|
||||
AccountSelectionListFragment dialog = new AccountSelectionListFragment();
|
||||
public void showSwitchAccountMenu(ConversationListActivity activity) {
|
||||
AccountSelectionListFragment dialog = new AccountSelectionListFragment(activity);
|
||||
dialog.show(((FragmentActivity) activity).getSupportFragmentManager(), null);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,11 +77,11 @@ public class DcHelper {
|
||||
}
|
||||
|
||||
public static DcEventCenter getEventCenter(@NonNull Context context) {
|
||||
return ApplicationContext.getInstance(context).eventCenter;
|
||||
return ApplicationContext.getInstance(context).getEventCenter();
|
||||
}
|
||||
|
||||
public static NotificationCenter getNotificationCenter(@NonNull Context context) {
|
||||
return ApplicationContext.getInstance(context).notificationCenter;
|
||||
return ApplicationContext.getInstance(context).getNotificationCenter();
|
||||
}
|
||||
|
||||
public static boolean isConfigured(Context context) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.qr.QrCodeHandler;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
import chat.delta.rpc.types.SecurejoinSource;
|
||||
import chat.delta.rpc.types.SecurejoinUiPath;
|
||||
|
||||
public class NewContactActivity extends PassphraseRequiredActionBarActivity
|
||||
@@ -104,10 +105,10 @@ public class NewContactActivity extends PassphraseRequiredActionBarActivity
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == IntentIntegrator.REQUEST_CODE) {
|
||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode == RESULT_OK && requestCode == IntentIntegrator.REQUEST_CODE) {
|
||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(resultCode, data);
|
||||
QrCodeHandler qrCodeHandler = new QrCodeHandler(this);
|
||||
qrCodeHandler.onScanPerformed(scanResult, SecurejoinUiPath.NewContact);
|
||||
qrCodeHandler.handleOnlySecureJoinQr(scanResult.getContents(), SecurejoinSource.Scan, SecurejoinUiPath.NewContact);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ import java.util.Observer;
|
||||
|
||||
import static android.content.Context.BIND_AUTO_CREATE;
|
||||
|
||||
import com.b44t.messenger.DcContext;
|
||||
|
||||
public class DcLocationManager implements Observer {
|
||||
|
||||
private static final String TAG = DcLocationManager.class.getSimpleName();
|
||||
@@ -40,10 +42,10 @@ public class DcLocationManager implements Observer {
|
||||
}
|
||||
};
|
||||
|
||||
public DcLocationManager(Context context) {
|
||||
public DcLocationManager(Context context, DcContext dcContext) {
|
||||
this.context = context.getApplicationContext();
|
||||
DcLocation.getInstance().addObserver(this);
|
||||
if (DcHelper.getContext(context).isSendingLocationsToChat(0)) {
|
||||
if (dcContext.isSendingLocationsToChat(0)) {
|
||||
startLocationEngine();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,7 +473,7 @@ public class AttachmentManager {
|
||||
|
||||
public static void selectLocation(Activity activity, int chatId) {
|
||||
ApplicationContext applicationContext = ApplicationContext.getInstance(activity);
|
||||
DcLocationManager dcLocationManager = applicationContext.dcLocationManager;
|
||||
DcLocationManager dcLocationManager = applicationContext.getLocationManager();
|
||||
|
||||
if (DcHelper.getContext(applicationContext).isSendingLocationsToChat(chatId)) {
|
||||
dcLocationManager.stopSharingLocation(chatId);
|
||||
|
||||
+5
-3
@@ -16,7 +16,6 @@ import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -33,8 +32,8 @@ import org.thoughtcrime.securesms.relay.RelayListActivity;
|
||||
import org.thoughtcrime.securesms.StatsSending;
|
||||
import org.thoughtcrime.securesms.connect.DcEventCenter;
|
||||
import org.thoughtcrime.securesms.proxy.ProxySettingsActivity;
|
||||
import org.thoughtcrime.securesms.util.IntentUtils;
|
||||
import org.thoughtcrime.securesms.util.Prefs;
|
||||
import org.thoughtcrime.securesms.util.ScreenLockUtil;
|
||||
import org.thoughtcrime.securesms.util.StreamUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
@@ -212,7 +211,10 @@ public class AdvancedPreferenceFragment extends ListSummaryPreferenceFragment
|
||||
Preference relayListBtn = this.findPreference("pref_relay_list_button");
|
||||
if (relayListBtn != null) {
|
||||
relayListBtn.setOnPreferenceClickListener(((preference) -> {
|
||||
openRelayListActivity();
|
||||
boolean result = ScreenLockUtil.applyScreenLock(requireActivity(), getString(R.string.transports), getString(R.string.enter_system_secret_to_continue), REQUEST_CODE_CONFIRM_CREDENTIALS_ACCOUNT);
|
||||
if (!result) {
|
||||
openRelayListActivity();
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.qr;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
@@ -27,11 +26,10 @@ import com.google.zxing.MultiFormatReader;
|
||||
import com.google.zxing.NotFoundException;
|
||||
import com.google.zxing.RGBLuminanceSource;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.client.android.Intents;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
|
||||
import org.thoughtcrime.securesms.BaseActionBarActivity;
|
||||
import org.thoughtcrime.securesms.ConversationListActivity;
|
||||
import org.thoughtcrime.securesms.NewConversationActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.contacts.NewContactActivity;
|
||||
@@ -44,9 +42,6 @@ import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import chat.delta.rpc.types.SecurejoinSource;
|
||||
import chat.delta.rpc.types.SecurejoinUiPath;
|
||||
|
||||
public class QrActivity extends BaseActionBarActivity implements View.OnClickListener {
|
||||
|
||||
private final static String TAG = QrActivity.class.getSimpleName();
|
||||
@@ -154,8 +149,7 @@ public class QrActivity extends BaseActionBarActivity implements View.OnClickLis
|
||||
} else if (itemId == R.id.load_from_image) {
|
||||
AttachmentManager.selectImage(this, REQUEST_CODE_IMAGE);
|
||||
} else if (itemId == R.id.paste) {
|
||||
QrCodeHandler qrCodeHandler = new QrCodeHandler(this);
|
||||
qrCodeHandler.handleQrData(Util.getTextFromClipboard(this), SecurejoinSource.Clipboard, getUiPath());
|
||||
setQrResult(Util.getTextFromClipboard(this));
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -203,10 +197,10 @@ public class QrActivity extends BaseActionBarActivity implements View.OnClickLis
|
||||
RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
|
||||
BinaryBitmap bBitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||
MultiFormatReader reader = new MultiFormatReader();
|
||||
|
||||
try {
|
||||
Result result = reader.decode(bBitmap);
|
||||
QrCodeHandler qrCodeHandler = new QrCodeHandler(this);
|
||||
qrCodeHandler.handleQrData(result.getText(), SecurejoinSource.ImageLoaded, getUiPath());
|
||||
setQrResult(result.getText());
|
||||
} catch (NotFoundException e) {
|
||||
Log.e(TAG, "decode exception", e);
|
||||
Toast.makeText(this, getString(R.string.qrscan_failed), Toast.LENGTH_LONG).show();
|
||||
@@ -219,19 +213,11 @@ public class QrActivity extends BaseActionBarActivity implements View.OnClickLis
|
||||
}
|
||||
}
|
||||
|
||||
private SecurejoinUiPath getUiPath() {
|
||||
SecurejoinUiPath uiPath = null;
|
||||
ComponentName caller = this.getCallingActivity();
|
||||
if (caller != null) {
|
||||
if (caller.getClassName().equals(NewConversationActivity.class.getName())) {
|
||||
uiPath = SecurejoinUiPath.NewContact;
|
||||
} else if (caller.getClassName().equals(ConversationListActivity.class.getName())
|
||||
// RoutingActivity is an alias for ConversationListActivity
|
||||
|| caller.getClassName().endsWith(".RoutingActivity")) {
|
||||
uiPath = SecurejoinUiPath.QrIcon;
|
||||
}
|
||||
}
|
||||
return uiPath;
|
||||
private void setQrResult(String qrData) {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Intents.Scan.RESULT, qrData);
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.connect.AccountManager;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.relay.RelayListActivity;
|
||||
import org.thoughtcrime.securesms.util.IntentUtils;
|
||||
import org.thoughtcrime.securesms.util.ScreenLockUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.views.ProgressDialog;
|
||||
|
||||
@@ -53,118 +54,182 @@ public class QrCodeHandler {
|
||||
accId = dcContext.getAccountId();
|
||||
}
|
||||
|
||||
public void onScanPerformed(IntentResult scanResult, SecurejoinUiPath uipath) {
|
||||
if (scanResult == null || scanResult.getFormatName() == null) {
|
||||
return; // aborted
|
||||
}
|
||||
|
||||
handleQrData(scanResult.getContents(), SecurejoinSource.Scan, uipath);
|
||||
/** Process only QR about getting in contact or joining chats */
|
||||
public void handleOnlySecureJoinQr(String rawString, SecurejoinSource source, SecurejoinUiPath uiPath) {
|
||||
final DcLot qrParsed = dcContext.checkQr(rawString);
|
||||
if (!handleSecureJoinQr(qrParsed, rawString, source, uiPath)) {
|
||||
handleDefault(new AlertDialog.Builder(activity), rawString, qrParsed);
|
||||
}
|
||||
}
|
||||
|
||||
public void handleQrData(String rawString, SecurejoinSource source, SecurejoinUiPath uiPath) {
|
||||
private boolean handleSecureJoinQr(DcLot qrParsed, String rawString, SecurejoinSource source, SecurejoinUiPath uiPath) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
String name = dcContext.getContact(qrParsed.getId()).getDisplayName();
|
||||
switch (qrParsed.getState()) {
|
||||
case DcContext.DC_QR_ASK_VERIFYCONTACT:
|
||||
case DcContext.DC_QR_ASK_VERIFYGROUP:
|
||||
case DcContext.DC_QR_ASK_JOIN_BROADCAST:
|
||||
showVerifyContactOrGroup(builder, rawString, qrParsed, name, source, uiPath);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_WITHDRAW_VERIFYCONTACT:
|
||||
case DcContext.DC_QR_WITHDRAW_VERIFYGROUP:
|
||||
case DcContext.DC_QR_WITHDRAW_JOINBROADCAST:
|
||||
String message = qrParsed.getState() == DcContext.DC_QR_WITHDRAW_VERIFYCONTACT ? activity.getString(R.string.withdraw_verifycontact_explain)
|
||||
: qrParsed.getState() == DcContext.DC_QR_WITHDRAW_VERIFYCONTACT ? activity.getString(R.string.withdraw_verifygroup_explain, qrParsed.getText1())
|
||||
: activity.getString(R.string.withdraw_joinbroadcast_explain, qrParsed.getText1());
|
||||
builder.setTitle(R.string.qrshow_title);
|
||||
builder.setMessage(message);
|
||||
builder.setNeutralButton(R.string.reset, (dialog, which) -> {
|
||||
dcContext.setConfigFromQr(rawString);
|
||||
});
|
||||
builder.setPositiveButton(R.string.ok, null);
|
||||
Util.redButton(builder.show(), AlertDialog.BUTTON_NEUTRAL);
|
||||
return true;
|
||||
|
||||
case DcContext.DC_QR_REVIVE_VERIFYCONTACT:
|
||||
case DcContext.DC_QR_REVIVE_VERIFYGROUP:
|
||||
case DcContext.DC_QR_REVIVE_JOINBROADCAST:
|
||||
builder.setTitle(R.string.qrshow_title);
|
||||
builder.setMessage(activity.getString(R.string.revive_verifycontact_explain));
|
||||
builder.setNeutralButton(R.string.revive_qr_code, (dialog, which) -> {
|
||||
dcContext.setConfigFromQr(rawString);
|
||||
});
|
||||
builder.setPositiveButton(R.string.ok, null);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_FPR_WITHOUT_ADDR:
|
||||
showVerifyFingerprintWithoutAddress(builder, qrParsed);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_FPR_MISMATCH:
|
||||
showFingerPrintError(builder, name);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_FPR_OK:
|
||||
case DcContext.DC_QR_ADDR:
|
||||
showFingerprintOrQrSuccess(builder, qrParsed, name);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
builder.create().show();
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Process only QR about adding relays/profiles (DCACCOUNT: / DCLOGIN:) */
|
||||
public void handleOnlyAddRelayQr(String rawString) {
|
||||
final DcLot qrParsed = dcContext.checkQr(rawString);
|
||||
if (!handleAddRelayQr(qrParsed, rawString)) {
|
||||
handleDefault(new AlertDialog.Builder(activity), rawString, qrParsed);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleAddRelayQr(DcLot qrParsed, String rawString) {
|
||||
switch (qrParsed.getState()) {
|
||||
case DcContext.DC_QR_ACCOUNT:
|
||||
case DcContext.DC_QR_LOGIN:
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
final DcLot qrParsed = dcContext.checkQr(rawString);
|
||||
String name = dcContext.getContact(qrParsed.getId()).getDisplayName();
|
||||
switch (qrParsed.getState()) {
|
||||
case DcContext.DC_QR_ASK_VERIFYCONTACT:
|
||||
case DcContext.DC_QR_ASK_VERIFYGROUP:
|
||||
case DcContext.DC_QR_ASK_JOIN_BROADCAST:
|
||||
showVerifyContactOrGroup(activity, builder, rawString, qrParsed, name, source, uiPath);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_FPR_WITHOUT_ADDR:
|
||||
showVerifyFingerprintWithoutAddress(builder, qrParsed);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_FPR_MISMATCH:
|
||||
showFingerPrintError(builder, name);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_FPR_OK:
|
||||
case DcContext.DC_QR_ADDR:
|
||||
showFingerprintOrQrSuccess(builder, qrParsed, name);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_URL:
|
||||
showQrUrl(builder, qrParsed);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_ACCOUNT:
|
||||
case DcContext.DC_QR_LOGIN:
|
||||
final String scope = qrParsed.getText1();
|
||||
setAddTransportDialog(activity, builder, rawString, scope);
|
||||
builder.setNegativeButton(R.string.cancel, null);
|
||||
builder.setCancelable(false);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_BACKUP2:
|
||||
builder.setTitle(R.string.multidevice_receiver_title);
|
||||
builder.setMessage(activity.getString(R.string.multidevice_receiver_scanning_ask) + "\n\n" + activity.getString(R.string.multidevice_same_network_hint));
|
||||
builder.setPositiveButton(R.string.perm_continue, (dialog, which) -> {
|
||||
AccountManager.getInstance().addAccountFromSecondDevice(activity, rawString);
|
||||
});
|
||||
builder.setNegativeButton(R.string.cancel, null);
|
||||
builder.setCancelable(false);
|
||||
|
||||
AlertDialog alertDialog = builder.create();
|
||||
alertDialog.show();
|
||||
BackupTransferActivity.appendSSID(activity, alertDialog.findViewById(android.R.id.message));
|
||||
return;
|
||||
|
||||
case DcContext.DC_QR_BACKUP_TOO_NEW:
|
||||
builder.setTitle(R.string.multidevice_receiver_title);
|
||||
builder.setMessage(activity.getString(R.string.multidevice_receiver_needs_update));
|
||||
builder.setNegativeButton(R.string.ok, null);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_PROXY:
|
||||
builder.setTitle(R.string.proxy_use_proxy);
|
||||
builder.setMessage(activity.getString(R.string.proxy_use_proxy_confirm, qrParsed.getText1()));
|
||||
builder.setPositiveButton(R.string.proxy_use_proxy, (dlg, btn) -> {
|
||||
dcContext.setConfigFromQr(rawString);
|
||||
dcContext.restartIo();
|
||||
showDoneToast(activity);
|
||||
});
|
||||
if (rawString.toLowerCase().startsWith("http")) {
|
||||
builder.setNeutralButton(R.string.open, (d, b) -> IntentUtils.showInBrowser(activity, rawString));
|
||||
}
|
||||
builder.setNegativeButton(R.string.cancel, null);
|
||||
builder.setCancelable(false);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_WITHDRAW_VERIFYCONTACT:
|
||||
case DcContext.DC_QR_WITHDRAW_VERIFYGROUP:
|
||||
case DcContext.DC_QR_WITHDRAW_JOINBROADCAST:
|
||||
String message = qrParsed.getState() == DcContext.DC_QR_WITHDRAW_VERIFYCONTACT ? activity.getString(R.string.withdraw_verifycontact_explain)
|
||||
: qrParsed.getState() == DcContext.DC_QR_WITHDRAW_VERIFYCONTACT ? activity.getString(R.string.withdraw_verifygroup_explain, qrParsed.getText1())
|
||||
: activity.getString(R.string.withdraw_joinbroadcast_explain, qrParsed.getText1());
|
||||
builder.setTitle(R.string.qrshow_title);
|
||||
builder.setMessage(message);
|
||||
builder.setNeutralButton(R.string.reset, (dialog, which) -> {
|
||||
dcContext.setConfigFromQr(rawString);
|
||||
});
|
||||
builder.setPositiveButton(R.string.ok, null);
|
||||
AlertDialog withdrawDialog = builder.show();
|
||||
Util.redButton(withdrawDialog, AlertDialog.BUTTON_NEUTRAL);
|
||||
return;
|
||||
|
||||
case DcContext.DC_QR_REVIVE_VERIFYCONTACT:
|
||||
case DcContext.DC_QR_REVIVE_VERIFYGROUP:
|
||||
case DcContext.DC_QR_REVIVE_JOINBROADCAST:
|
||||
builder.setTitle(R.string.qrshow_title);
|
||||
builder.setMessage(activity.getString(R.string.revive_verifycontact_explain));
|
||||
builder.setNeutralButton(R.string.revive_qr_code, (dialog, which) -> {
|
||||
dcContext.setConfigFromQr(rawString);
|
||||
});
|
||||
builder.setPositiveButton(R.string.ok, null);
|
||||
break;
|
||||
|
||||
default:
|
||||
handleDefault(builder, rawString, qrParsed);
|
||||
break;
|
||||
}
|
||||
builder.setTitle(R.string.confirm_add_transport);
|
||||
builder.setMessage(qrParsed.getText1());
|
||||
builder.setPositiveButton(R.string.ok, (d, w) -> {
|
||||
if (activity instanceof RelayListActivity) {
|
||||
// no need to protect with lock, RelayListActivity is already protected
|
||||
addRelay(rawString);
|
||||
} else {
|
||||
boolean result = ScreenLockUtil.applyScreenLock(activity, activity.getString(R.string.add_transport), activity.getString(R.string.enter_system_secret_to_continue), ScreenLockUtil.REQUEST_CODE_CONFIRM_CREDENTIALS);
|
||||
if (!result) {
|
||||
addRelay(rawString);
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(R.string.cancel, null);
|
||||
builder.setCancelable(false);
|
||||
builder.create().show();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Process a proxy QR, returns true if a dialog was shown, false if the QR is not a proxy QR */
|
||||
public boolean handleProxyQr(String rawString) {
|
||||
return handleProxyQr(dcContext.checkQr(rawString), rawString);
|
||||
}
|
||||
|
||||
private boolean handleProxyQr(DcLot qrParsed, String rawString) {
|
||||
if (qrParsed.getState() == DcContext.DC_QR_PROXY) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.setTitle(R.string.proxy_use_proxy);
|
||||
builder.setMessage(activity.getString(R.string.proxy_use_proxy_confirm, qrParsed.getText1()));
|
||||
builder.setPositiveButton(R.string.proxy_use_proxy, (dlg, btn) -> {
|
||||
dcContext.setConfigFromQr(rawString);
|
||||
dcContext.restartIo();
|
||||
showDoneToast();
|
||||
});
|
||||
if (rawString.toLowerCase().startsWith("http")) {
|
||||
builder.setNeutralButton(R.string.open, (d, b) -> IntentUtils.showInBrowser(activity, rawString));
|
||||
}
|
||||
builder.setNegativeButton(R.string.cancel, null);
|
||||
builder.setCancelable(false);
|
||||
builder.create().show();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Process a backup QR, returns true if a dialog was shown, false if the QR is not a backup QR */
|
||||
public boolean handleBackupQr(String rawString) {
|
||||
return handleBackupQr(dcContext.checkQr(rawString), rawString);
|
||||
}
|
||||
|
||||
private boolean handleBackupQr(DcLot qrParsed, String rawString) {
|
||||
switch (qrParsed.getState()) {
|
||||
case DcContext.DC_QR_BACKUP2:
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.setTitle(R.string.multidevice_receiver_title);
|
||||
builder.setMessage(activity.getString(R.string.multidevice_receiver_scanning_ask) + "\n\n" + activity.getString(R.string.multidevice_same_network_hint));
|
||||
builder.setPositiveButton(R.string.perm_continue, (dialog, which) -> {
|
||||
AccountManager.getInstance().addAccountFromSecondDevice(activity, rawString);
|
||||
});
|
||||
builder.setNegativeButton(R.string.cancel, null);
|
||||
builder.setCancelable(false);
|
||||
|
||||
AlertDialog alertDialog = builder.create();
|
||||
alertDialog.show();
|
||||
BackupTransferActivity.appendSSID(activity, alertDialog.findViewById(android.R.id.message));
|
||||
return true;
|
||||
|
||||
case DcContext.DC_QR_BACKUP_TOO_NEW:
|
||||
new AlertDialog.Builder(activity)
|
||||
.setTitle(R.string.multidevice_receiver_title)
|
||||
.setMessage(activity.getString(R.string.multidevice_receiver_needs_update))
|
||||
.setNegativeButton(R.string.ok, null)
|
||||
.create().show();
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Handle any kind of QR showing an AlertDialog adapted to the QR type. */
|
||||
public void handleQrData(String rawString, SecurejoinSource source, SecurejoinUiPath uiPath) {
|
||||
final DcLot qrParsed = dcContext.checkQr(rawString);
|
||||
if (handleSecureJoinQr(qrParsed, rawString, source, uiPath)
|
||||
|| handleAddRelayQr(qrParsed, rawString)
|
||||
|| handleProxyQr(qrParsed, rawString)
|
||||
|| handleBackupQr(qrParsed, rawString)) return;
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
if (qrParsed.getState() == DcContext.DC_QR_URL) {
|
||||
showQrUrl(builder, qrParsed);
|
||||
} else {
|
||||
handleDefault(builder, rawString, qrParsed);
|
||||
}
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
private void handleDefault(AlertDialog.Builder builder, String qrRawString, DcLot qrParsed) {
|
||||
String msg;
|
||||
@@ -187,7 +252,7 @@ public class QrCodeHandler {
|
||||
builder.setPositiveButton(android.R.string.ok, null);
|
||||
builder.setNeutralButton(R.string.menu_copy_to_clipboard, (dialog, which) -> {
|
||||
Util.writeTextToClipboard(activity, scannedText);
|
||||
showDoneToast(activity);
|
||||
showDoneToast();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -199,11 +264,11 @@ public class QrCodeHandler {
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
builder.setNeutralButton(R.string.menu_copy_to_clipboard, (dialog, which) -> {
|
||||
Util.writeTextToClipboard(activity, url);
|
||||
showDoneToast(activity);
|
||||
showDoneToast();
|
||||
});
|
||||
}
|
||||
|
||||
private void showDoneToast(Activity activity) {
|
||||
private void showDoneToast() {
|
||||
Toast.makeText(activity, activity.getString(R.string.done), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@@ -232,12 +297,11 @@ public class QrCodeHandler {
|
||||
builder.setPositiveButton(android.R.string.ok, null);
|
||||
builder.setNeutralButton(R.string.menu_copy_to_clipboard, (dialog, which) -> {
|
||||
Util.writeTextToClipboard(activity, qrParsed.getText1());
|
||||
showDoneToast(activity);
|
||||
showDoneToast();
|
||||
});
|
||||
}
|
||||
|
||||
private void showVerifyContactOrGroup(Activity activity,
|
||||
AlertDialog.Builder builder,
|
||||
private void showVerifyContactOrGroup(AlertDialog.Builder builder,
|
||||
String qrRawString,
|
||||
DcLot qrParsed,
|
||||
String name,
|
||||
@@ -275,51 +339,47 @@ public class QrCodeHandler {
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
}
|
||||
|
||||
private void setAddTransportDialog(Activity activity, AlertDialog.Builder builder, String qrData, String transportName) {
|
||||
builder.setTitle(R.string.confirm_add_transport);
|
||||
builder.setMessage(transportName);
|
||||
builder.setPositiveButton(R.string.ok, (d, w) -> {
|
||||
ProgressDialog progressDialog = new ProgressDialog(activity);
|
||||
progressDialog.setMessage(activity.getResources().getString(R.string.one_moment));
|
||||
progressDialog.setCanceledOnTouchOutside(false);
|
||||
progressDialog.setCancelable(false);
|
||||
String cancel = activity.getResources().getString(android.R.string.cancel);
|
||||
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, cancel, (d2, w2) -> {
|
||||
dcContext.stopOngoingProcess();
|
||||
});
|
||||
progressDialog.show();
|
||||
public void addRelay(String qrData) {
|
||||
ProgressDialog progressDialog = new ProgressDialog(activity);
|
||||
progressDialog.setMessage(activity.getResources().getString(R.string.one_moment));
|
||||
progressDialog.setCanceledOnTouchOutside(false);
|
||||
progressDialog.setCancelable(false);
|
||||
String cancel = activity.getResources().getString(android.R.string.cancel);
|
||||
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, cancel, (d, w) -> {
|
||||
dcContext.stopOngoingProcess();
|
||||
});
|
||||
progressDialog.show();
|
||||
|
||||
Util.runOnAnyBackgroundThread(() -> {
|
||||
String error = null;
|
||||
try {
|
||||
rpc.addTransportFromQr(accId, qrData);
|
||||
} catch (RpcException e) {
|
||||
Log.w(TAG, e);
|
||||
error = e.getMessage();
|
||||
}
|
||||
final String finalError = error;
|
||||
Util.runOnMain(() -> {
|
||||
if (!progressDialog.isShowing()) return; // canceled dialog, nothing to do
|
||||
if (finalError != null) {
|
||||
new AlertDialog.Builder(activity)
|
||||
.setTitle(R.string.error)
|
||||
.setMessage(finalError)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show();
|
||||
} else {
|
||||
showDoneToast(activity);
|
||||
if (!(activity instanceof RelayListActivity)) {
|
||||
activity.startActivity(new Intent(activity, RelayListActivity.class));
|
||||
}
|
||||
}
|
||||
try {
|
||||
progressDialog.dismiss();
|
||||
} catch (IllegalArgumentException e) {
|
||||
// see https://stackoverflow.com/a/5102572/4557005
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
});
|
||||
});
|
||||
Util.runOnAnyBackgroundThread(() -> {
|
||||
String error = null;
|
||||
try {
|
||||
rpc.addTransportFromQr(accId, qrData);
|
||||
} catch (RpcException e) {
|
||||
Log.w(TAG, e);
|
||||
error = e.getMessage();
|
||||
}
|
||||
final String finalError = error;
|
||||
Util.runOnMain(() -> {
|
||||
if (!progressDialog.isShowing()) return; // canceled dialog, nothing to do
|
||||
if (finalError != null) {
|
||||
new AlertDialog.Builder(activity)
|
||||
.setTitle(R.string.error)
|
||||
.setMessage(finalError)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show();
|
||||
} else {
|
||||
showDoneToast();
|
||||
if (!(activity instanceof RelayListActivity)) {
|
||||
activity.startActivity(new Intent(activity, RelayListActivity.class));
|
||||
}
|
||||
}
|
||||
try {
|
||||
progressDialog.dismiss();
|
||||
} catch (IllegalArgumentException e) {
|
||||
// see https://stackoverflow.com/a/5102572/4557005
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.connect.DcEventCenter;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.qr.QrActivity;
|
||||
import org.thoughtcrime.securesms.qr.QrCodeHandler;
|
||||
import org.thoughtcrime.securesms.util.ScreenLockUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
@@ -32,8 +33,6 @@ import java.util.List;
|
||||
import chat.delta.rpc.Rpc;
|
||||
import chat.delta.rpc.RpcException;
|
||||
import chat.delta.rpc.types.EnteredLoginParam;
|
||||
import chat.delta.rpc.types.SecurejoinSource;
|
||||
import chat.delta.rpc.types.SecurejoinUiPath;
|
||||
|
||||
public class RelayListActivity extends BaseActionBarActivity
|
||||
implements RelayListAdapter.OnRelayClickListener, DcEventCenter.DcEventDelegate {
|
||||
@@ -45,6 +44,9 @@ public class RelayListActivity extends BaseActionBarActivity
|
||||
private Rpc rpc;
|
||||
private int accId;
|
||||
|
||||
/** QR provided via Intent extras needs to be saved to pass it to QrCodeHandler when authorization finishes */
|
||||
private String qrData = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -67,6 +69,15 @@ public class RelayListActivity extends BaseActionBarActivity
|
||||
// Apply insets to prevent fab from being covered by system bars
|
||||
ViewUtil.applyWindowInsetsAsMargin(fabAdd);
|
||||
|
||||
qrData = getIntent().getStringExtra(EXTRA_QR_DATA);
|
||||
if (qrData != null) {
|
||||
// when the activity is opened with a QR data, we need to ask for authorization first
|
||||
boolean result = ScreenLockUtil.applyScreenLock(this, getString(R.string.add_transport), getString(R.string.enter_system_secret_to_continue), ScreenLockUtil.REQUEST_CODE_CONFIRM_CREDENTIALS);
|
||||
if (!result) {
|
||||
new QrCodeHandler(this).handleOnlyAddRelayQr(qrData);
|
||||
}
|
||||
}
|
||||
|
||||
fabAdd.setOnClickListener(v -> {
|
||||
new IntentIntegrator(this).setCaptureActivity(QrActivity.class).addExtra(QrActivity.EXTRA_SCAN_RELAY, true).initiateScan();
|
||||
});
|
||||
@@ -86,12 +97,6 @@ public class RelayListActivity extends BaseActionBarActivity
|
||||
|
||||
DcEventCenter eventCenter = DcHelper.getEventCenter(this);
|
||||
eventCenter.addObserver(DcContext.DC_EVENT_CONFIGURE_PROGRESS, this);
|
||||
|
||||
String qrdata = getIntent().getStringExtra(EXTRA_QR_DATA);
|
||||
if (qrdata != null) {
|
||||
QrCodeHandler qrCodeHandler = new QrCodeHandler(this);
|
||||
qrCodeHandler.handleQrData(qrdata, SecurejoinSource.Unknown, SecurejoinUiPath.Unknown);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -172,10 +177,22 @@ public class RelayListActivity extends BaseActionBarActivity
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode != RESULT_OK) {
|
||||
// if user canceled unlocking, then finish
|
||||
if (requestCode == ScreenLockUtil.REQUEST_CODE_CONFIRM_CREDENTIALS) finish();
|
||||
return;
|
||||
}
|
||||
|
||||
QrCodeHandler qrCodeHandler = new QrCodeHandler(this);
|
||||
if (requestCode == IntentIntegrator.REQUEST_CODE) {
|
||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
|
||||
QrCodeHandler qrCodeHandler = new QrCodeHandler(this);
|
||||
qrCodeHandler.onScanPerformed(scanResult, SecurejoinUiPath.Unknown);
|
||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(resultCode, data);
|
||||
qrCodeHandler.handleOnlyAddRelayQr(scanResult.getContents());
|
||||
} else if (requestCode == ScreenLockUtil.REQUEST_CODE_CONFIRM_CREDENTIALS) {
|
||||
// user authorized, then proceed to handle the QR data
|
||||
if (qrData != null) {
|
||||
qrCodeHandler.handleOnlyAddRelayQr(qrData);
|
||||
qrData = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,15 +82,11 @@ public class LongClickCopySpan extends ClickableSpan {
|
||||
}
|
||||
} else if (Util.isInviteURL(url)) {
|
||||
QrCodeHandler qrCodeHandler = new QrCodeHandler((Activity) widget.getContext());
|
||||
qrCodeHandler.handleQrData(url, SecurejoinSource.InternalLink, null);
|
||||
qrCodeHandler.handleOnlySecureJoinQr(url, SecurejoinSource.InternalLink, null);
|
||||
} else {
|
||||
Activity activity = (Activity) widget.getContext();
|
||||
DcContext dcContext = DcHelper.getContext(activity);
|
||||
if (dcContext.checkQr(url).getState() == DcContext.DC_QR_PROXY) {
|
||||
QrCodeHandler qrCodeHandler = new QrCodeHandler(activity);
|
||||
qrCodeHandler.handleQrData(url, null, null);
|
||||
} else {
|
||||
IntentUtils.showInBrowser(widget.getContext(), url);
|
||||
if (!new QrCodeHandler(activity).handleProxyQr(url)) {
|
||||
IntentUtils.showInBrowser(activity, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user