Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(windows): set the update state machine to idle in first run 💽 #12621

Draft
wants to merge 2 commits into
base: epic/windows-updates
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ TState = class abstract
procedure HandleDownload; virtual; abstract;
procedure HandleAbort; virtual; abstract;
procedure HandleInstallNow; virtual; abstract;
procedure HandleFirstRun; virtual;
end;

{ This class also controls the state flow see
Expand All @@ -70,6 +71,7 @@ TUpdateStateMachine = class
procedure SetStateOnly(const enumState: TUpdateState);
function ConvertStateToEnum(const StateClass: TStateClass): TUpdateState;
function IsCurrentStateAssigned: Boolean;
procedure HandleMSIInstallComplete;

function SetRegistryState(Update: TUpdateState): Boolean;
function GetAutomaticUpdates: Boolean;
Expand All @@ -88,6 +90,7 @@ TUpdateStateMachine = class
procedure HandleDownload;
procedure HandleAbort;
procedure HandleInstallNow;
procedure HandleFirstRun;
function CurrentStateName: string;

property ShowErrors: Boolean read FShowErrors write FShowErrors;
Expand Down Expand Up @@ -201,6 +204,7 @@ InstallingState = class(TState)
procedure HandleDownload; override;
procedure HandleAbort; override;
procedure HandleInstallNow; override;
procedure HandleFirstRun; override;
end;

RetryState = class(TState)
Expand All @@ -215,8 +219,6 @@ RetryState = class(TState)
end;

PostInstallState = class(TState)
private
procedure HandleMSIInstallComplete;
public
procedure Enter; override;
procedure Exit; override;
Expand All @@ -225,6 +227,7 @@ PostInstallState = class(TState)
procedure HandleDownload; override;
procedure HandleAbort; override;
procedure HandleInstallNow; override;
procedure HandleFirstRun; override;
end;

{ TUpdateStateMachine }
Expand Down Expand Up @@ -496,6 +499,22 @@ function TUpdateStateMachine.IsCurrentStateAssigned: Boolean;
end;
end;


procedure TUpdateStateMachine.HandleMSIInstallComplete;
var SavePath: string;
FileName: String;
FileNames: TStringDynArray;
begin
SavePath := IncludeTrailingPathDelimiter(TKeymanPaths.KeymanUpdateCachePath);

GetFileNamesInDirectory(SavePath, FileNames);
for FileName in FileNames do
begin
System.SysUtils.DeleteFile(FileName);
end;
CurrentState.ChangeState(IdleState);
end;

procedure TUpdateStateMachine.HandleCheck;
begin
if not IsCurrentStateAssigned then
Expand Down Expand Up @@ -531,13 +550,24 @@ procedure TUpdateStateMachine.HandleInstallNow;
CurrentState.HandleInstallNow;
end;

procedure TUpdateStateMachine.HandleFirstRun;
begin
CurrentState.HandleFirstRun;
end;

function TUpdateStateMachine.CurrentStateName: string;
begin
if not IsCurrentStateAssigned then
Exit('Undefined');
Result := CurrentState.ClassName;
end;

// base implmentation to be overiden
procedure TState.HandleFirstRun;
begin

end;

{ IdleState }

procedure IdleState.Enter;
Expand Down Expand Up @@ -718,7 +748,7 @@ procedure DownloadingState.Enter;
bucStateContext.SetRegistryState(usDownloading);
{ ## for testing log that we would download }
KL.Log('DownloadingState.HandleKmshell test code continue');
DownloadResult := True;
//DownloadResult := True;
{ End testing }
DownloadResult := DownloadUpdatesBackground;
// TODO check if keyman is running then send to Waiting Restart
Expand All @@ -736,7 +766,6 @@ procedure DownloadingState.Enter;
end
else
begin
bucStateContext.SetApplyNow(False);
ChangeState(InstallingState);
end;
end
Expand Down Expand Up @@ -988,6 +1017,12 @@ procedure InstallingState.HandleInstallNow;
// Do Nothing. Need the UI to let user know installation in progress OR
end;

procedure InstallingState.HandleFirstRun;
begin
bucStateContext.HandleMSIInstallComplete;
//Result := kmShellContinue;
end;

{ RetryState }

procedure RetryState.Enter;
Expand Down Expand Up @@ -1047,7 +1082,7 @@ procedure PostInstallState.HandleCheck;

function PostInstallState.HandleKmShell;
begin
HandleMSIInstallComplete;
bucStateContext.HandleMSIInstallComplete;
Result := kmShellContinue;
end;

Expand All @@ -1056,22 +1091,6 @@ procedure PostInstallState.HandleDownload;
// Do Nothing
end;

procedure PostInstallState.HandleMSIInstallComplete;
var
SavePath: string;
fileName: String;
Filenames: TStringDynArray;
begin
SavePath := IncludeTrailingPathDelimiter(TKeymanPaths.KeymanUpdateCachePath);

GetFileNamesInDirectory(SavePath, Filenames);
for fileName in Filenames do
begin
System.SysUtils.DeleteFile(fileName);
end;
ChangeState(IdleState);
end;

procedure PostInstallState.HandleAbort;
begin
// Handle Abort
Expand All @@ -1082,4 +1101,51 @@ procedure PostInstallState.HandleInstallNow;
// Do nothing as files will be cleaned via HandleKmShell
end;

procedure PostInstallState.HandleFirstRun;
begin
bucStateContext.HandleMSIInstallComplete;
//Result := kmShellContinue;
end;

// Private Functions:
function ConfigCheckContinue: Boolean;
var
registry: TRegistryErrorControlled;
begin
{ Verify that it has been at least CheckPeriod days since last update check }
Result := False;
try
registry := TRegistryErrorControlled.Create; // I2890
try
if registry.OpenKeyReadOnly(SRegKey_KeymanDesktop_CU) then
begin
if registry.ValueExists(SRegValue_CheckForUpdates) and not registry.ReadBool(SRegValue_CheckForUpdates) then
begin
Result := False;
Exit;
end;
if registry.ValueExists(SRegValue_LastUpdateCheckTime) and (Now - registry.ReadDateTime(SRegValue_LastUpdateCheckTime) > CheckPeriod) then
begin
Result := True;
end
else
begin
Result := False;
end;
Exit;
end;
finally
registry.Free;
end;
except
{ we will not run the check if an error occurs reading the settings }
on E:Exception do
begin
Result := False;
LogMessage(E.Message);
Exit;
end;
end;
end;

end.
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,25 @@ implementation
keymanapi_TLB,
ErrorControlledRegistry,
RegistryKeys,
Keyman.System.UpdateStateMachine,
UImportOlderKeyboardUtils;

function FirstRunInstallDefaults(DoDefaults,DoStartWithWindows,DoCheckForUpdates,DoAutomaticUpdates: Boolean; FDisablePackages, FDefaultUILanguage: string; DoAutomaticallyReportUsage: Boolean): Boolean; // I2753
var
n, I: Integer;
v: Integer;
p: string;
UpdateSM : TUpdateStateMachine;
begin
// send event to statemachine (should result in setting state to idle)
UpdateSM := TUpdateStateMachine.Create(False);
try
UpdateSM.HandleFirstRun;
Exit;
finally
UpdateSM.Free;
end;

{ Copy over all the user settings and set defaults for version 8.0: http://blog.tavultesoft.com/2011/02/keyman-desktop-80-default-options.html }

if DoDefaults then // I2753
Expand Down
Loading