Compare commits
9 Commits
v0.1-send-
...
master
Author | SHA1 | Date |
---|---|---|
Dan Ballard | 082beb5691 | |
Dan Ballard | 66a25b0efa | |
Dan Ballard | 2da20a5962 | |
Dan Ballard | 45d56ae601 | |
Dan Ballard | 9b1e768226 | |
Dan Ballard | 14fc595760 | |
Dan Ballard | fd5b1826de | |
Dan Ballard | 63b4a86999 | |
Dan Ballard | 3ee025fb23 |
|
@ -1,5 +1,6 @@
|
|||
*.iml
|
||||
*.aar
|
||||
*.apk
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
|
|
10
README.md
10
README.md
|
@ -4,3 +4,13 @@ A simple proof of concept usage of Ricochet + Tor on mobile
|
|||
Uses:
|
||||
- Orbot
|
||||
- gomobile: to leverage the go ricochet protocol library
|
||||
|
||||
## Orbot setup
|
||||
|
||||
In Orbot's Settings, find at the bottom `Debug / Torrc Custom Config` and input:
|
||||
|
||||
```
|
||||
ControlPort 9051
|
||||
CookieAuthentication 0
|
||||
DisableNetwork 0
|
||||
```
|
||||
|
|
|
@ -8,7 +8,7 @@ android {
|
|||
minSdkVersion 16
|
||||
targetSdkVersion 25
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
versionName "0.9.0"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
|
@ -24,9 +24,10 @@ dependencies {
|
|||
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
|
||||
exclude group: 'com.android.support', module: 'support-annotations'
|
||||
})
|
||||
compile project(':goRicochetMobile')
|
||||
compile project(':goRicochetMobileOd')
|
||||
|
||||
compile 'com.android.support:appcompat-v7:25.3.1'
|
||||
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||
compile project(':goRicochetMobile')
|
||||
|
||||
testCompile 'junit:junit:4.12'
|
||||
}
|
||||
|
|
|
@ -12,14 +12,14 @@
|
|||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
<activity android:name="im.ricochet.androidod.ConnectActivity">
|
||||
<activity android:name=".ConnectActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".RemoteActivity"></activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -1,5 +1,6 @@
|
|||
package im.ricochet.androidod;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.StrictMode;
|
||||
|
@ -15,6 +16,8 @@ import android.widget.ProgressBar;
|
|||
import android.widget.TextView;
|
||||
|
||||
import goRicochetMobile.GoRicochetMobile;
|
||||
import od.Od;
|
||||
|
||||
|
||||
public class ConnectActivity extends AppCompatActivity {
|
||||
|
||||
|
@ -38,9 +41,6 @@ public class ConnectActivity extends AppCompatActivity {
|
|||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
// Load identity and connect to addr. Enable appropriate buttons
|
||||
// If no identity, generate.
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(im.ricochet.androidod.R.layout.activity_connect);
|
||||
|
||||
|
@ -89,11 +89,11 @@ public class ConnectActivity extends AppCompatActivity {
|
|||
String privateKey = prefs.getString(PRIVATE_KEY_KEY, "");
|
||||
Log.i(TAG, "Private key loaded:\n"+privateKey);
|
||||
if (privateKey.equals("")) {
|
||||
Log.i(TAG, "regenerating pricate key");
|
||||
Log.i(TAG, "Generating pricate key");
|
||||
RegenIdentTask regenIdentTask = new RegenIdentTask();
|
||||
regenIdentTask.execute();
|
||||
} else {
|
||||
Log.i(TAG, "setting identity, enabling regen");
|
||||
Log.i(TAG, "Setting identity, Enabling regen");
|
||||
setIdentity(privateKey);
|
||||
Button regenButton = (Button)findViewById(R.id.regenIdentButton);
|
||||
regenButton.setEnabled(true);
|
||||
|
@ -122,7 +122,7 @@ public class ConnectActivity extends AppCompatActivity {
|
|||
String privateKey = params[0];
|
||||
String connectToAddr = params[1].replaceFirst(RICOCHET_ADDRESS_PREFIX, "");
|
||||
try {
|
||||
GoRicochetMobile.odClientConnect(privateKey, connectToAddr);
|
||||
Od.odClientConnect(privateKey, connectToAddr);
|
||||
return "";
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, e.toString());
|
||||
|
@ -139,14 +139,16 @@ public class ConnectActivity extends AppCompatActivity {
|
|||
connectButton.setEnabled(true);
|
||||
regenButton.setEnabled(true);
|
||||
} else {
|
||||
connectStatusText.setText("");
|
||||
// TODO: Open OD control activity
|
||||
connectStatusText.setText("Connected!");
|
||||
Intent i = new Intent(getApplicationContext(), RemoteActivity.class);
|
||||
// i,putExtra("key", "val")
|
||||
startActivity(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setIdentity(String privateKey) {
|
||||
Log.i(TAG, "setIdentity(): " + privateKey);
|
||||
Log.i(TAG, "setIdentity()");
|
||||
String addr = GoRicochetMobile.getOnionAddress(privateKey);
|
||||
Log.i(TAG, "setIdentity(): addr: '" + addr + "'");
|
||||
idetityText.setText("ricochet:" + addr);
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
package im.ricochet.androidod;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import od.Od;
|
||||
|
||||
public class RemoteActivity extends AppCompatActivity {
|
||||
private static final String DEVICE_NAME_KEY = "deviceName";
|
||||
private static final String BATTERY_LEVEL_KEY = "batteryLevel";
|
||||
private static final String VIBE_LEVEL_KEY = "vibeLEvel";
|
||||
|
||||
TextView deviceText;
|
||||
TextView batteryText;
|
||||
TextView statusText;
|
||||
|
||||
Button offButton;
|
||||
Button lowButton;
|
||||
Button medButton;
|
||||
Button highButton;
|
||||
Button disconnectButton;
|
||||
|
||||
int vibeLevel = 0;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_remote);
|
||||
|
||||
deviceText = (TextView)findViewById(R.id.deviceName);
|
||||
batteryText = (TextView)findViewById(R.id.batteryLevel);
|
||||
statusText = (TextView)findViewById(R.id.status);
|
||||
|
||||
offButton = (Button)findViewById(R.id.offButton);
|
||||
lowButton = (Button)findViewById(R.id.lowButton);
|
||||
medButton = (Button)findViewById(R.id.medButton);
|
||||
highButton = (Button)findViewById(R.id.highButton);
|
||||
disconnectButton = (Button)findViewById(R.id.disconnetButton);
|
||||
|
||||
offButton.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
SetLevelTask setLevelTask = new SetLevelTask();
|
||||
setLevelTask.execute(0);
|
||||
}
|
||||
});
|
||||
lowButton.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
SetLevelTask setLevelTask = new SetLevelTask();
|
||||
setLevelTask.execute(2);
|
||||
}
|
||||
});
|
||||
medButton.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
SetLevelTask setLevelTask = new SetLevelTask();
|
||||
setLevelTask.execute(4);
|
||||
}
|
||||
});
|
||||
highButton.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
SetLevelTask setLevelTask = new SetLevelTask();
|
||||
setLevelTask.execute(6);
|
||||
}
|
||||
});
|
||||
|
||||
disconnectButton.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
DisconnectTask disconnectTask = new DisconnectTask();
|
||||
disconnectTask.execute();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
deviceText.setText(savedInstanceState.getString(DEVICE_NAME_KEY));
|
||||
batteryText.setText(savedInstanceState.getString(BATTERY_LEVEL_KEY));
|
||||
vibeLevel = savedInstanceState.getInt(VIBE_LEVEL_KEY);
|
||||
setVibeLevel(vibeLevel);
|
||||
} else {
|
||||
GetDeviceNameTask getDeviceNameTask = new GetDeviceNameTask();
|
||||
getDeviceNameTask.execute();
|
||||
|
||||
GetBatteryTask getBatteryTask = new GetBatteryTask();
|
||||
getBatteryTask.execute();
|
||||
|
||||
GetLevelTask getLevelTask = new GetLevelTask();
|
||||
getLevelTask.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(final Bundle outState) {
|
||||
outState.putString(DEVICE_NAME_KEY, deviceText.getText().toString());
|
||||
outState.putString(BATTERY_LEVEL_KEY, batteryText.getText().toString());
|
||||
outState.putInt(VIBE_LEVEL_KEY, vibeLevel);
|
||||
}
|
||||
|
||||
// current impelementation of OD server can return 0 to 6 (potentially downsampled from 12?)
|
||||
// The go API respects that, further downsample to [off low med high] here
|
||||
// Assuming 1 means off and 2-6 are active states...
|
||||
private void setVibeLevel(int newVibeLevel) {
|
||||
vibeLevel = newVibeLevel;
|
||||
if (vibeLevel == 1) {
|
||||
statusText.setText("Off");
|
||||
} else if (vibeLevel == 2) {
|
||||
statusText.setText("Low");
|
||||
} else if (vibeLevel == 3 || vibeLevel == 4) {
|
||||
statusText.setText("Medium");
|
||||
} else if (vibeLevel == 5 || vibeLevel == 6) {
|
||||
statusText.setText("High");
|
||||
}
|
||||
}
|
||||
|
||||
private class GetDeviceNameTask extends AsyncTask<Void, Void, String> {
|
||||
@Override
|
||||
protected String doInBackground(Void... params) {
|
||||
String name = Od.getDeviceName();
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String deviceName) {
|
||||
deviceText.setText(deviceName);
|
||||
}
|
||||
}
|
||||
|
||||
private class GetBatteryTask extends AsyncTask<Void, Void, String> {
|
||||
@Override
|
||||
protected String doInBackground(Void... params) {
|
||||
String batteryLevel = Od.getBatteryLevel();
|
||||
return batteryLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String batteryLevel) {
|
||||
batteryText.setText(batteryLevel + "%");
|
||||
}
|
||||
}
|
||||
|
||||
private class GetLevelTask extends AsyncTask<Void, Void, Integer> {
|
||||
@Override
|
||||
protected Integer doInBackground(Void... params) {
|
||||
Integer vibeLevel = (int) Od.getVibeLevel();
|
||||
return vibeLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Integer newVibeLevel) {
|
||||
setVibeLevel(newVibeLevel);
|
||||
}
|
||||
}
|
||||
|
||||
private class SetLevelTask extends AsyncTask<Integer, Void, Integer> {
|
||||
@Override
|
||||
protected Integer doInBackground(Integer... params) {
|
||||
Integer newVibeLevel = params[0];
|
||||
Od.setVibeLevel(newVibeLevel);
|
||||
return newVibeLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Integer newVibeLevel) {
|
||||
setVibeLevel(newVibeLevel);
|
||||
}
|
||||
}
|
||||
|
||||
private class DisconnectTask extends AsyncTask<Void, Void, Void> {
|
||||
@Override
|
||||
protected Void doInBackground(Void ...params) {
|
||||
Od.odClientDisconnect();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void nothing) {
|
||||
Intent i = new Intent(getApplicationContext(), ConnectActivity.class);
|
||||
startActivity(i);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="im.ricochet.androidod.RemoteActivity">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView7"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Device:"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:layout_marginRight="8dp"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/deviceName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toRightOf="@+id/textView7"
|
||||
android:layout_marginLeft="8dp"
|
||||
app:layout_constraintTop_toTopOf="@+id/textView7"
|
||||
android:layout_marginTop="0dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView9"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Battery:"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView7" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/batteryLevel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:text="0%"
|
||||
app:layout_constraintLeft_toRightOf="@+id/textView9"
|
||||
app:layout_constraintTop_toTopOf="@+id/textView9"
|
||||
android:layout_marginTop="0dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/TextView10"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Status:"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView9" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
app:layout_constraintLeft_toRightOf="@+id/TextView10"
|
||||
app:layout_constraintTop_toTopOf="@+id/TextView10"
|
||||
android:layout_marginTop="0dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/offButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Off"
|
||||
app:layout_constraintTop_toBottomOf="@+id/TextView10"
|
||||
android:layout_marginLeft="8dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:layout_marginRight="8dp"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/lowButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="7dp"
|
||||
android:text="Low"
|
||||
app:layout_constraintTop_toBottomOf="@+id/offButton"
|
||||
android:layout_marginLeft="8dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:layout_marginRight="8dp"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/medButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Medium"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/lowButton" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/highButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="High"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/medButton" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/disconnetButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginTop="64dp"
|
||||
android:text="Disconnect"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/highButton" />
|
||||
</android.support.constraint.ConstraintLayout>
|
|
@ -8,4 +8,5 @@ gobind {
|
|||
GOMOBILE = "/home/user/src/go/bin/gomobile"
|
||||
GOBIND = "/home/user/src/go/bin/gobind"
|
||||
GO = "/home/user/go/bin/go"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
plugins {
|
||||
id "org.golang.mobile.bind" version "0.2.7"
|
||||
}
|
||||
|
||||
gobind {
|
||||
pkg = "github.com/dballard/goRicochetMobile/od"
|
||||
GOPATH = "/home/user/src/go"
|
||||
GOMOBILE = "/home/user/src/go/bin/gomobile"
|
||||
GOBIND = "/home/user/src/go/bin/gobind"
|
||||
GO = "/home/user/go/bin/go"
|
||||
}
|
|
@ -1 +1 @@
|
|||
include ':app', 'goRicochetMobile'
|
||||
include ':app', 'goRicochetMobile', 'goRicochetMobileOd'
|
||||
|
|
Loading…
Reference in New Issue