propagate from branch 'i2p.i2p' (head 44eff3cb8553cf29a7e4eb6c02f624648f91b124)

to branch 'i2p.i2p.zzz.android' (head 66bd014debdd51906e18555d12906ee20c016ef6)
This commit is contained in:
zzz
2009-06-29 14:04:49 +00:00
23 changed files with 935 additions and 29 deletions

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.i2p.router"
android:versionCode="1"
android:versionName="1.0.0">
<uses-permission android:name="android.permission.INTERNET" />
<application android:label="@string/app_name">
<activity android:name=".I2PAndroid"
android:label="@string/app_name"
android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

18
android/README.txt Normal file
View File

@ -0,0 +1,18 @@
#Unzip the android SDK in ../../
#So then the android tools will be in ../../android-sdk-linux_x86-1.1_r1/tools/
#then build the android apk file:
ant
#then run the emulator:
../../android-sdk-linux_x86-1.1_r1/tools/emulator &
#then wait a couple minutes until the emulator is up
#then install the I2P app
ant install
#then run the debugger
../../android-sdk-linux_x86-1.1_r1/tools/ddms &
#to rebuild and reinstall to emulator:
ant reinstall

341
android/build.xml Normal file
View File

@ -0,0 +1,341 @@
<?xml version="1.0" ?>
<project name="I2PAndroid" default="debug">
<!-- SDK Locations -->
<property name="sdk-folder" value="../../android-sdk-linux_x86-1.1_r1" />
<property name="android-tools" value="../../android-sdk-linux_x86-1.1_r1/tools" />
<!-- Application Package Name -->
<property name="application-package" value="net.i2p.router" />
<!-- The intermediates directory -->
<!-- Eclipse uses "bin" for its own output, so we do the same. -->
<property name="outdir" value="bin" />
<!-- ************************************************************************************* -->
<!-- No user servicable parts below. -->
<property name="android-framework" value="${android-tools}/lib/framework.aidl" />
<!-- Input directories -->
<property name="resource-dir" value="res" />
<property name="asset-dir" value="assets" />
<property name="srcdir" value="src" />
<condition property="srcdir-ospath"
value="${basedir}\${srcdir}"
else="${basedir}/${srcdir}" >
<os family="windows"/>
</condition>
<property name="external-libs" value="libs" />
<condition property="external-libs-ospath"
value="${basedir}\${external-libs}"
else="${basedir}/${external-libs}" >
<os family="windows"/>
</condition>
<!-- Output directories -->
<property name="outdir-classes" value="${outdir}/classes" />
<condition property="outdir-classes-ospath"
value="${basedir}\${outdir-classes}"
else="${basedir}/${outdir-classes}" >
<os family="windows"/>
</condition>
<!-- Create R.java in the source directory -->
<property name="outdir-r" value="src" />
<!-- Intermediate files -->
<property name="dex-file" value="classes.dex" />
<property name="intermediate-dex" value="${outdir}/${dex-file}" />
<condition property="intermediate-dex-ospath"
value="${basedir}\${intermediate-dex}"
else="${basedir}/${intermediate-dex}" >
<os family="windows"/>
</condition>
<!-- The final package file to generate -->
<property name="resources-package" value="${outdir}/${ant.project.name}.ap_" />
<condition property="resources-package-ospath"
value="${base`....${resources-package}"
else="${basedir}/${resources-package}" >
<os family="windows"/>
</condition>
<property name="out-debug-package" value="${outdir}/${ant.project.name}-debug.apk" />
<condition property="out-debug-package-ospath"
value="${basedir}\${out-debug-package}"
else="${basedir}/${out-debug-package}" >
<os family="windows"/>
</condition>
<property name="out-unsigned-package" value="${outdir}/${ant.project.name}-unsigned.apk" />
<condition property="out-unsigned-package-ospath"
value="${basedir}\${out-unsigned-package}"
else="${basedir}/${out-unsigned-package}" >
<os family="windows"/>
</condition>
<!-- Tools -->
<condition property="aapt" value="${android-tools}/aapt.exe" else="${android-tools}/aapt" >
<os family="windows"/>
</condition>
<condition property="aidl" value="${android-tools}/aidl.exe" else="${android-tools}/aidl" >
<os family="windows"/>
</condition>
<condition property="adb" value="${android-tools}/adb.exe" else="${android-tools}/adb" >
<os family="windows"/>
</condition>
<condition property="dx" value="${android-tools}/dx.bat" else="${android-tools}/dx" >
<os family="windows"/>
</condition>
<condition property="apk-builder" value="${android-tools}/apkbuilder.bat" else="${android-tools}/apkbuilder" >
<os family="windows"/>
</condition>
<property name="android-jar" value="${sdk-folder}/android.jar" />
<!-- Rules -->
<!-- Create the output directories if they don't exist yet. -->
<target name="dirs">
<echo>Creating output directories if needed...</echo>
<mkdir dir="${outdir}" />
<mkdir dir="${outdir-classes}" />
<mkdir dir="${external-libs}" />
</target>
<target name="clean">
<delete dir="${outdir}" />
<delete dir="${external-libs}" />
<delete dir="tmp/" />
<delete dir="res/drawable/" />
<delete file="res/raw/blocklist_txt" />
<delete file="${outdir-r}/net/i2p/router/R.java" />
</target>
<!-- Generate the R.java file for this project's resources. -->
<target name="resource-src" depends="dirs">
<echo>Generating R.java / Manifest.java from the resources...</echo>
<exec executable="${aapt}" failonerror="true">
<arg value="package" />
<arg value="-m" />
<arg value="-J" />
<arg value="${outdir-r}" />
<arg value="-M" />
<arg value="AndroidManifest.xml" />
<arg value="-S" />
<arg value="${resource-dir}" />
<arg value="-I" />
<arg value="${android-jar}" />
</exec>
</target>
<!-- Generate java classes from .aidl files. -->
<target name="aidl" depends="dirs">
<echo>Compiling aidl files into Java classes...</echo>
<apply executable="${aidl}" failonerror="true">
<arg value="-p${android-framework}" />
<arg value="-I${srcdir}" />
<fileset dir="${srcdir}">
<include name="**/*.aidl"/>
</fileset>
</apply>
</target>
<!-- Compile this project's .java files into .class files. -->
<target name="compile" depends="buildrouter, dirs, resource-src, aidl">
<javac encoding="ascii" target="1.5" debug="true" extdirs=""
srcdir="."
destdir="${outdir-classes}"
bootclasspath="${android-jar}">
<classpath>
<fileset dir="${external-libs}" includes="*.jar"/>
</classpath>
</javac>
</target>
<target name="buildrouter" depends="dirs" >
<!-- for now, we just need the ReseedHandler from routerconsole -->
<ant dir="../apps/routerconsole/java" target="compile" />
<jar destfile="${external-libs}/routerconsole.jar" >
<fileset dir="../apps/routerconsole/java/build/obj/" >
<include name="net/i2p/router/web/ContextHelper.class" />
<include name="net/i2p/router/web/ReseedHandler.class" />
<include name="net/i2p/router/web/ReseedHandler$ReseedRunner.class" />
</fileset>
</jar>
<!-- build router and core (actually the routerconsole builds these anyway) -->
<ant dir=".." target="buildrouter" />
<!-- router -->
<copy file="../build/router.jar" todir="${external-libs}" />
<!-- core -->
<mkdir dir="tmp" />
<unjar src="../build/i2p.jar" dest="tmp/" />
<delete file="tmp/net/i2p/util/LogWriter.class" />
<delete file="tmp/net/i2p/util/FileStreamFactory.class" />
<delete file="tmp/net/i2p/util/I2PFile.class" />
<!-- org.bouncycastle.crypto already in android
but we need a little trickery because our HMac is incompatible...
and the libs aren't in the SDK to compile against??? -->
<jar destfile="${external-libs}/crypto.jar" >
<fileset dir="tmp/" >
<include name="org/bouncycastle/crypto/Digest.class" />
<include name="org/bouncycastle/crypto/Mac.class" />
<include name="org/bouncycastle/crypto/digests/GeneralDigest.class" />
<include name="org/bouncycastle/crypto/digests/MD5Digest.class" />
</fileset>
</jar>
<delete>
<fileset dir="tmp/" >
<include name="org/bouncycastle/crypto/Digest.class" />
<include name="org/bouncycastle/crypto/Mac.class" />
<include name="org/bouncycastle/crypto/digests/GeneralDigest.class" />
<include name="org/bouncycastle/crypto/digests/MD5Digest.class" />
</fileset>
</delete>
<!--
<delete dir="tmp/org/bouncycastle/" />
<delete file="tmp/net/i2p/crypto/HMACGenerator.class" />
-->
<delete file="tmp/org/bouncycastle/" />
<!-- lots of unneeded stuff could be deleted here -->
<jar destfile="${external-libs}/i2p.jar" basedir="tmp/" />
<!-- some resources -->
<mkdir dir="res/drawable/" />
<copy file="../apps/routerconsole/jsp/i2plogo.png" todir="res/drawable/" />
<copy file="../installer/resources/blocklist.txt" tofile="res/raw/blocklist_txt" />
</target>
<target name="hackcleanup">
<delete file="${external-libs}/crypto.jar" />
</target>
<!-- Convert this project's .class files into .dex files. -->
<target name="dex" depends="compile, hackcleanup">
<echo>Converting compiled files and external libraries into ${outdir}/${dex-file}...</echo>
<apply executable="${dx}" failonerror="true" parallel="true">
<!-- this is a bad sign that we need this -->
<arg value="-JXmx256m" />
<arg value="--dex" />
<arg value="--output=${intermediate-dex-ospath}" />
<arg path="${outdir-classes-ospath}" />
<fileset dir="${external-libs}" includes="*.jar"/>
</apply>
</target>
<!-- Put the project's resources into the output package file. -->
<target name="package-res-and-assets">
<echo>Packaging resources and assets...</echo>
<exec executable="${aapt}" failonerror="true">
<arg value="package" />
<arg value="-f" />
<arg value="-M" />
<arg value="AndroidManifest.xml" />
<arg value="-S" />
<arg value="${resource-dir}" />
<arg value="-A" />
<arg value="${asset-dir}" />
<arg value="-I" />
<arg value="${android-jar}" />
<arg value="-F" />
<arg value="${resources-package}" />
</exec>
</target>
<!-- Same as package-res-and-assets, but without "-A ${asset-dir}" -->
<target name="package-res-no-assets">
<echo>Packaging resources...</echo>
<exec executable="${aapt}" failonerror="true">
<arg value="package" />
<arg value="-f" />
<arg value="-M" />
<arg value="AndroidManifest.xml" />
<arg value="-S" />
<arg value="${resource-dir}" />
<!-- No assets directory -->
<arg value="-I" />
<arg value="${android-jar}" />
<arg value="-F" />
<arg value="${resources-package}" />
</exec>
</target>
<!-- Invoke the proper target depending on whether or not
an assets directory is present. -->
<!-- TODO: find a nicer way to include the "-A ${asset-dir}" argument
only when the assets dir exists. -->
<target name="package-res">
<available file="${asset-dir}" type="dir"
property="res-target" value="and-assets" />
<property name="res-target" value="no-assets" />
<antcall target="package-res-${res-target}" />
</target>
<!-- Package the application and sign it with a debug key.
This is the default target when building. It is used for debug. -->
<target name="debug" depends="dex, package-res">
<echo>Packaging ${out-debug-package}, and signing it with a debug key...</echo>
<exec executable="${apk-builder}" failonerror="true">
<arg value="${out-debug-package-ospath}" />
<arg value="-z" />
<arg value="${resources-package-ospath}" />
<arg value="-f" />
<arg value="${intermediate-dex-ospath}" />
<arg value="-rf" />
<arg value="${srcdir-ospath}" />
<arg value="-rj" />
<arg value="${external-libs-ospath}" />
</exec>
</target>
<!-- Package the application without signing it.
This allows for the application to be signed later with an official publishing key. -->
<target name="release" depends="dex, package-res">
<echo>Packaging ${out-unsigned-package} for release...</echo>
<exec executable="${apk-builder}" failonerror="true">
<arg value="${out-unsigned-package-ospath}" />
<arg value="-u" />
<arg value="-z" />
<arg value="${resources-package-ospath}" />
<arg value="-f" />
<arg value="${intermediate-dex-ospath}" />
<arg value="-rf" />
<arg value="${srcdir-ospath}" />
<arg value="-rj" />
<arg value="${external-libs-ospath}" />
</exec>
<echo>It will need to be signed with jarsigner before being published.</echo>
</target>
<!-- Install the package on the default emulator -->
<target name="install" depends="debug">
<echo>Installing ${out-debug-package} onto default emulator...</echo>
<exec executable="${adb}" failonerror="true">
<arg value="install" />
<arg value="${out-debug-package}" />
</exec>
</target>
<target name="reinstall" depends="debug">
<echo>Installing ${out-debug-package} onto default emulator...</echo>
<exec executable="${adb}" failonerror="true">
<arg value="install" />
<arg value="-r" />
<arg value="${out-debug-package}" />
</exec>
</target>
<!-- Uinstall the package from the default emulator -->
<target name="uninstall">
<echo>Uninstalling ${application-package} from the default emulator...</echo>
<exec executable="${adb}" failonerror="true">
<arg value="uninstall" />
<arg value="${application-package}" />
</exec>
</target>
</project>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, I2PAndroid"
/>
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="@drawable/i2plogo"
/>
</LinearLayout>

