Files
briar/briar-android/src/org/briarproject/android/keyagreement/KeyAgreementActivity.java
Torsten Grote b3d6e7d12d Open Camera in UI Thread to prevent crash on some devices
Also properly handle back navigation when trying to add contacts.
2016-08-10 20:00:01 -03:00

248 lines
6.6 KiB
Java

package org.briarproject.android.keyagreement;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import org.briarproject.R;
import org.briarproject.android.ActivityComponent;
import org.briarproject.android.BriarFragmentActivity;
import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
import org.briarproject.android.keyagreement.ChooseIdentityFragment.IdentitySelectedListener;
import org.briarproject.android.util.CustomAnimations;
import org.briarproject.api.contact.ContactExchangeListener;
import org.briarproject.api.contact.ContactExchangeTask;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.KeyAgreementFinishedEvent;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.keyagreement.KeyAgreementResult;
import java.util.logging.Logger;
import javax.inject.Inject;
import static android.widget.Toast.LENGTH_LONG;
import static java.util.logging.Level.WARNING;
public class KeyAgreementActivity extends BriarFragmentActivity implements
BaseFragmentListener, IdentitySelectedListener, EventListener,
ContactExchangeListener {
private static final Logger LOG =
Logger.getLogger(KeyAgreementActivity.class.getName());
private static final String LOCAL_AUTHOR_ID = "briar.LOCAL_AUTHOR_ID";
private static final int STEP_ID = 1;
private static final int STEP_QR = 2;
@Inject
protected EventBus eventBus;
private Toolbar toolbar;
private View progressContainer;
private TextView progressTitle;
private AuthorId localAuthorId;
// Fields that are accessed from background threads must be volatile
@Inject
protected volatile ContactExchangeTask contactExchangeTask;
@Inject
protected volatile IdentityManager identityManager;
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
}
@SuppressWarnings("ConstantConditions")
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.activity_with_loading);
toolbar = (Toolbar) findViewById(R.id.toolbar);
progressContainer = findViewById(R.id.container_progress);
progressTitle = (TextView) findViewById(R.id.title_progress_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (state != null) {
byte[] b = state.getByteArray(LOCAL_AUTHOR_ID);
if (b != null)
localAuthorId = new AuthorId(b);
}
getSupportActionBar().setTitle(R.string.add_contact_title);
showStep(localAuthorId == null ? STEP_ID : STEP_QR);
}
private void showStep(int step) {
switch (step) {
case STEP_QR:
startFragment(ShowQrCodeFragment.newInstance(), true);
break;
case STEP_ID:
default:
startFragment(ChooseIdentityFragment.newInstance(), true);
break;
}
}
@Override
public void onResume() {
super.onResume();
eventBus.addListener(this);
}
@Override
protected void onPause() {
super.onPause();
eventBus.removeListener(this);
}
@Override
public void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
if (localAuthorId != null) {
byte[] b = localAuthorId.getBytes();
state.putByteArray(LOCAL_AUTHOR_ID, b);
}
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
supportFinishAfterTransition();
} else {
super.onBackPressed();
}
}
@Override
public void showLoadingScreen(boolean isBlocking, int stringId) {
if (isBlocking) {
CustomAnimations.animateHeight(toolbar, false, 250);
}
progressTitle.setText(stringId);
progressContainer.setVisibility(View.VISIBLE);
}
@Override
public void hideLoadingScreen() {
CustomAnimations.animateHeight(toolbar, true, 250);
progressContainer.setVisibility(View.INVISIBLE);
}
@Override
public void identitySelected(AuthorId localAuthorId) {
this.localAuthorId = localAuthorId;
showStep(STEP_QR);
}
@Override
public void eventOccurred(Event e) {
if (e instanceof KeyAgreementFinishedEvent) {
KeyAgreementFinishedEvent event = (KeyAgreementFinishedEvent) e;
keyAgreementFinished(event.getResult());
}
}
private void keyAgreementFinished(final KeyAgreementResult result) {
runOnUiThread(new Runnable() {
@Override
public void run() {
showLoadingScreen(false, R.string.exchanging_contact_details);
startContactExchange(result);
}
});
}
private void startContactExchange(final KeyAgreementResult result) {
runOnDbThread(new Runnable() {
@Override
public void run() {
LocalAuthor localAuthor;
// Load the local pseudonym
try {
localAuthor = identityManager.getLocalAuthor(localAuthorId);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
contactExchangeFailed();
return;
}
// Exchange contact details
contactExchangeTask.startExchange(KeyAgreementActivity.this,
localAuthor, result.getMasterKey(),
result.getConnection(), result.getTransportId(),
result.wasAlice());
}
});
}
@Override
public void contactExchangeSucceeded(final Author remoteAuthor) {
runOnUiThread(new Runnable() {
@Override
public void run() {
String contactName = remoteAuthor.getName();
String format = getString(R.string.contact_added_toast);
String text = String.format(format, contactName);
Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG)
.show();
finish();
}
});
}
@Override
public void duplicateContact(final Author remoteAuthor) {
runOnUiThread(new Runnable() {
@Override
public void run() {
String contactName = remoteAuthor.getName();
String format = getString(R.string.contact_already_exists);
String text = String.format(format, contactName);
Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG)
.show();
finish();
}
});
}
@Override
public void contactExchangeFailed() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(KeyAgreementActivity.this,
R.string.contact_exchange_failed, LENGTH_LONG).show();
finish();
}
});
}
}