Changed the root package from net.sf.briar to org.briarproject.

This commit is contained in:
akwizgran
2014-01-08 16:18:30 +00:00
parent dce70f487c
commit 832476412c
427 changed files with 2507 additions and 2507 deletions

View File

@@ -0,0 +1,465 @@
package org.briarproject.android.invitation;
import static android.bluetooth.BluetoothAdapter.ACTION_SCAN_MODE_CHANGED;
import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED;
import static android.bluetooth.BluetoothAdapter.EXTRA_STATE;
import static android.bluetooth.BluetoothAdapter.STATE_ON;
import static android.net.wifi.WifiManager.NETWORK_STATE_CHANGED_ACTION;
import static android.widget.Toast.LENGTH_LONG;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import java.util.Collection;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.inject.Inject;
import org.briarproject.R;
import org.briarproject.android.identity.LocalAuthorItem;
import org.briarproject.android.identity.LocalAuthorItemComparator;
import org.briarproject.android.identity.LocalAuthorSpinnerAdapter;
import org.briarproject.api.AuthorId;
import org.briarproject.api.LocalAuthor;
import org.briarproject.api.android.DatabaseUiExecutor;
import org.briarproject.api.android.ReferenceManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.invitation.InvitationListener;
import org.briarproject.api.invitation.InvitationState;
import org.briarproject.api.invitation.InvitationTask;
import org.briarproject.api.invitation.InvitationTaskFactory;
import org.briarproject.api.lifecycle.LifecycleManager;
import roboguice.activity.RoboActivity;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.widget.Toast;
public class AddContactActivity extends RoboActivity
implements InvitationListener {
private static final Logger LOG =
Logger.getLogger(AddContactActivity.class.getName());
@Inject private CryptoComponent crypto;
@Inject private InvitationTaskFactory invitationTaskFactory;
@Inject private ReferenceManager referenceManager;
private AddContactView view = null;
private InvitationTask task = null;
private long taskHandle = -1;
private AuthorId localAuthorId = null;
private String networkName = null;
private boolean bluetoothEnabled = false;
private BluetoothWifiStateReceiver receiver = null;
private int localInvitationCode = -1, remoteInvitationCode = -1;
private int localConfirmationCode = -1, remoteConfirmationCode = -1;
private boolean connected = false, connectionFailed = false;
private boolean localCompared = false, remoteCompared = false;
private boolean localMatched = false, remoteMatched = false;
private String contactName = null;
// Fields that are accessed from background threads must be volatile
@Inject private volatile DatabaseComponent db;
@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
@Inject private volatile LifecycleManager lifecycleManager;
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
if(state == null) {
// This is a new activity
setView(new NetworkSetupView(this));
} else {
// Restore the activity's state
byte[] b = state.getByteArray("org.briarproject.LOCAL_AUTHOR_ID");
if(b != null) localAuthorId = new AuthorId(b);
taskHandle = state.getLong("org.briarproject.TASK_HANDLE", -1);
task = referenceManager.getReference(taskHandle,
InvitationTask.class);
if(task == null) {
// No background task - we must be in an initial or final state
localInvitationCode = state.getInt("org.briarproject.LOCAL_CODE");
remoteInvitationCode = state.getInt("org.briarproject.REMOTE_CODE");
connectionFailed = state.getBoolean("org.briarproject.FAILED");
contactName = state.getString("org.briarproject.CONTACT_NAME");
if(contactName != null) {
localCompared = remoteCompared = true;
localMatched = remoteMatched = true;
}
// Set the appropriate view for the state
if(localInvitationCode == -1) {
setView(new NetworkSetupView(this));
} else if(remoteInvitationCode == -1) {
setView(new InvitationCodeView(this));
} else if(connectionFailed) {
setView(new ConnectionFailedView(this));
} else if(contactName == null) {
setView(new CodesDoNotMatchView(this));
} else {
showToastAndFinish();
return;
}
} else {
// A background task exists - listen to it and get its state
InvitationState s = task.addListener(this);
localInvitationCode = s.getLocalInvitationCode();
remoteInvitationCode = s.getRemoteInvitationCode();
localConfirmationCode = s.getLocalConfirmationCode();
remoteConfirmationCode = s.getRemoteConfirmationCode();
connected = s.getConnected();
connectionFailed = s.getConnectionFailed();
localCompared = s.getLocalCompared();
remoteCompared = s.getRemoteCompared();
localMatched = s.getLocalMatched();
remoteMatched = s.getRemoteMatched();
contactName = s.getContactName();
// Set the appropriate view for the state
if(localInvitationCode == -1) {
setView(new NetworkSetupView(this));
} else if(remoteInvitationCode == -1) {
setView(new InvitationCodeView(this));
} else if(connectionFailed) {
setView(new ConnectionFailedView(this));
} else if(connected && localConfirmationCode == -1) {
setView(new ConnectedView(this));
} else if(localConfirmationCode == -1) {
setView(new ConnectionView(this));
} else if(!localCompared) {
setView(new ConfirmationCodeView(this));
} else if(!remoteCompared) {
setView(new WaitForContactView(this));
} else if(localMatched && remoteMatched) {
if(contactName == null) {
setView(new ContactDetailsView(this));
} else {
showToastAndFinish();
return;
}
} else {
setView(new CodesDoNotMatchView(this));
}
}
}
// Listen for Bluetooth and WiFi state changes
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_STATE_CHANGED);
filter.addAction(ACTION_SCAN_MODE_CHANGED);
filter.addAction(NETWORK_STATE_CHANGED_ACTION);
receiver = new BluetoothWifiStateReceiver();
registerReceiver(receiver, filter);
// Get the current Bluetooth and WiFi state
BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
if(bluetooth != null) bluetoothEnabled = bluetooth.isEnabled();
view.bluetoothStateChanged();
WifiManager wifi = (WifiManager) getSystemService(WIFI_SERVICE);
if(wifi != null && wifi.isWifiEnabled()) {
WifiInfo info = wifi.getConnectionInfo();
if(info.getNetworkId() != -1) networkName = info.getSSID();
}
view.wifiStateChanged();
}
private void showToastAndFinish() {
Toast.makeText(this, R.string.contact_added_toast, LENGTH_LONG).show();
finish();
}
@Override
public void onResume() {
super.onResume();
view.populate();
}
@Override
public void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
if(localAuthorId != null) {
byte[] b = localAuthorId.getBytes();
state.putByteArray("org.briarproject.LOCAL_AUTHOR_ID", b);
}
state.putInt("org.briarproject.LOCAL_CODE", localInvitationCode);
state.putInt("org.briarproject.REMOTE_CODE", remoteInvitationCode);
state.putBoolean("org.briarproject.FAILED", connectionFailed);
state.putString("org.briarproject.CONTACT_NAME", contactName);
if(task != null) state.putLong("org.briarproject.TASK_HANDLE", taskHandle);
}
@Override
public void onDestroy() {
super.onDestroy();
if(task != null) task.removeListener(this);
if(receiver != null) unregisterReceiver(receiver);
}
void setView(AddContactView view) {
this.view = view;
view.init(this);
setContentView(view);
}
void reset(AddContactView view) {
// Don't reset localAuthorId, networkName or bluetoothEnabled
task = null;
taskHandle = -1;
localInvitationCode = -1;
localConfirmationCode = remoteConfirmationCode = -1;
connected = connectionFailed = false;
localCompared = remoteCompared = false;
localMatched = remoteMatched = false;
contactName = null;
setView(view);
}
void loadLocalAuthors(final LocalAuthorSpinnerAdapter adapter) {
dbUiExecutor.execute(new Runnable() {
public void run() {
try {
lifecycleManager.waitForDatabase();
long now = System.currentTimeMillis();
Collection<LocalAuthor> localAuthors = db.getLocalAuthors();
long duration = System.currentTimeMillis() - now;
if(LOG.isLoggable(INFO))
LOG.info("Loading authors took " + duration + " ms");
displayLocalAuthors(adapter, localAuthors);
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} catch(InterruptedException e) {
LOG.info("Interrupted while waiting for database");
Thread.currentThread().interrupt();
}
}
});
}
private void displayLocalAuthors(final LocalAuthorSpinnerAdapter adapter,
final Collection<LocalAuthor> localAuthors) {
runOnUiThread(new Runnable() {
public void run() {
if(localAuthors.isEmpty()) throw new IllegalStateException();
adapter.clear();
for(LocalAuthor a : localAuthors)
adapter.add(new LocalAuthorItem(a));
adapter.sort(LocalAuthorItemComparator.INSTANCE);
adapter.notifyDataSetChanged();
}
});
}
void setLocalAuthorId(AuthorId localAuthorId) {
this.localAuthorId = localAuthorId;
}
AuthorId getLocalAuthorId() {
return localAuthorId;
}
String getNetworkName() {
return networkName;
}
boolean isBluetoothEnabled() {
return bluetoothEnabled;
}
int getLocalInvitationCode() {
if(localInvitationCode == -1)
localInvitationCode = crypto.generateInvitationCode();
return localInvitationCode;
}
void remoteInvitationCodeEntered(int code) {
if(localAuthorId == null) throw new IllegalStateException();
if(localInvitationCode == -1) throw new IllegalStateException();
setView(new ConnectionView(this));
task = invitationTaskFactory.createTask(localAuthorId,
localInvitationCode, code);
taskHandle = referenceManager.putReference(task, InvitationTask.class);
task.addListener(AddContactActivity.this);
// Add a second listener so we can remove the first in onDestroy(),
// allowing the activity to be garbage collected if it's destroyed
task.addListener(new ReferenceCleaner(referenceManager, taskHandle));
task.connect();
}
int getLocalConfirmationCode() {
return localConfirmationCode;
}
void remoteConfirmationCodeEntered(int code) {
localCompared = true;
if(code == remoteConfirmationCode) {
localMatched = true;
if(remoteMatched) setView(new ContactDetailsView(this));
else if(remoteCompared) setView(new CodesDoNotMatchView(this));
else setView(new WaitForContactView(this));
task.localConfirmationSucceeded();
} else {
localMatched = false;
setView(new CodesDoNotMatchView(this));
task.localConfirmationFailed();
}
}
String getContactName() {
return contactName;
}
public void connectionSucceeded() {
runOnUiThread(new Runnable() {
public void run() {
connected = true;
setView(new ConnectedView(AddContactActivity.this));
}
});
}
public void connectionFailed() {
runOnUiThread(new Runnable() {
public void run() {
connectionFailed = true;
setView(new ConnectionFailedView(AddContactActivity.this));
}
});
}
public void keyAgreementSucceeded(final int localCode,
final int remoteCode) {
runOnUiThread(new Runnable() {
public void run() {
localConfirmationCode = localCode;
remoteConfirmationCode = remoteCode;
setView(new ConfirmationCodeView(AddContactActivity.this));
}
});
}
public void keyAgreementFailed() {
runOnUiThread(new Runnable() {
public void run() {
connectionFailed = true;
setView(new ConnectionFailedView(AddContactActivity.this));
}
});
}
public void remoteConfirmationSucceeded() {
runOnUiThread(new Runnable() {
public void run() {
remoteCompared = true;
remoteMatched = true;
if(localMatched)
setView(new ContactDetailsView(AddContactActivity.this));
}
});
}
public void remoteConfirmationFailed() {
runOnUiThread(new Runnable() {
public void run() {
remoteCompared = true;
remoteMatched = false;
if(localMatched)
setView(new CodesDoNotMatchView(AddContactActivity.this));
}
});
}
public void pseudonymExchangeSucceeded(final String remoteName) {
runOnUiThread(new Runnable() {
public void run() {
contactName = remoteName;
showToastAndFinish();
}
});
}
public void pseudonymExchangeFailed() {
runOnUiThread(new Runnable() {
public void run() {
setView(new ConnectionFailedView(AddContactActivity.this));
}
});
}
private class BluetoothWifiStateReceiver extends BroadcastReceiver {
public void onReceive(Context ctx, Intent intent) {
String action = intent.getAction();
if(action.equals(ACTION_STATE_CHANGED)) {
int state = intent.getIntExtra(EXTRA_STATE, 0);
bluetoothEnabled = state == STATE_ON;
view.bluetoothStateChanged();
} else if(action.equals(ACTION_SCAN_MODE_CHANGED)) {
view.bluetoothStateChanged();
} else if(action.equals(NETWORK_STATE_CHANGED_ACTION)) {
WifiManager wifi = (WifiManager) getSystemService(WIFI_SERVICE);
if(wifi == null || !wifi.isWifiEnabled()) {
networkName = null;
} else {
WifiInfo info = wifi.getConnectionInfo();
if(info.getNetworkId() == -1) networkName = null;
else networkName = info.getSSID();
}
view.wifiStateChanged();
}
}
}
/**
* Cleans up the reference to the invitation task when the task completes.
* This class is static to prevent memory leaks.
*/
private static class ReferenceCleaner implements InvitationListener {
private final ReferenceManager referenceManager;
private final long handle;
private ReferenceCleaner(ReferenceManager referenceManager,
long handle) {
this.referenceManager = referenceManager;
this.handle = handle;
}
public void connectionSucceeded() {
// Wait for key agreement to succeed or fail
}
public void connectionFailed() {
referenceManager.removeReference(handle, InvitationTask.class);
}
public void keyAgreementSucceeded(int localCode, int remoteCode) {
// Wait for remote confirmation to succeed or fail
}
public void keyAgreementFailed() {
referenceManager.removeReference(handle, InvitationTask.class);
}
public void remoteConfirmationSucceeded() {
// Wait for the pseudonym exchange to succeed or fail
}
public void remoteConfirmationFailed() {
referenceManager.removeReference(handle, InvitationTask.class);
}
public void pseudonymExchangeSucceeded(String remoteName) {
referenceManager.removeReference(handle, InvitationTask.class);
}
public void pseudonymExchangeFailed() {
referenceManager.removeReference(handle, InvitationTask.class);
}
}
}

