Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
trudyhood committed Nov 18, 2023
2 parents d22b451 + fe7288d commit 60b7b9a
Show file tree
Hide file tree
Showing 16 changed files with 223 additions and 32 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# v3.1.436
### Client
Update: Improve UI
Fix: Android: Keyboard cover input fields in the UI
Fix: Android: Frequently asking for adding the system tile

# v3.1.430
### Client
Update: Improve UI
Expand Down
6 changes: 4 additions & 2 deletions Pub/PublishToGitHub.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,16 @@ $releaseRootDir = (&{if($isLatest) {$packagesRootDirLatest} else {$packagesRootD
$releaseClientDir = (&{if($isLatest) {$packagesClientDirLatest} else {$packagesClientDir}})
$releaseServerDir = (&{if($isLatest) {$packagesServerDirLatest} else {$packagesServerDir}})

$anroidStore = (&{if($prerelease) {"-web"} else {""}});

# $releaseClientDir/android/VpnHoodClient-android-web.apk `
# $releaseClientDir/android/VpnHoodClient-android-web.json `
gh release create "$versionTag" `
--title "$versionTag" `
(&{if($prerelease) {"--prerelease"} else {"--latest"}}) `
-F $releaseRootDir/ReleaseNote.txt `
$releaseClientDir/android/VpnHoodClient-android.apk `
$releaseClientDir/android/VpnHoodClient-android.json `
$releaseClientDir/android/VpnHoodClient-android$anroidStore.apk `
$releaseClientDir/android/VpnHoodClient-android$anroidStore.json `
$releaseClientDir/windows/VpnHoodClient-win-x64.msi `
$releaseClientDir/windows/VpnHoodClient-win-x64.txt `
$releaseClientDir/windows/VpnHoodClient-win-x64.json `
Expand Down
4 changes: 2 additions & 2 deletions Pub/Version.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Version": "3.1.434",
"BumpTime": "2023-10-28T22:39:54.0779711Z",
"Version": "3.1.436",
"BumpTime": "2023-11-18T00:52:54.0879268Z",
"Prerelease": false,
"DeprecatedVersion": "3.0.400"
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

176 changes: 176 additions & 0 deletions Tests/VpnHood.Test/Utils/TestUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
using System;
using System.Net;
using System.Threading.Tasks;
using VpnHood.Common.Client;
using VpnHood.Common.Exceptions;

namespace VpnHood.Test.Utils;

public static class TestUtil
{
public class AssertException : Exception
{
public AssertException(string? message = null)
: base(message)
{
}

public AssertException(string message, Exception innerException)
: base(message, innerException)
{
}
}

public static async Task<bool> WaitForValue<TValue>(object? expectedValue, Func<TValue?> valueFactory, int timeout = 5000)
{
const int waitTime = 100;
for (var elapsed = 0; elapsed < timeout; elapsed += waitTime)
{
if (Equals(expectedValue, valueFactory()))
return true;

await Task.Delay(waitTime);
}

return false;
}

public static async Task<bool> WaitForValue<TValue>(object? expectedValue, Func<Task<TValue?>> valueFactory, int timeout = 5000)
{
const int waitTime = 100;
for (var elapsed = 0; elapsed < timeout; elapsed += waitTime)
{
if (Equals(expectedValue, await valueFactory()))
return true;

await Task.Delay(waitTime);
}

return false;
}

private static void AssertEquals(object? expected, object? actual, string? message)
{
message ??= "Unexpected Value";
if (!Equals(expected, actual))
throw new AssertException($"{message}. Expected: {expected}, Actual: {actual}");
}

public static async Task AssertEqualsWait<TValue>(object? expectedValue, Func<TValue?> valueFactory,
string? message = null, int timeout = 5000)
{
await WaitForValue(expectedValue, valueFactory, timeout);
AssertEquals(expectedValue, valueFactory(), message);
}

public static async Task AssertEqualsWait<TValue>(object? expectedValue, Func<Task<TValue?>> valueFactory,
string? message = null, int timeout = 5000)
{
await WaitForValue(expectedValue, valueFactory, timeout);
AssertEquals(expectedValue, await valueFactory(), message);
}

public static Task AssertApiException(HttpStatusCode expectedStatusCode, Task task, string? message = null)
{
return AssertApiException((int)expectedStatusCode, task, message);
}

private static void AssertExceptionContains(Exception ex, string? contains)
{
if (contains != null && !ex.Message.Contains(contains, StringComparison.OrdinalIgnoreCase))
throw new Exception($"Actual error message does not contain \"{contains}\".");
}

public static async Task AssertApiException(int expectedStatusCode, Task task,
string? message = null, string? contains = null)
{
try
{
await task;
throw new AssertException($"Expected {expectedStatusCode} but the actual was OK. {message}");
}
catch (ApiException ex)
{
if (ex.StatusCode != expectedStatusCode)
throw new Exception($"Expected {expectedStatusCode} but the actual was {ex.StatusCode}. {message}");

AssertExceptionContains(ex, contains);
}

}

public static Task AssertApiException<T>(Task task, string? message = null, string? contains = null)
{
return AssertApiException(typeof(T).Name, task, message, contains);
}

public static async Task AssertApiException(string expectedExceptionType, Task task,
string? message = null, string? contains = null)
{
try
{
await task;
throw new AssertException($"Expected {expectedExceptionType} exception but was OK. {message}");
}
catch (ApiException ex)
{
if (ex.ExceptionTypeName != expectedExceptionType)
throw new AssertException($"Expected {expectedExceptionType} but was {ex.ExceptionTypeName}. {message}");

AssertExceptionContains(ex, contains);
}
catch (Exception ex) when (ex is not AssertException)
{
if (ex.GetType().Name != expectedExceptionType)
throw new AssertException($"Expected {expectedExceptionType} but was {ex.GetType().Name}. {message}", ex);

AssertExceptionContains(ex, contains);
}
}

public static async Task AssertNotExistsException(Task task, string? message = null, string? contains = null)
{
try
{
await task;
throw new AssertException($"Expected kind of {nameof(NotExistsException)} but was OK. {message}");
}
catch (ApiException ex)
{
if (ex.ExceptionTypeName != nameof(NotExistsException))
throw new AssertException($"Expected {nameof(NotExistsException)} but was {ex.ExceptionTypeName}. {message}");

AssertExceptionContains(ex, contains);
}
catch (Exception ex) when (ex is not AssertException)
{
if (!NotExistsException.Is(ex))
throw new AssertException($"Expected kind of {nameof(NotExistsException)} but was {ex.GetType().Name}. {message}", ex);

AssertExceptionContains(ex, contains);
}
}

public static async Task AssertAlreadyExistsException(Task task, string? message = null, string? contains = null)
{
try
{
await task;
throw new AssertException($"Expected kind of {nameof(AlreadyExistsException)} but was OK. {message}");
}
catch (ApiException ex)
{
if (ex.ExceptionTypeName != nameof(AlreadyExistsException))
throw new AssertException($"Expected {nameof(AlreadyExistsException)} but was {ex.ExceptionTypeName}. {message}");

AssertExceptionContains(ex, contains);
}
catch (Exception ex) when (ex is not AssertException)
{
if (!AlreadyExistsException.Is(ex))
throw new AssertException($"Expected kind of {nameof(AlreadyExistsException)} but was {ex.GetType().Name}. {message}", ex);

AssertExceptionContains(ex, contains);
}
}
}
7 changes: 5 additions & 2 deletions VpnHood.Client.App.Android.Xamarin/MainActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace VpnHood.Client.App.Droid;
Theme = "@android:style/Theme.DeviceDefault.NoActionBar",
MainLauncher = true,
Exported = true,
WindowSoftInputMode = SoftInput.AdjustResize,
AlwaysRetainTaskState = true,
LaunchMode = LaunchMode.SingleInstance,
ScreenOrientation = ScreenOrientation.Unspecified,
Expand Down Expand Up @@ -78,7 +79,8 @@ protected override void OnCreate(Bundle? savedInstanceState)
private async Task RequestFeatures()
{
// request for adding tile
if (Device.Droid.OperatingSystem.IsAndroidVersionAtLeast(33))// && !VpnHoodApp.Instance.Settings.IsQuickLaunchRequested)
if (!VpnHoodApp.Instance.Settings.IsQuickLaunchRequested &&
Device.Droid.OperatingSystem.IsAndroidVersionAtLeast(33))
{
VpnHoodApp.Instance.Settings.IsQuickLaunchRequested = true;
VpnHoodApp.Instance.Settings.Save();
Expand Down Expand Up @@ -208,11 +210,12 @@ private void InitWebUi()
WebView.Settings.JavaScriptCanOpenWindowsAutomatically = true;
WebView.Settings.SetSupportMultipleWindows(true);
WebView.SetLayerType(LayerType.Hardware, null);

var webViewClient = new AppWebViewClient();
webViewClient.PageLoaded += WebViewClient_PageLoaded;
WebView.SetWebViewClient(webViewClient);
WebView.SetWebChromeClient(new AppWebChromeClient());

#if DEBUG
WebView.SetWebContentsDebuggingEnabled(true);
#endif
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="434" package="com.vpnhood.client.android" android:installLocation="preferExternal" android:versionName="3.1.434">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="436" package="com.vpnhood.client.android" android:installLocation="preferExternal" android:versionName="3.1.436">
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="33" />
<application android:label="@string/app_name" android:icon="@mipmap/appicon" android:allowBackup="true" android:usesCleartextTraffic="true" android:supportsRtl="true">
</application>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="434" package="com.vpnhood.client.android.web" android:installLocation="preferExternal" android:versionName="3.1.434">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="436" package="com.vpnhood.client.android.web" android:installLocation="preferExternal" android:versionName="3.1.436">
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="33" />
<application android:label="@string/app_name" android:icon="@mipmap/appicon" android:allowBackup="true" android:usesCleartextTraffic="true" android:supportsRtl="true">
</application>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 2 additions & 9 deletions VpnHood.Client.App.Android.Xamarin/_publish.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ PrepareModuleFolder $moduleDir $moduleDirLatest;

$module_infoFile = "$moduleDir/VpnHoodClient-android-web.json";
$module_packageFile = "$moduleDir/VpnHoodClient-android-web.apk";
if ($prerelease)
{
$module_infoFile = "$moduleDir/VpnHoodClient-android.json";
$module_packageFile = "$moduleDir/VpnHoodClient-android.apk";
}

# Calcualted Path
$module_infoFileName = $(Split-Path "$module_infoFile" -leaf);
Expand All @@ -30,6 +25,8 @@ $keystoreAlias = $credentials.Android.KeyStoreAlias
$manifestFile = Join-Path $projectDir "Properties/AndroidManifest.xml";
$manifestFileAab = Join-Path $projectDir "Properties/AndroidManifest.aab.xml";
$appIconXml = Join-Path $projectDir "Resources\mipmap-anydpi-v26\appicon.xml";
$appIconXmlDoc = [xml](Get-Content $appIconXml);
$appIconXmlNode = $appIconXmlDoc.selectSingleNode("adaptive-icon/background");

# set android version
$xmlDoc = [xml](Get-Content $manifestFile);
Expand All @@ -38,8 +35,6 @@ $xmlDoc.manifest.versionName = $version.ToString(3);
$xmlDoc.save($manifestFile);

# set app icon
$appIconXmlDoc = [xml](Get-Content $appIconXml);
$appIconXmlNode = $appIconXmlDoc.selectSingleNode("adaptive-icon/background");
$appIconXmlNode.SetAttribute("android:drawable", "@mipmap/appicon_background_dev");
$appIconXmlDoc.save($appIconXml);

Expand Down Expand Up @@ -100,8 +95,6 @@ if (-not $noclean) { & $msbuild $projectFile /p:Configuration=Release /t:Clean
/p:AndroidSigningKeyPass=$keystorePass /p:AndroidKeyStore=True;

# set app icon
$appIconXmlDoc = [xml](Get-Content $appIconXml);
$appIconXmlNode = $appIconXmlDoc.selectSingleNode("adaptive-icon/background");
$appIconXmlNode.SetAttribute("android:drawable", "@mipmap/appicon_background_dev");
$appIconXmlDoc.save($appIconXml);

Expand Down
Binary file modified VpnHood.Client.App.Resources/Resources/SPA.zip
Binary file not shown.
2 changes: 1 addition & 1 deletion VpnHood.Client.App/VpnHoodApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ public async Task Disconnect(bool byUser = false)
{
_hasAnyDataArrived = Client.Stat.SessionTraffic.Received > 1000;
if (_lastError == null && !_hasAnyDataArrived && UserSettings is { IpGroupFiltersMode: FilterMode.All, TunnelClientCountry: true })
_lastError = "No data has arrived!";
_lastError = "No data has been received.";
}

// check diagnose
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 18 additions & 7 deletions VpnHood.Client.Device.WinDivert/WinDivertDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ public class WinDivertDevice : IDevice
public string OperatingSystemInfo =>
Environment.OSVersion + ", " + (Environment.Is64BitOperatingSystem ? "64-bit" : "32-bit");

public bool IsExcludeAppsSupported => false;
public bool IsExcludeAppsSupported => IsDebugMode;

public bool IsIncludeAppsSupported => false;
public bool IsIncludeAppsSupported => IsDebugMode;

public DeviceAppInfo[] InstalledApps
{
get
{
#if DEBUG
if (!IsDebugMode)
throw new NotSupportedException();

var list = new List<DeviceAppInfo>();
for (var i = 0; i < 60; i++)
list.Add(new DeviceAppInfo(
Expand All @@ -30,15 +32,24 @@ public DeviceAppInfo[] InstalledApps
"iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAV7SURBVFiFpZdNjBzFFcd/r6pnMd7FblhjYT6SdQgXpOAx9gkhGIQwioF4TA4cYpN1gnLEIHxBfC0SEhyMWCGwhPhYIyAhFzwOUZCQjOeYm3ekcIrRLoIg2TjWLMvi2Zmu9zj0zGxPb6/XC2/U6uqq7vf/v3+9V1UjrMFOV++uCm6PYWOCxGBlAMymDW0KMuvUals/Pnn8Un3Kai/MVCuxutIrGFUgHhg0y9wH2k0zat7z+NZavfmTCXzx4K4JzA4iEg8Apg8pZr8vS6B3s6YYkzf+s/78mgjMVCtxh+ik9748GGUWP99fRCBtmDEdlbirSA2X7/h8d6U8H5hR07IFXYn4mkzEyiGxmZndt5WXjWUfTlXKMcNXzHhxceQckTicc8tlWkP0A+Nqs/4Ht31rfUmJAQXal62rq1qspgQzAobmpf85Jowl6/VktqtPYOfbj0wobAsaUDPUFFXFTDEyJFaJnlX4CpT/u/uOiQECY1Pj8bkhDs6GNGJVQ1UJpmk7aC7jwcxom9EKunSpciEEWqoshoTFoLQ06Y6n/S1VWkEPzlTKMUAEQCmaFCR+avwWXn2nweYIHB4VQy0g3iOmOBGaUYlfv/1hYXRnP9nHUHIO78E5iLwgYvhIcE5YNwQ+EkQkRoYnqTMedb+tWlfoxvUb2PHNPKOiSDCC84gaIoHRNz5g0/AIAM8cE2bOpTN4zQbj8EPK5t++j4U2Cyf24JwwdBkMX+4AQRwg0p8H8HsAZOy9P1cROdaXFuPIOw2GnOdK70irwbPlzb8RjYzw3HHHF2eX6iI79VcNG6/9QTELjEzv7YMJYC5VA5H0ZSc4bK9TqJoZvQuDI7tuQlX5LgTUoOWEaGSEiZoUgvfs/ILw6F8dIp7v/S+QyCGRg5JDIoHII94hJY9EDo181YnZWH4u/3PdelQDZsZ8CNz0wT8AOP3tUtVmwbNl/+18SlBueQ0iD5FDIp/mkXcpiS4xF7kxh+Q2mK4dHC+nZagBgJf+VRy5LWvAI0dTohJJFzwFFO8QJ9nlb6MD2ZYFtu6v5eF8JKDpcvz5N7IyeK69sNh9VzwicpEtz8rOGPxlXR7a/5s0L7oIhbKzPBeWTFi+Mg0+O4NGfyiTjD2nx8pbALj5Wit2UQA+PGRd+GQlZj3qDWdmzX4F5IeBj27dDMCT91m/LyVbHLkZvHUgnTaRvPa55RtpOjFm86B5v7cfPwTAL0e1D1IYk6VrAYDMvrACeLZLp11wVisCzebFeTrMdy7w4u+NG68uRu+BH9mvBFWuCI0Bb8vaZmBSF4Dr3z3QNGHjSltZb3pOPfAy63wJgEN/d/yvmUp81Xrj9f2pOkGVK7/6CyRzBQQy/tXmZOeJOAJQrCbwx2Ua5Phs//gJbhjexKf3PMvhh5afln734dN8fWaW0/cvXhw8dVyDboXGU+PxerFZhI2FElAwRWaUnAeD9g8tWGhjnYQz9y4CWvBVVnrm8GFMttebDqB54GgTscki0Hx+ZCumrQmLoQ2tBFNl7ya/OjiA2KRsT49lA3Wy5d2Hp/Mr49J3+TLtnv86AZtrQSfh7L2tYuAsONaQHZ/1D6cDZ8IL6ipmzGUjteyfjtyKaapoJwFV/n3XhksB/xKnlSzmAIHmgaPNYJ2KqmZTeIWFGjQJ0A5ICPxq6MylgFd70vescJuIp8bjIZK6SH6jyrSTgLUTbKHFuV0lCN9dDLyB00oefEUCPds8tW8CeAyRgeowM3SxDe2EG5KEU5UL5HOkn+1ik7Ljs4mVMFb9cxpPjcclkkmgKiIbzQzrJOnV7vD/Oxchu+n0gKGGD48VRb0mAlkbndpXJYQq7WRMO0n8p1G37fDNc4A1MGsC05jUZeeJ2qX6/BFJwTP1ncDguQAAAABJRU5ErkJggg=="
));
return list.ToArray();
#else
throw new NotSupportedException();
#endif
}
}

public Task<IPacketCapture> CreatePacketCapture()
{
var res = (IPacketCapture) new WinDivertPacketCapture();
var res = (IPacketCapture)new WinDivertPacketCapture();
return Task.FromResult(res);
}

private static bool IsDebugMode
{
get
{
#if DEBUG
return true;
#else
return false;
#endif
}
}
}
4 changes: 2 additions & 2 deletions VpnHood.Client.Device/VpnHood.Client.Device.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
<RepositoryUrl>https://github.com/vpnhood/vpnhood</RepositoryUrl>
<RepositoryType></RepositoryType>
<RootNamespace>VpnHood.Client.Device</RootNamespace>
<Version>3.1.434</Version>
<AssemblyVersion>3.1.434</AssemblyVersion>
<Version>3.1.436</Version>
<AssemblyVersion>3.1.436</AssemblyVersion>
<FileVersion>$([System.DateTime]::Now.ToString("yyyy.M.d.HHmm"))</FileVersion>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
Expand Down
Loading

0 comments on commit 60b7b9a

Please sign in to comment.