diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationListActivity.java b/src/main/java/org/thoughtcrime/securesms/ConversationListActivity.java index cf5c3179f..c37585a39 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationListActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationListActivity.java @@ -46,6 +46,8 @@ import android.widget.TextView; import android.widget.Toast; import androidx.activity.OnBackPressedCallback; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.Toolbar; @@ -98,7 +100,6 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit public static final String ACCOUNT_ID_EXTRA = "account_id"; public static final String FROM_WELCOME = "from_welcome"; public static final String FROM_WELCOME_RAW_QR = "from_welcome_raw_qr"; - private static final int REQUEST_CODE_CONFIRM_CREDENTIALS_DELETE_PROFILE = ScreenLockUtil.REQUEST_CODE_CONFIRM_CREDENTIALS+1; private ConversationListFragment conversationListFragment; public TextView title; @@ -112,8 +113,11 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit /** used to store temporarily scanned QR to pass it back to QrCodeHandler when ScreenLockUtil is used */ private String qrData = null; + private ActivityResultLauncher relayLockLauncher; + /** used to store temporarily profile ID to delete after authorization is granted via ScreenLockUtil */ private int deleteProfileId = 0; + private ActivityResultLauncher deleteProfileLockLauncher; @Override protected void onPreCreate() { @@ -123,6 +127,31 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit @Override protected void onCreate(Bundle icicle, boolean ready) { + relayLockLauncher = registerForActivityResult( + new ActivityResultContracts.StartActivityForResult(), + result -> { + if (result.getResultCode() == RESULT_OK) { + // QrCodeHandler requested user authorization before adding a relay + // and it was granted, so proceed to add the relay + if (qrData != null) { + new QrCodeHandler(this).addRelay(qrData); + qrData = null; + } + } + } + ); + deleteProfileLockLauncher = registerForActivityResult( + new ActivityResultContracts.StartActivityForResult(), + result -> { + if (result.getResultCode() == RESULT_OK) { + if (deleteProfileId != 0) { + deleteProfile(deleteProfileId); + deleteProfileId = 0; + } + } + } + ); + addDeviceMessages(getIntent().getBooleanExtra(FROM_WELCOME, false)); if (getIntent().getIntExtra(ACCOUNT_ID_EXTRA, -1) <= 0) { getIntent().putExtra(ACCOUNT_ID_EXTRA, DcHelper.getContext(this).getAccountId()); @@ -628,7 +657,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit 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); + boolean result = ScreenLockUtil.applyScreenLock(this, getString(R.string.delete_account), getString(R.string.enter_system_secret_to_continue), deleteProfileLockLauncher); if (!result) { deleteProfile(profileId); } @@ -660,29 +689,10 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit 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(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; + if (requestCode == IntentIntegrator.REQUEST_CODE) { + IntentResult scanResult = IntentIntegrator.parseActivityResult(resultCode, data); + qrData = scanResult.getContents(); + new QrCodeHandler(this).handleQrData(qrData, SecurejoinSource.Scan, SecurejoinUiPath.QrIcon, relayLockLauncher); } } diff --git a/src/main/java/org/thoughtcrime/securesms/qr/QrCodeHandler.java b/src/main/java/org/thoughtcrime/securesms/qr/QrCodeHandler.java index 3cef03312..55d925af5 100644 --- a/src/main/java/org/thoughtcrime/securesms/qr/QrCodeHandler.java +++ b/src/main/java/org/thoughtcrime/securesms/qr/QrCodeHandler.java @@ -6,6 +6,8 @@ import android.content.Intent; import android.util.Log; import android.widget.Toast; +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; @@ -121,16 +123,16 @@ public class QrCodeHandler { } /** Process only QR about adding relays/profiles (DCACCOUNT: / DCLOGIN:) */ - public void handleOnlyAddRelayQr(String rawString) { + public void handleOnlyAddRelayQr(String rawString, @Nullable ActivityResultLauncher screenLockLauncher) { final DcLot qrParsed = dcContext.checkQr(rawString); - if (!handleAddRelayQr(qrParsed, rawString)) { + if (!handleAddRelayQr(qrParsed, rawString, screenLockLauncher)) { AlertDialog.Builder builder = new AlertDialog.Builder(activity); handleDefault(builder, rawString, qrParsed); builder.create().show(); } } - private boolean handleAddRelayQr(DcLot qrParsed, String rawString) { + private boolean handleAddRelayQr(DcLot qrParsed, String rawString, @Nullable ActivityResultLauncher screenLockLauncher) { switch (qrParsed.getState()) { case DcContext.DC_QR_ACCOUNT: case DcContext.DC_QR_LOGIN: @@ -138,14 +140,13 @@ public class QrCodeHandler { 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 (screenLockLauncher != null) { + boolean result = ScreenLockUtil.applyScreenLock(activity, activity.getString(R.string.add_transport), activity.getString(R.string.enter_system_secret_to_continue), screenLockLauncher); if (!result) { addRelay(rawString); } + } else { // Screen lock not needed + addRelay(rawString); } }); builder.setNegativeButton(R.string.cancel, null); @@ -219,10 +220,10 @@ public class QrCodeHandler { } /** Handle any kind of QR showing an AlertDialog adapted to the QR type. */ - public void handleQrData(String rawString, SecurejoinSource source, SecurejoinUiPath uiPath) { + public void handleQrData(String rawString, SecurejoinSource source, SecurejoinUiPath uiPath, ActivityResultLauncher relayLockLauncher) { final DcLot qrParsed = dcContext.checkQr(rawString); if (handleSecureJoinQr(qrParsed, rawString, source, uiPath) - || handleAddRelayQr(qrParsed, rawString) + || handleAddRelayQr(qrParsed, rawString, relayLockLauncher) || handleProxyQr(qrParsed, rawString) || handleBackupQr(qrParsed, rawString)) return; diff --git a/src/main/java/org/thoughtcrime/securesms/relay/RelayListActivity.java b/src/main/java/org/thoughtcrime/securesms/relay/RelayListActivity.java index b4493d22b..0aff977c3 100644 --- a/src/main/java/org/thoughtcrime/securesms/relay/RelayListActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/relay/RelayListActivity.java @@ -7,6 +7,8 @@ import android.view.ContextMenu; import android.view.MenuItem; import android.view.View; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; @@ -48,6 +50,7 @@ public class RelayListActivity extends BaseActionBarActivity /** QR provided via Intent extras needs to be saved to pass it to QrCodeHandler when authorization finishes */ private String qrData = null; + private ActivityResultLauncher screenLockLauncher; /** Relay selected for context menu via onRelayLongClick() */ private EnteredLoginParam contextMenuRelay = null; @@ -57,6 +60,22 @@ public class RelayListActivity extends BaseActionBarActivity super.onCreate(savedInstanceState); setContentView(R.layout.activity_relay_list); + screenLockLauncher = registerForActivityResult( + new ActivityResultContracts.StartActivityForResult(), + result -> { + if (result.getResultCode() != RESULT_OK) { + // if user canceled unlocking, then finish + finish(); + return; + } + // user authorized, then proceed to handle the QR data + if (qrData != null) { + new QrCodeHandler(this).handleOnlyAddRelayQr(qrData, null); + qrData = null; + } + } + ); + rpc = DcHelper.getRpc(this); accId = DcHelper.getContext(this).getAccountId(); @@ -77,9 +96,9 @@ public class RelayListActivity extends BaseActionBarActivity 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); + boolean result = ScreenLockUtil.applyScreenLock(this, getString(R.string.add_transport), getString(R.string.enter_system_secret_to_continue), screenLockLauncher); if (!result) { - new QrCodeHandler(this).handleOnlyAddRelayQr(qrData); + new QrCodeHandler(this).handleOnlyAddRelayQr(qrData, null); } } @@ -223,22 +242,9 @@ 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) { + if (resultCode == RESULT_OK && requestCode == IntentIntegrator.REQUEST_CODE) { 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; - } + new QrCodeHandler(this).handleOnlyAddRelayQr(scanResult.getContents(), null); } } diff --git a/src/main/java/org/thoughtcrime/securesms/util/ScreenLockUtil.java b/src/main/java/org/thoughtcrime/securesms/util/ScreenLockUtil.java index 3e0394202..3b07b0025 100644 --- a/src/main/java/org/thoughtcrime/securesms/util/ScreenLockUtil.java +++ b/src/main/java/org/thoughtcrime/securesms/util/ScreenLockUtil.java @@ -9,21 +9,6 @@ import androidx.activity.result.ActivityResultLauncher; public class ScreenLockUtil { - public static final int REQUEST_CODE_CONFIRM_CREDENTIALS = 1001; - - public static boolean applyScreenLock(Activity activity, String title, String descr, int requestCode) { - KeyguardManager keyguardManager = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE); - Intent intent; - if (keyguardManager != null) { - intent = keyguardManager.createConfirmDeviceCredentialIntent(title, descr); - if (intent != null) { - activity.startActivityForResult(intent, requestCode); - return true; - } - } - return false; - } - public static boolean applyScreenLock(Activity activity, String title, String descr, ActivityResultLauncher launcher) { KeyguardManager keyguardManager = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE); Intent intent;