View File

@ -0,0 +1,3 @@
logger.defaultLevel=INFO
logger.record.net.i2p.router.transport.FIFOBandwidthRefiller=ERROR
logger.record.net.i2p.stat.Rate=ERROR

View File

@ -0,0 +1,9 @@
# initial router.config
# save memory
router.prng.buffers=2
router.decayingBloomFilterM=20
stat.full=false
# no I2CP
i2p.dummyClientFacade=true
# for now
i2np.ntcp.enable=false

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">I2PAndroid</string>
</resources>

View File

@ -0,0 +1,127 @@
package net.i2p.router;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.os.Bundle;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import net.i2p.router.Router;
import net.i2p.router.web.ContextHelper;
import net.i2p.router.web.ReseedChecker;
import net.i2p.util.I2PFile;
public class I2PAndroid extends Activity
{
static Context _context;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
_context = this; // Activity extends Context
debugStuff();
initialize();
}
public void onRestart()
{
System.err.println("onRestart called");
super.onRestart();
}
public void onStart()
{
System.err.println("onStart called");
super.onStart();
Router.main(null);
System.err.println("Router.main finished");
ReseedChecker.checkReseed();
}
public void onResume()
{
System.err.println("onResume called");
super.onResume();
}
public void onPause()
{
System.err.println("onPause called");
super.onPause();
}
public void onStop()
{
System.err.println("onStop called");
super.onStop();
// shutdown() doesn't return so use shutdownGracefully()
ContextHelper.getContext(null).router().shutdownGracefully(Router.EXIT_HARD);
System.err.println("shutdown complete");
}
public void onDestroy()
{
System.err.println("onDestroy called");
super.onDestroy();
}
public static Context getContext() {
return _context;
}
private void debugStuff() {
System.err.println("java.vendor" + ": " + System.getProperty("java.vendor"));
System.err.println("java.version" + ": " + System.getProperty("java.version"));
System.err.println("os.arch" + ": " + System.getProperty("os.arch"));
System.err.println("os.name" + ": " + System.getProperty("os.name"));
System.err.println("os.version" + ": " + System.getProperty("os.version"));
System.err.println("user.dir" + ": " + System.getProperty("user.dir"));
System.err.println("user.home" + ": " + System.getProperty("user.home"));
System.err.println("user.name" + ": " + System.getProperty("user.name"));
}
private void initialize() {
// Until we can edit the router.config on the device,
// copy it from the resource every time.
// File f = new I2PFile("router.config");
// if (!f.exists()) {
copyResourceToFile(R.raw.router_config, "router.config");
copyResourceToFile(R.raw.logger_config, "logger.config");
copyResourceToFile(R.raw.blocklist_txt, "blocklist.txt");
// }
}
private void copyResourceToFile(int resID, String f) {
InputStream in = null;
FileOutputStream out = null;
System.err.println("Creating file " + f + " from resource");
byte buf[] = new byte[4096];
try {
// Context methods
in = getResources().openRawResource(resID);
out = openFileOutput(f, 0);
int read = 0;
while ( (read = in.read(buf)) != -1)
out.write(buf, 0, read);
} catch (IOException ioe) {
} catch (Resources.NotFoundException nfe) {
} finally {
if (in != null) try { in.close(); } catch (IOException ioe) {}
if (out != null) try { out.close(); } catch (IOException ioe) {}
}
}
}

