Compare commits

...

106 Commits

Author SHA1 Message Date
05c2dbd388 Javadoc improvements
This is the client library 0.2 commit
2014-09-29 23:54:28 +00:00
c8e1643326 New client library translations for ru 2014-09-29 23:53:48 +00:00
d72c936a0e Fix addressbook settings header Intent bug 2014-09-29 23:52:59 +00:00
06d4d7d10d New client lib translations for fr 2014-09-29 04:08:30 +00:00
b506b5e740 New translations for client library 2014-09-26 23:19:38 +00:00
2d65bd373c Configure Transifex for client library strings 2014-09-26 12:28:15 +00:00
7c869adf58 Client library helper class
Based on OrbotHelper from libnetcipher, with logic from i2p.i2p-bote.android
2014-09-26 12:27:51 +00:00
61a7566007 Client library 0.2
i2p.i2p tag: i2p-0.9.15
2014-09-25 05:00:28 +00:00
9d42901079 Updated translations 2014-09-25 04:57:47 +00:00
fb31818a3c 0.9.14.1-rc3 2014-08-23 01:24:52 +00:00
6355214b5f Updated translations 2014-08-23 01:01:37 +00:00
d5c0704477 Updated TODO 2014-08-23 00:45:18 +00:00
411131b8a6 Updated translations 2014-08-23 00:45:04 +00:00
10ed266d2c Clarify property inversion 2014-08-23 00:25:40 +00:00
bccfe03b5d Sync settings XML defaults with router.config defaults 2014-08-22 23:30:35 +00:00
a44ac8a45c Another domain name fix 2014-08-22 14:02:23 +00:00
5610752c6d Updated old domain names 2014-08-22 14:01:19 +00:00
7047913b45 Updated translations 2014-08-22 13:57:33 +00:00
a41aa79920 Explain to users that graphs need to be configured 2014-08-22 13:22:38 +00:00
4fcc1121b7 Padding tweak 2014-08-22 12:09:55 +00:00
514aa51224 Fixed images in peers WebView 2014-08-22 11:50:53 +00:00
0c46dc9bd0 Display auto-start setting in I2PTunnel details 2014-08-22 11:27:11 +00:00
4b7f951e32 0.9.14.1-rc2 2014-08-21 14:37:40 +00:00
a58a9d7540 Fixed "called on wrong thread" issue in browser 2014-08-21 14:33:39 +00:00
d3eaebd324 Temporary fix for a settings bug 2014-08-21 13:40:59 +00:00
37c366a528 Client library 0.1.1 2014-08-21 10:55:32 +00:00
8f6289984b 0.9.14.1-rc1 2014-08-20 11:19:33 +00:00
7629bb54ce Feature graphic for Google Play 2014-08-20 06:41:41 +00:00
ee7d227990 Fixed sq translation 2014-08-20 04:34:44 +00:00
4cc940c995 Updated TODO 2014-08-20 04:28:19 +00:00
2336eebdd0 New translations: sq U id 2014-08-20 04:02:50 +00:00
62035050c5 Padding tweak, prevent status headings flicker when opening app 2014-08-20 03:37:20 +00:00
6775d57c22 Rearranged nav drawer, only show graphs peers and netdb for advanced users 2014-08-20 03:02:29 +00:00
d3a1910b2e Return null on unknown State in Parcel 2014-08-20 02:37:27 +00:00
aa43d960dc Revert AndroidManifest.xml package name change
Changing this requires changing the import path of the generated R file, which
will unnecessarily affect most of the code. R is built in a package based on
the AndroidManifest.xml package name, whereas the final app package name is
overridden in app/build.gradle for free and donate versions.
2014-08-18 14:50:54 +00:00
2e3047274e Added legacy flavor with old app ID, fixed package names in manifests 2014-08-18 13:11:47 +00:00
a3cef11e08 Updated ignores 2014-08-17 23:13:23 +00:00
543fb51d76 Simplify adding client library to a local flatDir repo 2014-08-15 01:41:16 +00:00
4328db1908 Fixed source and javadoc jar creation 2014-08-07 13:25:02 +00:00
69fbb5dc92 Updated translations 2014-08-07 06:57:43 +00:00
0c5d8f8e9e Moved jbigi to client library, so clients get benefit 2014-08-06 22:45:06 +00:00
b88e150803 Final changes, x86 and MIPS libjbigi.so now build
Untested, we need to find x86 and MIPS devices to test with.
2014-08-06 10:52:22 +00:00
35fe44fc59 Initial x86 and MIPS support (not enabled, missing --host parameters) 2014-08-06 00:08:03 +00:00
464adb9e71 More non-ABI-specific script 2014-08-05 23:31:01 +00:00
66d370abeb Reorganized to run non-ABI-specific parts of script first 2014-08-05 23:25:10 +00:00
11aded07ca Refactored to pull out ABI-specific settings 2014-08-04 01:29:04 +00:00
5d0861e22e Only allow numbers in I2PTunnel wizard port fields (ticket #1331) 2014-08-03 21:18:05 +00:00
5778eb9d1c Updated translations 2014-07-26 02:44:45 +00:00
0e47bc5042 Updated translations 2014-07-19 23:26:55 +00:00
8f9a6922ad Bugfixes 2014-07-17 06:40:17 +00:00
05cc0634b7 Updated README 2014-07-17 06:31:04 +00:00
583666695c Improved Maven upload code, collected parameters in gradle.properties
maven-push.gradle source:
https://github.com/chrisbanes/gradle-mvn-push
2014-07-17 06:29:40 +00:00
e67ba59e51 Uploading to the Central Repository 2014-07-17 05:41:57 +00:00
ab619f904d Reverted to Enum for State, make it Parcelable
Talked with zzz and did more research, the overhead of Enum is minimal compared
to the benefits it provides.
2014-07-17 00:56:04 +00:00
f2f7418c8b Ignore old Enum state 2014-07-16 05:26:44 +00:00
23c55d50fb Remove I2CP port starting, clients can use domain sockets now 2014-07-16 04:20:40 +00:00
e0acb322a5 Lint 2014-07-16 03:47:17 +00:00
2a1427054d Use static int constants for State instead of Enums
Enums often require more than twice as much memory as static constants, and
should be strictly avoided on Android.
https://developer.android.com/training/articles/memory.html#Overhead

The advantage of this change is that client library users can directly compare
the status values they get from IRouterState to the constants, instead of
parsing a string representation of an Enum.
2014-07-16 01:28:49 +00:00
d878d2d8a4 Moved AIDL interfaces to client library 2014-07-16 01:25:19 +00:00
5386829edf Implemented I2CP connections over Android Local[Server]Sockets 2014-07-15 13:03:33 +00:00
5d74e7ffef Comments 2014-07-15 11:13:55 +00:00
332ec1e0ad Corrected client library package group 2014-07-15 11:08:39 +00:00
060262ee52 Separated client library version 2014-07-15 10:16:07 +00:00
c75fe55e56 Updated client library package 2014-07-15 08:56:41 +00:00
bccf5e0965 Bundle I2P libs in client AAR 2014-07-15 06:19:31 +00:00
6bd905a027 Fixed client building (thanks alkemist from Freenode#gradle) 2014-07-15 03:40:47 +00:00
fc0b393b14 Markdown fix 2014-07-15 01:52:59 +00:00
f2acde73fe Specify full version for Android Gradle plugin so script compiles when offline 2014-07-14 12:39:32 +00:00
77a7f5f603 Client library AndroidManifest.xml 2014-07-13 21:56:26 +00:00
d235da093f Build script for client library 2014-07-11 05:18:46 +00:00
795d3ab314 Updated translations 2014-07-07 02:58:49 +00:00
dd40931a23 Correct version code for current release
If we move to increment-by-one instead of calculating the version code, we need
to keep the code above the current highest generated code, so that F-Droid will
order new builds correctly above old builds.

If we decide to go back to calculating version codes later, it is possible - we
can increment the version code 2047 times before it will clash with the one for
0.9.14.
2014-07-07 02:43:16 +00:00
8b71e4fc2e Fixed CacheProvider authorities clash 2014-07-07 02:38:51 +00:00
ed61f0414e Padding tweak 2014-07-07 01:24:57 +00:00
06ef95c7ac Better layout padding for main view 2014-07-07 01:14:58 +00:00
2936bfc2b7 wrap long lines 2014-07-04 00:41:33 +00:00
9c655ffebf move from cat|grep|sed to awk 2014-07-04 00:41:17 +00:00
9d8fb684d2 Fixed building armeabi libjbigi.so 2014-07-03 22:36:20 +00:00
0d744e269c Static verification of remote dependencies using Gradle Witness
https://github.com/WhisperSystems/gradle-witness
2014-07-01 05:06:48 +00:00
36ffb6eda4 Default to ../i2p.i2p for copying I2P resources 2014-07-01 04:54:19 +00:00
df7ee4bd05 Updated README 2014-06-29 02:58:32 +00:00
d98d6abff3 Updated android gradle plugin version 2014-06-29 02:33:47 +00:00
260cc8a5a2 Updated gradle specified in wrapper to 1.12 2014-06-28 23:42:13 +00:00
zzz
a0a1df8093 Remove local copies of I2P Secure* utilities since we are
now on Java 6 (API 9).
2014-06-28 15:37:59 +00:00
e4110eb894 Signing instructions 2014-06-28 04:21:45 +00:00
d0264bf475 Addressbook license is copied over, should not be checked in 2014-06-28 02:04:12 +00:00
7ec8b0a592 Copy I2P resources 2014-06-28 02:03:39 +00:00
e3ecac8fec Rquirement: Android Support Repository 2014-06-28 00:40:02 +00:00
4fdc7940dd Version 2014-06-27 17:26:04 +00:00
9920ad34cd Renamed package to net.i2p.android, added free and donate flavors 2014-06-27 17:08:44 +00:00
8a7025038a New translations 2014-06-27 16:40:17 +00:00
a47c80df8c Updated Transifex config 2014-06-27 16:40:10 +00:00
a1a5aeaf6c Don't abort on lint errors 2014-06-27 16:34:01 +00:00
3a8eeabe3e Improved handling of signing keys 2014-06-27 16:29:43 +00:00
3e34bac295 Updated README 2014-06-27 16:19:36 +00:00
66d0dce40c Dropped Eclipse files 2014-06-27 15:55:20 +00:00
c8d3ee7aac Updated ignores 2014-06-27 15:51:55 +00:00
959537adc2 Reflowed AndroidManifest.xml, added missing parent meta-data for below API 16 2014-06-27 15:46:34 +00:00
7ca050fdf5 Cleaned up routerjars 2014-06-27 15:20:58 +00:00
07130abf23 Update min API to 9 (Gingerbread) 2014-06-27 15:15:15 +00:00
ba82d59b89 merge of '3a37cc3435714b0ed267c4f01159b77e1e59cd87'
and 'b1d84ce6fa493115c9ddc12b5a5a5a62c4dadee6'
2014-06-27 15:13:02 +00:00
8819dc5f30 Build scripts 2014-06-27 15:11:49 +00:00
zzz
a034b78dfd Update min API to 9 (Gingerbread).
API 8 (Froyo) is now less than 1% of active devices, and
these devices are generally too low-powered to run I2P effectively.
This allows us to move the remaining I2P jars to Java 6.
2014-06-27 13:52:29 +00:00
2dc56d57d4 Reorganized files 2014-06-27 11:42:20 +00:00
3aff1c4f75 Added gradle wrapper 2014-06-27 06:56:12 +00:00
55509adda6 Ask user to enable I2CP if app requests start with I2CP disabled 2014-06-20 02:33:22 +00:00
335 changed files with 6176 additions and 1309 deletions

View File

@ -1,14 +0,0 @@
<?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 exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry combineaccessrules="false" kind="src" path="/i2p_sdk"/>
<classpathentry combineaccessrules="false" kind="src" path="/i2p_router"/>
<classpathentry combineaccessrules="false" kind="src" path="/i2ptunnel"/>
<classpathentry combineaccessrules="false" kind="src" path="/BOB"/>
<classpathentry combineaccessrules="false" kind="src" path="/addressbook"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@ -24,14 +24,19 @@ _jsp\.java$
/classes/
# Android-specific ignores
^bin
^gen
^routerjars/bin
^routerjars/gen
^routerjars/lib
AndroidManifest.xml
lint.xml
^routerjars/libs
local.properties
signing.properties
#IntelliJ IDEA
^.idea
.*.iml
.*.ipr
.*.iws
#Gradle
^.gradle
build
# I2P-specific ignores
^res/raw/blocklist_txt

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>I2P_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>

View File

@ -3,8 +3,15 @@ host = https://www.transifex.com
lang_map = pt_BR: pt-rBR, ru_RU: ru, sv_SE: sv, tr_TR: tr, zh_CN: zh
[I2P.android]
file_filter = res/values-<lang>/strings.xml
source_file = res/values/strings.xml
file_filter = app/src/main/res/values-<lang>/strings.xml
source_file = app/src/main/res/values/strings.xml
source_lang = en
type = ANDROID
minimum_perc = 50
[I2P.android_lib_client]
file_filter = client/src/main/res/values-<lang>/strings.xml
source_file = client/src/main/res/values/strings.xml
source_lang = en
type = ANDROID
minimum_perc = 50

View File

@ -1,127 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.i2p.android.router"
android:versionCode="0"
android:versionName="0.0.0-0_b0-API8"
android:installLocation="auto"
>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-sdk android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application android:label="@string/app_name"
android:theme="@style/Theme.AppCompat"
android:icon="@drawable/ic_launcher_itoopie" >
<service android:name=".service.RouterService"
android:label="@string/app_name"
android:icon="@drawable/ic_launcher_itoopie" >
<intent-filter>
<action android:name="net.i2p.android.router.service.IRouterState" />
</intent-filter>
</service>
<provider android:name=".provider.CacheProvider"
android:authorities="net.i2p.android.router" />
<activity android:name=".MainActivity"
android:label="@string/app_name"
android:icon="@drawable/ic_launcher_itoopie"
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="net.i2p.android.router.START_I2P" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name=".NewsActivity"
android:label="I2P News"
android:configChanges="orientation|keyboardHidden" >
</activity>
<activity android:name=".HelpActivity"
android:label="Help"
android:parentActivityName=".MainActivity" >
</activity>
<activity android:name=".LicenseActivity"
android:label="I2P License Information"
android:parentActivityName=".HelpActivity" >
</activity>
<activity android:name=".web.WebActivity"
android:label="I2P Web Browser"
android:configChanges="orientation|keyboardHidden" >
<!-- Disabled, this browser is not very secure
Temporarily enabled until an alternative browser is ready -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="*.i2p" android:scheme="http" />
</intent-filter>
</activity>
<activity android:name=".SettingsActivity"
android:label="I2P Settings"
android:parentActivityName=".MainActivity" >
</activity>
<activity android:name=".addressbook.AddressbookSettingsActivity"
android:label="I2P Addressbook Settings"
android:parentActivityName=".addressbook.AddressbookActivity"
android:launchMode="singleTop" >
</activity>
<activity android:name=".addressbook.AddressbookActivity"
android:label="Addressbook"
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="@xml/searchable_addressbook"/>
</activity>
<activity android:name=".addressbook.AddressbookAddWizardActivity"
android:label="Add new Destination"
android:parentActivityName=".addressbook.AddressbookActivity" >
</activity>
<activity android:name="net.i2p.android.i2ptunnel.TunnelListActivity"
android:label="I2PTunnel"
android:launchMode="singleTop" >
</activity>
<activity android:name="net.i2p.android.i2ptunnel.TunnelDetailActivity"
android:label="I2PTunnel"
android:parentActivityName="net.i2p.android.i2ptunnel.TunnelListActivity" >
</activity>
<activity android:name="net.i2p.android.i2ptunnel.TunnelWizardActivity"
android:label="Tunnel Creation Wizard"
android:parentActivityName="net.i2p.android.i2ptunnel.TunnelListActivity" >
</activity>
<activity android:name=".log.LogActivity"
android:label="I2P Logs"
android:parentActivityName=".MainActivity" >
</activity>
<activity android:name=".log.LogDetailActivity"
android:label="Log Entry"
android:parentActivityName=".log.LogActivity" >
</activity>
<activity android:name=".stats.RateGraphActivity"
android:label="Rate Graph"
android:parentActivityName=".MainActivity" >
</activity>
<activity android:name=".stats.PeersActivity"
android:label="I2P Peers and Transport Status"
android:configChanges="orientation|keyboardHidden"
android:launchMode="singleTop" >
</activity>
<activity android:name=".netdb.NetDbActivity"
android:label="NetDB"
android:parentActivityName=".MainActivity" >
</activity>
<activity android:name=".netdb.NetDbDetailActivity"
android:label="NetDB Detail"
android:parentActivityName=".netdb.NetDbActivity" >
</activity>
</application>
</manifest>

159
README.md Normal file
View File

@ -0,0 +1,159 @@
# I2P Android
## Build process
### Dependencies:
- Java SDK (preferably Oracle/Sun or OpenJDK) 1.6.0 or higher
- Apache Ant 1.8.0 or higher
- I2P source
- Android SDK (tested with Rev 22.6.4 and platform-tools version 19.1)
- Android Support Repository
- Gradle 1.12
### Gradle
The build system is based on Gradle. There are several methods for setting Gradle up:
* It can be downloaded from [the Gradle website](http://www.gradle.org/downloads).
* Most distributions will have Gradle packages. Be careful to check the
provided version; Debian and Ubuntu have old versions in their main
repositories. There is a [PPA](https://launchpad.net/~cwchien/+archive/gradle)
for Ubuntu with the latest version of Gradle.
* A Gradle wrapper is provided in the codebase. It takes all the same commands
as the regular `gradle` command. The first time that any command is run, it
will automatically download, cache and use the correct version of Gradle.
This is the simplest way to get started with the codebase. To use it, replace
`gradle` with `./gradlew` (or `./gradlew.bat` on Windows) in the commands
below.
Gradle will pull dependencies over the clearnet by default. To send all Gradle
connections from your user over Tor, create a `gradle.properties` file in
`~/.gradle/` containing:
```
systemProp.socksProxyHost=localhost
systemProp.socksProxyPort=9150
```
### Preparation
1. Download the Android SDK. The simplest method is to download [Android Studio](https://developer.android.com/sdk/installing/studio.html).
* If you are using an existing Android SDK, install the Android Support
Repository via the SDK Manager.
2. Check out the [`i2p.i2p`](https://github.com/i2p/i2p.i2p) repository.
3. Create a `local.properties` file in `i2p.android.base/routerjars` containing:
```
i2psrc=/path/to/i2p.i2p
```
### Building from the command line
1. Create a `local.properties` file in `i2p.android.base` containing:
```
sdk.dir=/path/to/android-studio/sdk
```
2. `gradle assembleDebug`
3. The APK will be placed in `i2p.android.base/app/build/outputs/apk`.
### Building with Android Studio
1. Import `i2p.android.base` into Android Studio. (This creates the `local.properties` file automatically).
2. Build and run the app (`Shift+F10`).
### Signing release builds
1. Create a `signing.properties` file in `i2p.android.base` containing:
```
STORE_FILE=/path/to/android.keystore
STORE_PASSWORD=store.password
KEY_ALIAS=key.alias
KEY_PASSWORD=key.password
```
2. `gradle assembleRelease`
## Client library
### "Uploading" to a local file repository (to use a local build of the library in a project)
1. Add the following line to your `~/.gradle/gradle.properties`:
```
localFileRepoDir=/path/to/local/file/repo
```
2. `gradle :client:uploadArchives`
3. Add the resulting directory to your project as a repository. For Gradle projects, add the following above any existing repositories (so it is checked first):
```
repositories {
flatDir {
name 'fileRepo'
dirs file('/path/to/local/file/repo')
}
}
```
### Uploading to Maven Central via Sonatype OSSRH
1. Add the following lines to your `~/.gradle/gradle.properties` (filling in the blanks):
```
signing.keyId=
signing.password=
signing.secretKeyRingFile=/path/to/secring.gpg
ossrhUsername=
ossrhPassword=
```
2. `gradle :client:uploadArchives`
### Commands from the old build instructions that might be useful
```
# Create the android 4.4 (API 19) virtual device
# (don't make a custom hardware profile)
../android-sdk-linux/tools/android create avd --name i2p --target android-19
# then run the emulator:
# This may take a LONG time the first time (half an hour or more)...
# Run the debugger to ensure it is making progress
# -no-boot-anim for faster boot
# -dns-server 8.8.8.8 if the router can't reseed
# ../android-sdk-linux/tools/emulator -avd i2p -no-boot-anim -dns-server 8.8.8.8 &
../android-sdk-linux/tools/emulator -avd i2p &
# or to talk to a real device in debug mode:
# You have to do this if you get a permission error -
# Stop ddms, unplug the device, do the following,
# then plug in the device, then start ddms
adb kill-server
sudo adb start-server
adb devices
# Anyway, with I2P installed, click on the I2P icon on your device and enjoy!
#other helpful commands
../android-sdk-linux/platform-tools/adb shell
../android-sdk-linux/platform-tools/adb pull /some/file/on/emulator some-local-dir/
# copy the Dev Tools app from the emulator to your device
adb -e pull /system/app/Development.apk ./Development.apk
adb -d install Development.apk
# reinstall an existing apk onto the emulator
adb -e install -r bin/I2PAndroid-debug.apk
```

View File

@ -1,116 +0,0 @@
These instructions are for a recent Android SDK (Rev 20 or better) on Linux.
Windows building is not currently supported.
These instructions were last updated for SDK Tools Version 20 with
SDK Platform-tools Version 12 from updates.
The i2p source must be installed in ../i2p.i2p,
or else add i2psrc=/path/to/source in the local.properties file.
=====================
Dependencies:
- Java SDK (preferably Oracle/Sun or OpenJDK) 1.6.0 or higher
- Apache Ant 1.8.0 or higher
- I2P source in ../i2p.i2p
- Android SDK (tested with Rev 22.3 and platform-tools version 19)
=====================
Instructions:
# Download the SDK from http://developer.android.com/sdk/index.html
# Unzip the android SDK in ../
# So then the android tools will be in ../android-sdk-linux/tools/
#
# Run the GUI updater, which you must do to get an SDK Platform:
../android-sdk-linux/tools/android &
# now go to the available packages tab, check the box and click refresh,
# and download an SDK Platform
# Since I2P is targeted at 4.4 (API 19)
# download at least that one. Otherwise you must change the
# target in project.properties from android-19 to andriod-x
# where x is the API version.
# I2P is configured to run on 2.2 (API 8) or higher using the
# Android Support Library, so download that as well
# (it's under "Extras").
# update the compatibility project
../android-sdk-linux/tools/android update lib-project -p ../android-sdk-linux/extras/android/support/v7/appcompat -t android-19
# To run the debugger (ddms) you also need to download the
# "Android SDK Platform-Tools" package from the GUI updater.
# create a file local.properties with the following line (without the leading # of course),
# do NOT use a relative path
# sdk.dir=/path/to/your/android-sdk-linux
# Copy this file to the routerjars/ directory, it is needed in both places.
# If your SDK is not in ../android-sdk-linux/ then you must
# override the location of the Android Support Library. Add
# the following line to local.properties
# do NOT use an absolute path
# android.library.reference.2=path/to/your/android-sdk-linux/extras/android/support/v7/appcompat
# Don't add it to the local.properties in the routerjars/ directory.
# DO NOT create a new project or anything. It's all set up right here for you.
# Create the android 4.4 (API 19) virtual device
# (don't make a custom hardware profile)
../android-sdk-linux/tools/android create avd --name i2p --target android-19
# then run the emulator:
# This may take a LONG time the first time (half an hour or more)...
# Run the debugger to ensure it is making progress
# -no-boot-anim for faster boot
# -dns-server 8.8.8.8 if the router can't reseed
# ../android-sdk-linux/tools/emulator -avd i2p -no-boot-anim -dns-server 8.8.8.8 &
../android-sdk-linux/tools/emulator -avd i2p &
# or to talk to a real device in debug mode:
# You have to do this if you get a permission error -
# Stop ddms, unplug the device, do the following,
# then plug in the device, then start ddms
adb kill-server
sudo adb start-server
adb devices
# then wait a couple minutes until the emulator or device is up
# compile and install for a release
ant release
ant installr
# or compile and install for a debug version
ant debug
ant installd
# then run the debugger
../android-sdk-linux/tools/ddms &
# to rebuild and reinstall to emulator or device:
ant clean
# then do which ever from the above compile and install choices.
# to uninstall
ant uninstall
# or use your device's menu.
# Other ant tagets are available, just type
ant
# Anyway, with I2P installed, click on the I2P icon on your device and enjoy!
#other helpful commands
../android-sdk-linux/platform-tools/adb shell
../android-sdk-linux/platform-tools/adb pull /some/file/on/emulator some-local-dir/
# copy the Dev Tools app from the emulator to your device
adb -e pull /system/app/Development.apk ./Development.apk
adb -d install Development.apk
# reinstall an existing apk onto the emulator
adb -e install -r bin/I2PAndroid-debug.apk

12
TODO
View File

@ -1,5 +1,13 @@
# Required for release
# Fixes
- Better addressbook column widths
<zzz> on the i2ptunnel and addressbook pages on the tablet, the columns are too skinny, they aren't as wide as the tab
<zzz> only a few addressbook entries wrap but on i2ptunnel everything is wrapped and most of the screen is empty
# Short-term
- Disable uPnP when on cell networks
<zzz> spewing UPnP out into cell networks is a waste of time at best and a security risk at worst, but you really want it for wifi
- Display release notes directly on new router version
- Text content
- Move help content from release notes to help page
@ -14,7 +22,7 @@
- Maybe change router-off mechanic for various pages? Enable as they become available?
- Add "copy (error) log" option
# Short-term
# Medium-term
- Expose log level overrides
- Improve graphs

View File

@ -1,4 +0,0 @@
application-package=net.i2p.router
key.store=${user.home}/.android/${application-package}.keystore
key.alias=${application-package}
key.store.password=android

158
app/build.gradle Normal file
View File

@ -0,0 +1,158 @@
apply plugin: 'android'
apply plugin: 'witness'
android {
compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
defaultConfig {
minSdkVersion 9
targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
}
signingConfigs {
release
}
buildTypes {
release {
signingConfig signingConfigs.release
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
lintOptions {
abortOnError false
}
productFlavors {
free {
applicationId 'net.i2p.android'
}
donate {
applicationId 'net.i2p.android.donate'
}
legacy {
applicationId 'net.i2p.android.router'
}
}
}
dependencies {
compile project(':routerjars')
compile project(':client')
compile 'com.android.support:support-v4:19.1.0'
compile 'com.android.support:appcompat-v7:19.1.0'
compile files('libs/androidplot-core-0.6.0.jar')
}
dependencyVerification {
verify = [
'com.android.support:support-v4:3f40fa7b3a4ead01ce15dce9453b061646e7fe2e7c51cb75ca01ee1e77037f3f',
'com.android.support:appcompat-v7:9df7637c5219202ddbbbf0924c2d5a9e6d64379166795a89d8f75d1e3f3372df',
]
}
project.ext.i2pbase = '../i2p.i2p'
def Properties props = new Properties()
def propFile = new File(project(':routerjars').projectDir, 'local.properties')
if (propFile.canRead()) {
props.load(new FileInputStream(propFile))
if (props != null &&
props.containsKey('i2psrc')) {
i2pbase = props['i2psrc']
} else {
println 'local.properties found but some entries are missing'
}
} else {
println 'local.properties not found'
}
task certificatesZip(type: Zip) {
archiveName = 'certificates_zip'
from files('' + i2pbase + '/installer/resources/certificates')
}
task copyI2PResources(type: Copy) {
into 'src/main'
into('res/drawable') {
from file(i2pbase + '/installer/resources/themes/console/images/i2plogo.png')
}
into('res/raw') {
from(i2pbase + '/installer/resources/blocklist.txt') { rename {'blocklist_txt' } }
from(i2pbase + '/installer/resources/hosts.txt') { rename {'hosts_txt' } }
from('../LICENSE.txt') { rename {'license_app_txt' } }
from('../licenses/LICENSE-Apache2.0.txt') { rename {'license_apache20_txt' } }
from(i2pbase + '/licenses') {
include { elem ->
elem.name in [
'LICENSE-ElGamalDSA.txt',
'LICENSE-SHA256.txt',
'LICENSE-BSD.txt',
'LICENSE-SNTP.txt',
'LICENSE-LGPLv2.1.txt',
'LICENSE-InstallCert.txt',
'LICENSE-BlockFile.txt',
'LICENSE-GPLv2.txt',
'LICENSE-GPLv3.txt',
'LICENSE-LGPLv3.txt',
'LICENSE-FatCowIcons.txt',
'LICENSE-Addressbook.txt',
]
}
rename { String name ->
String part = name.substring(8, name.lastIndexOf('.txt'))
String.format('license_%s_txt',
part.toLowerCase(Locale.US).replace('.', '_'))
}
}
from certificatesZip
}
// For peers WebView
into('assets/themes/console/images') {
from file(i2pbase + '/installer/resources/themes/console/images/i2plogo.png')
from file(i2pbase + '/installer/resources/themes/console/images/inbound.png')
from file(i2pbase + '/installer/resources/themes/console/images/outbound.png')
}
into ('assets/themes/console/light') {
from file(i2pbase + '/installer/resources/themes/console/light/console.css')
}
into('assets/themes/console/light/images') {
from file(i2pbase + '/installer/resources/themes/console/light/images/header.png')
}
}
task cleanI2PResources(type: Delete) {
delete file('src/main/res/drawable/i2plogo.png')
delete fileTree('src/main/res/raw') {
include 'blocklist_txt'
include 'hosts_txt'
include 'license_*'
include 'certificates_zip'
}
delete fileTree('src/main/assets/themes/console/images')
delete file('src/main/assets/themes/console/light/console.css')
delete file('src/main/assets/themes/console/light/images/header.png')
}
preBuild.dependsOn copyI2PResources
clean.dependsOn cleanI2PResources
props = new Properties()
propFile = new File(project.rootDir, 'signing.properties')
if (propFile.canRead()) {
props.load(new FileInputStream(propFile))
if (props != null &&
props.containsKey('STORE_FILE') &&
props.containsKey('STORE_PASSWORD') &&
props.containsKey('KEY_ALIAS') &&
props.containsKey('KEY_PASSWORD')) {
android.signingConfigs.release.storeFile = file(props['STORE_FILE'])
android.signingConfigs.release.storePassword = props['STORE_PASSWORD']
android.signingConfigs.release.keyAlias = props['KEY_ALIAS']
android.signingConfigs.release.keyPassword = props['KEY_PASSWORD']
} else {
println 'signing.properties found but some entries are missing'
android.buildTypes.release.signingConfig = null
}
} else {
println 'signing.properties not found'
android.buildTypes.release.signingConfig = null
}

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
<header
android:fragment="net.i2p.android.router.SettingsActivity$SettingsFragment"
android:title="@string/settings_label_bandwidth_net">
<extra
android:name="settings"
android:value="net" />
</header>
<header
android:fragment="net.i2p.android.router.SettingsActivity$SettingsFragment"
android:title="@string/label_graphs">
<extra
android:name="settings"
android:value="graphs" />
</header>
<header
android:fragment="net.i2p.android.router.SettingsActivity$SettingsFragment"
android:title="@string/settings_label_logging">
<extra
android:name="settings"
android:value="logging" />
</header>
<header
android:title="@string/label_addressbook">
<intent
android:targetPackage="net.i2p.android.donate"
android:targetClass="net.i2p.android.router.addressbook.AddressbookSettingsActivity" />
</header>
<header
android:fragment="net.i2p.android.router.SettingsActivity$SettingsFragment"
android:title="@string/settings_label_advanced">
<extra
android:name="settings"
android:value="advanced" />
</header>
</preference-headers>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<Preference android:title="@string/settings_label_bandwidth_net">
<intent
android:targetPackage="net.i2p.android.donate"
android:targetClass="net.i2p.android.router.SettingsActivity"
android:action="net.i2p.android.router.PREFS_NET" />
</Preference>
<Preference android:title="@string/label_graphs">
<intent
android:targetPackage="net.i2p.android.donate"
android:targetClass="net.i2p.android.router.SettingsActivity"
android:action="net.i2p.android.router.PREFS_GRAPHS" />
</Preference>
<Preference android:title="@string/settings_label_logging">
<intent
android:targetPackage="net.i2p.android.donate"
android:targetClass="net.i2p.android.router.SettingsActivity"
android:action="net.i2p.android.router.PREFS_LOGGING" />
</Preference>
<Preference android:title="@string/label_addressbook">
<intent
android:targetPackage="net.i2p.android.donate"
android:targetClass="net.i2p.android.router.addressbook.AddressbookSettingsActivity" />
</Preference>
<Preference android:title="@string/settings_label_advanced">
<intent
android:targetPackage="net.i2p.android.donate"
android:targetClass="net.i2p.android.router.SettingsActivity"
android:action="net.i2p.android.router.PREFS_ADVANCED" />
</Preference>
</PreferenceScreen>

View File

@ -0,0 +1,204 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.i2p.android.router"
android:installLocation="auto"
android:versionCode="4745219"
android:versionName="0.9.14.1-rc3">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="19" />
<application
android:icon="@drawable/ic_launcher_itoopie"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat">
<service
android:name=".service.RouterService"
android:icon="@drawable/ic_launcher_itoopie"
android:label="@string/app_name">
<intent-filter>
<action android:name="net.i2p.android.router.service.IRouterState" />
</intent-filter>
</service>
<provider
android:name=".provider.CacheProvider"
android:authorities="net.i2p.android" />
<activity
android:name=".MainActivity"
android:icon="@drawable/ic_launcher_itoopie"
android:label="@string/app_name"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="net.i2p.android.router.START_I2P" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".NewsActivity"
android:configChanges="orientation|keyboardHidden"
android:label="I2P News"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.MainActivity" />
</activity>
<activity
android:name=".HelpActivity"
android:label="Help"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.MainActivity" />
</activity>
<activity
android:name=".LicenseActivity"
android:label="I2P License Information"
android:parentActivityName=".HelpActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.HelpActivity" />
</activity>
<activity
android:name=".web.WebActivity"
android:configChanges="orientation|keyboardHidden"
android:label="I2P Web Browser">
<!-- Disabled, this browser is not very secure
Temporarily enabled until an alternative browser is ready -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="*.i2p"
android:scheme="http" />
</intent-filter>
</activity>
<activity
android:name=".SettingsActivity"
android:label="I2P Settings"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.MainActivity" />
</activity>
<activity
android:name=".addressbook.AddressbookSettingsActivity"
android:label="I2P Addressbook Settings"
android:launchMode="singleTop"
android:parentActivityName=".addressbook.AddressbookActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.addressbook.AddressbookActivity" />
</activity>
<activity
android:name=".addressbook.AddressbookActivity"
android:label="Addressbook"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable_addressbook" />
</activity>
<activity
android:name=".addressbook.AddressbookAddWizardActivity"
android:label="Add new Destination"
android:parentActivityName=".addressbook.AddressbookActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.addressbook.AddressbookActivity" />
</activity>
<activity
android:name="net.i2p.android.i2ptunnel.TunnelListActivity"
android:label="I2PTunnel"
android:launchMode="singleTop"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.MainActivity" />
</activity>
<activity
android:name="net.i2p.android.i2ptunnel.TunnelDetailActivity"
android:label="I2PTunnel"
android:parentActivityName="net.i2p.android.i2ptunnel.TunnelListActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.i2ptunnel.TunnelListActivity" />
</activity>
<activity
android:name="net.i2p.android.i2ptunnel.TunnelWizardActivity"
android:label="Tunnel Creation Wizard"
android:parentActivityName="net.i2p.android.i2ptunnel.TunnelListActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.i2ptunnel.TunnelListActivity" />
</activity>
<activity
android:name=".log.LogActivity"
android:label="I2P Logs"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.MainActivity" />
</activity>
<activity
android:name=".log.LogDetailActivity"
android:label="Log Entry"
android:parentActivityName=".log.LogActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.log.LogActivity" />
</activity>
<activity
android:name=".stats.RateGraphActivity"
android:label="Rate Graph"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.MainActivity" />
</activity>
<activity
android:name=".stats.PeersActivity"
android:configChanges="orientation|keyboardHidden"
android:label="I2P Peers and Transport Status"
android:launchMode="singleTop"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.MainActivity" />
</activity>
<activity
android:name=".netdb.NetDbActivity"
android:label="NetDB"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.MainActivity" />
</activity>
<activity
android:name=".netdb.NetDbDetailActivity"
android:label="NetDB Detail"
android:parentActivityName=".netdb.NetDbActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.netdb.NetDbActivity" />
</activity>
</application>
</manifest>

View File

@ -18,6 +18,7 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
@ -100,6 +101,9 @@ public class TunnelDetailFragment extends Fragment {
TextView accessIfacePort = (TextView) v.findViewById(R.id.tunnel_access_interface_port);
accessIfacePort.setText(mTunnel.getIfacePort());
CheckBox autoStart = (CheckBox) v.findViewById(R.id.tunnel_autostart);
autoStart.setChecked(mTunnel.startAutomatically());
}
return v;

View File

@ -90,6 +90,7 @@ public class TunnelWizardModel extends AbstractWizardModel {
new SingleTextFieldPage(this, res.getString(R.string.i2ptunnel_wizard_k_target_port))
.setDescription(res.getString(R.string.i2ptunnel_wizard_desc_target_port))
.setNumeric(true)
.setRequired(true)
.setEqualCondition(cTunnelType, res.getString(R.string.i2ptunnel_wizard_v_server)),
@ -110,6 +111,7 @@ public class TunnelWizardModel extends AbstractWizardModel {
new SingleTextFieldPage(this, res.getString(R.string.i2ptunnel_wizard_k_binding_port))
.setDescription(res.getString(R.string.i2ptunnel_wizard_k_binding_port))
.setNumeric(true)
.setRequired(true)
.setEqualCondition(cTunnelType, res.getString(R.string.i2ptunnel_wizard_v_client))
.setEqualCondition(cServerType, res.getString(R.string.i2ptunnel_type_httpbidirserver)),

View File

@ -7,22 +7,23 @@ import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar.Tab;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import net.i2p.android.i2ptunnel.TunnelListActivity;
import net.i2p.android.router.R;
import net.i2p.android.router.addressbook.AddressbookActivity;
import net.i2p.android.router.log.LogActivity;
import net.i2p.android.router.netdb.NetDbActivity;
@ -46,7 +47,6 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mActivityTitles;
/**
* Router variables
@ -103,7 +103,14 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
setContentView(R.layout.activity_navdrawer_onepane);
mTitle = mDrawerTitle = getTitle();
mActivityTitles = getResources().getStringArray(R.array.navdrawer_activity_titles);
String[] activityTitles = getResources().getStringArray(R.array.navdrawer_activity_titles);
if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("i2pandroid.main.showStats", false)) {
String[] advActivityTitles = getResources().getStringArray(R.array.navdrawer_activity_titles_advanced);
String[] allTitles = new String[activityTitles.length + advActivityTitles.length];
System.arraycopy(activityTitles, 0, allTitles, 0, activityTitles.length);
System.arraycopy(advActivityTitles, 0, allTitles, activityTitles.length, advActivityTitles.length);
activityTitles = allTitles;
}
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.drawer);
@ -112,7 +119,7 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
mDrawerList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
// Set the adapter for the list view
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mActivityTitles));
android.R.layout.simple_list_item_1, activityTitles));
// Set the list's click listener
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
@ -161,37 +168,37 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
private void selectItem(int pos) {
switch (pos) {
case 1:
Intent news = new Intent(I2PActivityBase.this, NewsActivity.class);
startActivity(news);
break;
case 2:
Intent ab = new Intent(I2PActivityBase.this, AddressbookActivity.class);
startActivity(ab);
break;
case 2:
case 3:
Intent itb = new Intent(I2PActivityBase.this, TunnelListActivity.class);
startActivity(itb);
break;
case 3:
case 4:
Intent log = new Intent(I2PActivityBase.this, LogActivity.class);
startActivity(log);
break;
case 4:
Intent active = new Intent(I2PActivityBase.this, RateGraphActivity.class);
startActivity(active);
break;
case 5:
Intent peers = new Intent(I2PActivityBase.this, PeersActivity.class);
startActivity(peers);
break;
case 6:
Intent netdb = new Intent(I2PActivityBase.this, NetDbActivity.class);
startActivity(netdb);
break;
case 7:
Intent wp = new Intent(I2PActivityBase.this, WebActivity.class);
wp.putExtra(WebFragment.HTML_RESOURCE_ID, R.raw.welcome_html);
startActivity(wp);
break;
case 6:
Intent active = new Intent(I2PActivityBase.this, RateGraphActivity.class);
startActivity(active);
break;
case 7:
Intent peers = new Intent(I2PActivityBase.this, PeersActivity.class);
startActivity(peers);
break;
case 8:
Intent news = new Intent(I2PActivityBase.this, NewsActivity.class);
startActivity(news);
Intent netdb = new Intent(I2PActivityBase.this, NetDbActivity.class);
startActivity(netdb);
break;
default:
Intent main = new Intent(I2PActivityBase.this, MainActivity.class);
@ -362,7 +369,7 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
Util.d(this + " calling startService");
ComponentName name = startService(intent);
if (name == null)
Util.d(this + " XXXXXXXXXXXXXXXXXXXX got from startService: " + name);
Util.d(this + " XXXXXXXXXXXXXXXXXXXX got null from startService!");
Util.d(this + " got from startService: " + name);
boolean success = bindRouter(true);
if (!success)

View File

@ -58,7 +58,7 @@ class InitActivities {
Util.d("MODEL" + ": " + Build.MODEL);
Util.d("DISPLAY" + ": " + Build.DISPLAY);
Util.d("VERSION" + ": " + Build.VERSION.RELEASE);
Util.d("SDK" + ": " + Build.VERSION.SDK);
Util.d("SDK" + ": " + Build.VERSION.SDK_INT);
}
void initialize() {
@ -234,7 +234,7 @@ class InitActivities {
* and write back
*
* @param f relative to base dir
* @param props local overrides or null
* @param overrides local overrides or null
*/
public void mergeResourceToFile(int resID, String f, Properties overrides) {
InputStream in = null;

View File

@ -1,25 +1,36 @@
package net.i2p.android.router;
import java.io.File;
import java.util.List;
import java.util.Properties;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.support.v4.app.DialogFragment;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import net.i2p.android.router.R;
import net.i2p.android.router.dialog.AboutDialog;
import net.i2p.android.router.dialog.TextResourceDialog;
import net.i2p.android.router.service.IRouterState;
import net.i2p.android.router.service.IRouterStateCallback;
import net.i2p.android.router.service.RouterService;
import net.i2p.android.router.service.State;
import net.i2p.android.router.util.Util;
import net.i2p.router.RouterContext;
import net.i2p.util.OrderedProperties;
public class MainActivity extends I2PActivityBase implements
MainFragment.RouterControlListener {
@ -71,15 +82,21 @@ public class MainActivity extends I2PActivityBase implements
return;
if (action.equals("net.i2p.android.router.START_I2P")) {
if (canStart()) {
if (Util.isConnected(this)) {
mAutoStartFromIntent = true;
onStartRouterClicked();
} else {
// Not connected to a network
// TODO: Notify user
}
autoStart();
}
}
private void autoStart() {
if (canStart()) {
if (Util.isConnected(this)) {
mAutoStartFromIntent = true;
onStartRouterClicked();
} else {
// Not connected to a network
// TODO: Notify user
}
} else {
// TODO: Notify user
}
}
@ -91,9 +108,9 @@ public class MainActivity extends I2PActivityBase implements
if (mStateService.isStarted()) {
// Update for the current state.
Util.d("Fetching state.");
String curState = mStateService.getState();
State curState = mStateService.getState();
Message msg = mHandler.obtainMessage(STATE_MSG);
msg.getData().putString("state", curState);
msg.getData().putParcelable(MSG_DATA, curState);
mHandler.sendMessage(msg);
} else {
Util.d("StateService not started yet");
@ -189,9 +206,9 @@ public class MainActivity extends I2PActivityBase implements
mStateService.registerCallback(mStateCallback);
// Update for the current state.
Util.d("Fetching state.");
String curState = mStateService.getState();
State curState = mStateService.getState();
Message msg = mHandler.obtainMessage(STATE_MSG);
msg.getData().putString("state", curState);
msg.getData().putParcelable(MSG_DATA, curState);
mHandler.sendMessage(msg);
} else {
// Unbind
@ -222,23 +239,24 @@ public class MainActivity extends I2PActivityBase implements
* NOT be running in our main thread like most other things -- so,
* to update the UI, we need to use a Handler to hop over there.
*/
public void stateChanged(String newState) throws RemoteException {
public void stateChanged(State newState) throws RemoteException {
Message msg = mHandler.obtainMessage(STATE_MSG);
msg.getData().putString("state", newState);
msg.getData().putParcelable(MSG_DATA, newState);
mHandler.sendMessage(msg);
}
};
private static final int STATE_MSG = 1;
private static final String MSG_DATA = "state";
private Handler mHandler = new Handler() {
private String lastRouterState = null;
private State lastRouterState = null;
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case STATE_MSG:
String state = msg.getData().getString("state");
if (lastRouterState == null || !lastRouterState.equals(state)) {
State state = msg.getData().getParcelable(MSG_DATA);
if (lastRouterState == null || lastRouterState != state) {
if (mMainFragment == null)
mMainFragment = (MainFragment) getSupportFragmentManager().findFragmentById(R.id.main_fragment);
if (mMainFragment != null) {
@ -246,7 +264,7 @@ public class MainActivity extends I2PActivityBase implements
lastRouterState = state;
}
if ("RUNNING".equals(state) && mAutoStartFromIntent) {
if (state == State.RUNNING && mAutoStartFromIntent) {
setResult(RESULT_OK);
finish();
}

View File

@ -8,24 +8,17 @@ import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.ToggleButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ToggleButton;
import java.text.Collator;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import net.i2p.android.router.R;
import net.i2p.android.router.dialog.FirstStartDialog;
import net.i2p.android.router.dialog.VersionDialog;
import net.i2p.android.router.service.State;
import net.i2p.android.router.util.LongToggleButton;
import net.i2p.android.router.util.Util;
import net.i2p.data.DataHelper;
@ -36,6 +29,13 @@ import net.i2p.router.RouterContext;
import net.i2p.router.TunnelPoolSettings;
import net.i2p.util.Translate;
import java.text.Collator;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class MainFragment extends I2PFragmentBase {
private Handler _handler;
@ -159,7 +159,7 @@ public class MainFragment extends I2PFragmentBase {
}
private void updateOneShot() {
_handler.postDelayed(_oneShotUpdate, 100);
_handler.postDelayed(_oneShotUpdate, 10);
}
private class OneShotUpdate implements Runnable {
@ -198,7 +198,7 @@ public class MainFragment extends I2PFragmentBase {
// is not received. Ensure that the state image is correct.
// TODO: Fix the race between RouterService shutdown and
// IRouterState unbinding.
updateState("INIT");
updateState(State.INIT);
}
}
@ -235,25 +235,25 @@ public class MainFragment extends I2PFragmentBase {
}
}
public void updateState(String newState) {
public void updateState(State newState) {
final ImageView lightImage = (ImageView) getView().findViewById(R.id.main_lights);
if ("INIT".equals(newState) ||
"STOPPED".equals(newState) ||
"MANUAL_STOPPED".equals(newState) ||
"MANUAL_QUITTED".equals(newState) ||
"NETWORK_STOPPED".equals(newState)) {
if (newState == State.INIT ||
newState == State.STOPPED ||
newState == State.MANUAL_STOPPED ||
newState == State.MANUAL_QUITTED ||
newState == State.NETWORK_STOPPED) {
lightImage.setImageResource(R.drawable.routerlogo_0);
} else if ("STARTING".equals(newState) ||
"STOPPING".equals(newState) ||
"MANUAL_STOPPING".equals(newState) ||
"MANUAL_QUITTING".equals(newState) ||
"NETWORK_STOPPING".equals(newState)) {
} else if (newState == State.STARTING ||
newState == State.STOPPING ||
newState == State.MANUAL_STOPPING ||
newState == State.MANUAL_QUITTING ||
newState == State.NETWORK_STOPPING) {
lightImage.setImageResource(R.drawable.routerlogo_1);
} else if ("RUNNING".equals(newState)) {
} else if (newState == State.RUNNING) {
lightImage.setImageResource(R.drawable.routerlogo_2);
} else if ("ACTIVE".equals(newState)) {
} else if (newState == State.ACTIVE) {
lightImage.setImageResource(R.drawable.routerlogo_3);
} else if ("WAITING".equals(newState)) {
} else if (newState == State.WAITING) {
lightImage.setImageResource(R.drawable.routerlogo_4);
} // Ignore unknown states.
}
@ -266,7 +266,7 @@ public class MainFragment extends I2PFragmentBase {
if(!Util.isConnected(getActivity())) {
// Manually set state, RouterService won't be running
updateState("WAITING");
updateState(State.WAITING);
vStatusText.setText("No Internet connection is available");
vStatus.setVisibility(View.VISIBLE);
sv.setVisibility(View.VISIBLE);
@ -357,7 +357,7 @@ public class MainFragment extends I2PFragmentBase {
vStatusText.setText(_savedStatus);
vStatus.setVisibility(View.VISIBLE);
} else {
vStatus.setVisibility(View.INVISIBLE);
vStatus.setVisibility(View.GONE);
}
sv.setVisibility(View.VISIBLE);
} else {
@ -401,6 +401,7 @@ public class MainFragment extends I2PFragmentBase {
// Client or server
ImageView type = new ImageView(getActivity());
type.setPadding(6, 6, 6, 6);
if (ctx.clientManager().shouldPublishLeaseSet(h))
type.setImageDrawable(getActivity().getResources()
.getDrawable(R.drawable.server));
@ -411,6 +412,7 @@ public class MainFragment extends I2PFragmentBase {
// Name
TextView destName = new TextView(getActivity());
destName.setPadding(6, 0, 0, 0);
destName.setText(name);
//destName.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
dest.addView(destName);

View File

@ -36,7 +36,7 @@ import net.i2p.util.OrderedProperties;
public class SettingsActivity extends PreferenceActivity {
// Actions for legacy settings
private static final String ACTION_PREFS_NET = "net.i2p.android.router.PREFS_NET";
private static final String ACTION_PREFS_GRAPHS = "net.i2p.android.router.PREFS_GRAPHS";
public static final String ACTION_PREFS_GRAPHS = "net.i2p.android.router.PREFS_GRAPHS";
private static final String ACTION_PREFS_LOGGING = "net.i2p.android.router.PREFS_LOGGING";
private static final String ACTION_PREFS_ADVANCED = "net.i2p.android.router.PREFS_ADVANCED";

View File

@ -99,7 +99,7 @@ public class AddressbookActivity extends I2PActivityBase
// AddressbookFragment.OnAddressSelectedListener
public void onAddressSelected(CharSequence host) {
if (getIntent().getAction() == Intent.ACTION_PICK) {
if (Intent.ACTION_PICK.equals(getIntent().getAction())) {
Intent result = new Intent();
result.setData(Uri.parse("http://" + host));
setResult(Activity.RESULT_OK, result);

View File

@ -34,14 +34,14 @@ public class AddressbookFragment extends ListFragment implements
public static final String PRIVATE_BOOK = "privatehosts.txt";
public static final String ADD_WIZARD_DATA = "add_wizard_data";
static final int ADD_WIZARD_REQUEST = 1;
private static final int ADD_WIZARD_REQUEST = 1;
private static final int ROUTER_LOADER_ID = 1;
private static final int PRIVATE_LOADER_ID = 2;
private boolean mOnActivityCreated;
RouterContextProvider mRouterContextProvider;
OnAddressSelectedListener mCallback;
private RouterContextProvider mRouterContextProvider;
private OnAddressSelectedListener mCallback;
private AddressEntryAdapter mAdapter;
private String mBook;
private String mCurFilter;

View File

@ -16,8 +16,8 @@ import net.i2p.util.FileUtil;
public class AddressbookSettingsActivity extends Activity {
protected EditText text_content_subscriptions;
protected Button btn_save_subscriptions;
private EditText text_content_subscriptions;
private Button btn_save_subscriptions;
private String filename = "/addressbook/subscriptions.txt";
private File i2pDir;

View File

@ -168,7 +168,7 @@ public class LogFragment extends ListFragment implements
if (loader.getId() == ("ERROR".equals(mLogLevel) ?
LEVEL_ERROR : LEVEL_ALL)) {
mAdapter.setData(data);
String header = getHeader(data.size(), (mLogLevel == "ERROR"));
String header = getHeader(data.size(), ("ERROR".equals(mLogLevel)));
mHeaderView.setText(header);
if (isResumed()) {

View File

@ -1,7 +1,16 @@
package net.i2p.android.router.netdb;
import java.util.Map;
import java.util.Set;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import net.i2p.android.router.I2PFragmentBase;
import net.i2p.android.router.R;
@ -14,17 +23,8 @@ import net.i2p.data.Lease;
import net.i2p.data.LeaseSet;
import net.i2p.data.RouterAddress;
import net.i2p.data.RouterInfo;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import java.util.Map;
public class NetDbDetailFragment extends I2PFragmentBase {
public static final String IS_RI = "is_routerinfo";
@ -131,7 +131,7 @@ public class NetDbDetailFragment extends I2PFragmentBase {
TableLayout stats = (TableLayout) getView().findViewById(R.id.ri_stats);
Map<Object, Object> p = ri.getOptionsMap();
for (Map.Entry<Object,Object> e : (Set<Map.Entry<Object,Object>>) p.entrySet()) {
for (Map.Entry<Object,Object> e : p.entrySet()) {
String key = (String)e.getKey();
String val = (String)e.getValue();
addTableRow(stats, DataHelper.stripHTML(key), DataHelper.stripHTML(val));
@ -149,7 +149,7 @@ public class NetDbDetailFragment extends I2PFragmentBase {
addTableRow(table, "cost", ""+cost);
Map<Object, Object> p = addr.getOptionsMap();
for (Map.Entry<Object,Object> e : (Set<Map.Entry<Object,Object>>) p.entrySet()) {
for (Map.Entry<Object,Object> e : p.entrySet()) {
String key = (String)e.getKey();
String val = (String)e.getValue();
addTableRow(table, DataHelper.stripHTML(key), DataHelper.stripHTML(val));

View File

@ -31,7 +31,7 @@ public class NetDbEntry {
}
public static NetDbEntry fromLeaseSet(RouterContext ctx, LeaseSet ls) {
String nick = "";
String nick;
boolean local = false;
boolean unpublished = false;
Destination dest = ls.getDestination();
@ -55,8 +55,8 @@ public class NetDbEntry {
return new NetDbEntry(ls, nick, local, unpublished);
}
public NetDbEntry(RouterInfo ri,
boolean isUs, String country) {
private NetDbEntry(RouterInfo ri,
boolean isUs, String country) {
mIsRI = true;
mEntry = ri;
@ -67,8 +67,8 @@ public class NetDbEntry {
mLocal = mUnpublished = false;
}
public NetDbEntry(LeaseSet ls,
String nick, boolean local, boolean unpublished) {
private NetDbEntry(LeaseSet ls,
String nick, boolean local, boolean unpublished) {
mIsRI = false;
mEntry = ls;

View File

@ -1,14 +1,5 @@
package net.i2p.android.router.netdb;
import java.util.List;
import net.i2p.android.router.I2PFragmentBase;
import net.i2p.android.router.R;
import net.i2p.android.router.I2PFragmentBase.RouterContextProvider;
import net.i2p.android.router.I2PFragmentBase.RouterContextUser;
import net.i2p.data.Hash;
import net.i2p.router.RouterContext;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
@ -20,6 +11,14 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import net.i2p.android.router.I2PFragmentBase;
import net.i2p.android.router.I2PFragmentBase.RouterContextProvider;
import net.i2p.android.router.R;
import net.i2p.data.Hash;
import net.i2p.router.RouterContext;
import java.util.List;
public class NetDbListFragment extends ListFragment implements
I2PFragmentBase.RouterContextUser,
LoaderManager.LoaderCallbacks<List<NetDbEntry>> {
@ -34,8 +33,8 @@ public class NetDbListFragment extends ListFragment implements
private static final String STATE_ACTIVATED_POSITION = "activated_position";
private boolean mOnActivityCreated;
RouterContextProvider mRouterContextProvider;
OnEntrySelectedListener mEntrySelectedCallback;
private RouterContextProvider mRouterContextProvider;
private OnEntrySelectedListener mEntrySelectedCallback;
private NetDbEntryAdapter mAdapter;
private boolean mRouters;
/**

View File

@ -22,7 +22,7 @@ import android.view.ViewGroup;
public class NetDbSummaryPagerFragment extends I2PFragmentBase implements
LoaderManager.LoaderCallbacks<List<ObjectCounter<String>>> {
NetDbPagerAdapter mNetDbPagerAdapter;
private NetDbPagerAdapter mNetDbPagerAdapter;
ViewPager mViewPager;
@Override

View File

@ -45,7 +45,7 @@ public class CacheProvider extends ContentProvider {
//private static final String NONCE = Integer.toString(Math.abs((new java.util.Random()).nextInt()));
private static final String NONCE = "0";
private static final String SCHEME = "content";
public static final String AUTHORITY = "net.i2p.android.router";
public static final String AUTHORITY = "net.i2p.android";
/** includes the nonce */
public static final Uri CONTENT_URI = Uri.parse(SCHEME + "://" + AUTHORITY + '/' + NONCE);

View File

@ -49,7 +49,7 @@ class LoadClientsJob extends JobImpl {
getTiming().setStartAfter(getContext().clock().now() + LOAD_DELAY);
}
public String getName() { return "Start Clients"; };
public String getName() { return "Start Clients"; }
public void runJob() {
Job j = new RunI2PTunnel(getContext());
@ -83,7 +83,7 @@ class LoadClientsJob extends JobImpl {
super(ctx);
}
public String getName() { return "Start I2P Tunnel"; };
public String getName() { return "Start I2P Tunnel"; }
public void runJob() {
Util.d("Starting i2ptunnel");

View File

@ -34,18 +34,6 @@ import net.i2p.util.OrderedProperties;
*/
public class RouterService extends Service {
// These states persist even if we died... Yuck, it causes issues.
public enum State {
INIT, WAITING, STARTING, RUNNING, ACTIVE,
// unplanned (router stopped itself), next: killSelf()
STOPPING, STOPPED,
// button, don't kill service when stopped, stay in MANUAL_STOPPED
MANUAL_STOPPING, MANUAL_STOPPED,
// button, DO kill service when stopped, next: killSelf()
MANUAL_QUITTING, MANUAL_QUITTED,
// Stopped by listener (no network), next: WAITING (spin waiting for network)
NETWORK_STOPPING, NETWORK_STOPPED
}
private RouterContext _context;
private String _myDir;
//private String _apkPath;
@ -457,8 +445,8 @@ public class RouterService extends Service {
return mStartCalled;
}
public String getState() throws RemoteException {
return _state.name();
public State getState() throws RemoteException {
return _state;
}
};
@ -596,7 +584,7 @@ public class RouterService extends Service {
public void handleMessage(Message msg) {
switch (msg.what) {
case STATE_MSG:
String state = _state.name();
final State state = _state;
// Broadcast to all clients the new state.
final int N = mStateCallbacks.beginBroadcast();
for (int i = 0; i < N; i++) {
@ -779,12 +767,11 @@ public class RouterService extends Service {
private State getSavedState() {
SharedPreferences prefs = getSharedPreferences(SHARED_PREFS, 0);
String stateString = prefs.getString(LAST_STATE, State.INIT.toString());
for(State s : State.values()) {
if(s.toString().equals(stateString)) {
return s;
}
try {
return State.valueOf(stateString);
} catch (IllegalArgumentException e) {
return State.INIT;
}
return State.INIT;
}
private void setState(State s) {

View File

@ -0,0 +1,159 @@
package net.i2p.android.router.stats;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import net.i2p.android.router.I2PActivityBase;
import net.i2p.android.router.R;
import net.i2p.android.router.SettingsActivity;
import net.i2p.android.router.service.StatSummarizer;
import net.i2p.android.router.service.SummaryListener;
import net.i2p.stat.Rate;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.ActionBar;
import android.widget.ArrayAdapter;
import android.widget.SpinnerAdapter;
public class RateGraphActivity extends I2PActivityBase {
private static final String SELECTED_RATE = "selected_rate";
private boolean mFinishOnResume;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDrawerToggle.setDrawerIndicatorEnabled(false);
if (StatSummarizer.instance() != null) {
// Get the rates currently being graphed
List<SummaryListener> listeners = StatSummarizer.instance().getListeners();
TreeSet<SummaryListener> ordered = new TreeSet<SummaryListener>(new AlphaComparator());
ordered.addAll(listeners);
if (ordered.size() > 0) {
// Extract the rates and periods
final String[] mRates = new String[ordered.size()];
final long[] mPeriods = new long[ordered.size()];
int i = 0;
for (SummaryListener listener : ordered) {
Rate r = listener.getRate();
mRates[i] = r.getRateStat().getName();
mPeriods[i] = r.getPeriod();
i++;
}
// Set up action bar for drop-down list
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
SpinnerAdapter mSpinnerAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_dropdown_item, mRates);
ActionBar.OnNavigationListener mNavigationListener = new ActionBar.OnNavigationListener() {
String[] rates = mRates;
long[] periods = mPeriods;
public boolean onNavigationItemSelected(int position, long itemId) {
String rateName = rates[position];
long period = periods[position];
RateGraphFragment f = RateGraphFragment.newInstance(rateName, period);
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_fragment, f, rates[position]).commit();
return true;
}
};
actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationListener);
if (savedInstanceState != null) {
int selected = savedInstanceState.getInt(SELECTED_RATE);
actionBar.setSelectedNavigationItem(selected);
}
} else {
DialogFragment df = new DialogFragment() {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.no_graphs_configured)
.setPositiveButton(R.string.configure_graphs, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mFinishOnResume = true;
Intent i = new Intent(RateGraphActivity.this, SettingsActivity.class);
// Navigation to a sub-category doesn't seem to work yet
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
i.setAction(SettingsActivity.ACTION_PREFS_GRAPHS);
} else {
i.putExtra("settings", "graphs");
}
startActivity(i);
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {
dialog.cancel();
finish();
}
})
.setCancelable(false);
return builder.create();
}
};
df.show(getSupportFragmentManager(), "nographs");
}
} else {
DialogFragment df = new DialogFragment() {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.graphs_not_ready)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
})
.setCancelable(false);
return builder.create();
}
};
df.show(getSupportFragmentManager(), "graphsnotready");
}
}
@Override
public void onResume() {
super.onResume();
if (mFinishOnResume) {
finish();
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(SELECTED_RATE,
getSupportActionBar().getSelectedNavigationIndex());
}
private static class AlphaComparator implements Comparator<SummaryListener> {
public int compare(SummaryListener l, SummaryListener r) {
String lName = l.getRate().getRateStat().getName();
String rName = r.getRate().getRateStat().getName();
int rv = lName.compareTo(rName);
if (rv != 0)
return rv;
return (int) (l.getRate().getPeriod() - r.getRate().getPeriod());
}
}
}

View File

@ -1,12 +1,5 @@
package net.i2p.android.router.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
@ -15,9 +8,16 @@ import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.preference.PreferenceManager;
import net.i2p.I2PAppContext;
import net.i2p.util.OrderedProperties;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public abstract class Util {
private static final boolean _isEmulator = Build.MODEL.equals("sdk");
@ -154,11 +154,8 @@ public abstract class Util {
x.equals("i2cp.disableInterface")) {
// special exception, we must invert the bool for these properties only.
String string = all.get(x).toString();
String what="true";
if(string.equals(what)) {
what="false";
}
routerProps.setProperty(x, what);
String inverted = Boolean.toString(!Boolean.parseBoolean(string));
routerProps.setProperty(x, inverted);
} else {
String string = all.get(x).toString();
routerProps.setProperty(x, string);

View File

@ -261,14 +261,14 @@ public class I2PWebViewClient extends WebViewClient {
super(view, null);
}
protected Integer doInBackground(String... urls) {
protected Integer doInBackground(final String... urls) {
publishProgress(Integer.valueOf(-1));
try {
_view.loadUrl(urls[0]);
} catch (Exception e) {
// CalledFromWrongThreadException
cancel(false);
}
_view.post(new Runnable() {
@Override
public void run() {
_view.loadUrl(urls[0]);
}
});
return Integer.valueOf(0);
}
@ -301,20 +301,20 @@ public class I2PWebViewClient extends WebViewClient {
}
protected Integer doInBackground(String... urls) {
String url = urls[0];
final String url = urls[0];
Uri uri = Uri.parse(url);
File cacheFile = AppCache.getInstance(_view.getContext()).getCacheFile(uri);
if (cacheFile.exists()) {
Uri resUri = AppCache.getInstance(_view.getContext()).getCacheUri(uri);
final Uri resUri = AppCache.getInstance(_view.getContext()).getCacheUri(uri);
Util.d("Loading " + url + " from resource cache " + resUri);
_view.getSettings().setLoadsImagesAutomatically(true);
_view.getSettings().setBlockNetworkLoads(false);
try {
_view.loadUrl(resUri.toString());
} catch (Exception e) {
// CalledFromWrongThreadException
cancel(false);
}
_view.post(new Runnable() {
@Override
public void run() {
_view.getSettings().setLoadsImagesAutomatically(true);
_view.getSettings().setBlockNetworkLoads(false);
_view.loadUrl(resUri.toString());
}
});
// 1 means show the cache toast message
return Integer.valueOf(1);
}
@ -336,7 +336,7 @@ public class I2PWebViewClient extends WebViewClient {
if (success) {
// store in cache, get content URL, and load that way
// Set as current base
Uri content = AppCache.getInstance(_view.getContext()).addCacheFile(uri, true);
final Uri content = AppCache.getInstance(_view.getContext()).addCacheFile(uri, true);
if (content != null) {
Util.d("Stored cache in " + content);
} else {
@ -345,17 +345,17 @@ public class I2PWebViewClient extends WebViewClient {
return Integer.valueOf(0);
}
Util.d("loading data, base URL: " + uri + " content URL: " + content);
try {
_view.loadUrl(content.toString());
} catch (Exception exc) {
// CalledFromWrongThreadException
cancel(false);
}
_view.post(new Runnable() {
@Override
public void run() {
_view.loadUrl(content.toString());
}
});
Util.d("Fetch failed for " + url);
} else {
// Load the error message in as a string, delete the file
String t = fetcher.getContentType();
String e = fetcher.getEncoding();
final String t = fetcher.getContentType();
final String e = fetcher.getEncoding();
String msg;
int statusCode = fetcher.getStatusCode();
if (statusCode < 0) {
@ -380,13 +380,14 @@ public class I2PWebViewClient extends WebViewClient {
}
}
AppCache.getInstance(_view.getContext()).removeCacheFile(uri);
try {
Util.d("loading error data URL: " + url);
_view.loadDataWithBaseURL(url, msg, t, e, url);
} catch (Exception exc) {
// CalledFromWrongThreadException
cancel(false);
}
Util.d("loading error data URL: " + url);
final String finalMsg = msg;
_view.post(new Runnable() {
@Override
public void run() {
_view.loadDataWithBaseURL(url, finalMsg, t, e, url);
}
});
}
} catch (IOException ioe) {
Util.d("IOE for " + url, ioe);

Some files were not shown because too many files have changed in this diff Show More