View File

@@ -0,0 +1,29 @@
package org.briarproject.android.invitation;
import static android.view.Gravity.CENTER_HORIZONTAL;
import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH;
import android.content.Context;
import android.widget.LinearLayout;
abstract class AddContactView extends LinearLayout {
protected AddContactActivity container = null;
AddContactView(Context ctx) {
super(ctx);
}
void init(AddContactActivity container) {
this.container = container;
setLayoutParams(MATCH_MATCH);
setOrientation(VERTICAL);
setGravity(CENTER_HORIZONTAL);
populate();
}
abstract void populate();
void wifiStateChanged() {}
void bluetoothStateChanged() {}
}

View File

@@ -0,0 +1,84 @@
package org.briarproject.android.invitation;
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
import static android.provider.Settings.ACTION_BLUETOOTH_SETTINGS;
import static android.view.Gravity.CENTER;
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
import org.briarproject.R;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
class BluetoothStatusView extends LinearLayout implements OnClickListener {
public BluetoothStatusView(Context ctx) {
super(ctx);
}
void init() {
setOrientation(HORIZONTAL);
setGravity(CENTER);
populate();
}
void populate() {
removeAllViews();
Context ctx = getContext();
TextView status = new TextView(ctx);
status.setLayoutParams(WRAP_WRAP_1);
status.setTextSize(14);
status.setPadding(10, 10, 10, 10);
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if(adapter == null) {
ImageView warning = new ImageView(ctx);
warning.setPadding(5, 5, 5, 5);
warning.setImageResource(R.drawable.alerts_and_states_warning);
addView(warning);
status.setText(R.string.bluetooth_not_available);
addView(status);
} else if(adapter.getScanMode() == SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
ImageView ok = new ImageView(ctx);
ok.setPadding(5, 5, 5, 5);
ok.setImageResource(R.drawable.navigation_accept);
addView(ok);
status.setText(R.string.bluetooth_discoverable);
addView(status);
ImageButton settings = new ImageButton(ctx);
settings.setImageResource(R.drawable.action_settings);
settings.setOnClickListener(this);
addView(settings);
} else if(adapter.isEnabled()) {
ImageView warning = new ImageView(ctx);
warning.setPadding(5, 5, 5, 5);
warning.setImageResource(R.drawable.alerts_and_states_warning);
addView(warning);
status.setText(R.string.bluetooth_not_discoverable);
addView(status);
ImageButton settings = new ImageButton(ctx);
settings.setImageResource(R.drawable.action_settings);
settings.setOnClickListener(this);
addView(settings);
} else {
ImageView warning = new ImageView(ctx);
warning.setPadding(5, 5, 5, 5);
warning.setImageResource(R.drawable.alerts_and_states_warning);
addView(warning);
status.setText(R.string.bluetooth_disabled);
addView(status);
ImageButton settings = new ImageButton(ctx);
settings.setImageResource(R.drawable.action_settings);
settings.setOnClickListener(this);
addView(settings);
}
}
public void onClick(View view) {
getContext().startActivity(new Intent(ACTION_BLUETOOTH_SETTINGS));
}
}