View File

@ -0,0 +1,39 @@
package net.i2p.router.web;
import java.io.File;
import net.i2p.router.web.ReseedHandler;
import net.i2p.util.I2PFile;
/**
* Copied from RouterConsoleRunner.java
*/
public class ReseedChecker {
public static void checkReseed() {
System.err.println("Checking to see if we should reseed");
// we check the i2p installation directory (.) for a flag telling us not to reseed,
// but also check the home directory for that flag too, since new users installing i2p
// don't have an installation directory that they can put the flag in yet.
File noReseedFile = new I2PFile(new I2PFile(System.getProperty("user.home")), ".i2pnoreseed");
File noReseedFileAlt1 = new I2PFile(new I2PFile(System.getProperty("user.home")), "noreseed.i2p");
File noReseedFileAlt2 = new I2PFile(".i2pnoreseed");
File noReseedFileAlt3 = new I2PFile("noreseed.i2p");
if (!noReseedFile.exists() && !noReseedFileAlt1.exists() && !noReseedFileAlt2.exists() && !noReseedFileAlt3.exists()) {
File netDb = new I2PFile("netDb");
// sure, some of them could be "my.info" or various leaseSet- files, but chances are,
// if someone has those files, they've already been seeded (at least enough to let them
// get i2p started - they can reseed later in the web console)
String names[] = (netDb.exists() ? netDb.list() : null);
if ( (names == null) || (names.length < 15) ) {
System.err.println("Yes, reseeding now");
ReseedHandler reseedHandler = new ReseedHandler();
reseedHandler.requestReseed();
} else {
System.err.println("No, we have " + names.length + " routers in the netDb");
}
}
}
}

