Skip to content
Snippets Groups Projects
Commit 8fffc93b authored by akwizgran's avatar akwizgran
Browse files

Rewrote Android invitation wizard to use Views instead of Activities.

parent 538c3e1b
No related branches found
No related tags found
No related merge requests found
Showing
with 592 additions and 252 deletions
...@@ -32,35 +32,7 @@ ...@@ -32,35 +32,7 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name=".android.invitation.NetworkSetupActivity" android:name=".android.invitation.AddContactActivity"
android:label="@string/add_a_contact" >
</activity>
<activity
android:name=".android.invitation.InvitationCodeActivity"
android:label="@string/add_a_contact" >
</activity>
<activity
android:name=".android.invitation.ConnectionActivity"
android:label="@string/add_a_contact" >
</activity>
<activity
android:name=".android.invitation.ConnectionFailedActivity"
android:label="@string/add_a_contact" >
</activity>
<activity
android:name=".android.invitation.ConfirmationCodeActivity"
android:label="@string/add_a_contact" >
</activity>
<activity
android:name=".android.invitation.WaitForContactActivity"
android:label="@string/add_a_contact" >
</activity>
<activity
android:name=".android.invitation.CodesDoNotMatchActivity"
android:label="@string/add_a_contact" >
</activity>
<activity
android:name=".android.invitation.ContactAddedActivity"
android:label="@string/add_a_contact" > android:label="@string/add_a_contact" >
</activity> </activity>
</application> </application>
......
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
<string-array name="roboguice_modules"> <string-array name="roboguice_modules">
<item>net.sf.briar.android.AndroidModule</item> <item>net.sf.briar.android.AndroidModule</item>
<item>net.sf.briar.android.helloworld.HelloWorldModule</item> <item>net.sf.briar.android.helloworld.HelloWorldModule</item>
<item>net.sf.briar.android.invitation.AndroidInvitationModule</item>
<item>net.sf.briar.clock.ClockModule</item> <item>net.sf.briar.clock.ClockModule</item>
<item>net.sf.briar.crypto.CryptoModule</item> <item>net.sf.briar.crypto.CryptoModule</item>
<item>net.sf.briar.db.DatabaseModule</item> <item>net.sf.briar.db.DatabaseModule</item>
<item>net.sf.briar.invitation.InvitationModule</item>
<item>net.sf.briar.lifecycle.LifecycleModule</item> <item>net.sf.briar.lifecycle.LifecycleModule</item>
<item>net.sf.briar.plugins.PluginsModule</item> <item>net.sf.briar.plugins.PluginsModule</item>
<item>net.sf.briar.protocol.ProtocolModule</item> <item>net.sf.briar.protocol.ProtocolModule</item>
......
...@@ -9,7 +9,7 @@ import static java.util.logging.Level.INFO; ...@@ -9,7 +9,7 @@ import static java.util.logging.Level.INFO;
import java.util.logging.Logger; import java.util.logging.Logger;
import net.sf.briar.R; import net.sf.briar.R;
import net.sf.briar.android.invitation.NetworkSetupActivity; import net.sf.briar.android.invitation.AddContactActivity;
import roboguice.activity.RoboActivity; import roboguice.activity.RoboActivity;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
...@@ -66,6 +66,6 @@ implements OnClickListener { ...@@ -66,6 +66,6 @@ implements OnClickListener {
} }
public void onClick(View view) { public void onClick(View view) {
startActivity(new Intent(this, NetworkSetupActivity.class)); startActivity(new Intent(this, AddContactActivity.class));
} }
} }
package net.sf.briar.android.invitation;
import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.invitation.ConfirmationCallback;
import net.sf.briar.api.invitation.ConnectionCallback;
import net.sf.briar.api.invitation.InvitationManager;
import roboguice.activity.RoboActivity;
import com.google.inject.Inject;
public class AddContactActivity extends RoboActivity
implements ConnectionCallback, ConfirmationCallback {
@Inject private CryptoComponent crypto;
@Inject private InvitationManager invitationManager;
// All of the following must be accessed on the UI thread
private AddContactView view = null;
private String networkName = null;
private boolean useBluetooth = false;
private int localInvitationCode = -1;
private int localConfirmationCode = -1, remoteConfirmationCode = -1;
private ConfirmationCallback callback = null;
private boolean localMatched = false;
private boolean remoteCompared = false, remoteMatched = false;
@Override
public void onResume() {
super.onResume();
if(view == null) setView(new NetworkSetupView(this));
else view.populate();
}
void setView(AddContactView view) {
this.view = view;
view.init(this);
setContentView(view);
}
void setNetworkName(String networkName) {
this.networkName = networkName;
}
String getNetworkName() {
return networkName;
}
void setUseBluetooth(boolean useBluetooth) {
this.useBluetooth = useBluetooth;
}
boolean getUseBluetooth() {
return useBluetooth;
}
int generateLocalInvitationCode() {
localInvitationCode = crypto.generateInvitationCode();
return localInvitationCode;
}
int getLocalInvitationCode() {
return localInvitationCode;
}
void remoteInvitationCodeEntered(int code) {
setView(new ConnectionView(this));
localMatched = remoteCompared = remoteMatched = false;
invitationManager.connect(localInvitationCode, code, this);
}
int getLocalConfirmationCode() {
return localConfirmationCode;
}
void remoteConfirmationCodeEntered(int code) {
if(code == remoteConfirmationCode) {
localMatched = true;
if(remoteMatched) setView(new ContactAddedView(this));
else if(remoteCompared) setView(new CodesDoNotMatchView(this));
else setView(new WaitForContactView(this));
callback.codesMatch();
} else {
setView(new CodesDoNotMatchView(this));
callback.codesDoNotMatch();
}
}
public void connectionEstablished(final int localCode, final int remoteCode,
final ConfirmationCallback c) {
runOnUiThread(new Runnable() {
public void run() {
localConfirmationCode = localCode;
remoteConfirmationCode = remoteCode;
callback = c;
setView(new ConfirmationCodeView(AddContactActivity.this));
}
});
}
public void connectionNotEstablished() {
runOnUiThread(new Runnable() {
public void run() {
setView(new ConnectionFailedView(AddContactActivity.this));
}
});
}
public void codesMatch() {
runOnUiThread(new Runnable() {
public void run() {
remoteCompared = true;
remoteMatched = true;
if(localMatched)
setView(new ContactAddedView(AddContactActivity.this));
}
});
}
public void codesDoNotMatch() {
runOnUiThread(new Runnable() {
public void run() {
remoteCompared = true;
if(localMatched)
setView(new CodesDoNotMatchView(AddContactActivity.this));
}
});
}
}
package net.sf.briar.android.invitation;
import static android.view.Gravity.CENTER_HORIZONTAL;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import android.content.Context;
import android.widget.LinearLayout;
abstract class AddContactView extends LinearLayout {
protected AddContactActivity container = null;
AddContactView(Context context) {
super(context);
}
void init(AddContactActivity container) {
this.container = container;
setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT));
setOrientation(VERTICAL);
setGravity(CENTER_HORIZONTAL);
populate();
}
abstract void populate();
}
package net.sf.briar.android.invitation;
import javax.inject.Singleton;
import com.google.inject.AbstractModule;
public class AndroidInvitationModule extends AbstractModule {
@Override
protected void configure() {
bind(InvitationManager.class).to(InvitationManagerImpl.class).in(
Singleton.class);
}
}
...@@ -2,5 +2,5 @@ package net.sf.briar.android.invitation; ...@@ -2,5 +2,5 @@ package net.sf.briar.android.invitation;
interface CodeEntryListener { interface CodeEntryListener {
void codeEntered(String code); void codeEntered(int remoteCode);
} }
...@@ -3,6 +3,7 @@ package net.sf.briar.android.invitation; ...@@ -3,6 +3,7 @@ package net.sf.briar.android.invitation;
import static android.text.InputType.TYPE_CLASS_NUMBER; import static android.text.InputType.TYPE_CLASS_NUMBER;
import static android.view.Gravity.CENTER; import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL; import static android.view.Gravity.CENTER_HORIZONTAL;
import static net.sf.briar.api.plugins.InvitationConstants.MAX_CODE;
import net.sf.briar.R; import net.sf.briar.R;
import android.content.Context; import android.content.Context;
import android.view.KeyEvent; import android.view.KeyEvent;
...@@ -53,6 +54,7 @@ OnEditorActionListener, OnClickListener { ...@@ -53,6 +54,7 @@ OnEditorActionListener, OnClickListener {
codeEntry.setMaxEms(5); codeEntry.setMaxEms(5);
codeEntry.setMaxLines(1); codeEntry.setMaxLines(1);
codeEntry.setInputType(TYPE_CLASS_NUMBER); codeEntry.setInputType(TYPE_CLASS_NUMBER);
codeEntry.requestFocus();
LinearLayout innerLayout = new LinearLayout(ctx); LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL); innerLayout.setOrientation(HORIZONTAL);
...@@ -63,16 +65,24 @@ OnEditorActionListener, OnClickListener { ...@@ -63,16 +65,24 @@ OnEditorActionListener, OnClickListener {
} }
public boolean onEditorAction(TextView textView, int actionId, KeyEvent e) { public boolean onEditorAction(TextView textView, int actionId, KeyEvent e) {
validateAndReturnCode(); if(!validateAndReturnCode()) codeEntry.setText("");
return true; return true;
} }
public void onClick(View view) { public void onClick(View view) {
validateAndReturnCode(); if(!validateAndReturnCode()) codeEntry.setText("");
} }
private void validateAndReturnCode() { private boolean validateAndReturnCode() {
CharSequence code = codeEntry.getText(); String remoteCodeString = codeEntry.getText().toString();
if(code.length() == 6) listener.codeEntered(code.toString()); int remoteCode;
try {
remoteCode = Integer.valueOf(remoteCodeString);
} catch(NumberFormatException e) {
return false;
}
if(remoteCode < 0 || remoteCode > MAX_CODE) return false;
listener.codeEntered(remoteCode);
return true;
} }
} }
...@@ -2,68 +2,57 @@ package net.sf.briar.android.invitation; ...@@ -2,68 +2,57 @@ package net.sf.briar.android.invitation;
import static android.view.Gravity.CENTER; import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL; import static android.view.Gravity.CENTER_HORIZONTAL;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
import net.sf.briar.R; import net.sf.briar.R;
import android.app.Activity; import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
public class CodesDoNotMatchActivity extends Activity public class CodesDoNotMatchView extends AddContactView
implements OnClickListener { implements OnClickListener {
@Override CodesDoNotMatchView(Context ctx) {
public void onCreate(Bundle savedInstanceState) { super(ctx);
super.onCreate(savedInstanceState); }
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT));
layout.setOrientation(VERTICAL);
layout.setGravity(CENTER_HORIZONTAL);
LinearLayout innerLayout = new LinearLayout(this); void populate() {
removeAllViews();
Context ctx = getContext();
LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL); innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER); innerLayout.setGravity(CENTER);
ImageView icon = new ImageView(this); ImageView icon = new ImageView(ctx);
icon.setPadding(10, 10, 10, 10); icon.setPadding(10, 10, 10, 10);
icon.setImageResource(R.drawable.alerts_and_states_error); icon.setImageResource(R.drawable.alerts_and_states_error);
innerLayout.addView(icon); innerLayout.addView(icon);
TextView failed = new TextView(this); TextView failed = new TextView(ctx);
failed.setTextSize(20); failed.setTextSize(20);
failed.setText(R.string.codes_do_not_match); failed.setText(R.string.codes_do_not_match);
innerLayout.addView(failed); innerLayout.addView(failed);
layout.addView(innerLayout); addView(innerLayout);
TextView interfering = new TextView(this); TextView interfering = new TextView(ctx);
interfering.setGravity(CENTER_HORIZONTAL); interfering.setGravity(CENTER_HORIZONTAL);
interfering.setPadding(0, 0, 0, 10); interfering.setPadding(0, 0, 0, 10);
interfering.setText(R.string.interfering); interfering.setText(R.string.interfering);
layout.addView(interfering); addView(interfering);
Button tryAgain = new Button(this); Button tryAgain = new Button(ctx);
LayoutParams lp = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT); LayoutParams lp = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
tryAgain.setLayoutParams(lp); tryAgain.setLayoutParams(lp);
tryAgain.setText(R.string.try_again_button); tryAgain.setText(R.string.try_again_button);
tryAgain.setOnClickListener(this); tryAgain.setOnClickListener(this);
layout.addView(tryAgain); addView(tryAgain);
setContentView(layout);
} }
public void onClick(View view) { public void onClick(View view) {
Intent intent = new Intent(this, InvitationCodeActivity.class); // Try again
intent.putExtras(getIntent().getExtras()); container.setView(new NetworkSetupView(container));
startActivity(intent);
finish();
} }
} }
...@@ -2,78 +2,57 @@ package net.sf.briar.android.invitation; ...@@ -2,78 +2,57 @@ package net.sf.briar.android.invitation;
import static android.view.Gravity.CENTER; import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL; import static android.view.Gravity.CENTER_HORIZONTAL;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
import net.sf.briar.R; import net.sf.briar.R;
import roboguice.activity.RoboActivity; import android.content.Context;
import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Bundle;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import com.google.inject.Inject; public class ConfirmationCodeView extends AddContactView
public class ConfirmationCodeActivity extends RoboActivity
implements CodeEntryListener { implements CodeEntryListener {
@Inject private InvitationManager manager; ConfirmationCodeView(Context ctx) {
super(ctx);
@Override }
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT));
layout.setOrientation(VERTICAL);
layout.setGravity(CENTER_HORIZONTAL);
LinearLayout innerLayout = new LinearLayout(this); void populate() {
removeAllViews();
Context ctx = getContext();
LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL); innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER); innerLayout.setGravity(CENTER);
ImageView icon = new ImageView(this); ImageView icon = new ImageView(ctx);
icon.setPadding(10, 10, 10, 10); icon.setPadding(10, 10, 10, 10);
icon.setImageResource(R.drawable.navigation_accept); icon.setImageResource(R.drawable.navigation_accept);
innerLayout.addView(icon); innerLayout.addView(icon);
TextView connected = new TextView(this); TextView connected = new TextView(ctx);
connected.setTextSize(20); connected.setTextSize(20);
connected.setText(R.string.connected_to_contact); connected.setText(R.string.connected_to_contact);
innerLayout.addView(connected); innerLayout.addView(connected);
layout.addView(innerLayout); addView(innerLayout);
TextView yourCode = new TextView(this); TextView yourCode = new TextView(ctx);
yourCode.setGravity(CENTER_HORIZONTAL); yourCode.setGravity(CENTER_HORIZONTAL);
yourCode.setText(R.string.your_confirmation_code); yourCode.setText(R.string.your_confirmation_code);
layout.addView(yourCode); addView(yourCode);
TextView code = new TextView(this); TextView code = new TextView(ctx);
code.setGravity(CENTER_HORIZONTAL); code.setGravity(CENTER_HORIZONTAL);
code.setTextSize(50); code.setTextSize(50);
code.setText(manager.getLocalConfirmationCode()); int localCode = container.getLocalConfirmationCode();
layout.addView(code); code.setText(String.format("%06d", localCode));
addView(code);
CodeEntryWidget codeEntry = new CodeEntryWidget(this); CodeEntryWidget codeEntry = new CodeEntryWidget(ctx);
Resources res = getResources(); Resources res = getResources();
codeEntry.init(this, res.getString(R.string.enter_confirmation_code)); codeEntry.init(this, res.getString(R.string.enter_confirmation_code));
layout.addView(codeEntry); addView(codeEntry);
setContentView(layout);
} }
public void codeEntered(String code) { public void codeEntered(int remoteCode) {
if(code.equals(manager.getRemoteConfirmationCode())) { container.remoteConfirmationCodeEntered(remoteCode);
Intent intent = new Intent(this, WaitForContactActivity.class);
intent.putExtras(getIntent().getExtras());
startActivity(intent);
} else {
Intent intent = new Intent(this, CodesDoNotMatchActivity.class);
intent.putExtras(getIntent().getExtras());
startActivity(intent);
}
finish();
} }
} }
package net.sf.briar.android.invitation;
interface ConfirmationListener {
void confirmationReceived();
void confirmationNotReceived();
}
...@@ -2,108 +2,85 @@ package net.sf.briar.android.invitation; ...@@ -2,108 +2,85 @@ package net.sf.briar.android.invitation;
import static android.view.Gravity.CENTER; import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL; import static android.view.Gravity.CENTER_HORIZONTAL;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
import net.sf.briar.R; import net.sf.briar.R;
import android.app.Activity; import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
public class ConnectionFailedActivity extends Activity public class ConnectionFailedView extends AddContactView
implements WifiStateListener, BluetoothStateListener, OnClickListener { implements WifiStateListener, BluetoothStateListener, OnClickListener {
private WifiWidget wifi = null;
private BluetoothWidget bluetooth = null;
private Button tryAgainButton = null; private Button tryAgainButton = null;
private String networkName = null;
private boolean useBluetooth = false;
@Override ConnectionFailedView(Context ctx) {
public void onCreate(Bundle savedInstanceState) { super(ctx);
super.onCreate(savedInstanceState); }
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT));
layout.setOrientation(VERTICAL);
layout.setGravity(CENTER_HORIZONTAL);
LinearLayout innerLayout = new LinearLayout(this); void populate() {
removeAllViews();
Context ctx = getContext();
LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL); innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER); innerLayout.setGravity(CENTER);
ImageView icon = new ImageView(this); ImageView icon = new ImageView(ctx);
icon.setPadding(10, 10, 10, 10); icon.setPadding(10, 10, 10, 10);
icon.setImageResource(R.drawable.alerts_and_states_error); icon.setImageResource(R.drawable.alerts_and_states_error);
innerLayout.addView(icon); innerLayout.addView(icon);
TextView failed = new TextView(this); TextView failed = new TextView(ctx);
failed.setTextSize(20); failed.setTextSize(20);
failed.setText(R.string.connection_failed); failed.setText(R.string.connection_failed);
innerLayout.addView(failed); innerLayout.addView(failed);
layout.addView(innerLayout); addView(innerLayout);
TextView checkNetwork = new TextView(this); TextView checkNetwork = new TextView(ctx);
checkNetwork.setGravity(CENTER_HORIZONTAL); checkNetwork.setGravity(CENTER_HORIZONTAL);
checkNetwork.setText(R.string.check_same_network); checkNetwork.setText(R.string.check_same_network);
layout.addView(checkNetwork); addView(checkNetwork);
wifi = new WifiWidget(this); WifiWidget wifi = new WifiWidget(ctx);
wifi.init(this); wifi.init(this);
layout.addView(wifi); addView(wifi);
bluetooth = new BluetoothWidget(this); BluetoothWidget bluetooth = new BluetoothWidget(ctx);
bluetooth.init(this); bluetooth.init(this);
layout.addView(bluetooth); addView(bluetooth);
tryAgainButton = new Button(this); tryAgainButton = new Button(ctx);
LayoutParams lp = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT); LayoutParams lp = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
tryAgainButton.setLayoutParams(lp); tryAgainButton.setLayoutParams(lp);
tryAgainButton.setText(R.string.try_again_button); tryAgainButton.setText(R.string.try_again_button);
tryAgainButton.setOnClickListener(this); tryAgainButton.setOnClickListener(this);
enabledOrDisableTryAgainButton(); enabledOrDisableTryAgainButton();
layout.addView(tryAgainButton); addView(tryAgainButton);
setContentView(layout);
}
@Override
public void onResume() {
super.onResume();
wifi.populate();
bluetooth.populate();
} }
public void wifiStateChanged(String networkName) { public void wifiStateChanged(String networkName) {
this.networkName = networkName; container.setNetworkName(networkName);
enabledOrDisableTryAgainButton(); enabledOrDisableTryAgainButton();
} }
public void bluetoothStateChanged(boolean enabled) { public void bluetoothStateChanged(boolean enabled) {
useBluetooth = enabled; container.setUseBluetooth(enabled);
enabledOrDisableTryAgainButton(); enabledOrDisableTryAgainButton();
} }
private void enabledOrDisableTryAgainButton() { private void enabledOrDisableTryAgainButton() {
if(tryAgainButton == null) return; // Activity not created yet if(tryAgainButton == null) return; // Activity not created yet
boolean useBluetooth = container.getUseBluetooth();
String networkName = container.getNetworkName();
if(useBluetooth || networkName != null) tryAgainButton.setEnabled(true); if(useBluetooth || networkName != null) tryAgainButton.setEnabled(true);
else tryAgainButton.setEnabled(false); else tryAgainButton.setEnabled(false);
} }
public void onClick(View view) { public void onClick(View view) {
Intent intent = new Intent(this, InvitationCodeActivity.class); // Try again
intent.putExtra("net.sf.briar.android.invitation.NETWORK_NAME", container.setView(new InvitationCodeView(container));
networkName);
intent.putExtra("net.sf.briar.android.invitation.USE_BLUETOOTH",
useBluetooth);
startActivity(intent);
finish();
} }
} }
package net.sf.briar.android.invitation;
interface ConnectionListener {
void connectionEstablished();
void connectionNotEstablished();
}
...@@ -2,112 +2,70 @@ package net.sf.briar.android.invitation; ...@@ -2,112 +2,70 @@ package net.sf.briar.android.invitation;
import static android.view.Gravity.CENTER; import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL; import static android.view.Gravity.CENTER_HORIZONTAL;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
import net.sf.briar.R; import net.sf.briar.R;
import roboguice.activity.RoboActivity; import android.content.Context;
import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Bundle;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import com.google.inject.Inject; public class ConnectionView extends AddContactView {
public class ConnectionActivity extends RoboActivity ConnectionView(Context ctx) {
implements ConnectionListener { super(ctx);
}
@Inject private InvitationManager manager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT));
layout.setOrientation(VERTICAL);
layout.setGravity(CENTER_HORIZONTAL);
Bundle b = getIntent().getExtras();
String networkName = b.getString(
"net.sf.briar.android.invitation.NETWORK_NAME");
boolean useBluetooth = b.getBoolean(
"net.sf.briar.android.invitation.USE_BLUETOOTH");
TextView yourCode = new TextView(this); void populate() {
removeAllViews();
Context ctx = getContext();
TextView yourCode = new TextView(ctx);
yourCode.setGravity(CENTER_HORIZONTAL); yourCode.setGravity(CENTER_HORIZONTAL);
yourCode.setText(R.string.your_invitation_code); yourCode.setText(R.string.your_invitation_code);
layout.addView(yourCode); addView(yourCode);
TextView code = new TextView(this); TextView code = new TextView(ctx);
code.setGravity(CENTER_HORIZONTAL); code.setGravity(CENTER_HORIZONTAL);
code.setTextSize(50); code.setTextSize(50);
code.setText(manager.getLocalInvitationCode()); int localCode = container.getLocalInvitationCode();
layout.addView(code); code.setText(String.format("%06d", localCode));
addView(code);
String networkName = container.getNetworkName();
if(networkName != null) { if(networkName != null) {
LinearLayout innerLayout = new LinearLayout(this); LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL); innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER); innerLayout.setGravity(CENTER);
ProgressBar progress = new ProgressBar(this); ProgressBar progress = new ProgressBar(ctx);
progress.setIndeterminate(true); progress.setIndeterminate(true);
progress.setPadding(0, 10, 10, 0); progress.setPadding(0, 10, 10, 0);
innerLayout.addView(progress); innerLayout.addView(progress);
TextView connecting = new TextView(this); TextView connecting = new TextView(ctx);
Resources res = getResources(); Resources res = getResources();
String connectingVia = res.getString(R.string.connecting_wifi); String connectingVia = res.getString(R.string.connecting_wifi);
connecting.setText(String.format(connectingVia, networkName)); connecting.setText(String.format(connectingVia, networkName));
innerLayout.addView(connecting); innerLayout.addView(connecting);
layout.addView(innerLayout); addView(innerLayout);
manager.startWifiConnectionWorker(this);
} }
boolean useBluetooth = container.getUseBluetooth();
if(useBluetooth) { if(useBluetooth) {
LinearLayout innerLayout = new LinearLayout(this); LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL); innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER); innerLayout.setGravity(CENTER);
ProgressBar progress = new ProgressBar(this); ProgressBar progress = new ProgressBar(ctx);
progress.setPadding(0, 10, 10, 0); progress.setPadding(0, 10, 10, 0);
progress.setIndeterminate(true); progress.setIndeterminate(true);
innerLayout.addView(progress); innerLayout.addView(progress);
TextView connecting = new TextView(this); TextView connecting = new TextView(ctx);
connecting.setText(R.string.connecting_bluetooth); connecting.setText(R.string.connecting_bluetooth);
innerLayout.addView(connecting); innerLayout.addView(connecting);
layout.addView(innerLayout); addView(innerLayout);
manager.startBluetoothConnectionWorker(this);
} }
setContentView(layout);
manager.tryToConnect(this);
}
public void connectionEstablished() {
final Intent intent = new Intent(this, ConfirmationCodeActivity.class);
intent.putExtras(getIntent().getExtras());
runOnUiThread(new Runnable() {
public void run() {
startActivity(intent);
finish();
}
});
}
public void connectionNotEstablished() {
final Intent intent = new Intent(this, ConnectionFailedActivity.class);
runOnUiThread(new Runnable() {
public void run() {
startActivity(intent);
finish();
}
});
} }
} }
...@@ -2,17 +2,11 @@ package net.sf.briar.android.invitation; ...@@ -2,17 +2,11 @@ package net.sf.briar.android.invitation;
import static android.view.Gravity.CENTER; import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL; import static android.view.Gravity.CENTER_HORIZONTAL;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
import net.sf.briar.R; import net.sf.briar.R;
import android.app.Activity; import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
...@@ -20,43 +14,42 @@ import android.widget.LinearLayout; ...@@ -20,43 +14,42 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener; import android.widget.TextView.OnEditorActionListener;
public class ContactAddedActivity extends Activity implements OnClickListener, public class ContactAddedView extends AddContactView implements OnClickListener,
OnEditorActionListener { OnEditorActionListener {
private volatile Button done = null; private Button done = null;
@Override ContactAddedView(Context ctx) {
public void onCreate(Bundle savedInstanceState) { super(ctx);
super.onCreate(savedInstanceState); }
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT));
layout.setOrientation(VERTICAL);
layout.setGravity(CENTER_HORIZONTAL);
LinearLayout innerLayout = new LinearLayout(this); void populate() {
removeAllViews();
Context ctx = getContext();
LinearLayout innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL); innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER); innerLayout.setGravity(CENTER);
ImageView icon = new ImageView(this); ImageView icon = new ImageView(ctx);
icon.setImageResource(R.drawable.navigation_accept); icon.setImageResource(R.drawable.navigation_accept);
icon.setPadding(10, 10, 10, 10); icon.setPadding(10, 10, 10, 10);
innerLayout.addView(icon); innerLayout.addView(icon);
TextView failed = new TextView(this); TextView failed = new TextView(ctx);
failed.setText(R.string.contact_added); failed.setText(R.string.contact_added);
failed.setTextSize(20); failed.setTextSize(20);
innerLayout.addView(failed); innerLayout.addView(failed);
layout.addView(innerLayout); addView(innerLayout);
TextView enterNickname = new TextView(this); TextView enterNickname = new TextView(ctx);
enterNickname.setGravity(CENTER_HORIZONTAL); enterNickname.setGravity(CENTER_HORIZONTAL);
enterNickname.setText(R.string.enter_nickname); enterNickname.setText(R.string.enter_nickname);
layout.addView(enterNickname); addView(enterNickname);
final Button addAnother = new Button(this); final Button addAnother = new Button(ctx);
final Button done = new Button(this); final Button done = new Button(ctx);
this.done = done; this.done = done;
EditText nicknameEntry = new EditText(this) { EditText nicknameEntry = new EditText(ctx) {
@Override @Override
protected void onTextChanged(CharSequence text, int start, protected void onTextChanged(CharSequence text, int start,
int lengthBefore, int lengthAfter) { int lengthBefore, int lengthAfter) {
...@@ -68,9 +61,9 @@ OnEditorActionListener { ...@@ -68,9 +61,9 @@ OnEditorActionListener {
nicknameEntry.setMaxEms(20); nicknameEntry.setMaxEms(20);
nicknameEntry.setMaxLines(1); nicknameEntry.setMaxLines(1);
nicknameEntry.setOnEditorActionListener(this); nicknameEntry.setOnEditorActionListener(this);
layout.addView(nicknameEntry); addView(nicknameEntry);
innerLayout = new LinearLayout(this); innerLayout = new LinearLayout(ctx);
innerLayout.setOrientation(HORIZONTAL); innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER); innerLayout.setGravity(CENTER);
...@@ -83,20 +76,16 @@ OnEditorActionListener { ...@@ -83,20 +76,16 @@ OnEditorActionListener {
done.setEnabled(false); done.setEnabled(false);
done.setOnClickListener(this); done.setOnClickListener(this);
innerLayout.addView(done); innerLayout.addView(done);
layout.addView(innerLayout); addView(innerLayout);
setContentView(layout);
} }
public boolean onEditorAction(TextView textView, int actionId, KeyEvent e) { public boolean onEditorAction(TextView textView, int actionId, KeyEvent e) {
if(textView.getText().length() > 0) finish(); if(textView.getText().length() > 0) container.finish();
return true; return true;
} }
public void onClick(View view) { public void onClick(View view) {
if(done == null) return; if(view == done) container.finish(); // Done
if(view != done) else container.setView(new NetworkSetupView(container)); // Add another
startActivity(new Intent(this, NetworkSetupActivity.class));
finish();
} }
} }
package net.sf.briar.android.invitation;
import static android.view.Gravity.CENTER_HORIZONTAL;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.widget.LinearLayout.VERTICAL;
import net.sf.briar.R;
import roboguice.activity.RoboActivity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.google.inject.Inject;
public class InvitationCodeActivity extends RoboActivity
implements CodeEntryListener {
@Inject private InvitationManager manager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT));
layout.setOrientation(VERTICAL);
layout.setGravity(CENTER_HORIZONTAL);
TextView yourCode = new TextView(this);
yourCode.setGravity(CENTER_HORIZONTAL);
yourCode.setText(R.string.your_invitation_code);
layout.addView(yourCode);
TextView code = new TextView(this);
code.setGravity(CENTER_HORIZONTAL);
code.setTextSize(50);
code.setText(manager.getLocalInvitationCode());
layout.addView(code);
CodeEntryWidget codeEntry = new CodeEntryWidget(this);
Resources res = getResources();
codeEntry.init(this, res.getString(R.string.enter_invitation_code));
layout.addView(codeEntry);
setContentView(layout);
}
public void codeEntered(String code) {
manager.setRemoteInvitationCode(code);
Intent intent = new Intent(this, ConnectionActivity.class);
intent.putExtras(getIntent().getExtras());
startActivity(intent);
finish();
}
}
package net.sf.briar.android.invitation;
import static android.view.Gravity.CENTER_HORIZONTAL;
import net.sf.briar.R;
import android.content.Context;
import android.content.res.Resources;
import android.widget.TextView;
public class InvitationCodeView extends AddContactView
implements CodeEntryListener {
private int localCode = -1;
InvitationCodeView(Context ctx) {
super(ctx);
}
void init(AddContactActivity container) {
localCode = container.generateLocalInvitationCode();
super.init(container);
}
void populate() {
removeAllViews();
Context ctx = getContext();
TextView yourCode = new TextView(ctx);
yourCode.setGravity(CENTER_HORIZONTAL);
yourCode.setText(R.string.your_invitation_code);
addView(yourCode);
TextView code = new TextView(ctx);
code.setGravity(CENTER_HORIZONTAL);
code.setTextSize(50);
code.setText(String.format("%06d", localCode));
addView(code);
CodeEntryWidget codeEntry = new CodeEntryWidget(ctx);
Resources res = getResources();
codeEntry.init(this, res.getString(R.string.enter_invitation_code));
addView(codeEntry);
}
public void codeEntered(int remoteCode) {
container.remoteInvitationCodeEntered(remoteCode);
}
}
package net.sf.briar.android.invitation;
import android.content.Context;
interface InvitationManager {
int TIMEOUT = 20 * 1000;
void tryToConnect(ConnectionListener listener);
String getLocalInvitationCode();
String getRemoteInvitationCode();
void setRemoteInvitationCode(String code);
void startWifiConnectionWorker(Context ctx);
void startBluetoothConnectionWorker(Context ctx);
String getLocalConfirmationCode();
String getRemoteConfirmationCode();
void startConfirmationWorker(ConfirmationListener listener);
}
package net.sf.briar.android.invitation;
import android.content.Context;
import android.util.Log;
class InvitationManagerImpl implements InvitationManager {
public void tryToConnect(final ConnectionListener listener) {
new Thread() {
@Override
public void run() {
try {
// FIXME
Thread.sleep((long) (Math.random() * TIMEOUT));
if(Math.random() < 0.5) listener.connectionEstablished();
else listener.connectionNotEstablished();
} catch(InterruptedException e) {
Log.w(getClass().getName(), e.toString());
listener.connectionNotEstablished();
}
}
}.start();
}
public String getLocalInvitationCode() {
// FIXME
return "123456";
}
public String getRemoteInvitationCode() {
// FIXME
return "123456";
}
public void setRemoteInvitationCode(String code) {
// FIXME
}
public void startWifiConnectionWorker(Context ctx) {
// FIXME
}
public void startBluetoothConnectionWorker(Context ctx) {
// FIXME
}
public String getLocalConfirmationCode() {
// FIXME
return "123456";
}
public String getRemoteConfirmationCode() {
// FIXME
return "123456";
}
public void startConfirmationWorker(ConfirmationListener listener) {
// FIXME
try {
Thread.sleep(1000 + (int) (Math.random() * 4 * 1000));
} catch(InterruptedException e) {
Log.w(getClass().getName(), e.toString());
Thread.currentThread().interrupt();
}
listener.confirmationReceived();
}
}
package net.sf.briar.android.invitation; package net.sf.briar.android.invitation;
import static android.view.Gravity.CENTER_HORIZONTAL; import static android.view.Gravity.CENTER_HORIZONTAL;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.widget.LinearLayout.VERTICAL;
import net.sf.briar.R; import net.sf.briar.R;
import android.app.Activity; import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button; import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
public class NetworkSetupActivity extends Activity public class NetworkSetupView extends AddContactView
implements WifiStateListener, BluetoothStateListener, OnClickListener { implements WifiStateListener, BluetoothStateListener, OnClickListener {
private WifiWidget wifi = null;
private BluetoothWidget bluetooth = null;
private Button continueButton = null; private Button continueButton = null;
private String networkName = null;
private boolean useBluetooth = false;
@Override NetworkSetupView(Context ctx) {
public void onCreate(Bundle savedInstanceState) { super(ctx);
super.onCreate(savedInstanceState); }
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT));
layout.setOrientation(VERTICAL);
layout.setGravity(CENTER_HORIZONTAL);
TextView sameNetwork = new TextView(this); void populate() {
removeAllViews();
Context ctx = getContext();
TextView sameNetwork = new TextView(ctx);
sameNetwork.setGravity(CENTER_HORIZONTAL); sameNetwork.setGravity(CENTER_HORIZONTAL);
sameNetwork.setText(R.string.same_network); sameNetwork.setText(R.string.same_network);
layout.addView(sameNetwork); addView(sameNetwork);
wifi = new WifiWidget(this); WifiWidget wifi = new WifiWidget(ctx);
wifi.init(this); wifi.init(this);
layout.addView(wifi); addView(wifi);
bluetooth = new BluetoothWidget(this); BluetoothWidget bluetooth = new BluetoothWidget(ctx);
bluetooth.init(this); bluetooth.init(this);
layout.addView(bluetooth); addView(bluetooth);
continueButton = new Button(this); continueButton = new Button(ctx);
LayoutParams lp = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT); LayoutParams lp = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
continueButton.setLayoutParams(lp); continueButton.setLayoutParams(lp);
continueButton.setText(R.string.continue_button); continueButton.setText(R.string.continue_button);
continueButton.setOnClickListener(this); continueButton.setOnClickListener(this);
enableOrDisableContinueButton(); enableOrDisableContinueButton();
layout.addView(continueButton); addView(continueButton);
setContentView(layout);
}
@Override
public void onResume() {
super.onResume();
wifi.populate();
bluetooth.populate();
} }
public void wifiStateChanged(final String name) { public void wifiStateChanged(final String networkName) {
runOnUiThread(new Runnable() { container.runOnUiThread(new Runnable() {
public void run() { public void run() {
networkName = name; container.setNetworkName(networkName);
enableOrDisableContinueButton(); enableOrDisableContinueButton();
} }
}); });
} }
public void bluetoothStateChanged(final boolean enabled) { public void bluetoothStateChanged(final boolean enabled) {
runOnUiThread(new Runnable() { container.runOnUiThread(new Runnable() {
public void run() { public void run() {
useBluetooth = enabled; container.setUseBluetooth(enabled);
enableOrDisableContinueButton(); enableOrDisableContinueButton();
} }
}); });
...@@ -83,17 +63,14 @@ implements WifiStateListener, BluetoothStateListener, OnClickListener { ...@@ -83,17 +63,14 @@ implements WifiStateListener, BluetoothStateListener, OnClickListener {
private void enableOrDisableContinueButton() { private void enableOrDisableContinueButton() {
if(continueButton == null) return; // Activity not created yet if(continueButton == null) return; // Activity not created yet
boolean useBluetooth = container.getUseBluetooth();
String networkName = container.getNetworkName();
if(useBluetooth || networkName != null) continueButton.setEnabled(true); if(useBluetooth || networkName != null) continueButton.setEnabled(true);
else continueButton.setEnabled(false); else continueButton.setEnabled(false);
} }
public void onClick(View view) { public void onClick(View view) {
Intent intent = new Intent(this, InvitationCodeActivity.class); // Continue
intent.putExtra("net.sf.briar.android.invitation.NETWORK_NAME", container.setView(new InvitationCodeView(container));
networkName);
intent.putExtra("net.sf.briar.android.invitation.USE_BLUETOOTH",
useBluetooth);
startActivity(intent);
finish();
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment