Prevent activity loops when pressing back button while unlocking

This solution even works when "don't keep activities" is active
This commit is contained in:
Torsten Grote
2018-08-10 12:01:07 -03:00
parent afa3c3a70e
commit 4d63272c04
3 changed files with 41 additions and 24 deletions

View File

@@ -56,22 +56,32 @@ public abstract class BriarActivity extends BaseActivity {
@Override @Override
protected void onActivityResult(int request, int result, Intent data) { protected void onActivityResult(int request, int result, Intent data) {
super.onActivityResult(request, result, data); super.onActivityResult(request, result, data);
if (request == REQUEST_PASSWORD) { if (request == REQUEST_PASSWORD && result == RESULT_OK) {
if (result == RESULT_OK) briarController.startAndBindService(); // PasswordActivity finishes when password was entered correctly.
else supportFinishAfterTransition(); // When back button is pressed there, it will bring itself back,
} else if (request == REQUEST_UNLOCK) { // so that we never arrive here with a result that is not OK.
// if we don't finish here, we will enter onStart() briarController.startAndBindService();
if (result != RESULT_OK) supportFinishAfterTransition(); } else if (request == REQUEST_UNLOCK && result != RESULT_OK) {
// We arrive here, if the user presses 'back'
// in the Keyguard unlock screen, because UnlockActivity finishes.
// If we don't finish here, isFinishing will be false in onResume()
// and we launch a new UnlockActivity causing a loop.
supportFinishAfterTransition();
// If the result is OK, we don't need to do anything here
// and can resume normally.
} }
} }
@Override @Override
public void onStart() { public void onResume() {
super.onStart(); super.onResume();
if (!briarController.accountSignedIn() && !isFinishing()) { if (!briarController.accountSignedIn()) {
Intent i = new Intent(this, PasswordActivity.class); Intent i = new Intent(this, PasswordActivity.class);
startActivityForResult(i, REQUEST_PASSWORD); startActivityForResult(i, REQUEST_PASSWORD);
} else if (lockManager.isLocked()) { } else if (lockManager.isLocked() && !isFinishing()) {
// Also check that the activity isn't finishing already.
// This is possible if finishing in onActivityResult().
// Failure to do this check would cause an UnlockActivity loop.
Intent i = new Intent(this, UnlockActivity.class); Intent i = new Intent(this, UnlockActivity.class);
startActivityForResult(i, REQUEST_UNLOCK); startActivityForResult(i, REQUEST_UNLOCK);
} else if (SDK_INT >= 23) { } else if (SDK_INT >= 23) {

View File

@@ -23,8 +23,6 @@ import org.briarproject.briar.api.android.AndroidNotificationManager;
import javax.inject.Inject; import javax.inject.Inject;
import static android.content.Intent.ACTION_MAIN;
import static android.content.Intent.CATEGORY_HOME;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.view.View.INVISIBLE; import static android.view.View.INVISIBLE;
@@ -109,10 +107,9 @@ public class PasswordActivity extends BaseActivity {
@Override @Override
public void onBackPressed() { public void onBackPressed() {
// Show the home screen rather than another password prompt // Move task and activity to the background instead of showing another
Intent intent = new Intent(ACTION_MAIN); // password prompt. onActivityResult() won't be called in BriarActivity
intent.addCategory(CATEGORY_HOME); moveTaskToBack(true);
startActivity(intent);
} }
private void deleteAccount() { private void deleteAccount() {

View File

@@ -20,6 +20,7 @@ import javax.inject.Inject;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_KEYGUARD_UNLOCK; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_KEYGUARD_UNLOCK;
import static org.briarproject.briar.android.util.UiUtils.hasScreenLock;
@RequiresApi(21) @RequiresApi(21)
@MethodsNotNullByDefault @MethodsNotNullByDefault
@@ -27,7 +28,7 @@ import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_KEYGU
public class UnlockActivity extends BaseActivity { public class UnlockActivity extends BaseActivity {
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(UnlockActivity.class.getSimpleName()); Logger.getLogger(UnlockActivity.class.getName());
@Inject @Inject
LockManager lockManager; LockManager lockManager;
@@ -44,13 +45,6 @@ public class UnlockActivity extends BaseActivity {
Button button = findViewById(R.id.unlock); Button button = findViewById(R.id.unlock);
button.setOnClickListener(view -> requestKeyguardUnlock()); button.setOnClickListener(view -> requestKeyguardUnlock());
requestKeyguardUnlock();
}
@Override
public void onBackPressed() {
moveTaskToBack(true);
} }
@Override @Override
@@ -63,6 +57,22 @@ public class UnlockActivity extends BaseActivity {
} }
} }
@Override
protected void onResume() {
super.onResume();
// Show keyguard after onActivityResult() as been called.
// Check if app is still locked, lockable
// and not finishing (which is possible if recreated)
if (lockManager.isLocked() && hasScreenLock(this) && !isFinishing()) {
requestKeyguardUnlock();
}
}
@Override
public void onBackPressed() {
moveTaskToBack(true);
}
private void requestKeyguardUnlock() { private void requestKeyguardUnlock() {
KeyguardManager keyguardManager = KeyguardManager keyguardManager =
(KeyguardManager) getSystemService(KEYGUARD_SERVICE); (KeyguardManager) getSystemService(KEYGUARD_SERVICE);