View File

@@ -0,0 +1,6 @@
package org.briarproject.android.invitation;
interface CodeEntryListener {
void codeEntered(int remoteCode);
}

View File

@@ -0,0 +1,98 @@
package org.briarproject.android.invitation;
import static android.content.Context.INPUT_METHOD_SERVICE;
import static android.text.InputType.TYPE_CLASS_NUMBER;
import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL;
import static android.view.inputmethod.InputMethodManager.HIDE_IMPLICIT_ONLY;
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP;
import org.briarproject.R;
import android.content.Context;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
class CodeEntryView extends LinearLayout
implements OnEditorActionListener, OnClickListener {
private CodeEntryListener listener = null;
private EditText codeEntry = null;
private Button continueButton = null;
public CodeEntryView(Context ctx) {
super(ctx);
}
void init(CodeEntryListener listener, String prompt) {
this.listener = listener;
setOrientation(VERTICAL);
setGravity(CENTER_HORIZONTAL);
Context ctx = getContext();
TextView enterCode = new TextView(ctx);
enterCode.setGravity(CENTER_HORIZONTAL);
enterCode.setTextSize(14);
enterCode.setPadding(10, 10, 10, 0);
enterCode.setText(prompt);
addView(enterCode);
LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER);
codeEntry = new EditText(ctx) {
@Override
protected void onTextChanged(CharSequence text, int start,
int lengthBefore, int lengthAfter) {
if(continueButton != null)
continueButton.setEnabled(getText().length() == 6);
}
};
codeEntry.setId(1); // FIXME: State is not saved and restored
codeEntry.setTextSize(26);
codeEntry.setOnEditorActionListener(this);
codeEntry.setMinEms(5);
codeEntry.setMaxEms(5);
codeEntry.setMaxLines(1);
codeEntry.setInputType(TYPE_CLASS_NUMBER);
innerLayout.addView(codeEntry);
continueButton = new Button(ctx);
continueButton.setLayoutParams(WRAP_WRAP);
continueButton.setText(R.string.continue_button);
continueButton.setEnabled(false);
continueButton.setOnClickListener(this);
innerLayout.addView(continueButton);
addView(innerLayout);
}
public boolean onEditorAction(TextView textView, int actionId, KeyEvent e) {
if(!validateAndReturnCode()) codeEntry.setText("");
return true;
}
public void onClick(View view) {
if(!validateAndReturnCode()) codeEntry.setText("");
}
private boolean validateAndReturnCode() {
String remoteCodeString = codeEntry.getText().toString();
int remoteCode;
try {
remoteCode = Integer.parseInt(remoteCodeString);
} catch(NumberFormatException e) {
return false;
}
// Hide the soft keyboard
Object o = getContext().getSystemService(INPUT_METHOD_SERVICE);
((InputMethodManager) o).toggleSoftInput(HIDE_IMPLICIT_ONLY, 0);
listener.codeEntered(remoteCode);
return true;
}
}