View File

@ -0,0 +1,64 @@
/*
* This is free software, do as you please.
*/
package net.i2p.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import net.i2p.router.I2PAndroid;
/**
* Use android static file stream methods
* gaaah:
* 1) the CWD is /
* 2) we can only access /data/data/net.i2p.router/files/
* 3) you can't change your CWD in Java
* so we have this lovely and the one in I2PFile.
*
* @author zzz
*/
public class FileStreamFactory {
private static final String DIR = "/data/data/net.i2p.router/files/";
/** hopefully no path separators in string */
public static FileInputStream getFileInputStream(String f) throws FileNotFoundException {
System.err.println("Input file-s: " + I2PAndroid.getContext().getFileStreamPath(f).getAbsolutePath());
return I2PAndroid.getContext().openFileInput(f);
}
public static FileInputStream getFileInputStream(File f) throws FileNotFoundException {
System.err.println("Input file-f: " + getPath(f) +
' ' + f.getAbsolutePath());
//return I2PAndroid.getContext().openFileInput(f.getName());
return new FileInputStream(getPath(f));
}
/** hopefully no path separators in string */
public static FileOutputStream getFileOutputStream(String f) throws FileNotFoundException {
System.err.println("Output file-s: " + I2PAndroid.getContext().getFileStreamPath(f).getAbsolutePath());
return I2PAndroid.getContext().openFileOutput(f, 0);
}
public static FileOutputStream getFileOutputStream(File f) throws FileNotFoundException {
System.err.println("Output file-f: " + getPath(f) +
' ' + f.getAbsolutePath());
//return I2PAndroid.getContext().openFileOutput(f.getName(), 0);
return new FileOutputStream(getPath(f));
}
/**
* preserve path but convert /foo/blah to /data/data/net.i2p.router/files/foo/blah
* Although if the File arg was created with new I2PFile() then this isn't required
*
*/
private static String getPath(File f) {
String abs = f.getAbsolutePath();
if (abs.startsWith(DIR))
return abs;
return DIR + abs.substring(1); // strip extra '/'
}
}

