LenovoLegionToolkit
115 строк · 4.9 Кб
1using System;2using System.Linq;3using System.Threading.Tasks;4using LenovoLegionToolkit.Lib.Controllers;5using LenovoLegionToolkit.Lib.Controllers.GodMode;6using LenovoLegionToolkit.Lib.Listeners;7using LenovoLegionToolkit.Lib.System;8using LenovoLegionToolkit.Lib.System.Management;9using LenovoLegionToolkit.Lib.Utils;10
11namespace LenovoLegionToolkit.Lib.Features;12
13public class PowerModeUnavailableWithoutACException : Exception14{
15public PowerModeState PowerMode { get; }16
17public PowerModeUnavailableWithoutACException(PowerModeState powerMode)18{19PowerMode = powerMode;20}21}
22
23public class PowerModeFeature : AbstractWmiFeature<PowerModeState>24{
25private readonly GodModeController _godModeController;26private readonly PowerPlanController _powerPlanController;27private readonly ThermalModeListener _thermalModeListener;28private readonly PowerModeListener _powerModeListener;29
30public bool AllowAllPowerModesOnBattery { get; set; }31
32public PowerModeFeature(GodModeController godModeController, PowerPlanController powerPlanController, ThermalModeListener thermalModeListener, PowerModeListener powerModeListener)33: base(WMI.LenovoGameZoneData.GetSmartFanModeAsync, WMI.LenovoGameZoneData.SetSmartFanModeAsync, WMI.LenovoGameZoneData.IsSupportSmartFanAsync, 1)34{35_godModeController = godModeController ?? throw new ArgumentNullException(nameof(godModeController));36_powerPlanController = powerPlanController ?? throw new ArgumentNullException(nameof(powerPlanController));37_thermalModeListener = thermalModeListener ?? throw new ArgumentNullException(nameof(thermalModeListener));38_powerModeListener = powerModeListener ?? throw new ArgumentNullException(nameof(powerModeListener));39}40
41public override async Task<PowerModeState[]> GetAllStatesAsync()42{43var mi = await Compatibility.GetMachineInformationAsync().ConfigureAwait(false);44return mi.Properties.SupportsGodMode45? new[] { PowerModeState.Quiet, PowerModeState.Balance, PowerModeState.Performance, PowerModeState.GodMode }46: new[] { PowerModeState.Quiet, PowerModeState.Balance, PowerModeState.Performance };47}48
49public override async Task SetStateAsync(PowerModeState state)50{51var allStates = await GetAllStatesAsync().ConfigureAwait(false);52if (!allStates.Contains(state))53throw new InvalidOperationException($"Unsupported power mode {state}.");54
55if (state is PowerModeState.Performance or PowerModeState.GodMode56&& !AllowAllPowerModesOnBattery57&& await Power.IsPowerAdapterConnectedAsync().ConfigureAwait(false) is PowerAdapterStatus.Disconnected)58throw new PowerModeUnavailableWithoutACException(state);59
60var currentState = await GetStateAsync().ConfigureAwait(false);61
62var mi = await Compatibility.GetMachineInformationAsync().ConfigureAwait(false);63
64if (mi.Properties.HasQuietToPerformanceModeSwitchingBug && currentState == PowerModeState.Quiet && state == PowerModeState.Performance)65{66_thermalModeListener.SuppressNext();67await base.SetStateAsync(PowerModeState.Balance).ConfigureAwait(false);68await Task.Delay(TimeSpan.FromMilliseconds(500)).ConfigureAwait(false);69}70
71if (mi.Properties.HasGodModeToOtherModeSwitchingBug && currentState == PowerModeState.GodMode && state != PowerModeState.GodMode)72{73_thermalModeListener.SuppressNext();74
75switch (state)76{77case PowerModeState.Quiet:78await base.SetStateAsync(PowerModeState.Performance).ConfigureAwait(false);79break;80case PowerModeState.Balance:81await base.SetStateAsync(PowerModeState.Quiet).ConfigureAwait(false);82break;83case PowerModeState.Performance:84await base.SetStateAsync(PowerModeState.Balance).ConfigureAwait(false);85break;86}87
88await Task.Delay(TimeSpan.FromMilliseconds(500)).ConfigureAwait(false);89
90}91
92_thermalModeListener.SuppressNext();93await base.SetStateAsync(state).ConfigureAwait(false);94
95if (state == PowerModeState.GodMode)96await _godModeController.ApplyStateAsync().ConfigureAwait(false);97
98await _powerModeListener.NotifyAsync(state).ConfigureAwait(false);99}100
101public async Task EnsureCorrectPowerPlanIsSetAsync()102{103var state = await GetStateAsync().ConfigureAwait(false);104await _powerPlanController.ActivatePowerPlanAsync(state, true).ConfigureAwait(false);105}106
107public async Task EnsureGodModeStateIsAppliedAsync()108{109var state = await GetStateAsync().ConfigureAwait(false);110if (state != PowerModeState.GodMode)111return;112
113await _godModeController.ApplyStateAsync().ConfigureAwait(false);114}115}
116