View File

@@ -0,0 +1,55 @@
package org.briarproject.android.invitation;
import static android.view.Gravity.CENTER;
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP;
import org.briarproject.R;
import android.content.Context;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
class CodesDoNotMatchView extends AddContactView implements OnClickListener {
CodesDoNotMatchView(Context ctx) {
super(ctx);
}
void populate() {
removeAllViews();
Context ctx = getContext();
LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER);
ImageView icon = new ImageView(ctx);
icon.setImageResource(R.drawable.alerts_and_states_error);
innerLayout.addView(icon);
TextView failed = new TextView(ctx);
failed.setTextSize(22);
failed.setPadding(10, 10, 10, 10);
failed.setText(R.string.codes_do_not_match);
innerLayout.addView(failed);
addView(innerLayout);
TextView interfering = new TextView(ctx);
interfering.setTextSize(14);
interfering.setPadding(10, 0, 10, 10);
interfering.setText(R.string.interfering);
addView(interfering);
Button tryAgainButton = new Button(ctx);
tryAgainButton.setLayoutParams(WRAP_WRAP);
tryAgainButton.setText(R.string.try_again_button);
tryAgainButton.setOnClickListener(this);
addView(tryAgainButton);
}
public void onClick(View view) {
// Try again
container.reset(new NetworkSetupView(container));
}
}

