Browse Source

added network stats speed monitor but will need to change it...

Khubaib 11 months ago
parent
commit
56e865e164

+ 18 - 0
.idea/deploymentTargetSelector.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="deploymentTargetSelector">
+    <selectionStates>
+      <SelectionState runConfigName="app">
+        <option name="selectionMode" value="DROPDOWN" />
+        <DropdownSelection timestamp="2024-05-09T11:31:04.509803911Z">
+          <Target type="DEFAULT_BOOT">
+            <handle>
+              <DeviceId pluginId="PhysicalDevice" identifier="serial=1C051FDF60048Z" />
+            </handle>
+          </Target>
+        </DropdownSelection>
+        <DialogSelection />
+      </SelectionState>
+    </selectionStates>
+  </component>
+</project>

BIN
app/release/app-release.apk


+ 7 - 0
app/src/main/java/com/vpn/fastestvpnservice/interfaces/NetworkSpeedCallback.kt

@@ -0,0 +1,7 @@
+package com.vpn.fastestvpnservice.interfaces
+
+import androidx.compose.runtime.Composable
+
+interface NetworkSpeedCallback {
+    fun setNetworkSpeed(down: String, up: String)
+}

+ 1 - 0
app/src/main/java/com/vpn/fastestvpnservice/screens/bottomNavBarScreens/HelpScreen.kt

@@ -54,6 +54,7 @@ fun Help(navHostController: NavHostController) {
             modifier = Modifier
                 .background(MaterialTheme.colorScheme.background)
                 .fillMaxSize()
+                .padding(vertical = 10.dp)
                 .verticalScroll(rememberScrollState()),
 //        contentAlignment = Alignment.Center
 

+ 32 - 8
app/src/main/java/com/vpn/fastestvpnservice/screens/bottomNavBarScreens/HomeScreen.kt

@@ -3,9 +3,9 @@ package com.vpn.fastestvpnservice.screens.bottomNavBarScreens
 import android.content.Context
 import android.content.Intent
 import android.content.res.Configuration
+import android.net.TrafficStats
 import android.os.Handler
 import android.util.Log
-import android.widget.Toast
 import androidx.activity.ComponentActivity
 import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.ExperimentalFoundationApi
@@ -57,7 +57,7 @@ import androidx.compose.ui.graphics.ColorFilter
 import androidx.compose.ui.graphics.painter.Painter
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.layout.layoutId
+import androidx.compose.ui.platform.LocalConfiguration
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.LocalLifecycleOwner
 import androidx.compose.ui.res.colorResource
@@ -69,9 +69,7 @@ import androidx.compose.ui.unit.TextUnit
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import androidx.compose.ui.window.DialogProperties
-import androidx.constraintlayout.compose.ChainStyle
 import androidx.constraintlayout.compose.ConstraintLayout
-import androidx.constraintlayout.compose.ConstraintSet
 import androidx.constraintlayout.compose.Dimension
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleEventObserver
@@ -87,6 +85,7 @@ import com.vpn.fastestvpnservice.beans.toChangeServer
 import com.vpn.fastestvpnservice.constants.AppEnum
 import com.vpn.fastestvpnservice.constants.smartConnect
 import com.vpn.fastestvpnservice.helpers.BasePreferenceHelper
+import com.vpn.fastestvpnservice.interfaces.NetworkSpeedCallback
 import com.vpn.fastestvpnservice.interfaces.ServerCallbacks
 import com.vpn.fastestvpnservice.sealedClass.Screen
 import com.vpn.fastestvpnservice.ui.theme.customTypography
@@ -105,6 +104,9 @@ var serverObj: MutableState<Server> = mutableStateOf(Server())
 var protocolObj: MutableState<Protocol> = mutableStateOf(
     Protocol(AppEnum.WG_PROTOCOL.title,AppEnum.WG_PROTOCOL.key, 1)
 )
+var StringDown: MutableState<String> = mutableStateOf("")
+var StringUp: MutableState<String> = mutableStateOf("")
+
 lateinit var navHostController1: NavHostController
 lateinit var homeViewModel1: HomeViewModel
 lateinit var vpnConnectionsUtil: VPNConnectionsUtil
@@ -221,6 +223,15 @@ lateinit var vpnConnectionsUtil: VPNConnectionsUtil
 
  }
 
