Files
kam-mobile/code/GameDiagnosticsReport.pas
T
admin_d f1b253e842
Sync changed files to Google Drive / sync (push) Successful in 3m1s
Remove terrain readiness diagnostic and fix graphics container name
2026-10-10 03:02:42 +05:00

579 lines
23 KiB
ObjectPascal

unit GameDiagnosticsReport;
{$mode objfpc}{$H+}{$codepage utf8}
interface
type
TDiagnosticStatus = (dsNotRun, dsPass, dsFail);
TDiagnosticStageId = (
dsiResourceExists,
dsiResourceOpen,
dsiCallerStreamLoad,
dsiStreamState,
dsiSeekReadConsistency
);
TGraphicsReadinessDiagnosticStageId = (
grsiContextReady, grsiPhysicalSurface, grsiRendererSizeMatch,
grsiTextureBackend, grsiSampledProgram, grsiMaxTextureSize
);
TGraphicsTextureDiagnosticStageId = (
gtsiInitialCreate, gtsiNonZeroTextureId, gtsiFirstBind,
gtsiReplacementUpdate, gtsiSecondBind, gtsiTextureDelete,
gtsiResourceCleanup
);
TGraphicsVisibleDrawDiagnosticStageId = (
gvsiPreparation, gvsiSampledRgbaPhase, gvsiBrightnessPhase,
gvsiTextureDelete, gvsiResourceCleanup
);
TOptionalString = record
HasValue: Boolean;
Value: string;
end;
TOptionalInt64 = record
HasValue: Boolean;
Value: Int64;
end;
TOptionalBoolean = record
HasValue: Boolean;
Value: Boolean;
end;
TOptionalDiagnosticStageId = record
HasValue: Boolean;
Value: TDiagnosticStageId;
end;
TOptionalGraphicsReadinessDiagnosticStageId = record
HasValue: Boolean;
Value: TGraphicsReadinessDiagnosticStageId;
end;
TOptionalGraphicsTextureDiagnosticStageId = record
HasValue: Boolean;
Value: TGraphicsTextureDiagnosticStageId;
end;
TOptionalGraphicsVisibleDrawDiagnosticStageId = record
HasValue: Boolean;
Value: TGraphicsVisibleDrawDiagnosticStageId;
end;
TDiagnosticError = record
Present: Boolean;
ClassName: TOptionalString;
MessageText: TOptionalString;
end;
TFileIODiagnosticStreamResult = record
Size: TOptionalInt64;
PositionAfterLoad: TOptionalInt64;
ReadOffset: TOptionalInt64;
RequestedReadCount: TOptionalInt64;
FirstReadCount: TOptionalInt64;
PositionAfterFirstRead: TOptionalInt64;
SeekBackPosition: TOptionalInt64;
SecondReadCount: TOptionalInt64;
PositionAfterSecondRead: TOptionalInt64;
RepeatEqual: TOptionalBoolean;
end;
TFileIODiagnosticResult = record
Status: TDiagnosticStatus;
FailureStage: TOptionalDiagnosticStageId;
Error: TDiagnosticError;
Stages: array[TDiagnosticStageId] of TDiagnosticStatus;
Stream: TFileIODiagnosticStreamResult;
end;
TGraphicsReadinessDiagnosticEvidence = record
ContextAvailable, RendererContextSynced, PhysicalSizeKnown,
TextureBackendReady, SampledProgramReady: TOptionalBoolean;
PhysicalWidth, PhysicalHeight, RendererWidth, RendererHeight,
MaxTextureSize: TOptionalInt64;
end;
TGraphicsTextureDiagnosticEvidence = record
InitialWidth, InitialHeight, ReplacementWidth, ReplacementHeight: TOptionalInt64;
InitialFormat, ReplacementFormat, MinFilter, MagFilter: TOptionalString;
GenTextureCompleted, NonZeroTextureId, FirstBindCompleted,
ReplacementUpdateCompleted, SecondBindCompleted, DeleteAttempted,
DeleteCompleted, CleanupCompleted, ContextLost,
CleanupBlockedByContext: TOptionalBoolean;
SecondaryCleanupError: TDiagnosticError;
end;
TGraphicsVisibleDrawDiagnosticEvidence = record
TextureWidth, TextureHeight, BaseFramesCompleted,
BrightnessFramesCompleted, BrightnessAmount: TOptionalInt64;
TextureFormat, MinFilter, MagFilter: TOptionalString;
TextureCreated, NonZeroTextureId, BaseTripleRgbaDrawsCompleted,
BrightnessTripleRgbaDrawsCompleted, BrightnessOverlayAppliedAfterDraws,
ContextLost, DeleteAttempted, DeleteCompleted, CleanupCompleted,
CleanupBlockedByContext: TOptionalBoolean;
SecondaryCleanupError: TDiagnosticError;
end;
TGraphicsReadinessDiagnosticResult = record
Status: TDiagnosticStatus;
FailureStage: TOptionalGraphicsReadinessDiagnosticStageId;
Error: TDiagnosticError;
Stages: array[TGraphicsReadinessDiagnosticStageId] of TDiagnosticStatus;
Evidence: TGraphicsReadinessDiagnosticEvidence;
end;
TGraphicsTextureDiagnosticResult = record
Status: TDiagnosticStatus;
FailureStage: TOptionalGraphicsTextureDiagnosticStageId;
Error: TDiagnosticError;
Stages: array[TGraphicsTextureDiagnosticStageId] of TDiagnosticStatus;
Evidence: TGraphicsTextureDiagnosticEvidence;
end;
TGraphicsVisibleDrawDiagnosticResult = record
Status: TDiagnosticStatus;
FailureStage: TOptionalGraphicsVisibleDrawDiagnosticStageId;
Error: TDiagnosticError;
Stages: array[TGraphicsVisibleDrawDiagnosticStageId] of TDiagnosticStatus;
Evidence: TGraphicsVisibleDrawDiagnosticEvidence;
end;
TDiagnosticApplicationMetadata = record
Name: string;
PackageName: string;
Version: string;
VersionCode: Int64;
BuildId: TOptionalString;
end;
TDiagnosticRuntimeMetadata = record
Platform: string;
OsVersion: TOptionalString;
DeviceModel: TOptionalString;
CpuArch: TOptionalString;
end;
TDiagnosticSelectedMapMetadata = record
RelativePath: string;
Url: string;
end;
TDiagnosticReportState = record
ApplicationInfo: TDiagnosticApplicationMetadata;
RuntimeInfo: TDiagnosticRuntimeMetadata;
SelectedMap: TDiagnosticSelectedMapMetadata;
OverallStatus: TDiagnosticStatus;
FileIO: TFileIODiagnosticResult;
GraphicsReadiness: TGraphicsReadinessDiagnosticResult;
GraphicsTexture: TGraphicsTextureDiagnosticResult;
GraphicsVisibleDraw: TGraphicsVisibleDrawDiagnosticResult;
end;
function CurrentDiagnosticReport: TDiagnosticReportState;
procedure ReplaceFileIODiagnosticResult(const AResult: TFileIODiagnosticResult);
procedure ReplaceGraphicsReadinessDiagnosticResult(
const AResult: TGraphicsReadinessDiagnosticResult);
procedure ReplaceGraphicsTextureDiagnosticResult(
const AResult: TGraphicsTextureDiagnosticResult);
procedure ReplaceGraphicsVisibleDrawDiagnosticResult(
const AResult: TGraphicsVisibleDrawDiagnosticResult);
function DiagnosticStatusToken(const AStatus: TDiagnosticStatus): string;
function DiagnosticStageIdToken(const AStage: TDiagnosticStageId): string;
function GraphicsReadinessDiagnosticStageIdToken(
const AStage: TGraphicsReadinessDiagnosticStageId): string;
function GraphicsTextureDiagnosticStageIdToken(
const AStage: TGraphicsTextureDiagnosticStageId): string;
function GraphicsVisibleDrawDiagnosticStageIdToken(
const AStage: TGraphicsVisibleDrawDiagnosticStageId): string;
function DiagnosticReportJsonSnapshot: string;
implementation
uses
fpjson, GameSelectedMap;
var
CurrentFileIO: TFileIODiagnosticResult;
CurrentGraphicsReadiness: TGraphicsReadinessDiagnosticResult;
CurrentGraphicsTexture: TGraphicsTextureDiagnosticResult;
CurrentGraphicsVisibleDraw: TGraphicsVisibleDrawDiagnosticResult;
function DiagnosticStatusToken(const AStatus: TDiagnosticStatus): string;
begin
case AStatus of
dsNotRun: Result := 'NOT_RUN';
dsPass: Result := 'PASS';
dsFail: Result := 'FAIL';
end;
end;
function GraphicsReadinessDiagnosticStageIdToken(
const AStage: TGraphicsReadinessDiagnosticStageId): string;
begin
case AStage of
grsiContextReady: Result := 'context_ready';
grsiPhysicalSurface: Result := 'physical_surface';
grsiRendererSizeMatch: Result := 'renderer_size_match';
grsiTextureBackend: Result := 'texture_backend';
grsiSampledProgram: Result := 'sampled_program';
grsiMaxTextureSize: Result := 'max_texture_size';
end;
end;
function GraphicsTextureDiagnosticStageIdToken(
const AStage: TGraphicsTextureDiagnosticStageId): string;
begin
case AStage of
gtsiInitialCreate: Result := 'initial_create';
gtsiNonZeroTextureId: Result := 'non_zero_texture_id';
gtsiFirstBind: Result := 'first_bind';
gtsiReplacementUpdate: Result := 'replacement_update';
gtsiSecondBind: Result := 'second_bind';
gtsiTextureDelete: Result := 'texture_delete';
gtsiResourceCleanup: Result := 'resource_cleanup';
end;
end;
function GraphicsVisibleDrawDiagnosticStageIdToken(
const AStage: TGraphicsVisibleDrawDiagnosticStageId): string;
begin
case AStage of
gvsiPreparation: Result := 'preparation';
gvsiSampledRgbaPhase: Result := 'sampled_rgba_phase';
gvsiBrightnessPhase: Result := 'brightness_phase';
gvsiTextureDelete: Result := 'texture_delete';
gvsiResourceCleanup: Result := 'resource_cleanup';
end;
end;
function DiagnosticStageIdToken(const AStage: TDiagnosticStageId): string;
begin
case AStage of
dsiResourceExists: Result := 'resource_exists';
dsiResourceOpen: Result := 'resource_open';
dsiCallerStreamLoad: Result := 'caller_stream_load';
dsiStreamState: Result := 'stream_state';
dsiSeekReadConsistency: Result := 'seek_read_consistency';
end;
end;
function CurrentDiagnosticReport: TDiagnosticReportState;
begin
Result.ApplicationInfo.Name := 'kam_mobile';
Result.ApplicationInfo.PackageName := 'org.kammobile.kamremake';
Result.ApplicationInfo.Version := '0.4.0';
Result.ApplicationInfo.VersionCode := 30;
Result.ApplicationInfo.BuildId.HasValue := False;
Result.RuntimeInfo.Platform := 'android';
Result.RuntimeInfo.OsVersion.HasValue := False;
Result.RuntimeInfo.DeviceModel.HasValue := False;
Result.RuntimeInfo.CpuArch.HasValue := False;
Result.SelectedMap.RelativePath := SelectedMapRelativePath;
Result.SelectedMap.Url := SelectedMapUrl;
Result.FileIO := CurrentFileIO;
Result.GraphicsReadiness := CurrentGraphicsReadiness;
Result.GraphicsTexture := CurrentGraphicsTexture;
Result.GraphicsVisibleDraw := CurrentGraphicsVisibleDraw;
if (Result.FileIO.Status = dsFail)
or (Result.GraphicsReadiness.Status = dsFail)
or (Result.GraphicsTexture.Status = dsFail)
or (Result.GraphicsVisibleDraw.Status = dsFail) then
Result.OverallStatus := dsFail
else if (Result.FileIO.Status = dsPass)
and (Result.GraphicsReadiness.Status = dsPass)
and (Result.GraphicsTexture.Status = dsPass)
and (Result.GraphicsVisibleDraw.Status = dsPass) then
Result.OverallStatus := dsPass
else
Result.OverallStatus := dsNotRun;
end;
procedure ReplaceFileIODiagnosticResult(const AResult: TFileIODiagnosticResult);
begin
CurrentFileIO := AResult;
end;
procedure ReplaceGraphicsReadinessDiagnosticResult(
const AResult: TGraphicsReadinessDiagnosticResult);
begin
CurrentGraphicsReadiness := AResult;
end;
procedure ReplaceGraphicsTextureDiagnosticResult(
const AResult: TGraphicsTextureDiagnosticResult);
begin
CurrentGraphicsTexture := AResult;
end;
procedure ReplaceGraphicsVisibleDrawDiagnosticResult(
const AResult: TGraphicsVisibleDrawDiagnosticResult);
begin
CurrentGraphicsVisibleDraw := AResult;
end;
function OptionalStringJson(const AValue: TOptionalString): TJSONData;
begin
if AValue.HasValue then
Result := TJSONString.Create(AValue.Value)
else
Result := TJSONNull.Create;
end;
function OptionalInt64Json(const AValue: TOptionalInt64): TJSONData;
begin
if AValue.HasValue then
Result := TJSONIntegerNumber.Create(AValue.Value)
else
Result := TJSONNull.Create;
end;
function OptionalBooleanJson(const AValue: TOptionalBoolean): TJSONData;
begin
if AValue.HasValue then
Result := TJSONBoolean.Create(AValue.Value)
else
Result := TJSONNull.Create;
end;
function DiagnosticErrorJson(const AError: TDiagnosticError): TJSONData;
var
ObjectValue: TJSONObject;
begin
if not AError.Present then
Exit(TJSONNull.Create);
ObjectValue := TJSONObject.Create;
ObjectValue.Add('class', OptionalStringJson(AError.ClassName));
ObjectValue.Add('message', OptionalStringJson(AError.MessageText));
Result := ObjectValue;
end;
procedure AppendFileIOJson(AActions: TJSONArray; const AResult: TFileIODiagnosticResult);
var
Action, Stage, Stream: TJSONObject;
Stages: TJSONArray;
StageId: TDiagnosticStageId;
begin
Action := TJSONObject.Create;
Action.Add('id', 'file_io');
Action.Add('status', DiagnosticStatusToken(AResult.Status));
if AResult.FailureStage.HasValue then
Action.Add('failure_stage', DiagnosticStageIdToken(AResult.FailureStage.Value))
else
Action.Add('failure_stage', TJSONNull.Create);
Action.Add('error', DiagnosticErrorJson(AResult.Error));
Stages := TJSONArray.Create;
for StageId := Low(TDiagnosticStageId) to High(TDiagnosticStageId) do
begin
Stage := TJSONObject.Create;
Stage.Add('id', DiagnosticStageIdToken(StageId));
Stage.Add('status', DiagnosticStatusToken(AResult.Stages[StageId]));
Stages.Add(Stage);
end;
Action.Add('stages', Stages);
Stream := TJSONObject.Create;
Stream.Add('size', OptionalInt64Json(AResult.Stream.Size));
Stream.Add('position_after_load', OptionalInt64Json(AResult.Stream.PositionAfterLoad));
Stream.Add('read_offset', OptionalInt64Json(AResult.Stream.ReadOffset));
Stream.Add('requested_read_count', OptionalInt64Json(AResult.Stream.RequestedReadCount));
Stream.Add('first_read_count', OptionalInt64Json(AResult.Stream.FirstReadCount));
Stream.Add('position_after_first_read', OptionalInt64Json(AResult.Stream.PositionAfterFirstRead));
Stream.Add('seek_back_position', OptionalInt64Json(AResult.Stream.SeekBackPosition));
Stream.Add('second_read_count', OptionalInt64Json(AResult.Stream.SecondReadCount));
Stream.Add('position_after_second_read', OptionalInt64Json(AResult.Stream.PositionAfterSecondRead));
Stream.Add('repeat_equal', OptionalBooleanJson(AResult.Stream.RepeatEqual));
Action.Add('stream', Stream);
AActions.Add(Action);
end;
procedure AppendGraphicsReadinessJson(AActions: TJSONArray; const AResult: TGraphicsReadinessDiagnosticResult);
var
Action, Stage, Evidence: TJSONObject;
Stages: TJSONArray;
GraphicsReadinessStageId: TGraphicsReadinessDiagnosticStageId;
begin
Action := TJSONObject.Create;
Action.Add('id', 'graphics_readiness');
Action.Add('status', DiagnosticStatusToken(AResult.Status));
if AResult.FailureStage.HasValue then
Action.Add('failure_stage', GraphicsReadinessDiagnosticStageIdToken(
AResult.FailureStage.Value))
else
Action.Add('failure_stage', TJSONNull.Create);
Action.Add('error', DiagnosticErrorJson(AResult.Error));
Stages := TJSONArray.Create;
for GraphicsReadinessStageId := Low(TGraphicsReadinessDiagnosticStageId)
to High(TGraphicsReadinessDiagnosticStageId) do
begin
Stage := TJSONObject.Create;
Stage.Add('id', GraphicsReadinessDiagnosticStageIdToken(GraphicsReadinessStageId));
Stage.Add('status', DiagnosticStatusToken(
AResult.Stages[GraphicsReadinessStageId]));
Stages.Add(Stage);
end;
Action.Add('stages', Stages);
Evidence := TJSONObject.Create;
Evidence.Add('context_available', OptionalBooleanJson(AResult.Evidence.ContextAvailable));
Evidence.Add('renderer_context_synced', OptionalBooleanJson(AResult.Evidence.RendererContextSynced));
Evidence.Add('physical_size_known', OptionalBooleanJson(AResult.Evidence.PhysicalSizeKnown));
Evidence.Add('texture_backend_ready', OptionalBooleanJson(AResult.Evidence.TextureBackendReady));
Evidence.Add('sampled_program_ready', OptionalBooleanJson(AResult.Evidence.SampledProgramReady));
Evidence.Add('physical_width', OptionalInt64Json(AResult.Evidence.PhysicalWidth));
Evidence.Add('physical_height', OptionalInt64Json(AResult.Evidence.PhysicalHeight));
Evidence.Add('renderer_width', OptionalInt64Json(AResult.Evidence.RendererWidth));
Evidence.Add('renderer_height', OptionalInt64Json(AResult.Evidence.RendererHeight));
Evidence.Add('max_texture_size', OptionalInt64Json(AResult.Evidence.MaxTextureSize));
Action.Add('evidence', Evidence);
AActions.Add(Action);
end;
procedure AppendGraphicsTextureJson(AActions: TJSONArray; const AResult: TGraphicsTextureDiagnosticResult);
var
Action, Stage, Evidence: TJSONObject;
Stages: TJSONArray;
GraphicsTextureStageId: TGraphicsTextureDiagnosticStageId;
begin
Action := TJSONObject.Create;
Action.Add('id', 'graphics_texture');
Action.Add('status', DiagnosticStatusToken(AResult.Status));
if AResult.FailureStage.HasValue then
Action.Add('failure_stage', GraphicsTextureDiagnosticStageIdToken(
AResult.FailureStage.Value))
else
Action.Add('failure_stage', TJSONNull.Create);
Action.Add('error', DiagnosticErrorJson(AResult.Error));
Stages := TJSONArray.Create;
for GraphicsTextureStageId := Low(TGraphicsTextureDiagnosticStageId)
to High(TGraphicsTextureDiagnosticStageId) do
begin
Stage := TJSONObject.Create;
Stage.Add('id', GraphicsTextureDiagnosticStageIdToken(GraphicsTextureStageId));
Stage.Add('status', DiagnosticStatusToken(
AResult.Stages[GraphicsTextureStageId]));
Stages.Add(Stage);
end;
Action.Add('stages', Stages);
Evidence := TJSONObject.Create;
Evidence.Add('initial_width', OptionalInt64Json(AResult.Evidence.InitialWidth));
Evidence.Add('initial_height', OptionalInt64Json(AResult.Evidence.InitialHeight));
Evidence.Add('replacement_width', OptionalInt64Json(AResult.Evidence.ReplacementWidth));
Evidence.Add('replacement_height', OptionalInt64Json(AResult.Evidence.ReplacementHeight));
Evidence.Add('initial_format', OptionalStringJson(AResult.Evidence.InitialFormat));
Evidence.Add('replacement_format', OptionalStringJson(AResult.Evidence.ReplacementFormat));
Evidence.Add('min_filter', OptionalStringJson(AResult.Evidence.MinFilter));
Evidence.Add('mag_filter', OptionalStringJson(AResult.Evidence.MagFilter));
Evidence.Add('gen_texture_completed', OptionalBooleanJson(AResult.Evidence.GenTextureCompleted));
Evidence.Add('non_zero_texture_id', OptionalBooleanJson(AResult.Evidence.NonZeroTextureId));
Evidence.Add('first_bind_completed', OptionalBooleanJson(AResult.Evidence.FirstBindCompleted));
Evidence.Add('replacement_update_completed', OptionalBooleanJson(AResult.Evidence.ReplacementUpdateCompleted));
Evidence.Add('second_bind_completed', OptionalBooleanJson(AResult.Evidence.SecondBindCompleted));
Evidence.Add('delete_attempted', OptionalBooleanJson(AResult.Evidence.DeleteAttempted));
Evidence.Add('delete_completed', OptionalBooleanJson(AResult.Evidence.DeleteCompleted));
Evidence.Add('cleanup_completed', OptionalBooleanJson(AResult.Evidence.CleanupCompleted));
Evidence.Add('context_lost', OptionalBooleanJson(AResult.Evidence.ContextLost));
Evidence.Add('cleanup_blocked_by_context', OptionalBooleanJson(AResult.Evidence.CleanupBlockedByContext));
Evidence.Add('secondary_cleanup_error',
DiagnosticErrorJson(AResult.Evidence.SecondaryCleanupError));
Action.Add('evidence', Evidence);
AActions.Add(Action);
end;
procedure AppendGraphicsVisibleDrawJson(AActions: TJSONArray; const AResult: TGraphicsVisibleDrawDiagnosticResult);
var
Action, Stage, Evidence: TJSONObject;
Stages: TJSONArray;
GraphicsVisibleDrawStageId: TGraphicsVisibleDrawDiagnosticStageId;
begin
Action := TJSONObject.Create;
Action.Add('id', 'graphics_visible_draw');
Action.Add('status', DiagnosticStatusToken(AResult.Status));
if AResult.FailureStage.HasValue then
Action.Add('failure_stage', GraphicsVisibleDrawDiagnosticStageIdToken(
AResult.FailureStage.Value))
else
Action.Add('failure_stage', TJSONNull.Create);
Action.Add('error', DiagnosticErrorJson(AResult.Error));
Stages := TJSONArray.Create;
for GraphicsVisibleDrawStageId := Low(TGraphicsVisibleDrawDiagnosticStageId)
to High(TGraphicsVisibleDrawDiagnosticStageId) do
begin
Stage := TJSONObject.Create;
Stage.Add('id', GraphicsVisibleDrawDiagnosticStageIdToken(GraphicsVisibleDrawStageId));
Stage.Add('status', DiagnosticStatusToken(
AResult.Stages[GraphicsVisibleDrawStageId]));
Stages.Add(Stage);
end;
Action.Add('stages', Stages);
Evidence := TJSONObject.Create;
Evidence.Add('texture_width', OptionalInt64Json(AResult.Evidence.TextureWidth));
Evidence.Add('texture_height', OptionalInt64Json(AResult.Evidence.TextureHeight));
Evidence.Add('base_frames_completed', OptionalInt64Json(AResult.Evidence.BaseFramesCompleted));
Evidence.Add('brightness_frames_completed', OptionalInt64Json(AResult.Evidence.BrightnessFramesCompleted));
Evidence.Add('brightness_amount', OptionalInt64Json(AResult.Evidence.BrightnessAmount));
Evidence.Add('texture_format', OptionalStringJson(AResult.Evidence.TextureFormat));
Evidence.Add('min_filter', OptionalStringJson(AResult.Evidence.MinFilter));
Evidence.Add('mag_filter', OptionalStringJson(AResult.Evidence.MagFilter));
Evidence.Add('texture_created', OptionalBooleanJson(AResult.Evidence.TextureCreated));
Evidence.Add('non_zero_texture_id', OptionalBooleanJson(AResult.Evidence.NonZeroTextureId));
Evidence.Add('base_triple_rgba_draws_completed', OptionalBooleanJson(AResult.Evidence.BaseTripleRgbaDrawsCompleted));
Evidence.Add('brightness_triple_rgba_draws_completed', OptionalBooleanJson(AResult.Evidence.BrightnessTripleRgbaDrawsCompleted));
Evidence.Add('brightness_overlay_applied_after_draws', OptionalBooleanJson(AResult.Evidence.BrightnessOverlayAppliedAfterDraws));
Evidence.Add('context_lost', OptionalBooleanJson(AResult.Evidence.ContextLost));
Evidence.Add('delete_attempted', OptionalBooleanJson(AResult.Evidence.DeleteAttempted));
Evidence.Add('delete_completed', OptionalBooleanJson(AResult.Evidence.DeleteCompleted));
Evidence.Add('cleanup_completed', OptionalBooleanJson(AResult.Evidence.CleanupCompleted));
Evidence.Add('cleanup_blocked_by_context', OptionalBooleanJson(AResult.Evidence.CleanupBlockedByContext));
Evidence.Add('secondary_cleanup_error',
DiagnosticErrorJson(AResult.Evidence.SecondaryCleanupError));
Action.Add('evidence', Evidence);
AActions.Add(Action);
end;
function DiagnosticReportJsonSnapshot: string;
var
State: TDiagnosticReportState;
Root, ObjectValue: TJSONObject;
Actions: TJSONArray;
begin
State := CurrentDiagnosticReport;
Root := TJSONObject.Create;
try
Root.Add('schema', 'kam-mobile-diagnostics/1');
ObjectValue := TJSONObject.Create;
ObjectValue.Add('name', State.ApplicationInfo.Name);
ObjectValue.Add('package', State.ApplicationInfo.PackageName);
ObjectValue.Add('version', State.ApplicationInfo.Version);
ObjectValue.Add('version_code', State.ApplicationInfo.VersionCode);
ObjectValue.Add('build_id', OptionalStringJson(State.ApplicationInfo.BuildId));
Root.Add('application', ObjectValue);
ObjectValue := TJSONObject.Create;
ObjectValue.Add('platform', State.RuntimeInfo.Platform);
ObjectValue.Add('os_version', OptionalStringJson(State.RuntimeInfo.OsVersion));
ObjectValue.Add('device_model', OptionalStringJson(State.RuntimeInfo.DeviceModel));
ObjectValue.Add('cpu_arch', OptionalStringJson(State.RuntimeInfo.CpuArch));
Root.Add('runtime', ObjectValue);
ObjectValue := TJSONObject.Create;
ObjectValue.Add('relative_path', State.SelectedMap.RelativePath);
ObjectValue.Add('url', State.SelectedMap.Url);
Root.Add('selected_map', ObjectValue);
Root.Add('overall_status', DiagnosticStatusToken(State.OverallStatus));
Actions := TJSONArray.Create;
AppendFileIOJson(Actions, State.FileIO);
AppendGraphicsReadinessJson(Actions, State.GraphicsReadiness);
AppendGraphicsTextureJson(Actions, State.GraphicsTexture);
AppendGraphicsVisibleDrawJson(Actions, State.GraphicsVisibleDraw);
Root.Add('actions', Actions);
Result := Root.AsJSON;
finally
Root.Free;
end;
end;
end.