diff --git a/tordnscrypt/build.gradle b/tordnscrypt/build.gradle index 6119fd3a4..fd75e5626 100644 --- a/tordnscrypt/build.gradle +++ b/tordnscrypt/build.gradle @@ -7,23 +7,10 @@ android { flavorDimensions "version", "processor" productFlavors { - lite { - applicationId "pan.alexander.tordnscrypt.stable" - versionName "3.0.1" - dimension = 'version' - resValue 'string', 'package_name', applicationId - } - - pro { - applicationId "pan.alexander.tordnscrypt.stable" - versionName "3.0.1" - dimension = 'version' - resValue 'string', 'package_name', applicationId - } - beta{ + fdroid{ applicationId "pan.alexander.tordnscrypt" - versionName "0.6.1" + versionName "0.6.2" dimension = 'version' resValue 'string', 'package_name', applicationId } @@ -53,7 +40,7 @@ android { defaultConfig { minSdkVersion 19 targetSdkVersion 29 - versionCode 61 + versionCode 62 resConfigs "en", "ru-rRU" , "ru-rUA", "pl" @@ -131,7 +118,7 @@ dependencies { implementation 'com.google.android.material:material:1.2.0-alpha04' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.recyclerview:recyclerview:1.1.0' - testImplementation 'junit:junit:4.12' + testImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' //noinspection GradleDynamicVersion diff --git a/tordnscrypt/owner.gradle b/tordnscrypt/owner.gradle index 59acbb6e5..ff49f5c65 100644 --- a/tordnscrypt/owner.gradle +++ b/tordnscrypt/owner.gradle @@ -29,7 +29,7 @@ android { productFlavors { lite { applicationId "pan.alexander.tordnscrypt.stable" - versionName "3.0.1" + versionName "4.0.0" dimension = 'version' signingConfig signingConfigs.stablesign resValue 'string', 'package_name', applicationId @@ -37,7 +37,7 @@ android { pro { applicationId "pan.alexander.tordnscrypt.stable" - versionName "3.0.1" + versionName "4.0.0" dimension = 'version' signingConfig signingConfigs.stablesign resValue 'string', 'package_name', applicationId @@ -45,12 +45,22 @@ android { beta { applicationId "pan.alexander.tordnscrypt" - versionName "0.6.1" + versionName "0.6.2" dimension = 'version' signingConfig signingConfigs.betasign resValue 'string', 'package_name', applicationId } + google_play { + minSdkVersion 22 + applicationId "pan.alexander.tordnscrypt.gp" + versionName "4.0.0" + dimension = 'version' + signingConfig signingConfigs.stablesign + resValue 'string', 'package_name', applicationId + resValue 'string', 'gp_property', keystoreProperties['gpPublicKey'] + } + armv7a { dimension = 'processor' resValue 'string', 'appProcVersion', 'armv7a' @@ -76,7 +86,7 @@ android { defaultConfig { minSdkVersion 19 targetSdkVersion 29 - versionCode 61 + versionCode 62 resConfigs "en", "ru-rRU", "ru-rUA", "pl" @@ -155,7 +165,8 @@ dependencies { implementation 'com.google.android.material:material:1.2.0-alpha04' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.recyclerview:recyclerview:1.1.0' - testImplementation 'junit:junit:4.12' + google_playImplementation 'com.android.billingclient:billing:2.1.0' + testImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' //noinspection GradleDynamicVersion diff --git a/tordnscrypt/proguard-rules.pro b/tordnscrypt/proguard-rules.pro index 07953bd54..118a041b8 100644 --- a/tordnscrypt/proguard-rules.pro +++ b/tordnscrypt/proguard-rules.pro @@ -22,4 +22,5 @@ -keep public class pan.alexander.tordnscrypt.vpn.** { public *; -} \ No newline at end of file +} +-keep class com.android.vending.billing.** diff --git a/tordnscrypt/src/arm64/assets/tor.mp3 b/tordnscrypt/src/arm64/assets/tor.mp3 index b9075313f..784ee1e80 100644 Binary files a/tordnscrypt/src/arm64/assets/tor.mp3 and b/tordnscrypt/src/arm64/assets/tor.mp3 differ diff --git a/tordnscrypt/src/armv7a/assets/tor.mp3 b/tordnscrypt/src/armv7a/assets/tor.mp3 index 997563d2e..bd2903366 100644 Binary files a/tordnscrypt/src/armv7a/assets/tor.mp3 and b/tordnscrypt/src/armv7a/assets/tor.mp3 differ diff --git a/tordnscrypt/src/beta/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java b/tordnscrypt/src/beta/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java new file mode 100644 index 000000000..b5f38039d --- /dev/null +++ b/tordnscrypt/src/beta/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java @@ -0,0 +1,37 @@ +package pan.alexander.tordnscrypt.assistance; + +/* + This file is part of InviZible Pro. + + InviZible Pro is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InviZible Pro is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with InviZible Pro. If not, see <http://www.gnu.org/licenses/>. + + Copyright 2019-2020 by Garmatin Oleksandr invizible.soft@gmail.com +*/ + +import pan.alexander.tordnscrypt.MainActivity; + +public class AccelerateDevelop { + public final static String mSkuId = ""; + + public static boolean accelerated = true; + + public AccelerateDevelop(MainActivity activity) { + } + + public void initBilling() { + } + + public void launchBilling(String skuId) { + } +} diff --git a/tordnscrypt/src/fdroid/ic_launcher-web.png b/tordnscrypt/src/fdroid/ic_launcher-web.png new file mode 100644 index 000000000..61084120e Binary files /dev/null and b/tordnscrypt/src/fdroid/ic_launcher-web.png differ diff --git a/tordnscrypt/src/fdroid/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java b/tordnscrypt/src/fdroid/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java new file mode 100644 index 000000000..b5f38039d --- /dev/null +++ b/tordnscrypt/src/fdroid/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java @@ -0,0 +1,37 @@ +package pan.alexander.tordnscrypt.assistance; + +/* + This file is part of InviZible Pro. + + InviZible Pro is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InviZible Pro is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with InviZible Pro. If not, see <http://www.gnu.org/licenses/>. + + Copyright 2019-2020 by Garmatin Oleksandr invizible.soft@gmail.com +*/ + +import pan.alexander.tordnscrypt.MainActivity; + +public class AccelerateDevelop { + public final static String mSkuId = ""; + + public static boolean accelerated = true; + + public AccelerateDevelop(MainActivity activity) { + } + + public void initBilling() { + } + + public void launchBilling(String skuId) { + } +} diff --git a/tordnscrypt/src/fdroid/res/drawable/ic_help_title.png b/tordnscrypt/src/fdroid/res/drawable/ic_help_title.png new file mode 100644 index 000000000..682f52dd9 Binary files /dev/null and b/tordnscrypt/src/fdroid/res/drawable/ic_help_title.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-anydpi-v26/ic_launcher.xml b/tordnscrypt/src/fdroid/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 000000000..036d09bc5 --- /dev/null +++ b/tordnscrypt/src/fdroid/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> + <background android:drawable="@color/ic_launcher_background"/> + <foreground android:drawable="@mipmap/ic_launcher_foreground"/> +</adaptive-icon> \ No newline at end of file diff --git a/tordnscrypt/src/fdroid/res/mipmap-anydpi-v26/ic_launcher_round.xml b/tordnscrypt/src/fdroid/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 000000000..036d09bc5 --- /dev/null +++ b/tordnscrypt/src/fdroid/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> + <background android:drawable="@color/ic_launcher_background"/> + <foreground android:drawable="@mipmap/ic_launcher_foreground"/> +</adaptive-icon> \ No newline at end of file diff --git a/tordnscrypt/src/fdroid/res/mipmap-hdpi/ic_launcher.png b/tordnscrypt/src/fdroid/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..a7bfc62fc Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-hdpi/ic_launcher.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-hdpi/ic_launcher_foreground.png b/tordnscrypt/src/fdroid/res/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..cdb247e32 Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-hdpi/ic_launcher_round.png b/tordnscrypt/src/fdroid/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 000000000..0a9358adf Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-mdpi/ic_launcher.png b/tordnscrypt/src/fdroid/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..c927d0d80 Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-mdpi/ic_launcher.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-mdpi/ic_launcher_foreground.png b/tordnscrypt/src/fdroid/res/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..8e027297a Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-mdpi/ic_launcher_round.png b/tordnscrypt/src/fdroid/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 000000000..302dd21a6 Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-xhdpi/ic_launcher.png b/tordnscrypt/src/fdroid/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..4013d5d4c Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-xhdpi/ic_launcher_foreground.png b/tordnscrypt/src/fdroid/res/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..01f1789b3 Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-xhdpi/ic_launcher_round.png b/tordnscrypt/src/fdroid/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 000000000..23f8ea8ea Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-xxhdpi/ic_launcher.png b/tordnscrypt/src/fdroid/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..650ae0ed9 Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-xxhdpi/ic_launcher_foreground.png b/tordnscrypt/src/fdroid/res/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..eb3eb484c Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-xxhdpi/ic_launcher_round.png b/tordnscrypt/src/fdroid/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 000000000..e390999dc Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-xxxhdpi/ic_launcher.png b/tordnscrypt/src/fdroid/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..1a02da486 Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/tordnscrypt/src/fdroid/res/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..8111f6d5c Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/tordnscrypt/src/fdroid/res/mipmap-xxxhdpi/ic_launcher_round.png b/tordnscrypt/src/fdroid/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 000000000..3b845bdbf Binary files /dev/null and b/tordnscrypt/src/fdroid/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/tordnscrypt/src/fdroid/res/values/encoded.xml b/tordnscrypt/src/fdroid/res/values/encoded.xml new file mode 100644 index 000000000..9831a0762 --- /dev/null +++ b/tordnscrypt/src/fdroid/res/values/encoded.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="encoded" translatable="false">cGFuLmFsZXhhbmRlci50b3JkbnNjcnlwdC5hY3Rpb24uVE9QX0JST0FEQ0FTVA==</string> + <string name="appVersion" translatable="false">fd</string> + <string name="main_activity_label" translatable="false">InviZible Pro</string> +</resources> \ No newline at end of file diff --git a/tordnscrypt/src/fdroid/res/values/ic_launcher_background.xml b/tordnscrypt/src/fdroid/res/values/ic_launcher_background.xml new file mode 100644 index 000000000..c66adfa4c --- /dev/null +++ b/tordnscrypt/src/fdroid/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="ic_launcher_background">#64B5F6</color> +</resources> \ No newline at end of file diff --git a/tordnscrypt/src/google_play/AndroidManifest.xml b/tordnscrypt/src/google_play/AndroidManifest.xml new file mode 100644 index 000000000..638f708a5 --- /dev/null +++ b/tordnscrypt/src/google_play/AndroidManifest.xml @@ -0,0 +1,144 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + package="pan.alexander.tordnscrypt" + android:installLocation="internalOnly" + android:targetSandboxVersion="1" + tools:targetApi="o"> + + <uses-feature android:name="android.software.leanback" android:required="false" /> + <uses-feature android:name="android.hardware.touchscreen" android:required="false" /> + + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> + <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> + <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> + <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" + tools:node="remove"/> + <uses-permission android:name="android.permission.WAKE_LOCK" /> + <uses-permission + android:name="android.permission.WRITE_SETTINGS" + tools:node="remove" + tools:ignore="ProtectedPermissions" /> + <uses-permission + android:name="android.permission.MANAGE_USERS" + tools:node="remove" + tools:ignore="ProtectedPermissions" /> + <uses-permission + android:name="android.permission.INTERACT_ACROSS_USERS" + tools:node="remove" + tools:ignore="ProtectedPermissions" /> + <uses-permission android:name="com.android.vending.BILLING"/> + + <application + android:allowBackup="true" + android:hardwareAccelerated="true" + android:icon="@mipmap/ic_launcher" + android:label="@string/app_name" + android:networkSecurityConfig="@xml/network_security_config" + android:supportsRtl="true" + android:theme="@style/AppTheme" + android:banner="@drawable/banner_tv" + android:extractNativeLibs="true" + android:requestLegacyExternalStorage="true" + tools:ignore="AllowBackup" + tools:targetApi="q"> + + <service + android:name=".utils.AppExitDetectService" + android:enabled="true" + android:exported="false" /> + <service + android:name=".update.UpdateService" + android:enabled="true" + android:exported="false" /> + + <activity android:name=".help.HelpActivity" /> + + <service + android:name=".utils.RootExecService" + android:enabled="true" + android:exported="false" /> + <service + android:name=".modules.ModulesService" + android:enabled="true" + android:exported="false"/> + + <activity + android:name=".MainActivity" + android:label="@string/main_activity_label" + android:theme="@style/AppTheme.NoActionBar"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LEANBACK_LAUNCHER" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + <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="www.invizible.net" + android:scheme="https" /> + <data + android:host="invizible.net" + android:scheme="http" /> + </intent-filter> + </activity> + + <receiver + android:name=".BootCompleteReceiver" + android:enabled="true"> + <intent-filter> + <action android:name="android.intent.action.BOOT_COMPLETED" /> + <action android:name="android.intent.action.QUICKBOOT_POWERON" /> + <action android:name="android.intent.action.REBOOT" /> + <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/> + <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/> + + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </receiver> + + <activity + android:name=".backup.BackupActivity" + android:theme="@style/AppTheme" /> + <activity + android:name=".SettingsActivity" + android:label="@string/title_activity_settings" + android:theme="@style/AppTheme" /> + <activity android:name=".AboutActivity" /> + + <service + android:name=".utils.GetIPsJobService" + android:enabled="true" + android:exported="true" + android:permission="android.permission.BIND_JOB_SERVICE" /> + <service + android:name=".vpn.service.ServiceVPN" + android:label="@string/app_name" + android:permission="android.permission.BIND_VPN_SERVICE"> + <intent-filter> + <action android:name="android.net.VpnService" /> + </intent-filter> + </service> + + <provider + android:name="androidx.core.content.FileProvider" + android:authorities="${applicationId}.fileprovider" + android:exported="false" + android:grantUriPermissions="true"> + <meta-data + android:name="android.support.FILE_PROVIDER_PATHS" + android:resource="@xml/filepaths" /> + </provider> + </application> + +</manifest> \ No newline at end of file diff --git a/tordnscrypt/src/google_play/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java b/tordnscrypt/src/google_play/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java new file mode 100644 index 000000000..a9c6e5961 --- /dev/null +++ b/tordnscrypt/src/google_play/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java @@ -0,0 +1,322 @@ +package pan.alexander.tordnscrypt.assistance; + +/* + This file is part of InviZible Pro. + + InviZible Pro is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InviZible Pro is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with InviZible Pro. If not, see <http://www.gnu.org/licenses/>. + + Copyright 2019-2020 by Garmatin Oleksandr invizible.soft@gmail.com +*/ + +import android.text.TextUtils; +import android.util.Base64; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; + +import com.android.billingclient.api.AcknowledgePurchaseParams; +import com.android.billingclient.api.AcknowledgePurchaseResponseListener; +import com.android.billingclient.api.BillingClient; +import com.android.billingclient.api.BillingClientStateListener; +import com.android.billingclient.api.BillingFlowParams; +import com.android.billingclient.api.BillingResult; +import com.android.billingclient.api.Purchase; +import com.android.billingclient.api.PurchasesUpdatedListener; +import com.android.billingclient.api.SkuDetails; +import com.android.billingclient.api.SkuDetailsParams; +import com.android.billingclient.api.SkuDetailsResponseListener; + +import java.security.Key; +import java.security.KeyFactory; +import java.security.PublicKey; +import java.security.Signature; +import java.security.spec.X509EncodedKeySpec; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.crypto.Cipher; + +import pan.alexander.tordnscrypt.MainActivity; +import pan.alexander.tordnscrypt.R; +import pan.alexander.tordnscrypt.dialogs.NotificationDialogFragment; +import pan.alexander.tordnscrypt.dialogs.NotificationHelper; +import pan.alexander.tordnscrypt.utils.PrefManager; + +import static pan.alexander.tordnscrypt.utils.RootExecService.LOG_TAG; + +public class AccelerateDevelop implements BillingClientStateListener { + public final static String mSkuId = "invizible_premium_version"; + + public static boolean accelerated = false; + + private MainActivity activity; + private BillingClient mBillingClient; + private Map<String, SkuDetails> mSkuDetailsMap = new HashMap<>(); + private boolean billingServiceConnected = false; + + public AccelerateDevelop(MainActivity activity) { + this.activity = activity; + } + + public void initBilling() { + mBillingClient = BillingClient.newBuilder(activity) + .enablePendingPurchases() + .setListener(new PurchasesUpdatedListener() { + @Override + public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> purchasesList) { + if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchasesList != null) { + Log.i(LOG_TAG, "Purchases are updated"); + handlePurchases(purchasesList); + } + } + }).build(); + + new Thread(() -> { + mBillingClient.startConnection(AccelerateDevelop.this); + }).start(); + } + + public void launchBilling(String skuId) { + if (billingServiceConnected) { + + if (!mSkuDetailsMap.isEmpty()) { + + Log.i(LOG_TAG, "Launch billing"); + + BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() + .setSkuDetails(mSkuDetailsMap.get(skuId)) + .build(); + mBillingClient.launchBillingFlow(activity, billingFlowParams); + } else { + Log.w(LOG_TAG, "Launch billing but details map is empty"); + } + + } else { + Log.w(LOG_TAG, "Launch billing but billing client is disconnected"); + mBillingClient.startConnection(this); + } + } + + @Override + public void onBillingSetupFinished(BillingResult billingResult) { + if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { + billingServiceConnected = true; + Log.i(LOG_TAG, "Billing setup is finished"); + //below you can query information about products and purchase + querySkuDetails(); //query for products + List<Purchase> purchasesList = queryPurchases(); //query for purchases + + //if the purchase has already been made to give the goods + handlePurchases(purchasesList); + } + } + + @Override + public void onBillingServiceDisconnected() { + //here when something went wrong, e.g. no internet connection + billingServiceConnected = false; + + Log.w(LOG_TAG, "Billing service disconnected"); + + String signedData = new PrefManager(activity).getStrPref("gpData"); + String signature = new PrefManager(activity).getStrPref("gpSign"); + + if (!signedData.isEmpty() && !signature.isEmpty() && verifyValidSignature(signedData, signature)) { + payComplete(); + } + } + + private void querySkuDetails() { + + if (!billingServiceConnected) { + mBillingClient.startConnection(this); + return; + } + + SkuDetailsParams.Builder skuDetailsParamsBuilder = SkuDetailsParams.newBuilder(); + List<String> skuList = new ArrayList<>(); + skuList.add(mSkuId); + skuDetailsParamsBuilder.setSkusList(skuList).setType(BillingClient.SkuType.INAPP); + + mBillingClient.querySkuDetailsAsync(skuDetailsParamsBuilder.build(), new SkuDetailsResponseListener() { + @Override + public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) { + if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { + if (!skuDetailsList.isEmpty()) { + for (SkuDetails skuDetails : skuDetailsList) { + mSkuDetailsMap.put(skuDetails.getSku(), skuDetails); + } + } else { + Log.w(LOG_TAG, "Query SKU details is OK, but SKU list is empty " + billingResult.getDebugMessage()); + + + } + + } else { + Log.w(LOG_TAG, "Query SKU details warning " + billingResult.getResponseCode() + " " + billingResult.getDebugMessage()); + } + } + }); + } + + private List<Purchase> queryPurchases() { + Purchase.PurchasesResult purchasesResult = mBillingClient.queryPurchases(BillingClient.SkuType.INAPP); + return purchasesResult.getPurchasesList(); + } + + private void handlePurchases(@NonNull List<Purchase> purchasesList) { + if (!billingServiceConnected) { + mBillingClient.startConnection(this); + return; + } + + if (purchasesList.isEmpty()) { + String signedData = new PrefManager(activity).getStrPref("gpData"); + String signature = new PrefManager(activity).getStrPref("gpSign"); + + if (!signedData.isEmpty() && !signature.isEmpty() && verifyValidSignature(signedData, signature)) { + Log.w(LOG_TAG, "Purchases list is empty but saved signature is correct. Allowing..."); + payComplete(); + } else { + Log.w(LOG_TAG, "Purchases list is empty. Skipping..."); + } + + return; + } + + for (int i = 0; i < purchasesList.size(); i++) { + Purchase purchase = purchasesList.get(i); + String purchaseId = purchase.getSku(); + int purchaseState = purchase.getPurchaseState(); + boolean acknowledged = purchase.isAcknowledged(); + + if(TextUtils.equals(mSkuId, purchaseId) && purchaseState == Purchase.PurchaseState.PURCHASED) { + + if (!verifyValidSignature(purchase.getOriginalJson(), purchase.getSignature())) { + if (!acknowledged && activity != null) { + activity.runOnUiThread(() -> { + DialogFragment dialogFragment = NotificationDialogFragment.newInstance(R.string.wrong_purchase_signature_gp); + if (dialogFragment != null && activity != null) { + dialogFragment.show(activity.getSupportFragmentManager(), "wrong_purchase_signature"); + } + }); + } + + Log.w(LOG_TAG, "Got a purchase: " + purchase + "; but signature is bad. Skipping..."); + return; + } + + if (!acknowledged) { + AcknowledgePurchaseParams acknowledgePurchaseParams = + AcknowledgePurchaseParams.newBuilder() + .setPurchaseToken(purchase.getPurchaseToken()) + .build(); + mBillingClient.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener() { + @Override + public void onAcknowledgePurchaseResponse(BillingResult billingResult) { + if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { + Log.i(LOG_TAG, "Purchase is acknowledged " + purchase.getSku()); + + if (activity != null) { + activity.runOnUiThread(() -> { + + if (activity == null) { + return; + } + + String thanks = activity.getString(R.string.thanks_for_donate); + if (!thanks.contains(".")) { + return; + } + + DialogFragment dialogFragment = NotificationDialogFragment.newInstance( + thanks.substring(0, thanks.indexOf("."))); + if (dialogFragment != null && activity != null) { + dialogFragment.show(activity.getSupportFragmentManager(), "thanks_for_donate"); + } + }); + } + } else { + Log.i(LOG_TAG, "Purchase not acknowledged " + purchase.getSku() + billingResult.getDebugMessage()); + } + } + }); + } + + payComplete(); + } else if (purchaseState == Purchase.PurchaseState.PENDING) { + Log.i(LOG_TAG, "Purchase is pending " + purchase.getSku()); + + NotificationHelper notificationHelper = NotificationHelper.setHelperMessage( + activity, activity.getText(R.string.pending_purchase).toString() + + " " + purchase.getSku() + + " " + purchase.getOrderId(), "pending_purchase"); + if (notificationHelper != null) { + notificationHelper.show(activity.getSupportFragmentManager(), NotificationHelper.TAG_HELPER); + } + } + } + } + + private boolean verifyValidSignature(String signedData, String signature) { + new PrefManager(activity).setStrPref("gpData", signedData); + new PrefManager(activity).setStrPref("gpSign", signature); + + boolean result = false; + try { + PublicKey pkey = getAPKKey(); + Signature sig = Signature.getInstance("SHA1withRSA"); + //Signature sig = Signature.getInstance("RSASSA-PKCS1-v1_5"); + sig.initVerify(pkey); + sig.update(signedData.getBytes()); + + if(sig.verify(Base64.decode(signature, Base64.DEFAULT))) { + result = true; + } else { + Log.e(LOG_TAG, "AccelerateDevelop signature is wrong " + signature); + } + } catch (Exception e) { + Log.e(LOG_TAG, "AccelerateDevelop verifyValidSignature Exception " + e.getMessage() + " " + e.getCause()); + } + return result; + } + + private byte[] RSADecrypt(final String encryptedText, final Key key) { + byte[] result = new byte[]{0}; + try { + byte[] encryptedBytes = Base64.decode(encryptedText, Base64.DEFAULT); + Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding"); + cipher.init(Cipher.DECRYPT_MODE, key); + result = cipher.doFinal(encryptedBytes); + } catch (Exception e) { + Log.e(LOG_TAG, "RSADecrypt function fault " + e.getMessage()); + } + return result; + } + + private PublicKey getAPKKey() throws Exception{ + byte[] decodedKey = Base64.decode(activity.getString(R.string.gp_property), Base64.DEFAULT); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey)); + } + + private void payComplete() { + accelerated = true; + Log.i(LOG_TAG, "Payment completed"); + } +} diff --git a/tordnscrypt/src/google_play/res/drawable/ic_help_title.png b/tordnscrypt/src/google_play/res/drawable/ic_help_title.png new file mode 100644 index 000000000..da24f2c4f Binary files /dev/null and b/tordnscrypt/src/google_play/res/drawable/ic_help_title.png differ diff --git a/tordnscrypt/src/google_play/res/values/encoded.xml b/tordnscrypt/src/google_play/res/values/encoded.xml new file mode 100644 index 000000000..1e660adde --- /dev/null +++ b/tordnscrypt/src/google_play/res/values/encoded.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="encoded" translatable="false">p/JXl3lzfQLrpvCNXPibrsTLqF36DH6SMO3I1JEmxAwh+2emiTJw4R73lfUR1ru2</string> + <string name="appVersion" translatable="false">gp</string> + <string name="main_activity_label" translatable="false">InviZible Pro</string> +</resources> \ No newline at end of file diff --git a/tordnscrypt/src/lite/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java b/tordnscrypt/src/lite/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java new file mode 100644 index 000000000..b5f38039d --- /dev/null +++ b/tordnscrypt/src/lite/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java @@ -0,0 +1,37 @@ +package pan.alexander.tordnscrypt.assistance; + +/* + This file is part of InviZible Pro. + + InviZible Pro is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InviZible Pro is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with InviZible Pro. If not, see <http://www.gnu.org/licenses/>. + + Copyright 2019-2020 by Garmatin Oleksandr invizible.soft@gmail.com +*/ + +import pan.alexander.tordnscrypt.MainActivity; + +public class AccelerateDevelop { + public final static String mSkuId = ""; + + public static boolean accelerated = true; + + public AccelerateDevelop(MainActivity activity) { + } + + public void initBilling() { + } + + public void launchBilling(String skuId) { + } +} diff --git a/tordnscrypt/src/lite/res/menu/activity_main_drawer.xml b/tordnscrypt/src/lite/res/menu/activity_main_drawer.xml deleted file mode 100644 index 6ff9a4a3f..000000000 --- a/tordnscrypt/src/lite/res/menu/activity_main_drawer.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - tools:showIn="navigation_view"> - - <group android:checkableBehavior="none"> - <item - android:id="@+id/nav_fast_Pref" - android:icon="@drawable/ic_settings_fast" - android:title="@string/drawer_menu_fastSettings" /> - <item - android:id="@+id/nav_common_Pref" - android:icon="@drawable/ic_settings_common" - android:title="@string/drawer_menu_commonSettings" /> - <item - android:id="@+id/nav_DNS_Pref" - android:icon="@drawable/ic_settings_dnscrypt" - android:title="@string/drawer_menu_DNSSettings" /> - <item - android:id="@+id/nav_Tor_Pref" - android:icon="@drawable/ic_settings_tor" - android:title="@string/drawer_menu_TorSettings" /> - <item - android:id="@+id/nav_I2PD_Pref" - android:icon="@drawable/ic_settings_itpd" - android:title="@string/drawer_menu_I2PDSettings" /> - <item - android:id="@+id/nav_backup" - android:icon="@drawable/ic_save_black_24dp" - android:title="@string/drawer_menu_backup" /> - </group> - - <item android:title=""> - <menu> - <item - android:id="@+id/nav_Donate" - android:icon="@drawable/ic_attach_money_black_24dp" - android:title="@string/drawer_menu_donate" /> - <item - android:id="@+id/nav_Code" - android:icon="@drawable/ic_enter_black_24dp" - android:title="@string/enter_code_button" /> - <item - android:id="@+id/nav_about" - android:icon="@drawable/ic_info_black_24dp" - android:title="@string/drawer_menu_about" /> - <item - android:id="@+id/nav_help" - android:icon="@drawable/ic_help_black_24dp" - android:title="@string/drawer_menu_help" /> - </menu> - </item> - -</menu> diff --git a/tordnscrypt/src/lite/res/xml/preferences_fast.xml b/tordnscrypt/src/lite/res/xml/preferences_fast.xml index 8e213fd60..bfbc88b2f 100644 --- a/tordnscrypt/src/lite/res/xml/preferences_fast.xml +++ b/tordnscrypt/src/lite/res/xml/preferences_fast.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> -<android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> +<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + android:key="fast_preferences"> <PreferenceCategory android:title="@string/pref_fast_categ_autostart"> @@ -133,7 +134,7 @@ android:key="pref_fast_block_http" android:summary="@string/pref_fast_block_http_summ" android:title="@string/pref_fast_block_http" /> - <ListPreference + <androidx.preference.ListPreference android:defaultValue="4" android:entries="@array/pref_fast_theme_titles" android:entryValues="@array/pref_fast_theme_values" @@ -145,4 +146,4 @@ android:enabled="true" android:selectable="true" /> </PreferenceCategory> -</android.support.v7.preference.PreferenceScreen> +</androidx.preference.PreferenceScreen> diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/MainActivity.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/MainActivity.java index 0d09ec78e..4317840bc 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/MainActivity.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/MainActivity.java @@ -59,6 +59,7 @@ import java.util.Timer; import java.util.TimerTask; +import pan.alexander.tordnscrypt.assistance.AccelerateDevelop; import pan.alexander.tordnscrypt.backup.BackupActivity; import pan.alexander.tordnscrypt.dialogs.NotificationDialogFragment; import pan.alexander.tordnscrypt.dnscrypt_fragment.DNSCryptRunFragment; @@ -81,6 +82,8 @@ import pan.alexander.tordnscrypt.utils.enums.OperationMode; import pan.alexander.tordnscrypt.vpn.service.ServiceVPNHelper; +import static pan.alexander.tordnscrypt.TopFragment.appVersion; +import static pan.alexander.tordnscrypt.assistance.AccelerateDevelop.accelerated; import static pan.alexander.tordnscrypt.utils.RootExecService.LOG_TAG; import static pan.alexander.tordnscrypt.utils.enums.ModuleState.STOPPED; import static pan.alexander.tordnscrypt.utils.enums.OperationMode.PROXY_MODE; @@ -96,6 +99,7 @@ public class MainActivity extends LangAppCompatActivity private static final int CODE_IS_VPN_ALLOWED = 101; public boolean childLockActive = false; + public AccelerateDevelop accelerateDevelop; private Timer timer; private Handler handler; private TopFragment topFragment; @@ -132,6 +136,8 @@ protected void onCreate(Bundle savedInstanceState) { navigationView.setBackgroundColor(getResources().getColor(R.color.colorBackground)); navigationView.setNavigationItemSelectedListener(this); + changeDrawerWithVersionAndDestination(navigationView); + viewPager = findViewById(R.id.viewPager); if (viewPager != null) { viewPager.setOffscreenPageLimit(4); @@ -174,6 +180,11 @@ public void onResume() { checkUpdates(); showUpdateResultMessage(); + + if (appVersion.equals("gp")) { + accelerateDevelop = new AccelerateDevelop(this); + accelerateDevelop.initBilling(); + } } @Override @@ -208,6 +219,11 @@ private void setDayNightTheme() { SharedPreferences defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); try { String theme = defaultSharedPreferences.getString("pref_fast_theme", "4"); + + if (appVersion.startsWith("g") && !accelerated) { + theme = defaultSharedPreferences.getString("pref_fast_theme", "1"); + } + switch (Objects.requireNonNull(theme)) { case "1": AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); @@ -228,6 +244,11 @@ private void setDayNightTheme() { } private void checkUpdates() { + + if (appVersion.equals("gp") || appVersion.equals("fd")) { + return; + } + Intent intent = getIntent(); if (Objects.equals(intent.getAction(), "check_update")) { if (topFragment != null) { @@ -241,6 +262,11 @@ private void checkUpdates() { } public void showUpdateResultMessage() { + + if (appVersion.equals("gp") || appVersion.equals("fd")) { + return; + } + String updateResultMessage = new PrefManager(this).getStrPref("UpdateResultMessage"); if (!updateResultMessage.isEmpty()) { showUpdateMessage(updateResultMessage); @@ -753,8 +779,14 @@ public boolean onNavigationItemSelected(@NonNull MenuItem item) { Intent intent = new Intent(this, HelpActivity.class); startActivity(intent); } else if (id == R.id.nav_Donate) { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://invizible.net/donate")); - startActivity(intent); + if (appVersion.startsWith("g")) { + if (accelerateDevelop != null) { + accelerateDevelop.launchBilling(AccelerateDevelop.mSkuId); + } + } else { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://invizible.net/ru/donate/")); + startActivity(intent); + } } else if (id == R.id.nav_Code) { Registration registration = new Registration(this); registration.showEnterCodeDialog(); @@ -857,6 +889,38 @@ private void startVPNService(int resultCode) { } } + private void changeDrawerWithVersionAndDestination(NavigationView navigationView) { + if (navigationView == null) { + return; + } + + MenuItem item = navigationView.getMenu().findItem(R.id.nav_Donate); + if ((appVersion.startsWith("g") && accelerated) || appVersion.startsWith("p") || appVersion.startsWith("f")) { + if (item != null) { + item.setVisible(false); + } + } else { + if (item != null) { + item.setVisible(true); + + if (appVersion.startsWith("g")) { + item.setTitle(R.string.premium); + } + } + } + + item = navigationView.getMenu().findItem(R.id.nav_Code); + if (appVersion.startsWith("l")) { + if (item != null) { + item.setVisible(true); + } + } else { + if (item != null) { + item.setVisible(false); + } + } + } + @Override public void onDestroy() { super.onDestroy(); diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/TopFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/TopFragment.java index 7ba1a149b..4c2833527 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/TopFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/TopFragment.java @@ -46,6 +46,8 @@ import java.util.TimerTask; import eu.chainfire.libsuperuser.Shell; +import pan.alexander.tordnscrypt.dialogs.AgreementDialog; +import pan.alexander.tordnscrypt.dialogs.AskAccelerateDevelop; import pan.alexander.tordnscrypt.dialogs.InstallAppDialogFragment; import pan.alexander.tordnscrypt.dialogs.NewUpdateDialogFragment; import pan.alexander.tordnscrypt.dialogs.NotificationHelper; @@ -65,6 +67,7 @@ import pan.alexander.tordnscrypt.update.UpdateService; import pan.alexander.tordnscrypt.utils.enums.OperationMode; +import static pan.alexander.tordnscrypt.assistance.AccelerateDevelop.accelerated; import static pan.alexander.tordnscrypt.utils.RootExecService.LOG_TAG; import static pan.alexander.tordnscrypt.utils.enums.OperationMode.UNDEFINED; @@ -159,6 +162,10 @@ public void onResume() { } else { ModulesAux.requestModulesStatusUpdate(getActivity()); } + + if (!isModulesNotInstalled(getActivity()) && appVersion.endsWith("p")) { + checkAgreement(); + } } } @@ -294,13 +301,33 @@ protected void onPostExecute(Void result) { } private void showDonDialog() { + if (getActivity()== null) { + return; + } + if (appVersion.endsWith("e")) { Handler handler = new Handler(); Runnable performRegistration = () -> { - Registration registration = new Registration(getActivity()); - registration.showDonateDialog(); + if (getActivity() != null) { + Registration registration = new Registration(getActivity()); + registration.showDonateDialog(); + } }; handler.postDelayed(performRegistration, 5000); + } else if (appVersion.endsWith("p") && getFragmentManager() != null && !accelerated) { + + if (!new PrefManager(getActivity()).getBoolPref("Agreement")) { + return; + } + + Handler handler = new Handler(); + handler.postDelayed(() -> { + DialogFragment accelerateDevelop = AskAccelerateDevelop.getInstance(); + if (getActivity() != null && getFragmentManager() != null && !accelerated) { + accelerateDevelop.show(getFragmentManager(), "accelerateDevelop"); + } + },5000); + } } @@ -474,7 +501,7 @@ public void checkUpdates() { SharedPreferences spref = PreferenceManager.getDefaultSharedPreferences(getActivity()); boolean autoUpdate = spref.getBoolean("pref_fast_auto_update", true) - && !appVersion.startsWith("l"); + && !appVersion.startsWith("l") && !appVersion.endsWith("p") && !appVersion.startsWith("f"); if (autoUpdate) { boolean throughTorUpdate = spref.getBoolean("pref_fast through_tor_update", false); boolean torRunning = new PrefManager(getActivity()).getBoolPref("Tor Running"); @@ -496,7 +523,7 @@ public void checkUpdates() { public void checkNewVer() { - if (getActivity() == null) { + if (getActivity() == null || appVersion.endsWith("p") || appVersion.startsWith("f")) { return; } @@ -668,4 +695,14 @@ private void unRegisterReceiver() { } } + + private void checkAgreement() { + if (getActivity() == null) { + return; + } + + if (!new PrefManager(getActivity()).getBoolPref("Agreement")) { + AgreementDialog.getDialogBuilder(getActivity()).show(); + } + } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/AgreementDialog.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/AgreementDialog.java new file mode 100644 index 000000000..376e5e2c0 --- /dev/null +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/AgreementDialog.java @@ -0,0 +1,56 @@ +package pan.alexander.tordnscrypt.dialogs; + +/* + This file is part of InviZible Pro. + + InviZible Pro is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InviZible Pro is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with InviZible Pro. If not, see <http://www.gnu.org/licenses/>. + + Copyright 2019-2020 by Garmatin Oleksandr invizible.soft@gmail.com +*/ + +import android.annotation.SuppressLint; +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; + +import androidx.appcompat.app.AlertDialog; + +import java.util.Objects; + +import pan.alexander.tordnscrypt.R; +import pan.alexander.tordnscrypt.utils.PrefManager; + +public class AgreementDialog { + public static AlertDialog.Builder getDialogBuilder(Context context) { + AlertDialog.Builder alertDialog = new AlertDialog.Builder(context, R.style.CustomDialogTheme); + + LayoutInflater lInflater = (LayoutInflater) Objects.requireNonNull(context).getSystemService(Context.LAYOUT_INFLATER_SERVICE); + if (lInflater != null) { + @SuppressLint("InflateParams") + View view = lInflater.inflate(R.layout.agreement_layout, null, false); + if (view != null) { + alertDialog.setView(view); + } + } + + alertDialog.setCancelable(false); + + alertDialog.setPositiveButton(R.string.agree, (dialog, id) -> { + new PrefManager(context).setBoolPref("Agreement", true); + dialog.dismiss(); + }); + alertDialog.setNegativeButton(R.string.disagree, ((dialog, id) -> System.exit(0))); + return alertDialog; + } +} diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/AskAccelerateDevelop.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/AskAccelerateDevelop.java new file mode 100644 index 000000000..010b7e222 --- /dev/null +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/AskAccelerateDevelop.java @@ -0,0 +1,66 @@ +package pan.alexander.tordnscrypt.dialogs; + +/* + This file is part of InviZible Pro. + + InviZible Pro is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InviZible Pro is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with InviZible Pro. If not, see <http://www.gnu.org/licenses/>. + + Copyright 2019-2020 by Garmatin Oleksandr invizible.soft@gmail.com +*/ + +import android.os.Handler; +import android.os.Looper; + +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.DialogFragment; + +import pan.alexander.tordnscrypt.MainActivity; +import pan.alexander.tordnscrypt.R; +import pan.alexander.tordnscrypt.assistance.AccelerateDevelop; + +public class AskAccelerateDevelop extends ExtendedDialogFragment { + public static DialogFragment getInstance() { + return new AskAccelerateDevelop(); + } + + + @Override + public AlertDialog.Builder assignBuilder() { + + if (getActivity() == null) { + return null; + } + + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.CustomAlertDialogTheme); + builder.setMessage(R.string.buy_premium_gp) + .setTitle(getString(R.string.premium)) + .setPositiveButton(R.string.ok, (dialog, which) -> { + if (getActivity() != null && getActivity() instanceof MainActivity) { + MainActivity mainActivity = (MainActivity) getActivity(); + if (mainActivity.accelerateDevelop != null) { + Handler handler = new Handler(Looper.getMainLooper()); + handler.post(() -> { + if (mainActivity.accelerateDevelop != null) { + mainActivity.accelerateDevelop.launchBilling(AccelerateDevelop.mSkuId); + } + }); + } + } + + }) + .setNegativeButton(R.string.cancel, (dialog, id) -> dismiss()); + + return builder; + } +} diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dnscrypt_fragment/DNSCryptFragmentPresenter.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dnscrypt_fragment/DNSCryptFragmentPresenter.java index 664f0afae..9aaddd2a0 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dnscrypt_fragment/DNSCryptFragmentPresenter.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dnscrypt_fragment/DNSCryptFragmentPresenter.java @@ -54,6 +54,7 @@ import pan.alexander.tordnscrypt.vpn.service.ServiceVPNHelper; import static pan.alexander.tordnscrypt.TopFragment.DNSCryptVersion; +import static pan.alexander.tordnscrypt.TopFragment.appVersion; import static pan.alexander.tordnscrypt.utils.RootExecService.LOG_TAG; import static pan.alexander.tordnscrypt.utils.enums.ModuleState.RESTARTING; import static pan.alexander.tordnscrypt.utils.enums.ModuleState.RUNNING; @@ -429,6 +430,10 @@ private boolean displayDnsResponses(String savedLines) { for (int i = 0; i < savedResourceRecords.size(); i++) { rr = savedResourceRecords.get(i); + if (appVersion.startsWith("g") && rr.HInfo.contains("block_ipv6")) { + continue; + } + if (rr.Resource.equals("0.0.0.0") || rr.Resource.equals("127.0.0.1") || rr.HInfo.contains("dnscrypt") || rr.Rcode != 0) { if (!rr.AName.isEmpty()) { lines.append("<font color=#f08080>").append(rr.AName); diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/Installer.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/Installer.java index 4943384ee..dc689b988 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/Installer.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/Installer.java @@ -19,13 +19,16 @@ Copyright 2019-2020 by Garmatin Oleksandr invizible.soft@gmail.com */ +import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; import android.content.IntentFilter; -import androidx.fragment.app.FragmentManager; import android.util.Log; +import androidx.fragment.app.FragmentManager; + import java.io.File; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -272,7 +275,7 @@ protected void correctAppDir() { Log.i(LOG_TAG, "Installer: correctAppDir OK"); } - @SuppressWarnings("all") + @SuppressLint("SdCardPath") private void fixAppDirLinesList(String path, List<String> lines) { if (lines != null) { String line; @@ -283,12 +286,53 @@ private void fixAppDirLinesList(String path, List<String> lines) { lines.set(i, line); } } + + if (activity != null + && activity.getText(R.string.package_name).toString().contains(".gp") + && path.contains("dnscrypt-proxy.toml")) { + lines = prepareDNSCryptForGP(lines); + } + FileOperations.writeTextFileSynchronous(activity, path, lines); } else { throw new IllegalStateException("correctAppDir readTextFile return null " + path); } } + @SuppressLint("SdCardPath") + private List<String> prepareDNSCryptForGP(List<String> lines) { + ArrayList<String> prepared = new ArrayList<>(); + + for (String line : lines) { + if (line.contains("block_unqualified")) { + line = "block_unqualified = false"; + } else if (line.contains("block_undelegated")) { + line = "block_undelegated = false"; + } else if (line.contains("blacklist_file")) { + line = ""; + } else if (line.contains("whitelist_file")) { + line = ""; + } else if (line.matches("(^| )\\{ ?server_name([ =]).+")) { + line = ""; + } else if (line.matches("(^| )server_names([ =]).+")) { + line = "server_names = [\"dnswarden-dc1\", " + + "\"dnswarden-dc2\", " + + "\"dnswarden-doh1\", " + + "\"dnswarden-doh2\", " + + "\"cs-ch\", " + + "\"cs-ca\", " + + "\"doh-ibksturm\", " + + "\"scaleway-fr\"]"; + } + + if (!line.isEmpty()) { + prepared.add(line); + } + } + + return prepared; + } + protected void stopAllRunningModulesWithRootCommand() { Log.i(LOG_TAG, "Installer: stopAllRunningModulesWithRootCommand"); diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/InstallerUIChanger.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/InstallerUIChanger.java index 22f6ede69..4339c4d9e 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/InstallerUIChanger.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/InstallerUIChanger.java @@ -22,6 +22,8 @@ import androidx.drawerlayout.widget.DrawerLayout; import android.util.Log; +import pan.alexander.tordnscrypt.TopFragment; +import pan.alexander.tordnscrypt.dialogs.AgreementDialog; import pan.alexander.tordnscrypt.dnscrypt_fragment.DNSCryptRunFragment; import pan.alexander.tordnscrypt.itpd_fragment.ITPDRunFragment; import pan.alexander.tordnscrypt.MainActivity; @@ -29,6 +31,7 @@ import pan.alexander.tordnscrypt.tor_fragment.TorRunFragment; import pan.alexander.tordnscrypt.dialogs.DialogAfterInstallation; +import static pan.alexander.tordnscrypt.TopFragment.appVersion; import static pan.alexander.tordnscrypt.utils.RootExecService.LOG_TAG; class InstallerUIChanger { @@ -208,7 +211,12 @@ Runnable setModulesStartButtonsEnabled() { } Runnable showDialogAfterInstallation() { - return () -> DialogAfterInstallation.getDialogBuilder(mainActivity).show(); + if (appVersion.endsWith("p")) { + return () -> AgreementDialog.getDialogBuilder(mainActivity).show(); + } else { + return () -> DialogAfterInstallation.getDialogBuilder(mainActivity).show(); + } + } Runnable setModulesStatusTextError() { diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesBroadcastReceiver.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesBroadcastReceiver.java index c980b001e..4b49fab35 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesBroadcastReceiver.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesBroadcastReceiver.java @@ -24,6 +24,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.LinkProperties; import android.net.Network; @@ -35,6 +36,7 @@ import android.util.Log; import androidx.annotation.NonNull; +import androidx.preference.PreferenceManager; import java.net.InetAddress; import java.util.List; @@ -225,6 +227,13 @@ private void unlistenNetworkChanges() { private void updateIptablesRules() { + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); + boolean refreshRules = sharedPreferences.getBoolean("swRefreshRules", true); + + if (!refreshRules) { + return; + } + if (modulesStatus.getMode() == ROOT_MODE && !modulesStatus.isUseModulesWithRoot() && !lock) { diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesCommonFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesCommonFragment.java index c5ab1f2c2..bf789e68c 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesCommonFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesCommonFragment.java @@ -57,6 +57,7 @@ import pan.alexander.tordnscrypt.utils.file_operations.OnTextFileOperationsCompleteListener; import static pan.alexander.tordnscrypt.TopFragment.TOP_BROADCAST; +import static pan.alexander.tordnscrypt.TopFragment.appVersion; import static pan.alexander.tordnscrypt.TopFragment.wrongSign; import static pan.alexander.tordnscrypt.utils.RootExecService.LOG_TAG; import static pan.alexander.tordnscrypt.utils.enums.FileOperationsVariants.readTextFile; @@ -113,6 +114,14 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, removePreferences(); } + if (appVersion.startsWith("g")) { + PreferenceCategory hotspotSettingsCategory = findPreference("HOTSPOT"); + Preference blockHTTP = findPreference("pref_common_block_http"); + if (hotspotSettingsCategory != null && blockHTTP != null) { + hotspotSettingsCategory.removePreference(blockHTTP); + } + } + return super.onCreateView(inflater, container, savedInstanceState); } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesDNSFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesDNSFragment.java index 6f8869f53..5408e728a 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesDNSFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesDNSFragment.java @@ -20,7 +20,10 @@ import android.os.Bundle; import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.PreferenceScreen; + import android.util.Log; import android.widget.Toast; @@ -35,6 +38,7 @@ import pan.alexander.tordnscrypt.utils.PrefManager; import pan.alexander.tordnscrypt.utils.file_operations.FileOperations; +import static pan.alexander.tordnscrypt.TopFragment.appVersion; import static pan.alexander.tordnscrypt.utils.RootExecService.LOG_TAG; public class PreferencesDNSFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener { @@ -53,6 +57,10 @@ public void onCreate(Bundle savedInstanceState) { addPreferencesFromResource(R.xml.preferences_dnscrypt); + if (appVersion.endsWith("p")) { + removePreferencesWithGPVersion(); + } + ArrayList<Preference> preferences = new ArrayList<>(); preferences.add(findPreference("listen_port")); @@ -79,7 +87,7 @@ public void onCreate(Bundle savedInstanceState) { for (Preference preference : preferences) { if (preference != null) { preference.setOnPreferenceChangeListener(this); - } else { + } else if (!appVersion.startsWith("g")){ Log.e(LOG_TAG, "PreferencesDNSFragment preference is null exception"); } } @@ -209,4 +217,29 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { return false; } + + private void removePreferencesWithGPVersion() { + PreferenceScreen dnscryptSettings = findPreference("dnscrypt_settings"); + + ArrayList<PreferenceCategory> categories = new ArrayList<>(); + categories.add(findPreference("pref_dnscrypt_filters_categ")); + categories.add(findPreference("pref_dnscrypt_forwarding_rules")); + categories.add(findPreference("pref_dnscrypt_cloaking_rules")); + categories.add(findPreference("pref_dnscrypt_blacklist")); + categories.add(findPreference("pref_dnscrypt_ipblacklist")); + categories.add(findPreference("pref_dnscrypt_whitelist")); + + for (PreferenceCategory category : categories) { + if (dnscryptSettings != null && category != null) { + dnscryptSettings.removePreference(category); + } + } + + PreferenceCategory requireServersCategory = findPreference("dnscrypt_require_servers_prop_summ"); + Preference requireNofilter = findPreference("require_nofilter"); + + if (requireServersCategory != null && requireNofilter != null) { + requireServersCategory.removePreference(requireNofilter); + } + } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesFastFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesFastFragment.java index 642d012b7..53a305845 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesFastFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesFastFragment.java @@ -33,10 +33,12 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatDelegate; +import androidx.fragment.app.DialogFragment; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceManager; +import androidx.preference.PreferenceScreen; import java.util.ArrayList; import java.util.Date; @@ -45,6 +47,7 @@ import pan.alexander.tordnscrypt.MainActivity; import pan.alexander.tordnscrypt.R; +import pan.alexander.tordnscrypt.dialogs.NotificationDialogFragment; import pan.alexander.tordnscrypt.language.Language; import pan.alexander.tordnscrypt.modules.ModulesAux; import pan.alexander.tordnscrypt.modules.ModulesStatus; @@ -52,6 +55,7 @@ import pan.alexander.tordnscrypt.utils.PrefManager; import static pan.alexander.tordnscrypt.TopFragment.appVersion; +import static pan.alexander.tordnscrypt.assistance.AccelerateDevelop.accelerated; import static pan.alexander.tordnscrypt.utils.RootExecService.LOG_TAG; import static pan.alexander.tordnscrypt.utils.enums.ModuleState.RUNNING; import static pan.alexander.tordnscrypt.utils.enums.OperationMode.ROOT_MODE; @@ -106,12 +110,23 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, changePreferencesWithProxyMode(); } + if (appVersion.startsWith("g")) { + changePreferencesForGPVersion(); + } else if (appVersion.endsWith("d")) { + changePreferencesForFDVersion(); + } + return super.onCreateView(inflater, container, savedInstanceState); } @Override public void onCreatePreferences(Bundle bundle, String s) { - + if (appVersion.startsWith("g") && !accelerated && getActivity() != null) { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); + if (preferences != null) { + preferences.edit().putString("pref_fast_theme", "1").apply(); + } + } } @Override @@ -328,6 +343,15 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { } return true; case "pref_fast_theme": + if (appVersion.startsWith("g") && !accelerated) { + if (getFragmentManager() != null) { + DialogFragment notificationDialogFragment = NotificationDialogFragment.newInstance(R.string.only_premium_feature); + if (notificationDialogFragment != null) { + notificationDialogFragment.show(getFragmentManager(), "NotificationDialogFragment"); + } + } + return false; + } changeTheme(); return true; case "pref_fast_language": @@ -463,4 +487,27 @@ private void changePreferencesWithProxyMode() { fastOtherCategory.removePreference(blockHttp); } } + + private void changePreferencesForGPVersion() { + PreferenceScreen preferencesFast = findPreference("fast_preferences"); + PreferenceCategory fastUpdateCategory = findPreference("fast_update"); + if (preferencesFast != null && fastUpdateCategory != null) { + preferencesFast.removePreference(fastUpdateCategory); + } + + PreferenceCategory fastOtherCategory = findPreference("fast_other"); + + Preference blockHttp = findPreference("pref_fast_block_http"); + if (fastOtherCategory != null && blockHttp != null) { + fastOtherCategory.removePreference(blockHttp); + } + } + + private void changePreferencesForFDVersion() { + PreferenceScreen preferencesFast = findPreference("fast_preferences"); + PreferenceCategory fastUpdateCategory = findPreference("fast_update"); + if (preferencesFast != null && fastUpdateCategory != null) { + preferencesFast.removePreference(fastUpdateCategory); + } + } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesITPDFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesITPDFragment.java index bfdf1fa02..0e5780708 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesITPDFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesITPDFragment.java @@ -21,8 +21,11 @@ import android.content.SharedPreferences; import android.os.Bundle; import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceManager; +import androidx.preference.PreferenceScreen; + import android.util.Log; import android.widget.Toast; @@ -33,13 +36,16 @@ import pan.alexander.tordnscrypt.R; import pan.alexander.tordnscrypt.SettingsActivity; +import pan.alexander.tordnscrypt.modules.ModulesStatus; import pan.alexander.tordnscrypt.utils.PrefManager; import pan.alexander.tordnscrypt.utils.file_operations.FileOperations; import pan.alexander.tordnscrypt.modules.ModulesRestarter; +import static pan.alexander.tordnscrypt.TopFragment.appVersion; import static pan.alexander.tordnscrypt.utils.RootExecService.LOG_TAG; +import static pan.alexander.tordnscrypt.utils.enums.ModuleState.STOPPED; -public class PreferencesITPDFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener { +public class PreferencesITPDFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener { private ArrayList<String> key_itpd; private ArrayList<String> val_itpd; @@ -55,6 +61,10 @@ public void onCreate(Bundle savedInstanceState) { addPreferencesFromResource(R.xml.preferences_i2pd); + if (appVersion.endsWith("p")) { + changePreferencesForGPVersion(); + } + ArrayList<Preference> preferences = new ArrayList<>(); preferences.add(findPreference("Allow incoming connections")); @@ -90,11 +100,16 @@ public void onCreate(Bundle savedInstanceState) { for (Preference preference : preferences) { if (preference != null) { preference.setOnPreferenceChangeListener(this); - } else { + } else if (!appVersion.startsWith("g")){ Log.e(LOG_TAG, "PreferencesITPDFragment preference is null exception"); } } + Preference cleanITPDFolder = findPreference("cleanITPDFolder"); + if (cleanITPDFolder != null) { + cleanITPDFolder.setOnPreferenceClickListener(this); + } + if (getArguments() != null) { key_itpd = getArguments().getStringArrayList("key_itpd"); @@ -219,4 +234,102 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { return false; } + + @Override + public boolean onPreferenceClick(Preference preference) { + if (getActivity() == null) { + return false; + } + + if (ModulesStatus.getInstance().getItpdState() != STOPPED) { + Toast.makeText(getActivity(), R.string.btnITPDStop, Toast.LENGTH_SHORT).show(); + return true; + } + + if ("cleanITPDFolder".equals(preference.getKey())) { + new Thread(() -> { + boolean successfully = false; + if (getActivity() != null) { + successfully = FileOperations.deleteDirSynchronous(getActivity(), appDataDir + "/i2pd_data"); + } + + if (getActivity() != null) { + if (successfully) { + getActivity().runOnUiThread(() -> Toast.makeText(getActivity(), R.string.done, Toast.LENGTH_SHORT).show()); + } else { + getActivity().runOnUiThread(() -> Toast.makeText(getActivity(), R.string.wrong, Toast.LENGTH_SHORT).show()); + } + + } + }).start(); + + + return true; + } + return false; + } + + private void changePreferencesForGPVersion() { + PreferenceCategory categoryCommon = findPreference("itpd_settings_common"); + + if (categoryCommon != null) { + ArrayList<Preference> preferences = new ArrayList<>(); + preferences.add(findPreference("Allow incoming connections")); + preferences.add(findPreference("incoming host")); + preferences.add(findPreference("incoming port")); + preferences.add(findPreference("ipv4")); + preferences.add(findPreference("ipv6")); + + for (Preference preference : preferences) { + if (preference != null) { + categoryCommon.removePreference(preference); + } + } + } + + PreferenceScreen preferenceScreen = findPreference("itpd_settings_screen"); + + if (preferenceScreen != null) { + ArrayList<PreferenceCategory> categories = new ArrayList<>(); + categories.add(findPreference("category_itpd_sam_interface")); + categories.add(findPreference("category_itpd_cryptography")); + categories.add(findPreference("category_itpd_upnp")); + categories.add(findPreference("category_itpd_reseeding")); + + for (PreferenceCategory category : categories) { + if (category != null) { + preferenceScreen.removePreference(category); + } + } + } + + PreferenceCategory categoryLimits = findPreference("category_itpd_limits"); + + if (categoryLimits != null) { + ArrayList<Preference> preferences = new ArrayList<>(); + preferences.add(findPreference("openfiles")); + preferences.add(findPreference("coresize")); + preferences.add(findPreference("ntcpsoft")); + preferences.add(findPreference("ntcphard")); + + for (Preference preference : preferences) { + if (preference != null) { + categoryLimits.removePreference(preference); + } + } + } + + PreferenceCategory categorySocksProxy = findPreference("itpd_category_socks_proxy"); + Preference enableSocks = findPreference("Socks proxy"); + if (categorySocksProxy != null && enableSocks != null) { + categorySocksProxy.removePreference(enableSocks); + } + + PreferenceCategory categoryHTTPProxy = findPreference("itpd_category_http_proxy"); + Preference enableHTTP = findPreference("HTTP proxy"); + if (categoryHTTPProxy != null && enableHTTP != null) { + categoryHTTPProxy.removePreference(enableHTTP); + } + + } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesTorFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesTorFragment.java index fb21317cd..f662e556a 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesTorFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesTorFragment.java @@ -19,6 +19,7 @@ */ import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceManager; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; @@ -35,14 +36,17 @@ import pan.alexander.tordnscrypt.R; import pan.alexander.tordnscrypt.SettingsActivity; +import pan.alexander.tordnscrypt.modules.ModulesStatus; import pan.alexander.tordnscrypt.utils.file_operations.FileOperations; import pan.alexander.tordnscrypt.modules.ModulesRestarter; import pan.alexander.tordnscrypt.utils.PrefManager; +import static pan.alexander.tordnscrypt.TopFragment.appVersion; import static pan.alexander.tordnscrypt.utils.RootExecService.LOG_TAG; +import static pan.alexander.tordnscrypt.utils.enums.ModuleState.STOPPED; -public class PreferencesTorFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener { +public class PreferencesTorFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener { private static ArrayList<String> key_tor; private static ArrayList<String> val_tor; @@ -60,6 +64,10 @@ public void onCreate(Bundle savedInstanceState) { addPreferencesFromResource(R.xml.preferences_tor); + if (appVersion.endsWith("p")) { + changePreferencesForGPVersion(); + } + ArrayList<Preference> preferences = new ArrayList<>(); preferences.add(findPreference("VirtualAddrNetworkIPv4")); @@ -89,11 +97,16 @@ public void onCreate(Bundle savedInstanceState) { for (Preference preference: preferences) { if (preference != null) { preference.setOnPreferenceChangeListener(this); - } else { + } else if (!appVersion.startsWith("g")){ Log.e(LOG_TAG, "PreferencesTorFragment preference is null exception"); } } + Preference cleanTorFolder = findPreference("cleanTorFolder"); + if (cleanTorFolder != null) { + cleanTorFolder.setOnPreferenceClickListener(this); + } + if (getArguments() != null) { key_tor = getArguments().getStringArrayList("key_tor"); @@ -305,4 +318,64 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { return false; } + + @Override + public boolean onPreferenceClick(Preference preference) { + if (getActivity() == null) { + return false; + } + + if ("cleanTorFolder".equals(preference.getKey())) { + + if (ModulesStatus.getInstance().getTorState() != STOPPED) { + Toast.makeText(getActivity(), R.string.btnTorStop, Toast.LENGTH_SHORT).show(); + return true; + } + + new Thread(() -> { + boolean successfully = false; + if (getActivity() != null) { + successfully = FileOperations.deleteDirSynchronous(getActivity(), appDataDir + "/tor_data"); + } + + if (getActivity() != null) { + if (successfully) { + getActivity().runOnUiThread(() -> Toast.makeText(getActivity(), R.string.done, Toast.LENGTH_SHORT).show()); + } else { + getActivity().runOnUiThread(() -> Toast.makeText(getActivity(), R.string.wrong, Toast.LENGTH_SHORT).show()); + } + + } + }).start(); + + + return true; + } + return false; + } + + private void changePreferencesForGPVersion() { + PreferenceCategory torSettingsCategory = findPreference("tor_settings"); + + if (torSettingsCategory != null) { + ArrayList<Preference> preferences = new ArrayList<>(); + preferences.add(findPreference("ClientUseIPv4")); + preferences.add(findPreference("ClientUseIPv6")); + preferences.add(findPreference("AvoidDiskWrites")); + preferences.add(findPreference("ConnectionPadding")); + preferences.add(findPreference("ReducedConnectionPadding")); + preferences.add(findPreference("MaxCircuitDirtiness")); + preferences.add(findPreference("EnforceDistinctSubnets")); + preferences.add(findPreference("Enable SOCKS proxy")); + preferences.add(findPreference("Enable HTTPTunnel")); + preferences.add(findPreference("Enable Transparent proxy")); + preferences.add(findPreference("Enable DNS")); + + for (Preference preference : preferences) { + if (preference != null) { + torSettingsCategory.removePreference(preference); + } + } + } + } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DNSServerItem.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DNSServerItem.java index 3d0c93fc9..a811ab0fe 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DNSServerItem.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DNSServerItem.java @@ -29,6 +29,8 @@ import java.util.ArrayList; import java.util.Objects; +import pan.alexander.tordnscrypt.R; + public class DNSServerItem { private boolean checked = false; private boolean dnssec = false; @@ -56,6 +58,10 @@ public DNSServerItem(Context context, String name, String description, String sd boolean use_dns_servers = sp.getBoolean("dnscrypt_servers", true); boolean use_doh_servers = sp.getBoolean("doh_servers", true); + if (context.getText(R.string.package_name).toString().contains(".gp")) { + require_nofilter = true; + } + byte[] bin = Base64.decode(sdns.substring(0, 7).getBytes(), 16); if (bin[0] == 0x01) { protoDNSCrypt = true; diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/update/UpdateCheck.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/update/UpdateCheck.java index a056983ee..c4b2d0cd6 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/update/UpdateCheck.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/update/UpdateCheck.java @@ -270,6 +270,10 @@ private String convertKeyForPHP(byte[] key) { } public void requestUpdateData(final String domainName, final String appSign) { + if (appVersion.endsWith("p") || appVersion.startsWith("f")) { + return; + } + Thread requestDataThread = new Thread(() -> { try { String rsaSign = RSASign(appSign); diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/Verifier.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/Verifier.java index dec2f85e2..b2d114ee9 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/Verifier.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/Verifier.java @@ -47,6 +47,8 @@ import pan.alexander.tordnscrypt.TopFragment; import pan.alexander.tordnscrypt.settings.PathVars; +import static pan.alexander.tordnscrypt.TopFragment.appVersion; + public class Verifier { @@ -134,6 +136,9 @@ public String decryptStr(String text, String key, String vector) throws Exceptio byte[] ivBytes = vector.substring(vector.length() - 16).getBytes(); cipher.init(Cipher.DECRYPT_MODE, aesKey, new IvParameterSpec(ivBytes)); byte[] decrypted = Base64.decode(text.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT); + if (appVersion.endsWith("d")) { + return new String(decrypted); + } return new String(cipher.doFinal(decrypted)); } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/IPUtil.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/IPUtil.java index fcb627442..e9c05792e 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/IPUtil.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/IPUtil.java @@ -38,7 +38,7 @@ public static List<CIDR> toCIDR(String start, String end) throws UnknownHostExce public static List<CIDR> toCIDR(InetAddress start, InetAddress end) { List<CIDR> listResult = new ArrayList<>(); - Log.i(LOG_TAG, "toCIDR(" + start.getHostAddress() + "," + end.getHostAddress() + ")"); + //Log.i(LOG_TAG, "toCIDR(" + start.getHostAddress() + "," + end.getHostAddress() + ")"); long from = inet2long(start); long to = inet2long(end); @@ -60,9 +60,6 @@ public static List<CIDR> toCIDR(InetAddress start, InetAddress end) { from += Math.pow(2, (32 - prefix)); } - for (CIDR cidr : listResult) - Log.i(LOG_TAG, cidr.toString()); - return listResult; } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/service/ServiceVPN.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/service/ServiceVPN.java index 358b1d276..4a3f12036 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/service/ServiceVPN.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/service/ServiceVPN.java @@ -157,7 +157,7 @@ private static List<InetAddress> getDns(Context context) { List<String> sysDns = Util.getDefaultDNS(context); // Get custom DNS servers - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences prefs = androidx.preference.PreferenceManager.getDefaultSharedPreferences(context); boolean ip6 = prefs.getBoolean("ipv6", false); String vpnDns1 = prefs.getString("dns", "127.0.0.1"); String vpnDns2 = prefs.getString("dns2", "127.0.0.1"); @@ -377,7 +377,7 @@ BuilderVPN getBuilder(List<Rule> listAllowed, List<Rule> listRule) { } void startNative(final ParcelFileDescriptor vpn, List<Rule> listAllowed, List<Rule> listRule) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + SharedPreferences prefs = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this); // Prepare rules prepareUidAllowed(listAllowed, listRule); @@ -528,7 +528,7 @@ private void addForwardAddressRule(int protocol, String daddr, String raddr, int public void nativeExit(String reason) { Log.w(LOG_TAG, "VPN Native exit reason=" + reason); if (reason != null) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + SharedPreferences prefs = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this); prefs.edit().putBoolean("VPNServiceEnabled", false).apply(); } } @@ -815,10 +815,10 @@ public void onAvailable(@NonNull Network network) { public void onLinkPropertiesChanged(@NonNull Network network, LinkProperties linkProperties) { // Make sure the right DNS servers are being used List<InetAddress> dns = linkProperties.getDnsServers(); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ServiceVPN.this); + SharedPreferences prefs = androidx.preference.PreferenceManager.getDefaultSharedPreferences(ServiceVPN.this); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? !same(last_dns, dns) - : prefs.getBoolean("reload_onconnectivity", true)) { + : prefs.getBoolean("swRefreshRules", true)) { Log.i(LOG_TAG, "VPN Changed link properties=" + linkProperties + "DNS cur=" + TextUtils.join(",", dns) + "DNS prv=" + (last_dns == null ? null : TextUtils.join(",", last_dns))); @@ -869,7 +869,7 @@ private void listenConnectivityChanges() { @Override public int onStartCommand(Intent intent, int flags, int startId) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + SharedPreferences prefs = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this); filterUDP = prefs.getBoolean("VPN filter_udp", true); blockHttp = prefs.getBoolean("pref_fast_block_http", false); routeAllThroughInviZible = prefs.getBoolean("pref_fast_all_through_tor", true); @@ -918,7 +918,7 @@ public void onRevoke() { Log.i(LOG_TAG, "VPN Revoke"); // Disable firewall (will result in stop command) - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + SharedPreferences prefs = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this); prefs.edit().putBoolean("VPNServiceEnabled", false).apply(); ModulesAux.stopModulesIfRunning(this); diff --git a/tordnscrypt/src/main/res/layout/agreement_layout.xml b/tordnscrypt/src/main/res/layout/agreement_layout.xml new file mode 100644 index 000000000..e73f0bfc7 --- /dev/null +++ b/tordnscrypt/src/main/res/layout/agreement_layout.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <androidx.appcompat.widget.AppCompatImageView + android:id="@+id/imageView1" + android:layout_width="match_parent" + android:layout_height="100dp" + android:layout_gravity="center_horizontal" + android:adjustViewBounds="true" + android:cropToPadding="true" + app:srcCompat="@drawable/ic_help_title" + tools:ignore="ContentDescription" /> + + <androidx.appcompat.widget.AppCompatTextView + android:id="@+id/textView1" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:autoLink="all" + android:linksClickable="true" + android:scrollbarAlwaysDrawVerticalTrack="true" + android:scrollbars="vertical" + android:text="@string/agreement_text" + android:typeface="serif" /> +</LinearLayout> \ No newline at end of file diff --git a/tordnscrypt/src/main/res/menu/activity_main_drawer.xml b/tordnscrypt/src/main/res/menu/activity_main_drawer.xml index 35befa6e3..105bcc7bf 100644 --- a/tordnscrypt/src/main/res/menu/activity_main_drawer.xml +++ b/tordnscrypt/src/main/res/menu/activity_main_drawer.xml @@ -3,7 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" tools:showIn="navigation_view"> - <group android:checkableBehavior="none"> + <group android:checkableBehavior="none" + android:id="@+id/nav_main_group"> <item android:id="@+id/nav_fast_Pref" android:icon="@drawable/ic_settings_fast" @@ -24,32 +25,35 @@ android:id="@+id/nav_I2PD_Pref" android:icon="@drawable/ic_settings_itpd" android:title="@string/drawer_menu_I2PDSettings" /> + </group> + + <group android:checkableBehavior="none" + android:id="@+id/nav_donate_group"> + <item + android:id="@+id/nav_Donate" + android:icon="@drawable/ic_attach_money_black_24dp" + android:title="@string/drawer_menu_donate" /> + <item + android:id="@+id/nav_Code" + android:icon="@drawable/ic_enter_black_24dp" + android:title="@string/enter_code_button" + android:visible="false"/> + </group> + + <group android:checkableBehavior="none" + android:id="@+id/nav_secondary_group"> <item android:id="@+id/nav_backup" android:icon="@drawable/ic_save_black_24dp" android:title="@string/drawer_menu_backup" /> + <item + android:id="@+id/nav_help" + android:icon="@drawable/ic_help_black_24dp" + android:title="@string/drawer_menu_help" /> + <item + android:id="@+id/nav_about" + android:icon="@drawable/ic_info_black_24dp" + android:title="@string/drawer_menu_about" /> </group> - <item android:title=""> - <menu> - <item - android:id="@+id/nav_Donate" - android:icon="@drawable/ic_attach_money_black_24dp" - android:title="@string/drawer_menu_donate" /> - <item - android:id="@+id/nav_Code" - android:icon="@drawable/ic_enter_black_24dp" - android:title="@string/enter_code_button" - android:visible="false"/> - <item - android:id="@+id/nav_about" - android:icon="@drawable/ic_info_black_24dp" - android:title="@string/drawer_menu_about" /> - <item - android:id="@+id/nav_help" - android:icon="@drawable/ic_help_black_24dp" - android:title="@string/drawer_menu_help" /> - </menu> - </item> - </menu> diff --git a/tordnscrypt/src/main/res/values-pl/strings.xml b/tordnscrypt/src/main/res/values-pl/strings.xml index 455c31c24..b20fc9971 100644 --- a/tordnscrypt/src/main/res/values-pl/strings.xml +++ b/tordnscrypt/src/main/res/values-pl/strings.xml @@ -405,7 +405,7 @@ <string name="verifier_error">Chyba to nie jest oficjalna wersja InviZible. Uwazaj!</string> <string name="only_for_pro">Tylko wersja PRO</string> <string name="donate">Dotacja</string> - <string name="donate_project">Projekt InviZible Pro wymaga Twojego wsparcia. Prosze odwiedz strone dotacji lub wprowadz otrzymany kod rejestracyjny.</string> + <string name="donate_project">Projekt InviZible Pro potrzebuje Twojego wsparcia. Prosze odwiedz strone dotacji lub wprowadz otrzymany kod rejestracyjny.</string> <string name="donate_button">Odwiedz</string> <string name="enter_code_button">Wprowadz kod</string> <string name="enter_code">wprowadz kod</string> @@ -413,8 +413,6 @@ za wsparcie. Czy chcialbys pobrac i wykonac upgrade do wersji PRO? Aktualizacja będzie kontynuowana w tle.</string> <string name="pref_common_wakelock_summ">Dodatkowa ochrona bez trybu rootowania, aby zapobiec śmierci aplikacji przez Androida. Może wyczerpać baterię</string> <string name="pref_common_wakelock">Zapobiegaj uśpieniu urządzenia</string> - <string name="install_title_no_root">Odmowa roota</string> - <string name="install_title_root">Root dostepny</string> <string name="message_no_root_used">Możesz używać InviZible Pro z lokalnym trybem VPN lub aplikacjami z własnym proxy lub lokalną funkcją VPN w trybie proxy.</string> <string name="message_no_root_used_kitkat">Możesz używać InviZible Pro z aplikacjami z własnym proxy lub lokalną funkcją VPN w trybie proxy.</string> <string name="pref_dnscrypt_relays">Zrodla</string> @@ -440,4 +438,26 @@ Spróbuj zacząć od nowa. Wymuś zamknięcie…</string> <string name="add_custom_server_title">Dodaj serwer</string> <string name="add_custom_server_error">Niepoprawna niestandardowa konfiguracja serwera. Sprawdź pole SDNS.</string> + <string name="pref_tor_clean_module_folder">Wyczyść folder modułu</string> + <string name="done">Gotowy</string> + <string name="pending_purchase">Pamiętaj, że masz oczekujący zakup:</string> + <string name="buy_premium_gp">Projekt InviZible Pro potrzebuje Twojego wsparcia. Naciśnij OK, aby kupić funkcje premium.</string> + <string name="wrong_purchase_signature_gp">Przepraszamy, ale nie można potwierdzić zakupu. Otrzymasz zwrot pieniędzy po 3 dniach.</string> + <string name="premium">Wersja premium</string> + <string name="only_premium_feature">Niestety ta funkcja jest dostępna tylko w wersji premium.</string> + <string name="agree">Zgadzam</string> + <string name="disagree">Nie zgadzam</string> + <string name="agreement_text"> + \tThanks for choosing InviZible Pro. I hope that it will be useful for your privacy and comfortable use of the Internet. + \n\tInviZible Pro includes Tor, DNSCrypt and Purple I2P as modules. + \n\tInviZible Pro can use root, if your device has root privileges, or uses a local VPN to deliver Internet traffic to Tor, DNSCrypt and I2P networks. + \n\tThis product is produced independently from the Tor®, DNSCrypt, Purple I2P software and carries no guarantee from The Above Projects about quality, suitability or anything else. + \n\tInviZible Pro is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + \n\tCopyright © 2019-2020 + \n\tGarmatin Oleksandr + \n\tinvizible.soft@gmail.com + \n\tinvizible.net/en/privacy + </string> + <string name="pref_common_refresh_rules_summ">Zaktualizuj reguły przy każdej zmianie łączności</string> + <string name="pref_common_refresh_rules">Odśwież reguły</string> </resources> \ No newline at end of file diff --git a/tordnscrypt/src/main/res/values-ru-rRU/strings.xml b/tordnscrypt/src/main/res/values-ru-rRU/strings.xml index 6772d6d2a..169b68893 100644 --- a/tordnscrypt/src/main/res/values-ru-rRU/strings.xml +++ b/tordnscrypt/src/main/res/values-ru-rRU/strings.xml @@ -180,7 +180,7 @@ <string name="title_dnscrypt_query_log">Лог запросов DNS</string> <string name="title_dnscrypt_nx_log">Лог подозрительных запросов DNS</string> <string name="dnscrypt_empty_log">Лог пустой</string> - <string name="pref_dnscrypt_block_unqualified_summ">Немедленно отвечать на А и АААА запросы хостов без домменого имени.</string> + <string name="pref_dnscrypt_block_unqualified_summ">Немедленно отвечать на А и АААА запросы хостов без доменного имени.</string> <string name="pref_dnscrypt_block_undelegated_summ">Немедленно отвечать на запросы к локальным зонам вместо их утечки резолверам, что всегда приводит к ошибкам и лагам.</string> <string name="pref_tor_virtual_addr_network_IPv4_summ">Необходимо, чтоб Tor назначил неиспользованный виртуальный диаппазон адресов, для доступа к сайтам в зоне .onion</string> @@ -327,8 +327,7 @@ <string name="donate">Поддержка проекта</string> <string name="donate_button">Посетить</string> <string name="enter_code_button">Ввести код</string> - <string name="donate_project">Проект InviZible Pro нуждается в Вашей помощи. Пожалуйста, посетите - страницу поддержки или введите уже полученный регистрационный код.</string> + <string name="donate_project">Проект InviZible Pro нуждается в Вашей помощи. Пожалуйста, посетите страницу поддержки или введите уже полученный регистрационный код.</string> <string name="thanks_for_donate">Проект InviZible Pro и его автор благодарен за помощь. Загрузить и обновить до PRO? Обновление будет продолжено в фоновом режиме.</string> <string name="enter_code">Введите код</string> <string name="update_over_five_times">Вы проверяли обновление InviZible Pro больше 5 раз в день. Пожалуйста, попробуйте позже.</string> @@ -336,8 +335,6 @@ <string name="update_wrong_code">Похоже Ваш PRO код неверный. Пожалуйста, свяжитесь с разработчиком.</string> <string name="pref_common_wakelock">Запретить сон устройства</string> <string name="pref_common_wakelock_summ">Дополнительная защита в Безрутовом Режиме, чтоб андроид не закрыл приложение. Может привести к повышенному разряду батареи</string> - <string name="install_title_no_root">Рут отсутствует</string> - <string name="install_title_root">Рут разрешен</string> <string name="message_no_root_used">Вы можете использовать InviZible Pro в режиме локального VPN или совместно с приложениями с функцией прокси или собственным локальным VPN.</string> <string name="message_no_root_used_kitkat">Вы можете использовать @@ -365,4 +362,26 @@ Попробуйте запустить снова. Экстренное завершение…</string> <string name="add_custom_server_title">Добавить сервер</string> <string name="add_custom_server_error">Неправильная конфигурация сервера. Пожалуйста, проверьте поле SDNS.</string> + <string name="pref_tor_clean_module_folder">Очистить папку модуля</string> + <string name="done">Готово</string> + <string name="pending_purchase">Пожалуйста, обратите внимание. У Вас есть незавершенная покупка:</string> + <string name="buy_premium_gp">Проект InviZible Pro нуждается в Вашей помощи. Нажмите ОК, чтобы приобрести премиум возможности.</string> + <string name="wrong_purchase_signature_gp">К сожалению мы не можем подтвердить вашу покупку. Вы получите возврат средств через 3 дня.</string> + <string name="premium">Премиум версия</string> + <string name="only_premium_feature">К сожалению, эта опция доступна только в премиум версии.</string> + <string name="agree">Я согласен</string> + <string name="disagree">Не согласен</string> + <string name="agreement_text"> + \tСпасибо за выбор InviZible Pro. Надеюсь, приложение будет полезно для Вашей конфиденциальности и комфортного использования интернета. + \n\tInviZible Pro содержит Tor, DNSCrypt и Purple I2P в качестве модулей. + \n\tInviZible Pro может использовать рут, если у Вас есть рут права, или использовать локальный VPN для доставки интернет траффика в сети Tor, DNSCrypt и I2P. + \n\tЭто приложение созданно независимо от проектов Tor®, DNSCrypt и Purple I2P. Эти проекты не предоставляют данному приложению какие-либо гарантии в отношении качества, пригодности или чего-то еще. + \n\tInviZible Pro распространяется в надежде на то, что будет полезно, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ; в том числе подразумеваемых гарантией ТОВАРНОЙ ПРИГОДНОСТИ и ГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ. + \n\tCopyright © 2019-2020 + \n\tGarmatin Oleksandr + \n\tinvizible.soft@gmail.com + \n\tinvizible.net/en/privacy + </string> + <string name="pref_common_refresh_rules_summ">Обновлять правила при изменении подключения</string> + <string name="pref_common_refresh_rules">Обновлять правила</string> </resources> \ No newline at end of file diff --git a/tordnscrypt/src/main/res/values-ru-rUA/strings.xml b/tordnscrypt/src/main/res/values-ru-rUA/strings.xml index fcaabd439..691369afd 100644 --- a/tordnscrypt/src/main/res/values-ru-rUA/strings.xml +++ b/tordnscrypt/src/main/res/values-ru-rUA/strings.xml @@ -178,7 +178,7 @@ <string name="title_dnscrypt_query_log">Лог запросов DNS</string> <string name="title_dnscrypt_nx_log">Лог подозрительных запросов DNS</string> <string name="dnscrypt_empty_log">Лог пустой</string> - <string name="pref_dnscrypt_block_unqualified_summ">Немедленно отвечать на А и АААА запросы хостов без домменого имени.</string> + <string name="pref_dnscrypt_block_unqualified_summ">Немедленно отвечать на А и АААА запросы хостов без доменного имени.</string> <string name="pref_dnscrypt_block_undelegated_summ">Немедленно отвечать на запросы к локальным зонам вместо их утечки резолверам, что всегда приводит к ошибкам и лагам.</string> <string name="pref_tor_virtual_addr_network_IPv4_summ">Необходимо, чтоб Tor назначил неиспользованный виртуальный диаппазон адресов, для доступа к сайтам в зоне .onion</string> @@ -335,8 +335,6 @@ <string name="update_wrong_code">Похоже Ваш PRO код неверный. Пожалуйста, свяжитесь с разработчиком.</string> <string name="pref_common_wakelock">Запретить сон устройства</string> <string name="pref_common_wakelock_summ">Дополнительная защита в Безрутовом Режиме, чтоб андроид не закрыл приложение. Может привести к повышенному разряду батареи</string> - <string name="install_title_no_root">Рут отсутствует</string> - <string name="install_title_root">Рут разрешен</string> <string name="message_no_root_used">Вы можете использовать InviZible Pro в режиме локального VPN или совместно с приложениями с функцией прокси или собственным локальным VPN.</string> <string name="message_no_root_used_kitkat">Вы можете использовать @@ -365,4 +363,26 @@ Попробуйте запустить снова. Экстренное завершение…</string> <string name="add_custom_server_title">Добавить сервер</string> <string name="add_custom_server_error">Неправильная конфигурация сервера. Пожалуйста, проверьте поле SDNS.</string> + <string name="pref_tor_clean_module_folder">Очистить папку модуля</string> + <string name="done">Готово</string> + <string name="pending_purchase">Пожалуйста, обратите внимание. У Вас есть незавершенная покупка:</string> + <string name="buy_premium_gp">Проект InviZible Pro нуждается в Вашей помощи. Нажмите ОК, чтобы приобрести премиум возможности.</string> + <string name="wrong_purchase_signature_gp">К сожалению мы не можем подтвердить вашу покупку. Вы получите возврат средств через 3 дня.</string> + <string name="premium">Премиум версия</string> + <string name="only_premium_feature">К сожалению, эта опция доступна только в премиум версии.</string> + <string name="agree">Я согласен</string> + <string name="disagree">Не согласен</string> + <string name="agreement_text"> + \tСпасибо за выбор InviZible Pro. Надеюсь, приложение будет полезно для Вашей конфиденциальности и комфортного использования интернета. + \n\tInviZible Pro содержит Tor, DNSCrypt и Purple I2P в качестве модулей. + \n\tInviZible Pro может использовать рут, если у Вас есть рут права, или использовать локальный VPN для доставки интернет траффика в сети Tor, DNSCrypt и I2P. + \n\tЭто приложение созданно независимо от проектов Tor®, DNSCrypt и Purple I2P. Эти проекты не предоставляют данному приложению какие-либо гарантии в отношении качества, пригодности или чего-то еще. + \n\tInviZible Pro распространяется в надежде на то, что будет полезно, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ; в том числе подразумеваемых гарантией ТОВАРНОЙ ПРИГОДНОСТИ и ГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ. + \n\tCopyright © 2019-2020 + \n\tGarmatin Oleksandr + \n\tinvizible.soft@gmail.com + \n\tinvizible.net/en/privacy + </string> + <string name="pref_common_refresh_rules_summ">Обновлять правила при изменении подключения</string> + <string name="pref_common_refresh_rules">Обновлять правила</string> </resources> \ No newline at end of file diff --git a/tordnscrypt/src/main/res/values/strings.xml b/tordnscrypt/src/main/res/values/strings.xml index fb0638018..d7bdf4b44 100644 --- a/tordnscrypt/src/main/res/values/strings.xml +++ b/tordnscrypt/src/main/res/values/strings.xml @@ -63,10 +63,12 @@ <string name="no_root" translatable="false">NO ROOT!</string> <string name="install">Install</string> <string name="exit">Exit</string> + <string name="done">Done</string> <string name="wrong">Something went wrong!</string> <string name="install_message">Do you want to complete installation?</string> - <string name="install_title_root">Root granted</string> - <string name="install_title_no_root">Root denied</string> + <string name="premium">Premium version</string> + <string name="agree">I agree</string> + <string name="disagree">I disagree</string> <string name="message_no_root_used">You can use InviZible Pro with local VPN mode, or applications with own proxy or local VPN feature in proxy mode.</string> <string name="message_no_root_used_kitkat">You can use InviZible Pro with applications with own proxy or local VPN feature in proxy mode.</string> @@ -178,6 +180,8 @@ <string name="pref_common_block_http">Block HOTSPOT http</string> <string name="pref_common_block_http_summ">Deny connection to http port 80 for HOTSPOT</string> <string name="pref_common_notification_summ">Protect application with No Root Mode to prevent app being killed by android</string> + <string name="pref_common_refresh_rules">Refresh rules</string> + <string name="pref_common_refresh_rules_summ">Update rules on every connectivity change</string> <string name="pref_common_show_notification">Show notification</string> <string name="pref_common_wakelock">Prevent device sleep</string> <string name="pref_common_wakelock_summ">Additional Protection with No Root Mode to prevent app being killed by android. May drain battery</string> @@ -395,6 +399,7 @@ <string name="pref_tor_unlock_disabled">Disabled</string> <string name="pref_tor_unlock_app">Apps to Torify</string> <string name="pref_tor_clearnet_app">Apps to bypass Tor</string> + <string name="pref_tor_clean_module_folder">Clean module folder</string> <string name="pref_routing_unlock_app">Apps to use with InviZible</string> <string name="pref_routing_clearnet_app">Apps to bypass InviZible</string> @@ -565,7 +570,7 @@ <string name="verifier_error">Looks like this unofficial version of InviZible. Please be care of it!</string> <string name="only_for_pro">Only for PRO version</string> <string name="donate">Donate</string> - <string name="donate_project">InviZible Pro Project requires your assistance. Please visit donate page or enter received registration code.</string> + <string name="donate_project">InviZible Pro Project needs your assistance. Please visit donate page or enter received registration code.</string> <string name="donate_button">Visit</string> <string name="enter_code_button">Enter Code</string> <string name="enter_code">Enter Code</string> @@ -589,4 +594,21 @@ <string name="add_custom_server_title">Add custom server</string> <string name="add_custom_server_error">Invalid custom server configuration. Please check the SDNS field.</string> + + <string name="pending_purchase">Please note that you have a pending purchase:</string> + <string name="buy_premium_gp">InviZible Pro Project needs your assistance. Press OK to purchase premium features.</string> + <string name="wrong_purchase_signature_gp">Sorry, but it is impossible to confirm your purchase. You will receive a refund after 3 days.</string> + <string name="only_premium_feature">Unfortunately, this feature is available for the premium version only.</string> + <string name="agreement_text"> + \tThanks for choosing InviZible Pro. I hope that it will be useful for your privacy and comfortable use of the Internet. + \n\tInviZible Pro includes Tor, DNSCrypt and Purple I2P as modules. + \n\tInviZible Pro can use root, if your device has root privileges, or uses a local VPN to deliver Internet traffic to Tor, DNSCrypt and I2P networks. + \n\tThis product is produced independently from the Tor®, DNSCrypt, Purple I2P software and carries no guarantee from The Above Projects about quality, suitability or anything else. + \n\tInviZible Pro is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + \n\tCopyright © 2019-2020 + \n\tGarmatin Oleksandr + \n\tinvizible.soft@gmail.com + \n\tinvizible.net/en/privacy + </string> + </resources> diff --git a/tordnscrypt/src/main/res/xml/preferences_common.xml b/tordnscrypt/src/main/res/xml/preferences_common.xml index 25cfc2e1e..c6477053b 100644 --- a/tordnscrypt/src/main/res/xml/preferences_common.xml +++ b/tordnscrypt/src/main/res/xml/preferences_common.xml @@ -82,6 +82,12 @@ android:key="swShowNotification" android:summary="@string/pref_common_notification_summ" android:title="@string/pref_common_show_notification" /> + <SwitchPreference + android:id="@+id/swRefreshRules" + android:defaultValue="true" + android:key="swRefreshRules" + android:summary="@string/pref_common_refresh_rules_summ" + android:title="@string/pref_common_refresh_rules" /> <SwitchPreference android:id="@+id/swWakelock" android:defaultValue="false" diff --git a/tordnscrypt/src/main/res/xml/preferences_dnscrypt.xml b/tordnscrypt/src/main/res/xml/preferences_dnscrypt.xml index 812f26d2f..72183a9a5 100644 --- a/tordnscrypt/src/main/res/xml/preferences_dnscrypt.xml +++ b/tordnscrypt/src/main/res/xml/preferences_dnscrypt.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> -<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> +<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + android:key="dnscrypt_settings"> <PreferenceCategory android:title="@string/pref_advanced"> diff --git a/tordnscrypt/src/main/res/xml/preferences_fast.xml b/tordnscrypt/src/main/res/xml/preferences_fast.xml index b2762569d..54eb08fb8 100644 --- a/tordnscrypt/src/main/res/xml/preferences_fast.xml +++ b/tordnscrypt/src/main/res/xml/preferences_fast.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> -<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > +<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + android:key="fast_preferences"> <PreferenceCategory android:title="@string/pref_fast_categ_autostart"> diff --git a/tordnscrypt/src/main/res/xml/preferences_i2pd.xml b/tordnscrypt/src/main/res/xml/preferences_i2pd.xml index 93ef4492b..7482aeb9d 100644 --- a/tordnscrypt/src/main/res/xml/preferences_i2pd.xml +++ b/tordnscrypt/src/main/res/xml/preferences_i2pd.xml @@ -1,10 +1,12 @@ <?xml version="1.0" encoding="utf-8"?> -<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> +<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + android:key="itpd_settings_screen"> <PreferenceCategory android:title="@string/pref_advanced"> </PreferenceCategory> - <PreferenceCategory android:title="@string/pref_itpd_common"> + <PreferenceCategory android:title="@string/pref_itpd_common" + android:key="itpd_settings_common"> <SwitchPreference android:id="@+id/pref_itpd_com_incom_connect" @@ -96,7 +98,8 @@ android:summary="@string/pref_itpd_com_ntcpproxy_summ" android:title="@string/pref_itpd_com_ntcpproxy" /> </PreferenceCategory> - <PreferenceCategory android:title="@string/pref_itpd_HTTP_proxy"> + <PreferenceCategory android:title="@string/pref_itpd_HTTP_proxy" + android:key="itpd_category_http_proxy"> <SwitchPreference android:id="@+id/pref_itpd_HTTP_proxy_enabled" @@ -106,14 +109,14 @@ <EditTextPreference android:id="@+id/pref_itpd_HTTP_proxy_port" android:defaultValue="4444" - android:dependency="HTTP proxy" android:key="HTTP proxy port" android:selectAllOnFocus="false" android:singleLine="true" android:summary="@string/pref_itpd_HTTP_proxy_port_summ" android:title="@string/pref_itpd_HTTP_proxy_port" /> </PreferenceCategory> - <PreferenceCategory android:title="@string/pref_itpd_Socks_proxy"> + <PreferenceCategory android:title="@string/pref_itpd_Socks_proxy" + android:key="itpd_category_socks_proxy"> <SwitchPreference android:id="@+id/pref_itpd_Socks_proxy_enabled" @@ -123,14 +126,14 @@ <EditTextPreference android:id="@+id/pref_itpd_Socks_proxy_port" android:defaultValue="4447" - android:dependency="Socks proxy" android:key="Socks proxy port" android:selectAllOnFocus="false" android:singleLine="true" android:summary="@string/pref_itpd_Socks_proxy_port_summ" android:title="@string/pref_itpd_Socks_proxy_port" /> </PreferenceCategory> - <PreferenceCategory android:title="@string/pref_itpd_SAM_interface"> + <PreferenceCategory android:title="@string/pref_itpd_SAM_interface" + android:key="category_itpd_sam_interface"> <SwitchPreference android:id="@+id/pref_itpd_SAM_interface_enabled" @@ -147,7 +150,8 @@ android:summary="@string/pref_itpd_SAM_interface_port_summ" android:title="@string/pref_itpd_SAM_interface_port" /> </PreferenceCategory> - <PreferenceCategory android:title="@string/pref_itpd_Cryptography"> + <PreferenceCategory android:title="@string/pref_itpd_Cryptography" + android:key="category_itpd_cryptography"> <CheckBoxPreference android:id="@+id/pref_itp_delgamal_enabled" @@ -156,7 +160,8 @@ android:summary="@string/pref_itpd_elgamal_summ" android:title="@string/pref_itpd_elgamal_enabled" /> </PreferenceCategory> - <PreferenceCategory android:title="@string/pref_itpd_UPNP"> + <PreferenceCategory android:title="@string/pref_itpd_UPNP" + android:key="category_itpd_upnp"> <CheckBoxPreference android:id="@+id/pref_itpd_UPNP_enabled" @@ -173,7 +178,8 @@ android:key="ntcp2 enabled" android:title="@string/pref_itpd_ntcp2_enabled" /> </PreferenceCategory> - <PreferenceCategory android:title="@string/pref_itpd_reseeding"> + <PreferenceCategory android:title="@string/pref_itpd_reseeding" + android:key="category_itpd_reseeding"> <CheckBoxPreference android:id="@+id/pref_itpd_reseeding_enabled" @@ -182,7 +188,8 @@ android:summary="@string/pref_itpd_reseeding_summ" android:title="@string/pref_itpd_reseeding_enabled" /> </PreferenceCategory> - <PreferenceCategory android:title="@string/pref_itpd_limits"> + <PreferenceCategory android:title="@string/pref_itpd_limits" + android:key="category_itpd_limits"> <EditTextPreference android:id="@+id/pref_itpd_limits_transittunnels" @@ -245,4 +252,11 @@ android:targetPackage="@string/package_name" /> </Preference> </PreferenceCategory> + <PreferenceCategory + android:title="@string/pref_common_categ_other"> + <Preference + android:key="cleanITPDFolder" + android:title="@string/pref_tor_clean_module_folder"> + </Preference> + </PreferenceCategory> </androidx.preference.PreferenceScreen> \ No newline at end of file diff --git a/tordnscrypt/src/main/res/xml/preferences_tor.xml b/tordnscrypt/src/main/res/xml/preferences_tor.xml index 79f7ab479..265c34dc6 100644 --- a/tordnscrypt/src/main/res/xml/preferences_tor.xml +++ b/tordnscrypt/src/main/res/xml/preferences_tor.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> - <PreferenceCategory android:title="@string/pref_advanced"> + <PreferenceCategory android:title="@string/pref_advanced" + android:key="tor_settings"> <SwitchPreference android:id="@+id/pref_tor_exclude_exit_nodes" @@ -56,7 +57,6 @@ <CheckBoxPreference android:id="@+id/pref_tor_strict_nodes" android:defaultValue="false" - android:dependency="ExcludeNodes" android:key="StrictNodes" android:summary="@string/pref_tor_strict_nodes_summ" android:title="@string/pref_tor_strict_nodes" /> @@ -96,7 +96,6 @@ <EditTextPreference android:id="@+id/pref_tor_SOCKS_port" android:defaultValue="9050" - android:dependency="Enable SOCKS proxy" android:key="SOCKSPort" android:selectAllOnFocus="false" android:singleLine="true" @@ -110,7 +109,6 @@ <EditTextPreference android:id="@+id/pref_tor_HTTPTunnel_port" android:defaultValue="8118" - android:dependency="Enable HTTPTunnel" android:key="HTTPTunnelPort" android:selectAllOnFocus="false" android:singleLine="true" @@ -124,7 +122,6 @@ <EditTextPreference android:id="@+id/pref_tor_trans_port" android:defaultValue="9040" - android:dependency="Enable Transparent proxy" android:key="TransPort" android:selectAllOnFocus="false" android:singleLine="true" @@ -138,7 +135,6 @@ <EditTextPreference android:id="@+id/pref_tor_DNS_port" android:defaultValue="5400" - android:dependency="Enable DNS" android:key="DNSPort" android:selectAllOnFocus="false" android:singleLine="true" @@ -158,4 +154,11 @@ android:summary="@string/pref_tor_client_use_IPv6_summ" android:title="@string/pref_tor_client_use_IPv6" /> </PreferenceCategory> + <PreferenceCategory + android:title="@string/pref_common_categ_other"> + <Preference + android:key="cleanTorFolder" + android:title="@string/pref_tor_clean_module_folder"> + </Preference> + </PreferenceCategory> </androidx.preference.PreferenceScreen> \ No newline at end of file diff --git a/tordnscrypt/src/pro/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java b/tordnscrypt/src/pro/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java new file mode 100644 index 000000000..b5f38039d --- /dev/null +++ b/tordnscrypt/src/pro/java/pan/alexander/tordnscrypt/assistance/AccelerateDevelop.java @@ -0,0 +1,37 @@ +package pan.alexander.tordnscrypt.assistance; + +/* + This file is part of InviZible Pro. + + InviZible Pro is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InviZible Pro is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with InviZible Pro. If not, see <http://www.gnu.org/licenses/>. + + Copyright 2019-2020 by Garmatin Oleksandr invizible.soft@gmail.com +*/ + +import pan.alexander.tordnscrypt.MainActivity; + +public class AccelerateDevelop { + public final static String mSkuId = ""; + + public static boolean accelerated = true; + + public AccelerateDevelop(MainActivity activity) { + } + + public void initBilling() { + } + + public void launchBilling(String skuId) { + } +} diff --git a/tordnscrypt/src/pro/res/menu/activity_main_drawer.xml b/tordnscrypt/src/pro/res/menu/activity_main_drawer.xml deleted file mode 100644 index f590b8ae3..000000000 --- a/tordnscrypt/src/pro/res/menu/activity_main_drawer.xml +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - tools:showIn="navigation_view"> - - <group android:checkableBehavior="none"> - <item - android:id="@+id/nav_fast_Pref" - android:icon="@drawable/ic_settings_fast" - android:title="@string/drawer_menu_fastSettings" /> - <item - android:id="@+id/nav_common_Pref" - android:icon="@drawable/ic_settings_common" - android:title="@string/drawer_menu_commonSettings" /> - <item - android:id="@+id/nav_DNS_Pref" - android:icon="@drawable/ic_settings_dnscrypt" - android:title="@string/drawer_menu_DNSSettings" /> - <item - android:id="@+id/nav_Tor_Pref" - android:icon="@drawable/ic_settings_tor" - android:title="@string/drawer_menu_TorSettings" /> - <item - android:id="@+id/nav_I2PD_Pref" - android:icon="@drawable/ic_settings_itpd" - android:title="@string/drawer_menu_I2PDSettings" /> - <item - android:id="@+id/nav_backup" - android:icon="@drawable/ic_save_black_24dp" - android:title="@string/drawer_menu_backup" /> - </group> - - <item android:title=""> - <menu> - <item - android:id="@+id/nav_Donate" - android:icon="@drawable/ic_attach_money_black_24dp" - android:title="@string/drawer_menu_donate" - android:visible="false"/> - <item - android:id="@+id/nav_Code" - android:icon="@drawable/ic_enter_black_24dp" - android:title="@string/enter_code_button" - android:visible="false"/> - <item - android:id="@+id/nav_about" - android:icon="@drawable/ic_info_black_24dp" - android:title="@string/drawer_menu_about" /> - <item - android:id="@+id/nav_help" - android:icon="@drawable/ic_help_black_24dp" - android:title="@string/drawer_menu_help" /> - </menu> - </item> - -</menu>