View File

@ -0,0 +1,29 @@
/*
* This is free software, do as you please.
*/
package net.i2p.util;
import java.io.File;
/**
* gaaah:
* 1) the CWD is /
* 2) we can only access /data/data/net.i2p.router/files/
* 3) you can't change your CWD in Java
* so we have this lovely and the one in FileStreamFactory.
*
* @author zzz
*/
public class I2PFile extends File {
public I2PFile (String f) {
super("/data/data/net.i2p.router/files/" + f);
}
/** one level deep only */
public I2PFile (File p, String f) {
super("/data/data/net.i2p.router/files/" + p.getName(), f);
}
}

View File

@ -0,0 +1,160 @@
package net.i2p.util;
/*
* public domain
*
*/
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
/**
* bridge to android logging
*
* @author zzz
*/
class LogWriter implements Runnable {
private final static long CONFIG_READ_ITERVAL = 10 * 1000;
private long _lastReadConfig = 0;
private long _numBytesInCurrentFile = 0;
private OutputStream _currentOut; // = System.out
private int _rotationNum = -1;
private String _logFilenamePattern;
private File _currentFile;
private LogManager _manager;
private boolean _write;
private LogWriter() { // nop
}
public LogWriter(LogManager manager) {
_manager = manager;
}
public void stopWriting() {
_write = false;
}
public void run() {
_write = true;
try {
while (_write) {
flushRecords();
rereadConfig();
}
System.err.println("Done writing");
} catch (Exception e) {
System.err.println("Error writing the logs: " + e.getMessage());
e.printStackTrace();
}
}
public void flushRecords() { flushRecords(true); }
public void flushRecords(boolean shouldWait) {
try {
List records = _manager._removeAll();
if (records == null) return;
for (int i = 0; i < records.size(); i++) {
LogRecord rec = (LogRecord) records.get(i);
writeRecord(rec);
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
if (shouldWait) {
try {
synchronized (this) {
this.wait(10*1000);
}
} catch (InterruptedException ie) { // nop
}
}
}
}
private void rereadConfig() {
long now = Clock.getInstance().now();
if (now - _lastReadConfig > CONFIG_READ_ITERVAL) {
_manager.rereadConfig();
_lastReadConfig = now;
}
}
private void writeRecord(LogRecord rec) {
if (rec.getThrowable() == null)
log(rec.getPriority(), rec.getSource(), rec.getSourceName(), rec.getThreadName(), rec.getMessage());
else
log(rec.getPriority(), rec.getSource(), rec.getSourceName(), rec.getThreadName(), rec.getMessage(), rec.getThrowable());
}
public void log(int priority, Class src, String name, String threadName, String msg) {
if (src != null) {
String tag = src.getName();
int dot = tag.lastIndexOf(".");
if (dot >= 0)
tag = tag.substring(dot + 1);
android.util.Log.println(toAndroidLevel(priority),
tag,
'[' + threadName + "] " + msg);
} else if (name != null)
android.util.Log.println(toAndroidLevel(priority),
name,
'[' + threadName + "] " + msg);
else
android.util.Log.println(toAndroidLevel(priority),
threadName, msg);
}
public void log(int priority, Class src, String name, String threadName, String msg, Throwable t) {
if (src != null) {
String tag = src.getName();
int dot = tag.lastIndexOf(".");
if (dot >= 0)
tag = tag.substring(dot + 1);
android.util.Log.println(toAndroidLevel(priority),
tag,
'[' + threadName + "] " + msg +
' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t));
} else if (name != null)
android.util.Log.println(toAndroidLevel(priority),
name,
'[' + threadName + "] " + msg +
' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t));
else
android.util.Log.println(toAndroidLevel(priority),
threadName,
msg + ' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t));
}
private static int toAndroidLevel(int level) {
switch (level) {
case Log.DEBUG:
return android.util.Log.DEBUG;
case Log.INFO:
return android.util.Log.INFO;
case Log.WARN:
return android.util.Log.WARN;
case Log.ERROR:
case Log.CRIT:
default:
return android.util.Log.ERROR;
}
}
private static final String replace(String pattern, int num) {
char c[] = pattern.toCharArray();
StringBuffer buf = new StringBuffer();
for (int i = 0; i < c.length; i++) {
if ( (c[i] != '#') && (c[i] != '@') )
buf.append(c[i]);
else
buf.append(num);
}
return buf.toString();
}
}

View File

@ -5,7 +5,7 @@ import java.util.List;
import net.i2p.data.Hash;
import net.i2p.router.RouterContext;
class ContextHelper {
public class ContextHelper {
public static RouterContext getContext(String contextId) {
List contexts = RouterContext.listContexts();
if ( (contexts == null) || (contexts.size() <= 0) )

View File

@ -12,10 +12,11 @@ import net.i2p.util.Log;
* has been eaten)
*/
public class AsyncFortunaStandalone extends FortunaStandalone implements Runnable {
private static final int BUFFERS = 16;
private static final int DEFAULT_BUFFERS = 16;
private static final int BUFSIZE = 256*1024;
private final byte asyncBuffers[][] = new byte[BUFFERS][BUFSIZE];
private final int status[] = new int[BUFFERS];
private int _bufferCount;
private final byte asyncBuffers[][];
private final int status[];
private int nextBuf = 0;
private I2PAppContext _context;
private Log _log;
@ -27,7 +28,10 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl
public AsyncFortunaStandalone(I2PAppContext context) {
super();
for (int i = 0; i < BUFFERS; i++)
_bufferCount = context.getProperty("router.prng.buffers", DEFAULT_BUFFERS);
asyncBuffers = new byte[_bufferCount][BUFSIZE];
status = new int[_bufferCount];
for (int i = 0; i < _bufferCount; i++)
status[i] = STATUS_NEED_FILL;
_context = context;
context.statManager().createRateStat("prng.bufferWaitTime", "", "Encryption", new long[] { 60*1000, 10*60*1000, 60*60*1000 } );
@ -80,11 +84,11 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl
status[nextBuf] = STATUS_LIVE;
int prev=nextBuf-1;
if (prev<0)
prev = BUFFERS-1;
prev = _bufferCount-1;
if (status[prev] == STATUS_LIVE)
status[prev] = STATUS_NEED_FILL;
nextBuf++;
if (nextBuf >= BUFFERS)
if (nextBuf >= _bufferCount)
nextBuf = 0;
asyncBuffers.notify();
}
@ -95,7 +99,7 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl
int toFill = -1;
try {
synchronized (asyncBuffers) {
for (int i = 0; i < BUFFERS; i++) {
for (int i = 0; i < _bufferCount; i++) {
if (status[i] == STATUS_NEED_FILL) {
status[i] = STATUS_FILLING;
toFill = i;

View File

@ -7,7 +7,8 @@ import net.i2p.data.Hash;
import net.i2p.data.SessionKey;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.Mac;
import org.bouncycastle.crypto.macs.I2PHMac;
/**
* Calculate the HMAC-SHA256 of a key+message. All the good stuff occurs
@ -19,15 +20,15 @@ public class HMAC256Generator extends HMACGenerator {
public HMAC256Generator(I2PAppContext context) { super(context); }
@Override
protected HMac acquire() {
protected I2PHMac acquire() {
synchronized (_available) {
if (_available.size() > 0)
return (HMac)_available.remove(0);
return (I2PHMac)_available.remove(0);
}
// the HMAC is hardcoded to use SHA256 digest size
// for backwards compatability. next time we have a backwards
// incompatible change, we should update this by removing ", 32"
return new HMac(new Sha256ForMAC());
return new I2PHMac(new Sha256ForMAC());
}
private class Sha256ForMAC extends Sha256Standalone implements Digest {

View File

@ -10,7 +10,8 @@ import net.i2p.data.Hash;
import net.i2p.data.SessionKey;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.Mac;
import org.bouncycastle.crypto.macs.I2PHMac;
/**
* Calculate the HMAC-MD5 of a key+message. All the good stuff occurs
@ -49,7 +50,7 @@ public class HMACGenerator {
if ((key == null) || (key.getData() == null) || (data == null))
throw new NullPointerException("Null arguments for HMAC");
HMac mac = acquire();
I2PHMac mac = acquire();
mac.init(key.getData());
mac.update(data, offset, length);
//byte rv[] = new byte[Hash.HASH_LENGTH];
@ -73,7 +74,7 @@ public class HMACGenerator {
if ((key == null) || (key.getData() == null) || (curData == null))
throw new NullPointerException("Null arguments for HMAC");
HMac mac = acquire();
Mac mac = acquire();
mac.init(key.getData());
mac.update(curData, curOffset, curLength);
byte rv[] = acquireTmp();
@ -86,17 +87,17 @@ public class HMACGenerator {
return eq;
}
protected HMac acquire() {
protected I2PHMac acquire() {
synchronized (_available) {
if (_available.size() > 0)
return (HMac)_available.remove(0);
return (I2PHMac)_available.remove(0);
}
// the HMAC is hardcoded to use SHA256 digest size
// for backwards compatability. next time we have a backwards
// incompatible change, we should update this by removing ", 32"
return new HMac(new MD5Digest(), 32);
return new I2PHMac(new MD5Digest(), 32);
}
private void release(HMac mac) {
private void release(Mac mac) {
synchronized (_available) {
if (_available.size() < 64)
_available.add(mac);
@ -122,4 +123,4 @@ public class HMACGenerator {
_availableTmp.add((Object)tmp);
}
}
}
}

View File

@ -37,6 +37,7 @@ import java.util.TreeMap;
import java.util.zip.Deflater;
import net.i2p.util.ByteCache;
import net.i2p.util.FileStreamFactory;
import net.i2p.util.OrderedProperties;
import net.i2p.util.ReusableGZIPInputStream;
import net.i2p.util.ReusableGZIPOutputStream;
@ -217,7 +218,7 @@ public class DataHelper {
loadProps(props, file, false);
}
public static void loadProps(Properties props, File file, boolean forceLowerCase) throws IOException {
loadProps(props, new FileInputStream(file), forceLowerCase);
loadProps(props, FileStreamFactory.getFileInputStream(file), forceLowerCase);
}
public static void loadProps(Properties props, InputStream inStr) throws IOException {
loadProps(props, inStr, false);

View File

@ -30,6 +30,7 @@ public class DecayingBloomFilter {
private boolean _keepDecaying;
private DecayEvent _decayEvent;
private static final int DEFAULT_M = 23;
private static final boolean ALWAYS_MISS = false;
/**
@ -44,8 +45,12 @@ public class DecayingBloomFilter {
_context = context;
_log = context.logManager().getLog(DecayingBloomFilter.class);
_entryBytes = entryBytes;
_current = new BloomSHA1(23, 11); //new BloomSHA1(23, 11);
_previous = new BloomSHA1(23, 11); //new BloomSHA1(23, 11);
// this is instantiated in four different places, they may have different
// requirements, but for now use this as a gross method of memory reduction.
// m == 23 => 2MB each BloomSHA1 (8MB total)
int m = context.getProperty("router.decayingBloomFilterM", DEFAULT_M);
_current = new BloomSHA1(m, 11); //new BloomSHA1(23, 11);
_previous = new BloomSHA1(m, 11); //new BloomSHA1(23, 11);
_durationMs = durationMs;
int numExtenders = (32+ (entryBytes-1))/entryBytes - 1;
if (numExtenders < 0)

View File

@ -0,0 +1,36 @@
/*
* public domain
*/
package net.i2p.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
/**
* This is pulled out and replaced in the android build.
*
* @author zzz
*/
public class FileStreamFactory {
public static FileInputStream getFileInputStream(String f) throws FileNotFoundException {
return new FileInputStream(f);
}
public static FileInputStream getFileInputStream(File f) throws FileNotFoundException {
return new FileInputStream(f);
}
public static FileOutputStream getFileOutputStream(String f) throws FileNotFoundException {
return new FileOutputStream(f);
}
public static FileOutputStream getFileOutputStream(File f) throws FileNotFoundException {
return new FileOutputStream(f);
}
}

View File

@ -0,0 +1,24 @@
/*
* public domain
*/
package net.i2p.util;
import java.io.File;
/**
* This is pulled out and replaced in the android build.
*
* @author zzz
*/
public class I2PFile extends File {
public I2PFile (String f) {
super(f);
}
public I2PFile (File p, String f) {
super(p, f);
}
}

View File

@ -42,8 +42,12 @@ import org.bouncycastle.crypto.Mac;
* a frequently used buffer (called on doFinal). changes released into the public
* domain in 2005.
*
* This is renamed from HMac because the constructor HMac(digest, sz) does not exist
* in the standard bouncycastle library, thus it conflicts in JVMs that contain the
* standard library (Android).
*
*/
public class HMac
public class I2PHMac
implements Mac
{
private final static int BLOCK_LENGTH = 64;
@ -56,12 +60,12 @@ implements Mac
private byte[] inputPad = new byte[BLOCK_LENGTH];
private byte[] outputPad = new byte[BLOCK_LENGTH];
public HMac(
public I2PHMac(
Digest digest)
{
this(digest, digest.getDigestSize());
}
public HMac(
public I2PHMac(
Digest digest, int sz)
{
this.digest = digest;

View File

@ -26,6 +26,7 @@ import net.i2p.data.PublicKey;
import net.i2p.data.SigningPrivateKey;
import net.i2p.data.SigningPublicKey;
import net.i2p.util.Clock;
import net.i2p.util.FileStreamFactory;
import net.i2p.util.Log;
/**
@ -203,12 +204,12 @@ public class KeyManager {
FileInputStream in = null;
try {
if (exists) {
out = new FileOutputStream(keyFile);
out = FileStreamFactory.getFileOutputStream(keyFile);
structure.writeBytes(out);
return structure;
} else {
if (keyFile.exists()) {
in = new FileInputStream(keyFile);
in = FileStreamFactory.getFileInputStream(keyFile);
structure.readBytes(in);
return structure;
} else {

View File

@ -76,7 +76,7 @@ public class LoadRouterInfoJob extends JobImpl {
}
if (_keysExist) {
fis2 = new FileInputStream(rkf);
fis2 = FileStreamFactory.getFileInputStream(rkf);
PrivateKey privkey = new PrivateKey();
privkey.readBytes(fis2);
SigningPrivateKey signingPrivKey = new SigningPrivateKey();