+val networkSpeed = object : NetworkSpeedCallback {
+    override fun setNetworkSpeed(down: String, up: String) {
+        StringDown.value = down
+        StringUp.value = up
+        Log.d("setNetworkSpeed", "Down: ${StringDown.value} Up: ${StringUp.value}")
+    }
+
+}
+
 @OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
 @Composable
 fun Home(
@@ -328,6 +339,11 @@ fun Home(
         homeViewModel._mutableLiveDataValidate.value = null
     }
 
+    val configuration = LocalConfiguration.current
+    val expanded = configuration.screenWidthDp > 840
+
+    Log.d("test_istablet", "Is Tablet ? $expanded , width = ${configuration.screenWidthDp}, height = ${configuration.screenHeightDp}")
+
     Column(
         modifier = Modifier
             .background(MaterialTheme.colorScheme.background)
@@ -349,7 +365,12 @@ fun Home(
         }
 
         // 1st box
-        ConstraintLayout(modifier = Modifier.fillMaxSize().weight(0.6f)) {
+        ConstraintLayout(modifier = Modifier
+            .fillMaxSize()
+            .weight(0.6f)
+//            .background(Color.Green)
+        )
+        {
             val (firstComposable, secondComposable) = createRefs()
             val guideline = createGuidelineFromTop(0.6f)
             Box(
@@ -571,14 +592,16 @@ fun Home(
         Box(
             modifier = Modifier
                 .background(MaterialTheme.colorScheme.background)
+//                .background(Color.Blue)
                 .fillMaxSize()
                 .weight(0.4f)
 //                .background(Color.Gray),
         ) {
             Column(
                 modifier = Modifier.fillMaxSize(),
-                verticalArrangement = Arrangement.SpaceEvenly
+                verticalArrangement = Arrangement.Top
             ) {
+
                 Box(
                     modifier = Modifier
                         .fillMaxWidth()
@@ -681,11 +704,13 @@ fun Home(
                 /* Select Server Box*/
 //                if (isConnect != App.CONNECTED) { }
 
+//                Spacer(modifier = Modifier.weight(1f))
+
                 Box(
                     modifier = Modifier
                         .fillMaxWidth()
                         .padding(horizontal = 20.dp, vertical = 5.dp)
-                        .padding(bottom = 0.dp)
+                        .padding(top = 0.dp)
                         .height(70.dp)
                         .border(
                             border = BorderStroke(2.dp, MaterialTheme.colorScheme.onBackground),
@@ -702,7 +727,6 @@ fun Home(
             }
         }
     }
-
 }
 
 @OptIn(ExperimentalMaterial3Api::class)

+ 5 - 4
app/src/main/java/com/vpn/fastestvpnservice/utils/VPNConnectionsUtil.kt

@@ -1,6 +1,5 @@
 package com.vpn.fastestvpnservice.utils
 
-import android.app.Activity
 import android.content.BroadcastReceiver
 import android.content.ComponentName
 import android.content.Context
@@ -19,15 +18,12 @@ import android.os.RemoteException
 import android.util.Log
 import android.widget.Toast
 import androidx.activity.ComponentActivity
-import androidx.compose.runtime.livedata.observeAsState
 import androidx.localbroadcastmanager.content.LocalBroadcastManager
 import com.google.gson.Gson
 import com.google.gson.reflect.TypeToken
 import com.vpn.fastestvpnservice.MainActivity
 import com.vpn.fastestvpnservice.R
-import com.vpn.fastestvpnservice.beans.Server
 import com.vpn.fastestvpnservice.constants.AppConstant
-import de.blinkt.openvpn.core.App
 import com.vpn.fastestvpnservice.constants.AppEnum
 import com.vpn.fastestvpnservice.constants.splitList
 import com.vpn.fastestvpnservice.helpers.BasePreferenceHelper
@@ -45,6 +41,7 @@ import com.wireguard.config.Interface
 import com.wireguard.config.Peer
 import de.blinkt.openvpn.LaunchVPN
 import de.blinkt.openvpn.VpnProfile
+import de.blinkt.openvpn.core.App
 import de.blinkt.openvpn.core.ConfigParser
 import de.blinkt.openvpn.core.ConnectionStatus
 import de.blinkt.openvpn.core.IOpenVPNServiceInternal
@@ -476,6 +473,10 @@ class VPNConnectionsUtil: VpnStatus.StateListener {
 //            widgetIntent1.action = SimpleAppWidget.ACTION_DISCONNECT_VPN
 //            context.sendBroadcast(widgetIntent1)
 
+
+                OpenVPNService.isVpnActive = false
+
+
                 App.isShowNotify = false
                 OpenVPNService.abortConnectionVPN = true
                 ProfileManager.setConntectedVpnProfileDisconnected(context)

+ 80 - 2
app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java

@@ -28,6 +28,7 @@ import android.content.res.Resources;
 import android.graphics.BitmapFactory;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
+import android.net.TrafficStats;
 import android.net.VpnService;
 import android.os.Build;
 import android.os.Bundle;
@@ -38,6 +39,7 @@ import android.os.IBinder;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.system.OsConstants;
 import android.text.TextUtils;
 import android.util.Log;
@@ -75,6 +77,8 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Random;
 import java.util.SortedSet;
+import java.util.Timer;
+import java.util.TimerTask;
 import java.util.TreeSet;
 import java.util.Vector;
 import java.util.concurrent.TimeUnit;
@@ -151,6 +155,12 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
     private Toast mlastToast;
     private Runnable mOpenVPNThread;
 
+    private long lastUpdateTime;
+    private long lastTxBytes;
+    private long lastRxBytes;
+
+    public static boolean isVpnActive = false;
+
     // From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java
     public static String humanReadableByteCount(long bytes, boolean speed, Resources res) {
         if (speed) bytes = bytes * 8;
@@ -291,6 +301,72 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
         } else return false;
     }
 
+    private void monitorVpnTraffic() {
+        long currentTxBytes = TrafficStats.getUidTxBytes(android.os.Process.myUid());
+        long currentRxBytes = TrafficStats.getUidRxBytes(android.os.Process.myUid());
+
+        Log.d("test_network_stats", "MVT: currentTxBytes = " + currentTxBytes + " currentRxBytes = " + currentRxBytes);
+
+        long elapsedTime = SystemClock.elapsedRealtime() - lastUpdateTime;
+        long txBytes = currentTxBytes - lastTxBytes;
+        long rxBytes = currentRxBytes - lastRxBytes;
+
+        Log.d("test_network_stats", "MVT: elapsedTime = " + elapsedTime + " txBytes = " + txBytes + " rxBytes = " + rxBytes);
+
+        // Calculate VPN traffic statistics here
+
+        String StringDown = "", StringUp = "";
+        if (txBytes < 1000) {
+            StringUp = txBytes + " byte/s";
+        } else if ((txBytes >= 1000) && (txBytes <= 1000_000)) {
+            StringUp = txBytes / 1000 + " kb/s";
+        } else {
+            StringUp = txBytes / 1000_000 + " mb/s";
+        }
+
+        if (rxBytes < 1000) {
+            StringDown = rxBytes + " byte/s";
+        } else if ((rxBytes >= 1000) && (rxBytes <= 1000_000)) {
+            StringDown = rxBytes / 1000 + " kb/s";
+        } else {
+            StringDown = rxBytes / 1000_000 + " mb/s";
+        }
+
+        Log.d("test_network_stats_UD", "Down: " + StringDown + " Up: " + StringUp);
+
+        // Update last update time and byte counts for next calculation
+        lastUpdateTime = SystemClock.elapsedRealtime();
+        lastTxBytes = currentTxBytes;
+        lastRxBytes = currentRxBytes;
+    }
+
+    private void startTrafficMonitoring() {
+
+        lastUpdateTime = SystemClock.elapsedRealtime();
+        lastTxBytes = TrafficStats.getUidTxBytes(android.os.Process.myUid());
+        lastRxBytes = TrafficStats.getUidRxBytes(android.os.Process.myUid());
+
+        Log.d("test_network_stats", "STM: lastUpdateTime = " + lastUpdateTime + " lastTxBytes = " + lastTxBytes + " lastRxBytes = " + lastRxBytes);
+
+        // Start monitoring using a timer or background thread
+        // For example:
+        BasePreferenceHelper sessionManager = new BasePreferenceHelper(this);
+        Timer timer = new Timer();
+        timer.schedule(new TimerTask() {
+            @Override
+            public void run() {
+//                Log.d("test_network_stats_DU", "isVpnActive: " + isVpnActive);
+                if (isVpnActive) {
+                    monitorVpnTraffic();
+                } else {
+                    if (sessionManager.getConnectState() == 0) {
+                        cancel();
+                    }
+                }
+            }
+        }, 0, 1000); // Update every 1 second
+    }
+
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
         Intent notificationIntent = new Intent(this, MainActivity.class);
@@ -311,6 +387,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
 
         }
 
+        startTrafficMonitoring();
         Date Today = Calendar.getInstance().getTime();
         SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy");
 
@@ -1040,10 +1117,11 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
                 App.connection_status = 1;
                 Log.d("test notify udp", "LEVEL_NONETWORK");
                 updateNotification("");
-            } else if (level == LEVEL_CONNECTED) {
+            }
+            else if (level == LEVEL_CONNECTED) {
                 App.connection_status = 2;
+                isVpnActive = true;
                 sessionManager.setConnectState(App.CONNECTED);
-
                 Intent in = new Intent(ACTION_VPN_CONNECTED);
                 LocalBroadcastManager.getInstance(getBaseContext()).sendBroadcast(in);
             }

+ 4 - 0
app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java

@@ -5,11 +5,14 @@
 package de.blinkt.openvpn.core;
 
 import android.content.Context;
+import android.net.TrafficStats;
 import android.os.Build;
 import android.os.HandlerThread;
 import android.os.Message;
 import android.util.Log;
 
+import androidx.core.net.TrafficStatsCompat;
+
 import com.vpn.fastestvpnservice.R;
 
 import java.io.File;
@@ -29,6 +32,7 @@ public class VpnStatus {
     static final byte[] fdroidkey = {-92, 111, -42, -46, 123, -96, -60, 79, -27, -31, 49, 103, 11, -54, -68, -27, 17, 2, 121, 104};
     private static final LinkedList<LogItem> logbuffer;
     public static TrafficHistory trafficHistory;
+
     static boolean readFileLog = false;
     private static Vector<LogListener> logListener;
     private static Vector<StateListener> stateListener;

+ 84 - 1
app/src/main/java/org/strongswan/android/logic/CharonVpnService.java

@@ -37,12 +37,14 @@ import android.net.ConnectivityManager;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.net.TrafficStats;
 import android.net.VpnService;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.security.KeyChain;
 import android.security.KeyChainException;
@@ -60,6 +62,7 @@ import com.vpn.fastestvpnservice.beans.TvEnableApps;
 import com.vpn.fastestvpnservice.constants.AppConstant;
 import com.vpn.fastestvpnservice.constants.AppEnum;
 import com.vpn.fastestvpnservice.helpers.BasePreferenceHelper;
+import com.vpn.fastestvpnservice.screens.bottomNavBarScreens.HomeScreenKt;
 import com.vpn.fastestvpnservice.widgets.SimpleAppWidget;
 
 import org.strongswan.android.data.VpnProfile;
@@ -96,6 +99,8 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
 import java.util.SortedSet;
+import java.util.Timer;
+import java.util.TimerTask;
 import java.util.TreeSet;
 
 import de.blinkt.openvpn.core.App;
@@ -141,6 +146,12 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
     private volatile boolean mShowNotification;
     private Handler mHandler;
     private VpnStateService mService;
+
+    private long lastUpdateTime;
+    private long lastTxBytes;
+    private long lastRxBytes;
+
+    public static boolean isVpnActive = false;
     private final ServiceConnection mServiceConnection = new ServiceConnection() {
         @Override
         public void onServiceDisconnected(ComponentName name) {    /* since the service is local this is theoretically only called when the process is terminated */
@@ -245,7 +256,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
                     profile.setVpnType(VpnType.IKEV2_EAP);
                     profile.setName(server_name);
 
-
+                    startTrafficMonitoring();
 
                     UiModeManager uiModeManager = (UiModeManager) getApplicationContext().getSystemService(UI_MODE_SERVICE);
                     List<String> splitList = Arrays.asList("All apps use the VPN", "Only allow selected apps to use the vpn",
@@ -332,6 +343,74 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
         return START_NOT_STICKY;
     }
 
+
+
+    private void monitorVpnTraffic() {
+        long currentTxBytes = TrafficStats.getUidTxBytes(android.os.Process.myUid());
+        long currentRxBytes = TrafficStats.getUidRxBytes(android.os.Process.myUid());
+
+        Log.d("test_network_stat_IKev2", "MVT: currentTxBytes = " + currentTxBytes + " currentRxBytes = " + currentRxBytes);
+
+        long elapsedTime = SystemClock.elapsedRealtime() - lastUpdateTime;
+        long txBytes = currentTxBytes - lastTxBytes;
+        long rxBytes = currentRxBytes - lastRxBytes;
+
+        Log.d("test_network_stat_IKev2", "MVT: elapsedTime = " + elapsedTime + " txBytes = " + txBytes + " rxBytes = " + rxBytes);
+
+        // Calculate VPN traffic statistics here
+
+        String StringDown = "", StringUp = "";
+        if (txBytes < 1000) {
+            StringUp = txBytes + " byte/s";
+        } else if ((txBytes >= 1000) && (txBytes <= 1000_000)) {
+            StringUp = txBytes / 1000 + " kb/s";
+        } else {
+            StringUp = txBytes / 1000_000 + " mb/s";
+        }
+
+        if (rxBytes < 1000) {
+            StringDown = rxBytes + " byte/s";
+        } else if ((rxBytes >= 1000) && (rxBytes <= 1000_000)) {
+            StringDown = rxBytes / 1000 + " kb/s";
+        } else {
+            StringDown = rxBytes / 1000_000 + " mb/s";
+        }
+
+        Log.d("test_stat_IKev2_DU", "Down: " + StringDown + " Up: " + StringUp);
+        HomeScreenKt.getNetworkSpeed().setNetworkSpeed(StringDown, StringUp);
+
+        // Update last update time and byte counts for next calculation
+        lastUpdateTime = SystemClock.elapsedRealtime();
+        lastTxBytes = currentTxBytes;
+        lastRxBytes = currentRxBytes;
+    }
+
+    private void startTrafficMonitoring() {
+
+        lastUpdateTime = SystemClock.elapsedRealtime();
+        lastTxBytes = TrafficStats.getUidTxBytes(android.os.Process.myUid());
+        lastRxBytes = TrafficStats.getUidRxBytes(android.os.Process.myUid());
+
+        Log.d("test_network_stat_IKev2", "STM: lastUpdateTime = " + lastUpdateTime + " lastTxBytes = " + lastTxBytes + " lastRxBytes = " + lastRxBytes);
+
+        // Start monitoring using a timer or background thread
+        // For example:
+        BasePreferenceHelper sessionManager = new BasePreferenceHelper(this);
+        Timer timer = new Timer();
+        timer.schedule(new TimerTask() {
+            @Override
+            public void run() {
+//                Log.d("test_network_stats_DU", "isVpnActive: " + isVpnActive);
+                if (isVpnActive) {
+                    monitorVpnTraffic();
+                } else {
+                    if (sessionManager.getConnectState() == 0) {
+                        cancel();
+                    }
+                }
+            }
+        }, 0, 1000); // Update every 1 second
+    }
     @Override
     public void onCreate() {
         mLogFile = getFilesDir().getAbsolutePath() + File.separator + LOG_FILE;
@@ -646,6 +725,8 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
 
             Intent in2 = new Intent(ACTION_VPN_DISABLED);
             LocalBroadcastManager.getInstance(getBaseContext()).sendBroadcast(in2);
+
+            CharonVpnService.isVpnActive = false;
         }
 
         if (mShowNotification) {
@@ -662,6 +743,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
                 getApplicationContext().sendBroadcast(widgetIntent);
 
                 sessionManager.setConnectState(App.CONNECTED);
+                isVpnActive = true;
 
             } else if (mService.getState() == State.DISCONNECTING) {
                 Intent in = new Intent(ACTION_VPN_DISCONNECTED);
@@ -670,6 +752,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
                 Intent in2 = new Intent(ACTION_VPN_NOT_CONNECTED);
                 LocalBroadcastManager.getInstance(getBaseContext()).sendBroadcast(in2);
 
+                CharonVpnService.isVpnActive = false;
             } else if (mService.getState() == State.CONNECTING) {
                 Intent in = new Intent(ACTION_VPN_CONNECTING);
                 LocalBroadcastManager.getInstance(getBaseContext()).sendBroadcast(in);

+ 2 - 0
app/src/main/java/org/strongswan/android/ui/VpnProfileControlActivity.java

@@ -47,6 +47,7 @@ import org.strongswan.android.data.VpnProfile;
 import org.strongswan.android.data.VpnProfileDataSource;
 import org.strongswan.android.data.VpnType;
 import org.strongswan.android.data.VpnType.VpnTypeFeature;
+import org.strongswan.android.logic.CharonVpnService;
 import org.strongswan.android.logic.VpnStateService;
 import org.strongswan.android.logic.VpnStateService.State;
 
@@ -368,6 +369,7 @@ public class VpnProfileControlActivity extends AppCompatActivity {
         } else if (DISCONNECT.equals(intent.getAction())) {
             Log.d(tag, "DISCONNECT");
             disconnect(intent);
+            CharonVpnService.isVpnActive = false;
         }
     }