mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 04:18:53 +01:00
Separated Android code and core code into distinct Eclipse projects.
This should make it possible to develop the core in Eclipse without the ADT.
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
package net.sf.briar.android;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import net.sf.briar.api.android.AndroidExecutor;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
class AndroidExecutorImpl implements AndroidExecutor {
|
||||
|
||||
private static final int SHUTDOWN = 0, RUN = 1;
|
||||
|
||||
private final Runnable loop;
|
||||
private final AtomicBoolean started = new AtomicBoolean(false);
|
||||
private final CountDownLatch startLatch = new CountDownLatch(1);
|
||||
|
||||
private volatile Handler handler = null;
|
||||
|
||||
@Inject
|
||||
AndroidExecutorImpl() {
|
||||
loop = new Runnable() {
|
||||
public void run() {
|
||||
Looper.prepare();
|
||||
handler = new FutureTaskHandler();
|
||||
startLatch.countDown();
|
||||
Looper.loop();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void startIfNecessary() {
|
||||
if(started.getAndSet(true)) return;
|
||||
new Thread(loop, "AndroidExecutor").start();
|
||||
try {
|
||||
startLatch.await();
|
||||
} catch(InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public <V> V run(Callable<V> c) throws InterruptedException,
|
||||
ExecutionException {
|
||||
startIfNecessary();
|
||||
Future<V> f = new FutureTask<V>(c);
|
||||
Message m = Message.obtain(handler, RUN, f);
|
||||
handler.sendMessage(m);
|
||||
return f.get();
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
if(handler != null) {
|
||||
Message m = Message.obtain(handler, SHUTDOWN);
|
||||
handler.sendMessage(m);
|
||||
}
|
||||
}
|
||||
|
||||
private static class FutureTaskHandler extends Handler {
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message m) {
|
||||
switch(m.what) {
|
||||
case SHUTDOWN:
|
||||
Looper.myLooper().quit();
|
||||
break;
|
||||
case RUN:
|
||||
((FutureTask<?>) m.obj).run();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
briar-android/src/net/sf/briar/android/AndroidModule.java
Normal file
13
briar-android/src/net/sf/briar/android/AndroidModule.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package net.sf.briar.android;
|
||||
|
||||
import net.sf.briar.api.android.AndroidExecutor;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
|
||||
public class AndroidModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(AndroidExecutor.class).to(AndroidExecutorImpl.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package net.sf.briar.android.helloworld;
|
||||
|
||||
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.widget.LinearLayout.VERTICAL;
|
||||
import static java.util.logging.Level.INFO;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.sf.briar.R;
|
||||
import net.sf.briar.android.invitation.AddContactActivity;
|
||||
import roboguice.activity.RoboActivity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout.LayoutParams;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class HelloWorldActivity extends RoboActivity
|
||||
implements OnClickListener {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(HelloWorldActivity.class.getName());
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Created");
|
||||
LinearLayout layout = new LinearLayout(this);
|
||||
layout.setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT));
|
||||
layout.setOrientation(VERTICAL);
|
||||
layout.setGravity(CENTER_HORIZONTAL);
|
||||
|
||||
TextView welcome = new TextView(this);
|
||||
welcome.setPadding(0, 0, 0, 10);
|
||||
welcome.setText(R.string.welcome);
|
||||
layout.addView(welcome);
|
||||
|
||||
TextView faceToFace = new TextView(this);
|
||||
faceToFace.setPadding(0, 0, 0, 10);
|
||||
faceToFace.setText(R.string.face_to_face);
|
||||
layout.addView(faceToFace);
|
||||
|
||||
Button addContact = new Button(this);
|
||||
LayoutParams lp = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
|
||||
addContact.setLayoutParams(lp);
|
||||
addContact.setText(R.string.add_contact_button);
|
||||
addContact.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.social_add_person, 0, 0, 0);
|
||||
addContact.setOnClickListener(this);
|
||||
layout.addView(addContact);
|
||||
|
||||
setContentView(layout);
|
||||
|
||||
startService(new Intent(HelloWorldService.class.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Destroyed");
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
startActivity(new Intent(this, AddContactActivity.class));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package net.sf.briar.android.helloworld;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import net.sf.briar.api.crypto.Password;
|
||||
import net.sf.briar.api.db.DatabaseConfig;
|
||||
import net.sf.briar.api.ui.UiCallback;
|
||||
import android.app.Application;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
public class HelloWorldModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(UiCallback.class).toInstance(new UiCallback() {
|
||||
|
||||
public int showChoice(String[] options, String... message) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public boolean showConfirmationMessage(String... message) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void showMessage(String... message) {}
|
||||
});
|
||||
}
|
||||
|
||||
@Provides @Singleton
|
||||
DatabaseConfig getDatabaseConfig(final Application app) {
|
||||
return new DatabaseConfig() {
|
||||
|
||||
public File getDataDirectory() {
|
||||
return app.getApplicationContext().getDir("db", MODE_PRIVATE);
|
||||
}
|
||||
|
||||
public Password getPassword() {
|
||||
return new Password() {
|
||||
|
||||
public char[] getPassword() {
|
||||
return "foo bar".toCharArray();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public long getMaxSize() {
|
||||
return Long.MAX_VALUE;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package net.sf.briar.android.helloworld;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.sf.briar.api.crypto.KeyManager;
|
||||
import net.sf.briar.api.db.DatabaseComponent;
|
||||
import net.sf.briar.api.db.DbException;
|
||||
import net.sf.briar.api.plugins.PluginManager;
|
||||
import roboguice.service.RoboService;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
public class HelloWorldService extends RoboService {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(HelloWorldService.class.getName());
|
||||
|
||||
@Inject private DatabaseComponent db;
|
||||
@Inject private KeyManager keyManager;
|
||||
@Inject private PluginManager pluginManager;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Created");
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
startServices();
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Started");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Bound");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Destroyed");
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
stopServices();
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
private void startServices() {
|
||||
try {
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Starting");
|
||||
db.open(false);
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Database opened");
|
||||
keyManager.start();
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Key manager started");
|
||||
int pluginsStarted = pluginManager.start(this);
|
||||
if(LOG.isLoggable(INFO))
|
||||
LOG.info(pluginsStarted + " plugins started");
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void stopServices() {
|
||||
try {
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Shutting down");
|
||||
int pluginsStopped = pluginManager.stop();
|
||||
if(LOG.isLoggable(INFO))
|
||||
LOG.info(pluginsStopped + " plugins stopped");
|
||||
keyManager.stop();
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Key manager stopped");
|
||||
db.close();
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Database closed");
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
package net.sf.briar.android.invitation;
|
||||
|
||||
import net.sf.briar.api.crypto.CryptoComponent;
|
||||
import net.sf.briar.api.invitation.InvitationListener;
|
||||
import net.sf.briar.api.invitation.InvitationManager;
|
||||
import net.sf.briar.api.invitation.InvitationState;
|
||||
import net.sf.briar.api.invitation.InvitationTask;
|
||||
import roboguice.activity.RoboActivity;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
public class AddContactActivity extends RoboActivity
|
||||
implements InvitationListener {
|
||||
|
||||
@Inject private CryptoComponent crypto;
|
||||
@Inject private InvitationManager invitationManager;
|
||||
|
||||
// All of the following must be accessed on the UI thread
|
||||
private AddContactView view = null;
|
||||
private InvitationTask task = null;
|
||||
private String networkName = null;
|
||||
private boolean useBluetooth = false;
|
||||
private int localInvitationCode = -1, remoteInvitationCode = -1;
|
||||
private int localConfirmationCode = -1, remoteConfirmationCode = -1;
|
||||
private boolean connectionFailed = false;
|
||||
private boolean localCompared = false, remoteCompared = false;
|
||||
private boolean localMatched = false, remoteMatched = false;
|
||||
|
||||
@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
|
||||
networkName = state.getString("net.sf.briar.NETWORK_NAME");
|
||||
useBluetooth = state.getBoolean("net.sf.briar.USE_BLUETOOTH");
|
||||
int handle = state.getInt("TASK_HANDLE", -1);
|
||||
task = invitationManager.getTask(handle);
|
||||
if(task == null) {
|
||||
// No background task - we must be in an initial or final state
|
||||
localInvitationCode = state.getInt("net.sf.briar.LOCAL_CODE");
|
||||
remoteInvitationCode = state.getInt("net.sf.briar.REMOTE_CODE");
|
||||
connectionFailed = state.getBoolean("net.sf.briar.FAILED");
|
||||
if(state.getBoolean("net.sf.briar.MATCHED")) {
|
||||
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(localMatched && remoteMatched) {
|
||||
setView(new ContactAddedView(this));
|
||||
} else {
|
||||
setView(new CodesDoNotMatchView(this));
|
||||
}
|
||||
} 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();
|
||||
connectionFailed = s.getConnectionFailed();
|
||||
localCompared = s.getLocalCompared();
|
||||
remoteCompared = s.getRemoteCompared();
|
||||
localMatched = s.getLocalMatched();
|
||||
remoteMatched = s.getRemoteMatched();
|
||||
// Set the appropriate view for the state
|
||||
if(localInvitationCode == -1) {
|
||||
setView(new NetworkSetupView(this));
|
||||
} else if(remoteInvitationCode == -1) {
|
||||
setView(new InvitationCodeView(this));
|
||||
} else if(localConfirmationCode == -1) {
|
||||
setView(new ConnectionView(this));
|
||||
} else if(connectionFailed) {
|
||||
setView(new ConnectionFailedView(this));
|
||||
} else if(!localCompared) {
|
||||
setView(new ConfirmationCodeView(this));
|
||||
} else if(!remoteCompared) {
|
||||
setView(new WaitForContactView(this));
|
||||
} else if(localMatched && remoteMatched) {
|
||||
setView(new ContactAddedView(this));
|
||||
} else {
|
||||
setView(new CodesDoNotMatchView(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
view.populate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle state) {
|
||||
super.onSaveInstanceState(state);
|
||||
state.putString("net.sf.briar.NETWORK_NAME", networkName);
|
||||
state.putBoolean("net.sf.briar.USE_BLUETOOTH", useBluetooth);
|
||||
state.putInt("net.sf.briar.LOCAL_CODE", localInvitationCode);
|
||||
state.putInt("net.sf.briar.REMOTE_CODE", remoteInvitationCode);
|
||||
state.putBoolean("net.sf.briar.FAILED", connectionFailed);
|
||||
state.putBoolean("net.sf.briar.MATCHED", localMatched && remoteMatched);
|
||||
if(task != null) state.putInt("TASK_HANDLE", task.getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if(task != null) task.removeListener(this);
|
||||
}
|
||||
|
||||
void setView(AddContactView view) {
|
||||
this.view = view;
|
||||
view.init(this);
|
||||
setContentView(view);
|
||||
}
|
||||
|
||||
void reset(AddContactView view) {
|
||||
task = null;
|
||||
networkName = null;
|
||||
useBluetooth = false;
|
||||
localInvitationCode = -1;
|
||||
localConfirmationCode = remoteConfirmationCode = -1;
|
||||
connectionFailed = false;
|
||||
localCompared = remoteCompared = false;
|
||||
localMatched = remoteMatched = false;
|
||||
setView(view);
|
||||
}
|
||||
|
||||
void setNetworkName(String networkName) {
|
||||
this.networkName = networkName;
|
||||
}
|
||||
|
||||
String getNetworkName() {
|
||||
return networkName;
|
||||
}
|
||||
|
||||
void setUseBluetooth(boolean useBluetooth) {
|
||||
this.useBluetooth = useBluetooth;
|
||||
}
|
||||
|
||||
boolean getUseBluetooth() {
|
||||
return useBluetooth;
|
||||
}
|
||||
|
||||
int getLocalInvitationCode() {
|
||||
if(localInvitationCode == -1)
|
||||
localInvitationCode = crypto.generateInvitationCode();
|
||||
return localInvitationCode;
|
||||
}
|
||||
|
||||
void remoteInvitationCodeEntered(int code) {
|
||||
setView(new ConnectionView(this));
|
||||
// FIXME: These calls are blocking the UI thread for too long
|
||||
task = invitationManager.createTask(localInvitationCode, code);
|
||||
task.addListener(AddContactActivity.this);
|
||||
task.connect();
|
||||
}
|
||||
|
||||
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));
|
||||
task.localConfirmationSucceeded();
|
||||
} else {
|
||||
setView(new CodesDoNotMatchView(this));
|
||||
task.localConfirmationFailed();
|
||||
}
|
||||
}
|
||||
|
||||
public void connectionSucceeded(final int localCode, final int remoteCode) {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
localConfirmationCode = localCode;
|
||||
remoteConfirmationCode = remoteCode;
|
||||
setView(new ConfirmationCodeView(AddContactActivity.this));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void connectionFailed() {
|
||||
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 ContactAddedView(AddContactActivity.this));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void remoteConfirmationFailed() {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
remoteCompared = true;
|
||||
if(localMatched)
|
||||
setView(new CodesDoNotMatchView(AddContactActivity.this));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
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();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package net.sf.briar.android.invitation;
|
||||
|
||||
interface BluetoothStateListener {
|
||||
|
||||
void bluetoothStateChanged(boolean enabled);
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package net.sf.briar.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 android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
import net.sf.briar.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;
|
||||
|
||||
public class BluetoothWidget extends LinearLayout implements OnClickListener {
|
||||
|
||||
private BluetoothStateListener listener = null;
|
||||
|
||||
public BluetoothWidget(Context ctx) {
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
void init(BluetoothStateListener listener) {
|
||||
this.listener = listener;
|
||||
setOrientation(HORIZONTAL);
|
||||
setGravity(CENTER);
|
||||
populate();
|
||||
}
|
||||
|
||||
void populate() {
|
||||
removeAllViews();
|
||||
Context ctx = getContext();
|
||||
TextView status = new TextView(ctx);
|
||||
status.setLayoutParams(new LayoutParams(WRAP_CONTENT, WRAP_CONTENT, 1));
|
||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
if(adapter == null) {
|
||||
bluetoothStateChanged(false);
|
||||
ImageView warning = new ImageView(ctx);
|
||||
warning.setImageResource(R.drawable.alerts_and_states_warning);
|
||||
warning.setPadding(10, 10, 10, 10);
|
||||
addView(warning);
|
||||
status.setText(R.string.bluetooth_not_available);
|
||||
addView(status);
|
||||
} else if(adapter.getScanMode() == SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
|
||||
bluetoothStateChanged(true);
|
||||
ImageView ok = new ImageView(ctx);
|
||||
ok.setImageResource(R.drawable.navigation_accept);
|
||||
ok.setPadding(10, 10, 10, 10);
|
||||
addView(ok);
|
||||
status.setText(R.string.bluetooth_enabled);
|
||||
addView(status);
|
||||
ImageButton settings = new ImageButton(ctx);
|
||||
settings.setImageResource(R.drawable.action_settings);
|
||||
settings.setOnClickListener(this);
|
||||
addView(settings);
|
||||
} else if(adapter.isEnabled()) {
|
||||
bluetoothStateChanged(false);
|
||||
ImageView warning = new ImageView(ctx);
|
||||
warning.setImageResource(R.drawable.alerts_and_states_warning);
|
||||
warning.setPadding(10, 10, 10, 10);
|
||||
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 {
|
||||
bluetoothStateChanged(false);
|
||||
ImageView warning = new ImageView(ctx);
|
||||
warning.setImageResource(R.drawable.alerts_and_states_warning);
|
||||
warning.setPadding(10, 10, 10, 10);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private void bluetoothStateChanged(boolean enabled) {
|
||||
listener.bluetoothStateChanged(enabled);
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
getContext().startActivity(new Intent(ACTION_BLUETOOTH_SETTINGS));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package net.sf.briar.android.invitation;
|
||||
|
||||
interface CodeEntryListener {
|
||||
|
||||
void codeEntered(int remoteCode);
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package net.sf.briar.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 net.sf.briar.api.plugins.InvitationConstants.MAX_CODE;
|
||||
import net.sf.briar.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;
|
||||
|
||||
public class CodeEntryWidget extends LinearLayout implements
|
||||
OnEditorActionListener, OnClickListener {
|
||||
|
||||
private CodeEntryListener listener = null;
|
||||
private EditText codeEntry = null;
|
||||
|
||||
public CodeEntryWidget(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.setPadding(0, 0, 0, 10);
|
||||
enterCode.setText(prompt);
|
||||
addView(enterCode);
|
||||
|
||||
final Button continueButton = new Button(ctx);
|
||||
continueButton.setText(R.string.continue_button);
|
||||
continueButton.setEnabled(false);
|
||||
continueButton.setOnClickListener(this);
|
||||
|
||||
codeEntry = new EditText(ctx) {
|
||||
@Override
|
||||
protected void onTextChanged(CharSequence text, int start,
|
||||
int lengthBefore, int lengthAfter) {
|
||||
continueButton.setEnabled(text.length() == 6);
|
||||
}
|
||||
};
|
||||
codeEntry.setOnEditorActionListener(this);
|
||||
codeEntry.setMinEms(5);
|
||||
codeEntry.setMaxEms(5);
|
||||
codeEntry.setMaxLines(1);
|
||||
codeEntry.setInputType(TYPE_CLASS_NUMBER);
|
||||
|
||||
LinearLayout innerLayout = new LinearLayout(ctx);
|
||||
innerLayout.setOrientation(HORIZONTAL);
|
||||
innerLayout.setGravity(CENTER);
|
||||
innerLayout.addView(codeEntry);
|
||||
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.valueOf(remoteCodeString);
|
||||
} catch(NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
if(remoteCode < 0 || remoteCode > MAX_CODE) 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package net.sf.briar.android.invitation;
|
||||
|
||||
import static android.view.Gravity.CENTER;
|
||||
import static android.view.Gravity.CENTER_HORIZONTAL;
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
import net.sf.briar.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;
|
||||
|
||||
public 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.setPadding(10, 10, 10, 10);
|
||||
icon.setImageResource(R.drawable.alerts_and_states_error);
|
||||
innerLayout.addView(icon);
|
||||
|
||||
TextView failed = new TextView(ctx);
|
||||
failed.setTextSize(20);
|
||||
failed.setText(R.string.codes_do_not_match);
|
||||
innerLayout.addView(failed);
|
||||
addView(innerLayout);
|
||||
|
||||
TextView interfering = new TextView(ctx);
|
||||
interfering.setGravity(CENTER_HORIZONTAL);
|
||||
interfering.setPadding(0, 0, 0, 10);
|
||||
interfering.setText(R.string.interfering);
|
||||
addView(interfering);
|
||||
|
||||
Button tryAgain = new Button(ctx);
|
||||
LayoutParams lp = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
|
||||
tryAgain.setLayoutParams(lp);
|
||||
tryAgain.setText(R.string.try_again_button);
|
||||
tryAgain.setOnClickListener(this);
|
||||
addView(tryAgain);
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
// Try again
|
||||
container.reset(new NetworkSetupView(container));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package net.sf.briar.android.invitation;
|
||||
|
||||
import static android.view.Gravity.CENTER;
|
||||
import static android.view.Gravity.CENTER_HORIZONTAL;
|
||||
import net.sf.briar.R;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
public 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.setPadding(10, 10, 10, 10);
|
||||
icon.setImageResource(R.drawable.navigation_accept);
|
||||
innerLayout.addView(icon);
|
||||
|
||||
TextView connected = new TextView(ctx);
|
||||
connected.setTextSize(20);
|
||||
connected.setText(R.string.connected_to_contact);
|
||||
innerLayout.addView(connected);
|
||||
addView(innerLayout);
|
||||
|
||||
TextView yourCode = new TextView(ctx);
|
||||
yourCode.setGravity(CENTER_HORIZONTAL);
|
||||
yourCode.setText(R.string.your_confirmation_code);
|
||||
addView(yourCode);
|
||||
|
||||
TextView code = new TextView(ctx);
|
||||
code.setGravity(CENTER_HORIZONTAL);
|
||||
code.setTextSize(50);
|
||||
int localCode = container.getLocalConfirmationCode();
|
||||
code.setText(String.format("%06d", localCode));
|
||||
addView(code);
|
||||
|
||||
CodeEntryWidget codeEntry = new CodeEntryWidget(ctx);
|
||||
Resources res = getResources();
|
||||
codeEntry.init(this, res.getString(R.string.enter_confirmation_code));
|
||||
addView(codeEntry);
|
||||
}
|
||||
|
||||
public void codeEntered(int remoteCode) {
|
||||
container.remoteConfirmationCodeEntered(remoteCode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package net.sf.briar.android.invitation;
|
||||
|
||||
import static android.view.Gravity.CENTER;
|
||||
import static android.view.Gravity.CENTER_HORIZONTAL;
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
import net.sf.briar.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;
|
||||
|
||||
public class ConnectionFailedView extends AddContactView
|
||||
implements WifiStateListener, BluetoothStateListener, OnClickListener {
|
||||
|
||||
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.setPadding(10, 10, 10, 10);
|
||||
icon.setImageResource(R.drawable.alerts_and_states_error);
|
||||
innerLayout.addView(icon);
|
||||
|
||||
TextView failed = new TextView(ctx);
|
||||
failed.setTextSize(20);
|
||||
failed.setText(R.string.connection_failed);
|
||||
innerLayout.addView(failed);
|
||||
addView(innerLayout);
|
||||
|
||||
TextView checkNetwork = new TextView(ctx);
|
||||
checkNetwork.setGravity(CENTER_HORIZONTAL);
|
||||
checkNetwork.setText(R.string.check_same_network);
|
||||
addView(checkNetwork);
|
||||
|
||||
WifiWidget wifi = new WifiWidget(ctx);
|
||||
wifi.init(this);
|
||||
addView(wifi);
|
||||
|
||||
BluetoothWidget bluetooth = new BluetoothWidget(ctx);
|
||||
bluetooth.init(this);
|
||||
addView(bluetooth);
|
||||
|
||||
tryAgainButton = new Button(ctx);
|
||||
LayoutParams lp = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
|
||||
tryAgainButton.setLayoutParams(lp);
|
||||
tryAgainButton.setText(R.string.try_again_button);
|
||||
tryAgainButton.setOnClickListener(this);
|
||||
enabledOrDisableTryAgainButton();
|
||||
addView(tryAgainButton);
|
||||
}
|
||||
|
||||
public void wifiStateChanged(String networkName) {
|
||||
container.setNetworkName(networkName);
|
||||
enabledOrDisableTryAgainButton();
|
||||
}
|
||||
|
||||
public void bluetoothStateChanged(boolean enabled) {
|
||||
container.setUseBluetooth(enabled);
|
||||
enabledOrDisableTryAgainButton();
|
||||
}
|
||||
|
||||
private void enabledOrDisableTryAgainButton() {
|
||||
if(tryAgainButton == null) return; // Activity not created yet
|
||||
boolean useBluetooth = container.getUseBluetooth();
|
||||
String networkName = container.getNetworkName();
|
||||
if(useBluetooth || networkName != null) tryAgainButton.setEnabled(true);
|
||||
else tryAgainButton.setEnabled(false);
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
// Try again
|
||||
container.reset(new InvitationCodeView(container));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package net.sf.briar.android.invitation;
|
||||
|
||||
import static android.view.Gravity.CENTER;
|
||||
import static android.view.Gravity.CENTER_HORIZONTAL;
|
||||
import net.sf.briar.R;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
public 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.setText(R.string.your_invitation_code);
|
||||
addView(yourCode);
|
||||
|
||||
TextView code = new TextView(ctx);
|
||||
code.setGravity(CENTER_HORIZONTAL);
|
||||
code.setTextSize(50);
|
||||
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(0, 10, 10, 0);
|
||||
innerLayout.addView(progress);
|
||||
|
||||
TextView connecting = new TextView(ctx);
|
||||
Resources res = getResources();
|
||||
String connectingVia = res.getString(R.string.connecting_wifi);
|
||||
connecting.setText(String.format(connectingVia, networkName));
|
||||
innerLayout.addView(connecting);
|
||||
|
||||
addView(innerLayout);
|
||||
}
|
||||
|
||||
boolean useBluetooth = container.getUseBluetooth();
|
||||
if(useBluetooth) {
|
||||
LinearLayout innerLayout = new LinearLayout(ctx);
|
||||
innerLayout.setOrientation(HORIZONTAL);
|
||||
innerLayout.setGravity(CENTER);
|
||||
|
||||
ProgressBar progress = new ProgressBar(ctx);
|
||||
progress.setPadding(0, 10, 10, 0);
|
||||
progress.setIndeterminate(true);
|
||||
innerLayout.addView(progress);
|
||||
|
||||
TextView connecting = new TextView(ctx);
|
||||
connecting.setText(R.string.connecting_bluetooth);
|
||||
innerLayout.addView(connecting);
|
||||
|
||||
addView(innerLayout);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package net.sf.briar.android.invitation;
|
||||
|
||||
import static android.view.Gravity.CENTER;
|
||||
import static android.view.Gravity.CENTER_HORIZONTAL;
|
||||
import net.sf.briar.R;
|
||||
import android.content.Context;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
|
||||
public class ContactAddedView extends AddContactView implements OnClickListener,
|
||||
OnEditorActionListener {
|
||||
|
||||
ContactAddedView(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);
|
||||
icon.setPadding(10, 10, 10, 10);
|
||||
innerLayout.addView(icon);
|
||||
|
||||
TextView added = new TextView(ctx);
|
||||
added.setText(R.string.contact_added);
|
||||
added.setTextSize(20);
|
||||
innerLayout.addView(added);
|
||||
addView(innerLayout);
|
||||
|
||||
TextView enterNickname = new TextView(ctx);
|
||||
enterNickname.setGravity(CENTER_HORIZONTAL);
|
||||
enterNickname.setPadding(0, 0, 0, 10);
|
||||
enterNickname.setText(R.string.enter_nickname);
|
||||
addView(enterNickname);
|
||||
|
||||
innerLayout = new LinearLayout(ctx);
|
||||
innerLayout.setOrientation(HORIZONTAL);
|
||||
innerLayout.setGravity(CENTER);
|
||||
|
||||
final Button done = new Button(ctx);
|
||||
EditText nicknameEntry = new EditText(ctx) {
|
||||
@Override
|
||||
protected void onTextChanged(CharSequence text, int start,
|
||||
int lengthBefore, int lengthAfter) {
|
||||
done.setEnabled(text.length() > 0);
|
||||
}
|
||||
};
|
||||
nicknameEntry.setMinEms(10);
|
||||
nicknameEntry.setMaxEms(20);
|
||||
nicknameEntry.setMaxLines(1);
|
||||
nicknameEntry.setOnEditorActionListener(this);
|
||||
innerLayout.addView(nicknameEntry);
|
||||
|
||||
done.setText(R.string.done_button);
|
||||
done.setEnabled(false);
|
||||
done.setOnClickListener(this);
|
||||
innerLayout.addView(done);
|
||||
addView(innerLayout);
|
||||
}
|
||||
|
||||
public boolean onEditorAction(TextView textView, int actionId, KeyEvent e) {
|
||||
if(textView.getText().length() > 0) container.finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
container.finish(); // Done
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
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 {
|
||||
|
||||
InvitationCodeView(Context ctx) {
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
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);
|
||||
int localCode = container.getLocalInvitationCode();
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package net.sf.briar.android.invitation;
|
||||
|
||||
import static android.view.Gravity.CENTER_HORIZONTAL;
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
import net.sf.briar.R;
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class NetworkSetupView extends AddContactView
|
||||
implements WifiStateListener, BluetoothStateListener, OnClickListener {
|
||||
|
||||
private Button continueButton = null;
|
||||
|
||||
NetworkSetupView(Context ctx) {
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
void populate() {
|
||||
removeAllViews();
|
||||
Context ctx = getContext();
|
||||
TextView sameNetwork = new TextView(ctx);
|
||||
sameNetwork.setGravity(CENTER_HORIZONTAL);
|
||||
sameNetwork.setText(R.string.same_network);
|
||||
addView(sameNetwork);
|
||||
|
||||
WifiWidget wifi = new WifiWidget(ctx);
|
||||
wifi.init(this);
|
||||
addView(wifi);
|
||||
|
||||
BluetoothWidget bluetooth = new BluetoothWidget(ctx);
|
||||
bluetooth.init(this);
|
||||
addView(bluetooth);
|
||||
|
||||
continueButton = new Button(ctx);
|
||||
LayoutParams lp = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
|
||||
continueButton.setLayoutParams(lp);
|
||||
continueButton.setText(R.string.continue_button);
|
||||
continueButton.setOnClickListener(this);
|
||||
enableOrDisableContinueButton();
|
||||
addView(continueButton);
|
||||
}
|
||||
|
||||
public void wifiStateChanged(final String networkName) {
|
||||
container.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
container.setNetworkName(networkName);
|
||||
enableOrDisableContinueButton();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void bluetoothStateChanged(final boolean enabled) {
|
||||
container.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
container.setUseBluetooth(enabled);
|
||||
enableOrDisableContinueButton();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void enableOrDisableContinueButton() {
|
||||
if(continueButton == null) return; // Activity not created yet
|
||||
boolean useBluetooth = container.getUseBluetooth();
|
||||
String networkName = container.getNetworkName();
|
||||
if(useBluetooth || networkName != null) continueButton.setEnabled(true);
|
||||
else continueButton.setEnabled(false);
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
// Continue
|
||||
container.setView(new InvitationCodeView(container));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package net.sf.briar.android.invitation;
|
||||
|
||||
import static android.view.Gravity.CENTER;
|
||||
import static android.view.Gravity.CENTER_HORIZONTAL;
|
||||
import net.sf.briar.R;
|
||||
import android.content.Context;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
public 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.setPadding(10, 10, 10, 10);
|
||||
icon.setImageResource(R.drawable.navigation_accept);
|
||||
innerLayout.addView(icon);
|
||||
|
||||
TextView failed = new TextView(ctx);
|
||||
failed.setTextSize(20);
|
||||
failed.setText(R.string.connected_to_contact);
|
||||
innerLayout.addView(failed);
|
||||
addView(innerLayout);
|
||||
|
||||
TextView yourCode = new TextView(ctx);
|
||||
yourCode.setGravity(CENTER_HORIZONTAL);
|
||||
yourCode.setText(R.string.your_confirmation_code);
|
||||
addView(yourCode);
|
||||
|
||||
TextView code = new TextView(ctx);
|
||||
code.setGravity(CENTER_HORIZONTAL);
|
||||
code.setTextSize(50);
|
||||
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(0, 10, 10, 0);
|
||||
innerLayout.addView(progress);
|
||||
|
||||
TextView connecting = new TextView(ctx);
|
||||
connecting.setText(R.string.waiting_for_contact);
|
||||
innerLayout.addView(connecting);
|
||||
addView(innerLayout);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package net.sf.briar.android.invitation;
|
||||
|
||||
interface WifiStateListener {
|
||||
|
||||
void wifiStateChanged(String networkName);
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package net.sf.briar.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 android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
import net.sf.briar.R;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
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;
|
||||
|
||||
public class WifiWidget extends LinearLayout implements OnClickListener {
|
||||
|
||||
private WifiStateListener listener = null;
|
||||
|
||||
public WifiWidget(Context ctx) {
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
void init(WifiStateListener listener) {
|
||||
this.listener = listener;
|
||||
setOrientation(HORIZONTAL);
|
||||
setGravity(CENTER);
|
||||
populate();
|
||||
}
|
||||
|
||||
void populate() {
|
||||
removeAllViews();
|
||||
Context ctx = getContext();
|
||||
TextView status = new TextView(ctx);
|
||||
status.setLayoutParams(new LayoutParams(WRAP_CONTENT, WRAP_CONTENT, 1));
|
||||
WifiManager wifi = (WifiManager) ctx.getSystemService(WIFI_SERVICE);
|
||||
if(wifi == null) {
|
||||
wifiStateChanged(null);
|
||||
ImageView warning = new ImageView(ctx);
|
||||
warning.setImageResource(R.drawable.alerts_and_states_warning);
|
||||
warning.setPadding(10, 10, 10, 10);
|
||||
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) {
|
||||
wifiStateChanged(null);
|
||||
ImageView warning = new ImageView(ctx);
|
||||
warning.setImageResource(R.drawable.alerts_and_states_warning);
|
||||
warning.setPadding(10, 10, 10, 10);
|
||||
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 {
|
||||
wifiStateChanged(networkName);
|
||||
ImageView ok = new ImageView(ctx);
|
||||
ok.setImageResource(R.drawable.navigation_accept);
|
||||
ok.setPadding(10, 10, 10, 10);
|
||||
addView(ok);
|
||||
Resources res = getResources();
|
||||
String connected = res.getString(R.string.wifi_connected);
|
||||
status.setText(String.format(connected, networkName));
|
||||
addView(status);
|
||||
ImageButton settings = new ImageButton(ctx);
|
||||
settings.setImageResource(R.drawable.action_settings);
|
||||
settings.setOnClickListener(this);
|
||||
addView(settings);
|
||||
}
|
||||
} else {
|
||||
wifiStateChanged(null);
|
||||
ImageView warning = new ImageView(ctx);
|
||||
warning.setImageResource(R.drawable.alerts_and_states_warning);
|
||||
warning.setPadding(10, 10, 10, 10);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private void wifiStateChanged(String networkName) {
|
||||
if(listener != null) listener.wifiStateChanged(networkName);
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
getContext().startActivity(new Intent(ACTION_WIFI_SETTINGS));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user