View File

@@ -0,0 +1,60 @@
package org.briarproject.android.invitation;
import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL;
import org.briarproject.R;
import android.content.Context;
import android.content.res.Resources;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
class ConfirmationCodeView extends AddContactView implements CodeEntryListener {
ConfirmationCodeView(Context ctx) {
super(ctx);
}
void populate() {
removeAllViews();
Context ctx = getContext();
LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER);
ImageView icon = new ImageView(ctx);
icon.setImageResource(R.drawable.navigation_accept);
innerLayout.addView(icon);
TextView connected = new TextView(ctx);
connected.setTextSize(22);
connected.setPadding(10, 10, 10, 10);
connected.setText(R.string.connected_to_contact);
innerLayout.addView(connected);
addView(innerLayout);
TextView yourCode = new TextView(ctx);
yourCode.setGravity(CENTER_HORIZONTAL);
yourCode.setTextSize(14);
yourCode.setPadding(10, 10, 10, 10);
yourCode.setText(R.string.your_confirmation_code);
addView(yourCode);
TextView code = new TextView(ctx);
code.setGravity(CENTER_HORIZONTAL);
code.setTextSize(50);
code.setPadding(10, 0, 10, 10);
int localCode = container.getLocalConfirmationCode();
code.setText(String.format("%06d", localCode));
addView(code);
CodeEntryView codeEntry = new CodeEntryView(ctx);
Resources res = getResources();
codeEntry.init(this, res.getString(R.string.enter_confirmation_code));
addView(codeEntry);
}
public void codeEntered(int remoteCode) {
container.remoteConfirmationCodeEntered(remoteCode);
}
}

View File

@@ -0,0 +1,49 @@
package org.briarproject.android.invitation;
import static android.view.Gravity.CENTER;
import org.briarproject.R;
import android.content.Context;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
class ConnectedView extends AddContactView {
ConnectedView(Context ctx) {
super(ctx);
}
void populate() {
removeAllViews();
Context ctx = getContext();
LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER);
ImageView icon = new ImageView(ctx);
icon.setImageResource(R.drawable.navigation_accept);
innerLayout.addView(icon);
TextView connected = new TextView(ctx);
connected.setTextSize(22);
connected.setPadding(10, 10, 10, 10);
connected.setText(R.string.connected_to_contact);
innerLayout.addView(connected);
addView(innerLayout);
innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER);
ProgressBar progress = new ProgressBar(ctx);
progress.setIndeterminate(true);
progress.setPadding(10, 10, 10, 10);
innerLayout.addView(progress);
TextView connecting = new TextView(ctx);
connecting.setText(R.string.calculating_confirmation_code);
innerLayout.addView(connecting);
addView(innerLayout);
}
}

View File

@@ -0,0 +1,85 @@
package org.briarproject.android.invitation;
import static android.view.Gravity.CENTER;
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP;
import org.briarproject.R;
import android.content.Context;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
class ConnectionFailedView extends AddContactView implements OnClickListener {
private WifiStatusView wifi = null;
private BluetoothStatusView bluetooth = null;
private Button tryAgainButton = null;
ConnectionFailedView(Context ctx) {
super(ctx);
}
void populate() {
removeAllViews();
Context ctx = getContext();
LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER);
ImageView icon = new ImageView(ctx);
icon.setImageResource(R.drawable.alerts_and_states_error);
innerLayout.addView(icon);
TextView failed = new TextView(ctx);
failed.setTextSize(22);
failed.setPadding(10, 10, 10, 10);
failed.setText(R.string.connection_failed);
innerLayout.addView(failed);
addView(innerLayout);
TextView checkNetwork = new TextView(ctx);
checkNetwork.setTextSize(14);
checkNetwork.setPadding(10, 0, 10, 10);
checkNetwork.setText(R.string.check_same_network);
addView(checkNetwork);
wifi = new WifiStatusView(ctx);
wifi.init();
addView(wifi);
bluetooth = new BluetoothStatusView(ctx);
bluetooth.init();
addView(bluetooth);
tryAgainButton = new Button(ctx);
tryAgainButton.setLayoutParams(WRAP_WRAP);
tryAgainButton.setText(R.string.try_again_button);
tryAgainButton.setOnClickListener(this);
enableOrDisableTryAgainButton();
addView(tryAgainButton);
}
void wifiStateChanged() {
if(wifi != null) wifi.populate();
enableOrDisableTryAgainButton();
}
void bluetoothStateChanged() {
if(bluetooth != null) bluetooth.populate();
enableOrDisableTryAgainButton();
}
private void enableOrDisableTryAgainButton() {
if(tryAgainButton == null) return; // Activity not created yet
boolean bluetoothEnabled = container.isBluetoothEnabled();
String networkName = container.getNetworkName();
tryAgainButton.setEnabled(bluetoothEnabled || networkName != null);
}
public void onClick(View view) {
// Try again
container.reset(new InvitationCodeView(container));
}
}

View File

@@ -0,0 +1,72 @@
package org.briarproject.android.invitation;
import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL;
import org.briarproject.R;
import android.content.Context;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
class ConnectionView extends AddContactView {
ConnectionView(Context ctx) {
super(ctx);
}
void populate() {
removeAllViews();
Context ctx = getContext();
TextView yourCode = new TextView(ctx);
yourCode.setGravity(CENTER_HORIZONTAL);
yourCode.setTextSize(14);
yourCode.setPadding(10, 10, 10, 10);
yourCode.setText(R.string.your_invitation_code);
addView(yourCode);
TextView code = new TextView(ctx);
code.setGravity(CENTER_HORIZONTAL);
code.setTextSize(50);
code.setPadding(10, 0, 10, 10);
int localCode = container.getLocalInvitationCode();
code.setText(String.format("%06d", localCode));
addView(code);
String networkName = container.getNetworkName();
if(networkName != null) {
LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER);
ProgressBar progress = new ProgressBar(ctx);
progress.setIndeterminate(true);
progress.setPadding(10, 10, 10, 10);
innerLayout.addView(progress);
TextView connecting = new TextView(ctx);
String format = getResources().getString(
R.string.format_connecting_wifi);
connecting.setText(String.format(format, networkName));
innerLayout.addView(connecting);
addView(innerLayout);
}
if(container.isBluetoothEnabled()) {
LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER);
ProgressBar progress = new ProgressBar(ctx);
progress.setPadding(10, 10, 10, 10);
progress.setIndeterminate(true);
innerLayout.addView(progress);
TextView connecting = new TextView(ctx);
connecting.setText(R.string.connecting_bluetooth);
innerLayout.addView(connecting);
addView(innerLayout);
}
}
}

View File

@@ -0,0 +1,65 @@
package org.briarproject.android.invitation;
import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL;
import org.briarproject.R;
import android.content.Context;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
class ContactDetailsView extends AddContactView {
ContactDetailsView(Context ctx) {
super(ctx);
}
void populate() {
removeAllViews();
Context ctx = getContext();
LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER);
ImageView icon = new ImageView(ctx);
icon.setImageResource(R.drawable.navigation_accept);
innerLayout.addView(icon);
TextView connected = new TextView(ctx);
connected.setTextSize(22);
connected.setPadding(10, 10, 10, 10);
connected.setText(R.string.connected_to_contact);
innerLayout.addView(connected);
addView(innerLayout);
TextView yourCode = new TextView(ctx);
yourCode.setGravity(CENTER_HORIZONTAL);
yourCode.setTextSize(14);
yourCode.setPadding(10, 0, 10, 10);
yourCode.setText(R.string.your_confirmation_code);
addView(yourCode);
TextView code = new TextView(ctx);
code.setGravity(CENTER_HORIZONTAL);
code.setTextSize(50);
code.setPadding(10, 0, 10, 10);
int localCode = container.getLocalConfirmationCode();
code.setText(String.format("%06d", localCode));
addView(code);
innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER);
ProgressBar progress = new ProgressBar(ctx);
progress.setIndeterminate(true);
progress.setPadding(10, 10, 10, 10);
innerLayout.addView(progress);
TextView connecting = new TextView(ctx);
connecting.setText(R.string.exchanging_contact_details);
innerLayout.addView(connecting);
addView(innerLayout);
}
}

