Separated Android code and core code into distinct Eclipse projects.
This should make it possible to develop the core in Eclipse without the ADT.
9
briar-android/.classpath
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/briar-core"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
33
briar-android/.project
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>briar-android</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
39
briar-android/AndroidManifest.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="net.sf.briar"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="16" />
|
||||
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
|
||||
|
||||
<application
|
||||
android:theme="@style/LightTheme"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name" >
|
||||
<service
|
||||
android:name=".android.helloworld.HelloWorldService"
|
||||
android:exported="false" >
|
||||
<intent-filter>
|
||||
<action android:name="net.sf.briar.android.helloworld.HelloWorldService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
<activity
|
||||
android:name=".android.helloworld.HelloWorldActivity"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".android.invitation.AddContactActivity"
|
||||
android:label="@string/add_a_contact" >
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
17
briar-android/ant.properties
Normal file
@@ -0,0 +1,17 @@
|
||||
# This file is used to override default values used by the Ant build system.
|
||||
#
|
||||
# This file must be checked into Version Control Systems, as it is
|
||||
# integral to the build system of your project.
|
||||
|
||||
# This file is only used by the Ant script.
|
||||
|
||||
# You can use this to override default values such as
|
||||
# 'source.dir' for the location of your java source folder and
|
||||
# 'out.dir' for the location of your output folder.
|
||||
|
||||
# You can also use it define how the release builds are signed by declaring
|
||||
# the following properties:
|
||||
# 'key.store' for the location of your keystore and
|
||||
# 'key.alias' for the name of the key to use.
|
||||
# The password will be asked during the build when you use the 'release' target.
|
||||
|
||||
92
briar-android/build.xml
Normal file
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="Briar" default="help">
|
||||
|
||||
<!-- The local.properties file is created and updated by the 'android' tool.
|
||||
It contains the path to the SDK. It should *NOT* be checked into
|
||||
Version Control Systems. -->
|
||||
<property file="local.properties" />
|
||||
|
||||
<!-- The ant.properties file can be created by you. It is only edited by the
|
||||
'android' tool to add properties to it.
|
||||
This is the place to change some Ant specific build properties.
|
||||
Here are some properties you may want to change/update:
|
||||
|
||||
source.dir
|
||||
The name of the source directory. Default is 'src'.
|
||||
out.dir
|
||||
The name of the output directory. Default is 'bin'.
|
||||
|
||||
For other overridable properties, look at the beginning of the rules
|
||||
files in the SDK, at tools/ant/build.xml
|
||||
|
||||
Properties related to the SDK location or the project target should
|
||||
be updated using the 'android' tool with the 'update' action.
|
||||
|
||||
This file is an integral part of the build system for your
|
||||
application and should be checked into Version Control Systems.
|
||||
|
||||
-->
|
||||
<property file="ant.properties" />
|
||||
|
||||
<!-- if sdk.dir was not set from one of the property file, then
|
||||
get it from the ANDROID_HOME env var.
|
||||
This must be done before we load project.properties since
|
||||
the proguard config can use sdk.dir -->
|
||||
<property environment="env" />
|
||||
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
|
||||
<isset property="env.ANDROID_HOME" />
|
||||
</condition>
|
||||
|
||||
<!-- The project.properties file is created and updated by the 'android'
|
||||
tool, as well as ADT.
|
||||
|
||||
This contains project specific properties such as project target, and library
|
||||
dependencies. Lower level build properties are stored in ant.properties
|
||||
(or in .classpath for Eclipse projects).
|
||||
|
||||
This file is an integral part of the build system for your
|
||||
application and should be checked into Version Control Systems. -->
|
||||
<loadproperties srcFile="project.properties" />
|
||||
|
||||
<!-- quick check on sdk.dir -->
|
||||
<fail
|
||||
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
|
||||
unless="sdk.dir"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Import per project custom build rules if present at the root of the project.
|
||||
This is the place to put custom intermediary targets such as:
|
||||
-pre-build
|
||||
-pre-compile
|
||||
-post-compile (This is typically used for code obfuscation.
|
||||
Compiled code location: ${out.classes.absolute.dir}
|
||||
If this is not done in place, override ${out.dex.input.absolute.dir})
|
||||
-post-package
|
||||
-post-build
|
||||
-pre-clean
|
||||
-->
|
||||
<import file="custom_rules.xml" optional="true" />
|
||||
|
||||
<!-- Import the actual build file.
|
||||
|
||||
To customize existing targets, there are two options:
|
||||
- Customize only one target:
|
||||
- copy/paste the target into this file, *before* the
|
||||
<import> task.
|
||||
- customize it to your needs.
|
||||
- Customize the whole content of build.xml
|
||||
- copy/paste the content of the rules files (minus the top node)
|
||||
into this file, replacing the <import> task.
|
||||
- customize to your needs.
|
||||
|
||||
***********************
|
||||
****** IMPORTANT ******
|
||||
***********************
|
||||
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
|
||||
in order to avoid having your file be overridden by tools such as "android update project"
|
||||
-->
|
||||
<!-- version-tag: 1 -->
|
||||
<import file="${sdk.dir}/tools/ant/build.xml" />
|
||||
|
||||
</project>
|
||||
BIN
briar-android/libs/roboguice-2.0.jar
Normal file
4
briar-android/lint.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<lint>
|
||||
<issue id="UseSparseArrays" severity="ignore" />
|
||||
</lint>
|
||||
20
briar-android/proguard-project.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
14
briar-android/project.properties
Normal file
@@ -0,0 +1,14 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system edit
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
#
|
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=android-16
|
||||
BIN
briar-android/res/drawable-hdpi/action_settings.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-hdpi/alerts_and_states_error.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
briar-android/res/drawable-hdpi/alerts_and_states_warning.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
briar-android/res/drawable-hdpi/navigation_accept.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
briar-android/res/drawable-hdpi/social_add_person.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
briar-android/res/drawable-ldpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
briar-android/res/drawable-mdpi/action_settings.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
briar-android/res/drawable-mdpi/alerts_and_states_error.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
briar-android/res/drawable-mdpi/alerts_and_states_warning.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
briar-android/res/drawable-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
briar-android/res/drawable-mdpi/navigation_accept.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
briar-android/res/drawable-mdpi/social_add_person.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-xhdpi/action_settings.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
briar-android/res/drawable-xhdpi/alerts_and_states_error.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-xhdpi/alerts_and_states_warning.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
briar-android/res/drawable-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
briar-android/res/drawable-xhdpi/navigation_accept.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-xhdpi/social_add_person.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
4
briar-android/res/values-v11/styles.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="LightTheme" parent="android:Theme.Holo.Light" />
|
||||
</resources>
|
||||
18
briar-android/res/values/roboguice.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="roboguice_modules">
|
||||
<item>net.sf.briar.android.AndroidModule</item>
|
||||
<item>net.sf.briar.android.helloworld.HelloWorldModule</item>
|
||||
<item>net.sf.briar.clock.ClockModule</item>
|
||||
<item>net.sf.briar.crypto.CryptoModule</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.plugins.PluginsModule</item>
|
||||
<item>net.sf.briar.protocol.ProtocolModule</item>
|
||||
<item>net.sf.briar.protocol.duplex.DuplexProtocolModule</item>
|
||||
<item>net.sf.briar.protocol.simplex.SimplexProtocolModule</item>
|
||||
<item>net.sf.briar.serial.SerialModule</item>
|
||||
<item>net.sf.briar.transport.TransportModule</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
35
briar-android/res/values/strings.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Briar</string>
|
||||
<string name="welcome">Welcome to Briar! Add a contact to get started.</string>
|
||||
<string name="face_to_face">For security reasons you must be face to face with someone to add them as a contact.</string>
|
||||
<string name="add_contact_button">Add a contact</string>
|
||||
<string name="add_a_contact">Add a Contact</string>
|
||||
<string name="same_network">Briar can add contacts via Wi-Fi or Bluetooth. To use Wi-Fi you must both be connected to the same network.</string>
|
||||
<string name="wifi_not_available">Wi-Fi is not available on this device</string>
|
||||
<string name="wifi_disabled">Wi-Fi is OFF</string>
|
||||
<string name="wifi_disconnected">Wi-Fi is DISCONNECTED</string>
|
||||
<string name="wifi_connected">Wi-Fi is CONNECTED to %1$s</string>
|
||||
<string name="bluetooth_not_available">Bluetooth is not available on this device</string>
|
||||
<string name="bluetooth_disabled">Bluetooth is OFF</string>
|
||||
<string name="bluetooth_not_discoverable">Bluetooth is NOT DISCOVERABLE</string>
|
||||
<string name="bluetooth_enabled">Bluetooth is ON</string>
|
||||
<string name="continue_button">Continue</string>
|
||||
<string name="your_invitation_code">Your invitation code is</string>
|
||||
<string name="enter_invitation_code">Please enter your contact\'s invitation code:</string>
|
||||
<string name="connecting_wifi">Connecting via %1$s\u2026</string>
|
||||
<string name="connecting_bluetooth">Connecting via Bluetooth\u2026</string>
|
||||
<string name="connection_failed">Connection failed</string>
|
||||
<string name="check_same_network">Please check that you are both using the same network.</string>
|
||||
<string name="try_again_button">Try again</string>
|
||||
<string name="connected_to_contact">Connected to contact</string>
|
||||
<string name="your_confirmation_code">Your confirmation code is</string>
|
||||
<string name="enter_confirmation_code">Please enter your contact\'s confirmation code:</string>
|
||||
<string name="waiting_for_contact">Waiting for contact\u2026</string>
|
||||
<string name="codes_do_not_match">Codes do not match</string>
|
||||
<string name="interfering">This could mean that someone is trying to interfere with your connection.</string>
|
||||
<string name="contact_added">Contact added</string>
|
||||
<string name="enter_nickname">Please enter a nickname for this contact:</string>
|
||||
<string name="add_another_contact_button">Add another contact</string>
|
||||
<string name="done_button">Done</string>
|
||||
</resources>
|
||||
4
briar-android/res/values/styles.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="LightTheme" parent="android:Theme.Light" />
|
||||
</resources>
|
||||
@@ -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
@@ -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));
|
||||
}
|
||||
}
|
||||