Files
i2p.android.base/app/src/main/java/net/i2p/android/InitActivities.java
str4d 4f2a5fdc1f Dynamically include proxy header files
These get translated with the proxy message classes included in i2ptunnel.jar,
but the footer appended by I2PTunnelHTTPClientBase.writeErrorMessage() is not
because its strings are included in i2ptunnel.war.
2015-05-20 12:51:08 +00:00

281 lines
12 KiB
Java

package net.i2p.android;
import android.content.Context;
import android.content.res.Resources;
import android.os.Build;
import net.i2p.android.router.R;
import net.i2p.android.router.util.Util;
import net.i2p.data.DataHelper;
import net.i2p.util.FileUtil;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
// Wouldn't this be better as a private class in MainActivity?
class InitActivities {
private final Context ctx;
private final String myDir;
private final String _ourVersion;
private static final String CONFIG_FILE = "android.config";
private static final String PROP_NEW_INSTALL = "i2p.newInstall";
private static final String PROP_NEW_VERSION = "i2p.newVersion";
private static final String PROP_INSTALLED_VERSION = "i2p.version";
public InitActivities(Context c) {
ctx = c;
myDir = Util.getFileDir(c);
_ourVersion = Util.getOurVersion(c);
}
void debugStuff() {
Util.d("java.io.tmpdir" + ": " + System.getProperty("java.io.tmpdir"));
Util.d("java.vendor" + ": " + System.getProperty("java.vendor"));
Util.d("java.version" + ": " + System.getProperty("java.version"));
Util.d("os.arch" + ": " + System.getProperty("os.arch"));
Util.d("os.name" + ": " + System.getProperty("os.name"));
Util.d("os.version" + ": " + System.getProperty("os.version"));
Util.d("user.dir" + ": " + System.getProperty("user.dir"));
Util.d("user.home" + ": " + System.getProperty("user.home"));
Util.d("user.name" + ": " + System.getProperty("user.name"));
Util.d("getFilesDir()" + ": " + myDir);
Util.d("max mem" + ": " + DataHelper.formatSize(Runtime.getRuntime().maxMemory()));
Util.d("Package" + ": " + ctx.getPackageName());
Util.d("Version" + ": " + _ourVersion);
Util.d("MODEL" + ": " + Build.MODEL);
Util.d("DISPLAY" + ": " + Build.DISPLAY);
Util.d("VERSION" + ": " + Build.VERSION.RELEASE);
Util.d("SDK" + ": " + Build.VERSION.SDK_INT);
}
void initialize() {
if (checkNewVersion()) {
List<Properties> lProps = Util.getPropertiesFromPreferences(ctx);
Properties props = lProps.get(0);
props.setProperty("i2p.dir.temp", myDir + "/tmp");
props.setProperty("i2p.dir.pid", myDir + "/tmp");
// Time disabled in default router.config
// But lots of time problems on Android, not all carriers support NITZ
// and there was no NTP before 3.0. Tablets should be fine?
// Phones in airplane mode with wifi enabled still a problem.
// Deactivated phones in airplane mode definitely won't have correct time.
if (Build.VERSION.SDK_INT < 11) // Honeycomb 3.0
props.setProperty("time.disabled", "false");
mergeResourceToFile(R.raw.router_config, "router.config", props);
mergeResourceToFile(R.raw.logger_config, "logger.config", lProps.get(1));
// This is not needed for now, i2ptunnel.config only contains tunnel
// settings, which can now be configured manually. We don't want to
// overwrite the user's tunnels.
//mergeResourceToFile(R.raw.i2ptunnel_config, "i2ptunnel.config", null);
copyResourceToFileIfAbsent(R.raw.i2ptunnel_config, "i2ptunnel.config");
// FIXME this is a memory hog to merge this way
mergeResourceToFile(R.raw.hosts_txt, "hosts.txt", null);
mergeResourceToFile(R.raw.more_hosts_txt, "hosts.txt", null);
copyResourceToFile(R.raw.blocklist_txt, "blocklist.txt");
File abDir = new File(myDir, "addressbook");
abDir.mkdir();
copyResourceToFile(R.raw.subscriptions_txt, "addressbook/subscriptions.txt");
mergeResourceToFile(R.raw.addressbook_config_txt, "addressbook/config.txt", null);
File docsDir = new File(myDir, "docs");
docsDir.mkdir();
copyResourceToFile(R.raw.ahelper_conflict_header_ht, "docs/ahelper-conflict-header.ht");
copyResourceToFile(R.raw.ahelper_new_header_ht, "docs/ahelper-new-header.ht");
copyResourceToFile(R.raw.ahelper_notfound_header_ht, "docs/ahelper-notfound-header.ht");
copyResourceToFile(R.raw.auth_header_ht, "docs/auth-header.ht");
copyResourceToFile(R.raw.baduri_header_ht, "docs/baduri-header.ht");
copyResourceToFile(R.raw.denied_header_ht, "docs/denied-header.ht");
copyResourceToFile(R.raw.dnf_header_ht, "docs/dnf-header.ht");
copyResourceToFile(R.raw.dnfb_header_ht, "docs/dnfb-header.ht");
copyResourceToFile(R.raw.dnfh_header_ht, "docs/dnfh-header.ht");
copyResourceToFile(R.raw.dnfp_header_ht, "docs/dnfp-header.ht");
copyResourceToFile(R.raw.enc_header_ht, "docs/enc-header.ht");
copyResourceToFile(R.raw.encp_header_ht, "docs/encp-header.ht");
copyResourceToFile(R.raw.localhost_header_ht, "docs/localhost-header.ht");
copyResourceToFile(R.raw.nols_header_ht, "docs/nols-header.ht");
copyResourceToFile(R.raw.nolsp_header_ht, "docs/nolsp-header.ht");
copyResourceToFile(R.raw.noproxy_header_ht, "docs/noproxy-header.ht");
copyResourceToFile(R.raw.protocol_header_ht, "docs/protocol-header.ht");
copyResourceToFile(R.raw.reset_header_ht, "docs/reset-header.ht");
copyResourceToFile(R.raw.resetp_header_ht, "docs/resetp-header.ht");
File cssDir = new File(docsDir, "themes/console/light");
cssDir.mkdirs();
//copyResourceToFile(R.raw.console_css, "docs/themes/console/light/console.css");
//copyResourceToFile(R.raw.android_css, "docs/themes/console/light/android.css");
File imgDir = new File(docsDir, "themes/console/images");
imgDir.mkdir();
copyResourceToFile(R.drawable.i2plogo, "docs/themes/console/images/i2plogo.png");
copyResourceToFile(R.drawable.itoopie_sm, "docs/themes/console/images/itoopie_sm.png");
//copyResourceToFile(R.drawable.outbound, "docs/themes/console/images/outbound.png");
//copyResourceToFile(R.drawable.inbound, "docs/themes/console/images/inbound.png");
File img2Dir = new File(cssDir, "images");
img2Dir.mkdir();
//copyResourceToFile(R.drawable.header, "docs/themes/console/light/images/header.png");
File certDir = new File(myDir, "certificates");
certDir.mkdir();
File certificates = new File(myDir, "certificates");
File[] allcertificates = certificates.listFiles();
if ( allcertificates != null) {
for (File f : allcertificates) {
Util.d("Deleting old certificate file/dir " + f);
FileUtil.rmdir(f, false);
}
}
unzipResourceToDir(R.raw.certificates_zip, "certificates");
//File netDBDir = new File(myDir, "netDB");
//netDBDir.mkdir();
//unzipResourceToDir(R.raw.netdb_zip, "netDB");
}
// Set up the locations so settings can find them
System.setProperty("i2p.dir.base", myDir);
System.setProperty("i2p.dir.config", myDir);
System.setProperty("wrapper.logfile", myDir + "/wrapper.log");
}
/**
* @param f relative to base dir
*/
private void copyResourceToFileIfAbsent(int resID, String f) {
File file = new File(myDir, f);
if (!file.exists())
copyResourceToFile(resID, f);
}
/**
* @param f relative to base dir
*/
private void copyResourceToFile(int resID, String f) {
InputStream in = null;
FileOutputStream out = null;
Util.d("Creating file " + f + " from resource");
byte buf[] = new byte[4096];
try {
// Context methods
in = ctx.getResources().openRawResource(resID);
out = new FileOutputStream(new File(myDir, f));
int read;
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) {}
}
}
/**
* @param folder relative to base dir
*/
private void unzipResourceToDir(int resID, String folder) {
InputStream in = null;
FileOutputStream out = null;
ZipInputStream zis = null;
Util.d("Creating files in '" + myDir + "/" + folder + "/' from resource");
try {
// Context methods
in = ctx.getResources().openRawResource(resID);
zis = new ZipInputStream((in));
ZipEntry ze;
while ((ze = zis.getNextEntry()) != null) {
out = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int count;
while ((count = zis.read(buffer)) != -1) {
baos.write(buffer, 0, count);
}
String name = ze.getName();
File f = new File(myDir + "/" + folder +"/" + name);
if (ze.isDirectory()) {
Util.d("Creating directory " + myDir + "/" + folder +"/" + name + " from resource");
f.mkdir();
} else {
Util.d("Creating file " + myDir + "/" + folder +"/" + name + " from resource");
byte[] bytes = baos.toByteArray();
out = new FileOutputStream(f);
out.write(bytes);
}
} catch (IOException ioe) {
} finally {
if (out != null) { try { out.close(); } catch (IOException ioe) {} out = null; }
}
}
} 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) {}
if (zis != null) try { zis.close(); } catch (IOException ioe) {}
}
}
/**
* Load defaults from resource,
* then add props from settings,
* and write back.
*
* @param f relative to base dir
* @param overrides local overrides or null
*/
private void mergeResourceToFile(int resID, String f, Properties overrides) {
Util.mergeResourceToFile(ctx, myDir, f, resID, overrides, null);
}
/**
* Check for new version.
* FIXME we could just use shared prefs for this instead of storing in a file
* @return true if new version
*/
private boolean checkNewVersion() {
Properties props = new Properties();
InputStream fin = null;
try {
fin = ctx.openFileInput(CONFIG_FILE);
DataHelper.loadProps(props, fin);
} catch (IOException ioe) {
Util.d("Looks like a new install");
} finally {
if (fin != null) try { fin.close(); } catch (IOException ioe) {}
}
String oldVersion = props.getProperty(PROP_INSTALLED_VERSION);
boolean newInstall = oldVersion == null;
boolean newVersion = !_ourVersion.equals(oldVersion);
if (newVersion) {
Util.d("New version " + _ourVersion);
props.setProperty(PROP_INSTALLED_VERSION, _ourVersion);
try {
DataHelper.storeProps(props, ctx.getFileStreamPath(CONFIG_FILE));
} catch (IOException ioe) {
Util.d("Failed to write " + CONFIG_FILE);
}
}
return newVersion;
}
}