View File

@@ -0,0 +1,42 @@
package org.briarproject.android.invitation;
import static android.view.Gravity.CENTER_HORIZONTAL;
import org.briarproject.R;
import android.content.Context;
import android.content.res.Resources;
import android.widget.TextView;
class InvitationCodeView extends AddContactView implements CodeEntryListener {
InvitationCodeView(Context ctx) {
super(ctx);
}
void populate() {
removeAllViews();
Context ctx = getContext();
TextView yourCode = new TextView(ctx);
yourCode.setGravity(CENTER_HORIZONTAL);
yourCode.setTextSize(14);
yourCode.setPadding(10, 10, 10, 10);
yourCode.setText(R.string.your_invitation_code);
addView(yourCode);
TextView code = new TextView(ctx);
code.setGravity(CENTER_HORIZONTAL);
code.setTextSize(50);
code.setPadding(10, 0, 10, 10);
int localCode = container.getLocalInvitationCode();
code.setText(String.format("%06d", localCode));
addView(code);
CodeEntryView codeEntry = new CodeEntryView(ctx);
Resources res = getResources();
codeEntry.init(this, res.getString(R.string.enter_invitation_code));
addView(codeEntry);
}
public void codeEntered(int remoteCode) {
container.remoteInvitationCodeEntered(remoteCode);
}
}

View File

@@ -0,0 +1,121 @@
package org.briarproject.android.invitation;
import static android.view.Gravity.CENTER;
import static org.briarproject.android.identity.LocalAuthorItem.NEW;
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP;
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP;
import org.briarproject.R;
import org.briarproject.android.identity.CreateIdentityActivity;
import org.briarproject.android.identity.LocalAuthorItem;
import org.briarproject.android.identity.LocalAuthorSpinnerAdapter;
import org.briarproject.api.AuthorId;
import android.content.Context;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
class NetworkSetupView extends AddContactView
implements OnItemSelectedListener, OnClickListener {
private LocalAuthorSpinnerAdapter adapter = null;
private Spinner spinner = null;
private WifiStatusView wifi = null;
private BluetoothStatusView bluetooth = null;
private Button continueButton = null;
NetworkSetupView(Context ctx) {
super(ctx);
}
void populate() {
removeAllViews();
Context ctx = getContext();
LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setLayoutParams(MATCH_WRAP);
innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER);
TextView yourNickname = new TextView(ctx);
yourNickname.setTextSize(18);
yourNickname.setPadding(10, 10, 10, 10);
yourNickname.setText(R.string.your_nickname);
innerLayout.addView(yourNickname);
adapter = new LocalAuthorSpinnerAdapter(ctx, false);
spinner = new Spinner(ctx);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
container.loadLocalAuthors(adapter);
innerLayout.addView(spinner);
addView(innerLayout);
wifi = new WifiStatusView(ctx);
wifi.init();
addView(wifi);
bluetooth = new BluetoothStatusView(ctx);
bluetooth.init();
addView(bluetooth);
TextView faceToFace = new TextView(ctx);
faceToFace.setGravity(CENTER);
faceToFace.setTextSize(14);
faceToFace.setPadding(10, 10, 10, 10);
faceToFace.setText(R.string.fact_to_face);
addView(faceToFace);
continueButton = new Button(ctx);
continueButton.setLayoutParams(WRAP_WRAP);
continueButton.setText(R.string.continue_button);
continueButton.setOnClickListener(this);
enableOrDisableContinueButton();
addView(continueButton);
}
void wifiStateChanged() {
if(wifi != null) wifi.populate();
enableOrDisableContinueButton();
}
void bluetoothStateChanged() {
if(bluetooth != null) bluetooth.populate();
enableOrDisableContinueButton();
}
private void enableOrDisableContinueButton() {
if(continueButton == null) return; // Activity not created yet
AuthorId localAuthorId = container.getLocalAuthorId();
boolean bluetoothEnabled = container.isBluetoothEnabled();
String networkName = container.getNetworkName();
boolean networkAvailable = bluetoothEnabled || networkName != null;
continueButton.setEnabled(localAuthorId != null && networkAvailable);
}
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
LocalAuthorItem item = adapter.getItem(position);
if(item == NEW) {
container.setLocalAuthorId(null);
Intent i = new Intent(container, CreateIdentityActivity.class);
container.startActivity(i);
} else {
container.setLocalAuthorId(item.getLocalAuthor().getId());
}
enableOrDisableContinueButton();
}
public void onNothingSelected(AdapterView<?> parent) {
container.setLocalAuthorId(null);
}
public void onClick(View view) {
container.setView(new InvitationCodeView(container));
}
}

