Compare commits

...

11 Commits

Author SHA1 Message Date
R4SAS bb93876838 2.37.0
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-03-15 18:03:57 +03:00
orignal b30bd69ba9 2.37.0 2021-03-15 08:35:20 -04:00
R4SAS cc9ef22b28 layout fixes
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-03-06 01:40:22 +03:00
wipedlifepotato 17148b5511 Autostart button(switch) (#19)
* Enable/Disable button; Toast on webconsole if not enabled; i2pdpath;on boot autostart;getDataPath/iniEditor preinit for setting

* settings autostart switch

Co-authored-by: R4SAS <r4sas@users.noreply.github.com>
2021-03-05 22:27:22 +03:00
R4SAS 2e6a4c7c4b fix ifaddrs usage
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-03-05 03:32:48 +03:00
R4SAS 9d894cb62e update main activity layout
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-03-05 03:16:38 +03:00
R4SAS 67e6e28904 rename submodules, fetch new i2pd commits
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-03-02 19:13:49 +03:00
Aleksander Undisclosed Yvarov fd04d7070d Enable/Disable button; Toast on webconsole if not enabled; i2pdpath;on boot autostart;getDataPath/iniEditor preinit for setting 2021-03-01 15:54:49 +00:00
nonlinear-chaos-order-etc-etal 55cde8e11c Update ReadMe, closes #16 (#17) 2021-02-28 16:27:18 +03:00
R4SAS 6ee4db6680 [fastlane] update application info and add screenshots
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-02-24 12:02:36 +03:00
R4SAS 48555bd1af Main activity, replace drawables with SVGs
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2021-02-20 23:16:58 +03:00
37 changed files with 1790 additions and 74 deletions
+4 -4
View File
@@ -2,16 +2,16 @@
path = app/jni/i2pd
url = https://github.com/PurpleI2P/i2pd.git
branch = openssl
[submodule "app/jni/boost"]
[submodule "boost"]
path = app/jni/boost
url = https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git
branch = boost-1_72_0
[submodule "app/jni/openssl"]
[submodule "openssl"]
path = app/jni/openssl
url = https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
[submodule "app/jni/miniupnp"]
[submodule "miniupnp"]
path = app/jni/miniupnp
url = https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
[submodule "app/jni/android-ifaddrs"]
[submodule "android-ifaddrs"]
path = app/jni/android-ifaddrs
url = https://github.com/PurpleI2P/android-ifaddrs.git
+2 -2
View File
@@ -1,6 +1,6 @@
# i2pd android
### Install OpenJDK, gradle, download Android SDK and NDK r19c
### Install OpenJDK, gradle 5.1+ (6.8.3 has been tested and is working ok), download Android SDK and NDK r21e
https://gradle.org/install/
https://developer.android.com/studio#downloads
@@ -12,7 +12,7 @@ https://developer.android.com/ndk/
### Compile application
export ANDROID_SDK_ROOT=/opt/android-sdk
export ANDROID_NDK_HOME=/opt/android-ndk-r19c
export ANDROID_NDK_HOME=/opt/android-ndk-r21e
gradle clean assembleDebug
+5 -3
View File
@@ -3,7 +3,7 @@ plugins {
}
dependencies {
implementation 'androidx.core:core:1.3.0'
implementation 'androidx.core:core:1.3.2'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
}
@@ -14,10 +14,12 @@ android {
applicationId "org.purplei2p.i2pd"
targetSdkVersion 29
minSdkVersion 14
versionCode 23600
versionName "2.36.0"
versionCode 23700
versionName "2.37.0"
setProperty("archivesBaseName", archivesBaseName + "-" + versionName)
vectorDrawables.useSupportLibrary = true
ndk {
abiFilters "armeabi-v7a"
abiFilters "x86"
+6
View File
@@ -218,5 +218,11 @@ namespace android
{
dataDir = jdataDir;
}
std::string
GetDataDir(void)
{
return dataDir;
}
}
}
+2
View File
@@ -52,6 +52,8 @@ namespace android
// set datadir received from jni
void SetDataDir(std::string jdataDir);
// get datadir
std::string GetDataDir(void);
/*
class Worker : public QObject
{
+4
View File
@@ -56,6 +56,10 @@ JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
(JNIEnv *env, jclass clazz) {
return env->NewStringUTF(i2p::android::start().c_str());
}
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getDataDir
(JNIEnv *env, jclass clazz) {
return env->NewStringUTF( i2p::android::GetDataDir().c_str() );
}
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
(JNIEnv *env, jclass clazz) {
+3
View File
@@ -26,6 +26,9 @@ JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
(JNIEnv *, jclass);
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getDataDir
(JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
(JNIEnv *, jclass);
+14 -1
View File
@@ -10,20 +10,33 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="@drawable/icon"
android:icon="@drawable/ic_logo"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:theme="@android:style/Theme.Holo.Light.DarkActionBar"
android:usesCleartextTraffic="true">
<receiver
android:enabled="true"
android:name="org.purplei2p.i2pd.receivers.BootUpReceiver"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<meta-data
android:name="android.webkit.WebView.MetricsOptOut"
android:value="true" />
<activity android:name=".WebConsoleActivity" />
<activity android:name=".SettingsActivity" />
<receiver
android:name=".NetworkStateChangeReceiver"
@@ -24,6 +24,7 @@ import android.util.Log;
import androidx.annotation.RequiresApi;
public class DaemonWrapper {
private static final String TAG = "i2pd";
private final AssetManager assetManager;
private final ConnectivityManager connectivityManager;
@@ -118,31 +119,7 @@ public class DaemonWrapper {
this.assetManager = assetManager;
this.connectivityManager = connectivityManager;
setState(State.starting);
new Thread(() -> {
try {
processAssets();
I2PD_JNI.loadLibraries();
setState(State.jniLibraryLoaded);
registerNetworkCallback();
} catch (Throwable tr) {
lastThrowable = tr;
setState(State.startFailed);
return;
}
try {
synchronized (DaemonWrapper.this) {
I2PD_JNI.setDataDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd");
daemonStartResult = I2PD_JNI.startDaemon();
if ("ok".equals(daemonStartResult)) {
setState(State.startedOkay);
} else
setState(State.startFailed);
}
} catch (Throwable tr) {
lastThrowable = tr;
setState(State.startFailed);
}
}, "i2pdDaemonStart").start();
startDaemon();
}
private Throwable lastThrowable;
@@ -167,6 +144,16 @@ public class DaemonWrapper {
return daemonStartResult;
}
public static String getDataDir() { // for settings iniEditor
return I2PD_JNI.getDataDir();
}
public void changeDataDir(String dataDir, Boolean updateAssets) {
I2PD_JNI.setDataDir(dataDir);
if( updateAssets ) processAssets();
//ToDo: move old dir to new dir?
}
public boolean isStartedOkay() {
return getState().isStartedOkay();
}
@@ -182,6 +169,34 @@ public class DaemonWrapper {
setState(State.stopped);
}
}
public synchronized void startDaemon() {
if( getState() != State.stopped && getState() != State.starting ) return;
new Thread(() -> {
try {
processAssets();
I2PD_JNI.loadLibraries();
setState(State.jniLibraryLoaded);
registerNetworkCallback();
} catch (Throwable tr) {
lastThrowable = tr;
setState(State.startFailed);
return;
}
try {
synchronized (DaemonWrapper.this) {
I2PD_JNI.setDataDir(i2pdpath);//(Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd");
daemonStartResult = I2PD_JNI.startDaemon();
if ("ok".equals(daemonStartResult)) {
setState(State.startedOkay);
} else
setState(State.startFailed);
}
} catch (Throwable tr) {
lastThrowable = tr;
setState(State.startFailed);
}
}, "i2pdDaemonStart").start();
}
private void processAssets() {
if (!assetsCopied) {
@@ -92,7 +92,7 @@ public class ForegroundService extends Service {
public void onDestroy() {
cancelNotification();
deinitCheck();
instance=null;
instance = null;
}
public static void deinit() {
@@ -148,7 +148,7 @@ public class ForegroundService extends Service {
// Set the info for the views that show in the notification panel.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
.setOngoing(true)
.setSmallIcon(R.drawable.itoopie_notification_icon); // the status icon
.setSmallIcon(R.drawable.ic_notification_icon); // the status icon
if (Build.VERSION.SDK_INT >= 16)
builder = builder.setPriority(Notification.PRIORITY_DEFAULT);
if (Build.VERSION.SDK_INT >= 21)
@@ -27,6 +27,8 @@ import android.provider.Settings;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
@@ -34,20 +36,18 @@ import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
// For future package update checking
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import static android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS;
import static org.purplei2p.i2pd.DaemonWrapper.State.startedOkay;
import static org.purplei2p.i2pd.DaemonWrapper.State.starting;
import static org.purplei2p.i2pd.DaemonWrapper.State.stopped;
public class I2PDActivity extends Activity {
private static final String TAG = "i2pdActvt";
private static final int MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
public static final int GRACEFUL_DELAY_MILLIS = 10 * 60 * 1000;
public static final String PACKAGE_URI_SCHEME = "package:";
private Button enableButton;
private Button disableButton;
private TextView textView;
@@ -66,11 +66,14 @@ public class I2PDActivity extends Activity {
if (textView == null)
return;
Throwable tr = daemon.getLastThrowable();
if (tr!=null) {
if (tr != null) {
textView.setText(throwableToString(tr));
return;
}
DaemonWrapper.State state = daemon.getState();
if(state == startedOkay){
disableButton.setVisibility(View.VISIBLE);
}
String startResultStr = DaemonWrapper.State.startFailed.equals(state) ? String.format(": %s", daemon.getDaemonStartResult()) : "";
String graceStr = DaemonWrapper.State.gracefulShutdownInProgress.equals(state) ? String.format(": %s %s", formatGraceTimeRemaining(), getText(R.string.remaining)) : "";
textView.setText(String.format("%s%s%s", getText(state.getStatusStringResourceId()), startResultStr, graceStr));
@@ -98,18 +101,37 @@ public class I2PDActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState);
if (daemon==null) {
setContentView(R.layout.activity_main);
enableButton = findViewById(R.id.enableButton);
disableButton = findViewById(R.id.disableButton);
textView = (TextView) findViewById(R.id.textView);
if (daemon == null) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
daemon = new DaemonWrapper(getAssets(), connectivityManager);
}
ForegroundService.init(daemon);
textView = new TextView(this);
setContentView(textView);
daemon.addStateChangeListener(daemonStateUpdatedListener);
daemonStateUpdatedListener.daemonStateUpdate(DaemonWrapper.State.uninitialized, daemon.getState());
enableButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if( daemon.getState() != startedOkay && daemon.getState() != starting ){
daemon.stopDaemon();
daemon.startDaemon();
disableButton.setVisibility(View.VISIBLE);
}
}
});
disableButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if( daemon.getState() != stopped ){
daemon.stopDaemon();
disableButton.setVisibility(View.INVISIBLE);
}
}
});
// request permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
@@ -119,7 +141,6 @@ public class I2PDActivity extends Activity {
}
}
// set the app be foreground
doBindService();
final Timer gracefulQuitTimer = getGracefulQuitTimer();
@@ -273,7 +294,13 @@ public class I2PDActivity extends Activity {
return true;
case R.id.action_start_webview:
startActivity(new Intent(getApplicationContext(), WebConsoleActivity.class));
if( daemon.getState() == startedOkay)
startActivity(new Intent(getApplicationContext(), WebConsoleActivity.class));
else
Toast.makeText(this,"I2Pd not was started!", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_settings:
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
return true;
}
@@ -30,4 +30,6 @@ public class I2PD_JNI {
//System.loadLibrary("c++_shared");
System.loadLibrary("i2pd");
}
public static native String getDataDir();
}
@@ -0,0 +1,108 @@
package org.purplei2p.i2pd;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.Switch;
import java.io.File;
import java.util.List;
import org.purplei2p.i2pd.iniedotr.IniEditor;
public class SettingsActivity extends Activity {
protected IniEditor iniedit = new IniEditor();
private String dataDir = DaemonWrapper.getDataDir();//for inieditor
private String TAG = "i2pdSrvcSettings";
private File cacheDir;
public static String onBootFileName="/onBoot"; // just file, empty, if exist the do autostart, if not then no.
//https://gist.github.com/chandruark/3165a5ee3452f2b9ec7736cf1b4c5ea6
private void addAutoStartupswitch() {
try {
Intent intent = new Intent();
String manufacturer = android.os.Build.MANUFACTURER .toLowerCase();
switch (manufacturer){
case "xiaomi":
intent.setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity"));
break;
case "oppo":
intent.setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity"));
break;
case "vivo":
intent.setComponent(new ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity"));
break;
case "Letv":
intent.setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.AutobootManageActivity"));
break;
case "Honor":
intent.setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity"));
break;
case "oneplus":
intent.setComponent(new ComponentName("com.oneplus.security", "com.oneplus.security.chainlaunch.view.ChainLaunchAppListActivity"));
break;
}
List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (list.size() > 0) {
startActivity(intent);
}
} catch (Exception e) {
Log.e("exceptionAutostarti2pd" , String.valueOf(e));
}
}
//@Override
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(
Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName())
);
startActivityForResult(intent, 232);
} else {
//Permission Granted-System will work
}
}
}
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState);
cacheDir = getApplicationContext().getCacheDir();
setContentView(R.layout.activity_settings);
Switch autostart_switch = findViewById(R.id.autostart_enable);
File onBoot= new File( cacheDir.getAbsolutePath()+onBootFileName);
autostart_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// do something, the isChecked will be
// true if the switch is in the On position
if(isChecked){
if( !onBoot.exists() ) {
requestPermission();
addAutoStartupswitch();
try {
if( !onBoot.createNewFile()) Log.d(TAG, "Cant create new wile on: "+onBoot.getAbsolutePath());
} catch (Exception e) {
Log.d(TAG, "error: " + e.toString());
}
}
}else{
if( onBoot.exists() )
onBoot.delete();
}
}
});
if(onBoot.exists()) autostart_switch.setChecked(true);
}
}
@@ -35,13 +35,13 @@ public class WebConsoleActivity extends Activity {
@Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(true);
new Handler().postDelayed(new Runnable() {
new Handler().post(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(false);
webView.reload();
}
}, 1000);
});
}
});
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,31 @@
package org.purplei2p.i2pd.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
//import org.purplei2p.i2pd.ForegroundService;
//ToDo:* fix^^^ change to service, not on window on start.
import org.purplei2p.i2pd.I2PDPermsAskerActivity;
import java.io.File;
import static org.purplei2p.i2pd.SettingsActivity.onBootFileName;
public class BootUpReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
/* todo: disable the autostart? */
File onBoot =
new File(
context.getApplicationContext().getCacheDir().getAbsolutePath()
+ onBootFileName);
if(onBoot.exists()) {
Intent i = new Intent(context, I2PDPermsAskerActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportWidth="67.73333"
android:viewportHeight="67.73333">
<path
android:pathData="m8.0245,22.7306 l3.0405,8.9748c1.5868,8.52 4.2051,13.7196 7.5287,16.6465 3.3713,5.5488 7.1982,10.5662 11.7274,14.7649 4.7511,5.7799 10.8578,5.4198 16.9394,-1.158C55.1176,53.4605 59.0051,38.7386 60.7254,22.4411 62.721,3.5354 42.4318,-7.8385 33.7958,8.6896 28.6579,18.5229 27.1239,16.8872 19.8967,9.9923 12.8025,3.2243 3.3349,7.2924 8.0245,22.7306ZM13.0159,27.4774c8.3005,0.3473 14.1412,1.6329 15.1198,4.7738 -6.159,3.137 -10.9848,0.7573 -15.1198,-4.7738zM32.6816,52.0871c1.0397,0.5898 1.771,0.6068 2.5288,0 1.4061,-1.1262 2.4482,-1.0302 4.6962,-1.8419 3.5633,-1.2868 5.1391,-4.6341 7.7089,-6.9512 -4.9698,6.6991 -9.1788,18.7408 -16.8256,11.1857 -1.918,-1.8951 -1.9664,-2.4746 -7.4966,-7.0568 -0.227,-0.188 -0.4631,-0.3828 -0.709,-0.5847 2.5469,1.5209 4.8048,3.3307 7.6408,4.5628 0.8113,0.3309 1.3046,0.0329 2.4565,0.6862zM35.8244,31.5361c-1.4116,-5.7378 3.8919,-8.1189 14.2333,-7.9819 -4.2543,3.8297 -8.7242,7.145 -14.2333,7.9819z"
android:strokeWidth="0.93224764"
android:fillColor="#00000000"
android:strokeColor="#000000"/>
<path
android:pathData="m28.237,32.0881c-0.9786,-3.1408 -6.8193,-4.4264 -15.1199,-4.7737 4.1351,5.531 8.9609,7.9108 15.1199,4.7737zM50.159,23.3911c-10.3414,-0.137 -15.6448,2.2441 -14.2333,7.982 5.5091,-0.8369 9.979,-4.1522 14.2333,-7.982zM16.6812,21.3597c2.6043,2.2517 5.2086,4.0418 7.8132,4.5568 5.297,1.7061 5.6425,5.3779 5.281,9.3305v9.3306c-0.3217,3.4969 1.857,4.0152 3.1473,2.4946 0.6986,-0.8231 2.1465,-1.8057 3.3777,-1.9377 1.8931,-0.2029 3.3969,-0.1184 2.3733,-3.2692m-5.5705,0.5424c-0.0241,-4.2433 -0.0482,-8.4866 -0.0725,-12.73M16.6089,18.3219C26.541,27.559 30.9945,26.1085 34.7671,17.0923 39.72,5.2558 49.1877,4.4588 57.1215,16.3689m-9.4048,26.7619c-4.9696,6.6991 -9.1786,18.741 -16.8254,11.1857 -1.9968,-1.9727 -1.9672,-2.5199 -8.2055,-7.6415 2.5469,1.5209 4.8048,3.3307 7.6407,4.5628 0.8114,0.3309 1.3047,0.033 2.4566,0.6863 1.0397,0.5898 1.771,0.6068 2.5286,0 1.4062,-1.1262 2.4482,-1.0302 4.6963,-1.8421 3.5633,-1.2868 5.1391,-4.634 7.7087,-6.9512zM8.1259,22.5676C3.4362,7.1294 12.9037,3.0612 19.9981,9.8293 27.2253,16.7242 28.7593,18.3597 33.8971,8.5266 42.533,-8.0016 62.8223,3.3724 60.8266,22.2781 59.1064,38.5756 55.219,53.2975 47.3619,61.7957 41.2802,68.3735 35.1735,68.7337 30.4224,62.9537 25.8932,58.755 22.0663,53.7378 18.695,48.1889 15.3714,45.2618 12.7532,40.0624 11.1664,31.5422ZM33.3926,50.5808c0.1014,-0.4791 -0.0722,-4.2248 1.5204,-0.0957m1.5285,14.3353c-2.607,-2.3561 2.1116,-3.9639 1.4121,-0.4185M53.8771,36.4639C54.0218,43.6533 51.5124,52.1936 47.7962,57.4531M42.4392,40.3723c6.1774,-3.3295 9.073,-2.4125 8.687,2.7503M15.2932,40.8065c1.5452,3.6162 6.1047,4.1223 9.4827,-1.3028M10.0255,21.7213C9.1816,8.2922 13.3214,6.1141 21.0941,16.9476 25.1871,22.652 28.8678,23.6838 32.6692,15.3563 39.433,0.5392 50.2361,1.582 57.2465,12.0746M33.682,24.2528c6.4671,-11.5489 12.2697,-16.0091 17.0008,-9.0411"
android:strokeWidth="1.32291663"
android:fillColor="#00000000"
android:strokeColor="#1f1a17"/>
</vector>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

+95
View File
@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#9C27B0"
android:padding="@dimen/activity_horizontal_margin"
tools:context="org.purplei2p.i2pd.I2PDActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="140dp"
android:src="@drawable/ic_logo" />
<TextView
android:id="@+id/textViewDesc1"
style="@android:style/Widget.Holo.Light.TextView.SpinnerItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/app_description"
android:textColor="#FFFFFF"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:id="@+id/textViewDesc2"
style="@android:style/Widget.Holo.Light.TextView.SpinnerItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/app_description2"
android:textColor="#FFFFFF"
android:textSize="24sp"
android:textStyle="bold" />
<Space
android:layout_width="match_parent"
android:layout_height="@dimen/margin_medium" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_gravity="center">
<Button
android:id="@+id/enableButton"
style="@android:style/Widget.Button.Inset"
android:layout_width="@dimen/margin_huge"
android:layout_height="@dimen/margin_huge"
android:layout_centerInParent="true"
android:background="@android:drawable/presence_offline"
android:longClickable="true" />
<Button
android:id="@+id/disableButton"
style="@android:style/Widget.Button.Inset"
android:layout_width="@dimen/margin_huge"
android:layout_height="@dimen/margin_huge"
android:layout_centerInParent="true"
android:background="@android:drawable/presence_online"
android:longClickable="true"
android:visibility="invisible" />
</RelativeLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="@dimen/margin_medium" />
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textColor="#DFDFDF"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
</ScrollView>
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/margin_medium"
android:orientation="vertical"
tools:context=".SettingsActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_tiny"
android:clickable="false"
android:text="@string/settings_section0"
android:textSize="24sp"
android:verticalScrollbarPosition="defaultPosition" />
<Switch
android:id="@+id/autostart_enable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:textOff="@string/disabled"
android:textOn="@string/enabled"
android:text="@string/autostart_enabled" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider" />
<!--
<TextView
android:id="@+id/settings_section2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoText="true"
android:clickable="false"
android:cursorVisible="false"
android:text="@string/settings_section_tunnels"
android:textColor="#282528"
android:textStyle="bold|italic"
android:verticalScrollbarPosition="defaultPosition" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/add_tunnel" />
<Button
android:id="@+id/add_tunnel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/add_tunnel_button" />
</LinearLayout>
-->
</LinearLayout>
@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/layout_prompt"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
+4 -1
View File
@@ -23,9 +23,12 @@
android:id="@+id/action_graceful_stop"
android:orderInCategory="98"
android:title="@string/action_graceful_stop" />
<item
android:id="@+id/action_settings"
android:title="@string/action_settings" />
<item
android:id="@+id/action_stop"
android:orderInCategory="99"
android:title="@string/action_stop" />
android:title="@string/action_exit" />
</group>
</menu>
+17 -1
View File
@@ -1,12 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">i2pd</string>
<string name="app_description">Invisible Internet Protocol:</string>
<string name="app_description2">Сеть без границ</string>
<string name="action_start">Запустить</string>
<string name="action_stop">Остановить</string>
<string name="action_exit">Выход</string>
<string name="action_graceful_stop">Корректная остановка</string>
<string name="action_cancel_graceful_stop">Отменить корректную остановку</string>
<string name="action_reload_tunnels_config">Перезагрузить туннели</string>
<string name="action_start_webview">Открыть Веб Консоль</string>
<string name="action_settings">Настройки</string>
<string name="graceful_stop_is_already_in_progress">Корректная остановка уже запущена</string>
<string name="graceful_stop_is_in_progress">Корректная остановка запущена</string>
@@ -37,4 +41,16 @@
<string name="shutdown_canceled">Плановая остановка отменена</string>
<string name="tunnels_reloading">Перезагрузка конфигурации туннелей...</string>
<string name="autostart_enabled">Запуск после загрузки телефона</string>
<string name="settings_section0">Основные настройки</string>
<string name="settings_section_tunnels">Туннели</string>
<string name="add_tunnel_button">Добавить</string>
<string name="add_tunnel">Управление туннелями</string>
<string name="del_tunnel_button">Удалить</string>
<string name="enabled">Вкл</string>
<string name="disabled">Выкл</string>
</resources>
@@ -1,16 +1,12 @@
<resources>
<!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
<dimen name="margin_tiny">4dp</dimen>
<dimen name="margin_small">8dp</dimen>
<dimen name="margin_medium">16dp</dimen>
<dimen name="margin_large">32dp</dimen>
<dimen name="margin_huge">64dp</dimen>
<!-- Semantic definitions -->
<dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
<dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
<dimen name="activity_horizontal_margin">@dimen/margin_medium</dimen>
<dimen name="activity_vertical_margin">@dimen/margin_medium</dimen>
</resources>
+18 -1
View File
@@ -1,12 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_name">i2pd</string>
<string name="app_name" translatable="false">i2pd</string>
<string name="app_description">Invisible Internet Protocol:</string>
<string name="app_description2">Network without borders</string>
<string name="action_start">Start</string>
<string name="action_stop">Stop</string>
<string name="action_exit">Exit</string>
<string name="action_graceful_stop">Graceful Stop</string>
<string name="action_cancel_graceful_stop">Cancel Graceful Stop</string>
<string name="action_reload_tunnels_config">Reload tunnels</string>
<string name="action_start_webview">Open Web Console</string>
<string name="action_settings">Settings</string>
<string name="graceful_stop_is_already_in_progress">Graceful stop is already in progress</string>
<string name="graceful_stop_is_in_progress">Graceful stop is in progress</string>
@@ -38,4 +43,16 @@
<string name="shutdown_canceled">Planned shutdown canceled</string>
<string name="tunnels_reloading">Reloading tunnels config...</string>
<string name="settings_section0">Common settings</string>
<string name="settings_section_tunnels">Tunnels</string>
<string name="autostart_enabled">Start at boot</string>
<string name="add_tunnel_button">Add tunnel</string>
<string name="add_tunnel">Tunnels management</string>
<string name="del_tunnel_button">Delete tunnel</string>
<string name="enabled">On</string>
<string name="disabled">Off</string>
</resources>
@@ -1 +1 @@
* Updated codebase to 2.35.0
* Updated codebase to 2.35.0/0.9.48
@@ -1,2 +1,2 @@
* Updated codebase to 2.36.0
* Updated codebase to 2.36.0/0.9.49
* Add webconsole page reload by swipe
@@ -0,0 +1,2 @@
* Updated codebase to 2.37.0
* Changes in main activity
@@ -1,11 +1,13 @@
I2P (Invisible Internet Protocol) is a universal anonymous network layer.
<b>I2P</b> (Invisible Internet Protocol) is a universal anonymous network layer.
All communications over I2P are anonymous and end-to-end encrypted, participants
don't reveal their real IP addresses.
I2P client is a software used for building and using anonymous I2P
<b>I2P client</b> is a software used for building and using anonymous I2P
networks. Such networks are commonly used for anonymous peer-to-peer
applications (filesharing, cryptocurrencies) and anonymous client-server
applications (websites, instant messengers, chat-servers).
I2P allows people from all around the world to communicate and share information
<b>I2P</b> allows people from all around the world to communicate and share information
without restrictions.
For more information about <b>I2P</b>, you can read <a href="https://en.m.wikipedia.org/wiki/I2P">article on Wikipedia</a>.
Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

+2 -1
View File
@@ -1,3 +1,4 @@
android.enableJetifier=true
android.useAndroidX=true
org.gradle.parallel=true
org.gradle.parallel=true
android.defaultConfig.vectorDrawables.useSupportLibrary = true