View File

@@ -0,0 +1,65 @@
package org.briarproject.android.invitation;
import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL;
import org.briarproject.R;
import android.content.Context;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
class WaitForContactView extends AddContactView {
WaitForContactView(Context ctx) {
super(ctx);
}
void populate() {
removeAllViews();
Context ctx = getContext();
LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER);
ImageView icon = new ImageView(ctx);
icon.setImageResource(R.drawable.navigation_accept);
innerLayout.addView(icon);
TextView connected = new TextView(ctx);
connected.setTextSize(22);
connected.setPadding(10, 10, 10, 10);
connected.setText(R.string.connected_to_contact);
innerLayout.addView(connected);
addView(innerLayout);
TextView yourCode = new TextView(ctx);
yourCode.setGravity(CENTER_HORIZONTAL);
yourCode.setTextSize(14);
yourCode.setPadding(10, 0, 10, 10);
yourCode.setText(R.string.your_confirmation_code);
addView(yourCode);
TextView code = new TextView(ctx);
code.setGravity(CENTER_HORIZONTAL);
code.setTextSize(50);
code.setPadding(10, 0, 10, 10);
int localCode = container.getLocalConfirmationCode();
code.setText(String.format("%06d", localCode));
addView(code);
innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER);
ProgressBar progress = new ProgressBar(ctx);
progress.setIndeterminate(true);
progress.setPadding(10, 10, 10, 10);
innerLayout.addView(progress);
TextView connecting = new TextView(ctx);
connecting.setText(R.string.waiting_for_contact);
innerLayout.addView(connecting);
addView(innerLayout);
}
}

View File

@@ -0,0 +1,92 @@
package org.briarproject.android.invitation;
import static android.content.Context.WIFI_SERVICE;
import static android.provider.Settings.ACTION_WIFI_SETTINGS;
import static android.view.Gravity.CENTER;
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
import org.briarproject.R;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
class WifiStatusView extends LinearLayout implements OnClickListener {
public WifiStatusView(Context ctx) {
super(ctx);
}
void init() {
setOrientation(HORIZONTAL);
setGravity(CENTER);
populate();
}
void populate() {
removeAllViews();
Context ctx = getContext();
TextView status = new TextView(ctx);
status.setTextSize(14);
status.setPadding(10, 10, 10, 10);
status.setLayoutParams(WRAP_WRAP_1);
WifiManager wifi = (WifiManager) ctx.getSystemService(WIFI_SERVICE);
if(wifi == null) {
ImageView warning = new ImageView(ctx);
warning.setPadding(5, 5, 5, 5);
warning.setImageResource(R.drawable.alerts_and_states_warning);
addView(warning);
status.setText(R.string.wifi_not_available);
addView(status);
} else if(wifi.isWifiEnabled()) {
WifiInfo info = wifi.getConnectionInfo();
String networkName = info.getSSID();
int networkId = info.getNetworkId();
if(networkName == null || networkId == -1) {
ImageView warning = new ImageView(ctx);
warning.setPadding(5, 5, 5, 5);
warning.setImageResource(R.drawable.alerts_and_states_warning);
addView(warning);
status.setText(R.string.wifi_disconnected);
addView(status);
ImageButton settings = new ImageButton(ctx);
settings.setImageResource(R.drawable.action_settings);
settings.setOnClickListener(this);
addView(settings);
} else {
ImageView ok = new ImageView(ctx);
ok.setPadding(5, 5, 5, 5);
ok.setImageResource(R.drawable.navigation_accept);
addView(ok);
String format = getResources().getString(
R.string.format_wifi_connected);
status.setText(String.format(format, networkName));
addView(status);
ImageButton settings = new ImageButton(ctx);
settings.setImageResource(R.drawable.action_settings);
settings.setOnClickListener(this);
addView(settings);
}
} else {
ImageView warning = new ImageView(ctx);
warning.setPadding(5, 5, 5, 5);
warning.setImageResource(R.drawable.alerts_and_states_warning);
addView(warning);
status.setText(R.string.wifi_disabled);
addView(status);
ImageButton settings = new ImageButton(ctx);
settings.setImageResource(R.drawable.action_settings);
settings.setOnClickListener(this);
addView(settings);
}
}
public void onClick(View view) {
getContext().startActivity(new Intent(ACTION_WIFI_SETTINGS));
}
}