From d6a460c93112da04dc2630cebcf4b115d0dffc9a Mon Sep 17 00:00:00 2001 From: sunnylqm Date: Mon, 29 Jun 2026 18:34:35 +0800 Subject: [PATCH 1/3] fix(harmony): align isFirstTime and rollback mechanism with android/ios --- .../pushy/src/main/ets/PushyTurboModule.ts | 2 +- harmony/pushy/src/main/ets/UpdateContext.ts | 21 +++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/harmony/pushy/src/main/ets/PushyTurboModule.ts b/harmony/pushy/src/main/ets/PushyTurboModule.ts index 421b5c18..ee71638a 100644 --- a/harmony/pushy/src/main/ets/PushyTurboModule.ts +++ b/harmony/pushy/src/main/ets/PushyTurboModule.ts @@ -75,7 +75,7 @@ export class PushyTurboModule extends UITurboModule { const currentVersionInfo = currentVersion ? this.context.getKv(`hash_${currentVersion}`) : ''; - const isFirstTime = this.context.isFirstTime(); + const isFirstTime = this.context.consumeFirstLoadMarker(); const rolledBackVersion = this.context.rolledBackVersion(); const uuid = this.context.getKv('uuid'); const isUsingBundleUrl = this.context.getIsUsingBundleUrl(); diff --git a/harmony/pushy/src/main/ets/UpdateContext.ts b/harmony/pushy/src/main/ets/UpdateContext.ts index 9a96c52e..fb6adf59 100644 --- a/harmony/pushy/src/main/ets/UpdateContext.ts +++ b/harmony/pushy/src/main/ets/UpdateContext.ts @@ -25,6 +25,7 @@ export class UpdateContext { private preferences!: preferences.Preferences; private static DEBUG: boolean = false; private static isUsingBundleUrl: boolean = false; + private static ignoreRollback: boolean = false; constructor(context: common.UIAbilityContext) { this.context = context; @@ -245,6 +246,7 @@ export class UpdateContext { return; } + UpdateContext.ignoreRollback = false; this.cleanUp(); this.persistState(nextState, { clearExisting: true }); } @@ -361,23 +363,38 @@ export class UpdateContext { } this.runStateOperation(STATE_OP_SWITCH_VERSION, hash); + UpdateContext.ignoreRollback = false; } catch (e) { console.error('Failed to switch version:', e); throw e; } } + public consumeFirstLoadMarker(): boolean { + const marked = this.readString('firstLoadMarked') === 'true'; + if (marked) { + this.setKv('firstLoadMarked', 'false'); + } + return marked; + } + public getBundleUrl() { UpdateContext.isUsingBundleUrl = true; const launchState = NativePatchCore.runStateCore( STATE_OP_RESOLVE_LAUNCH, this.getStateSnapshot(), '', - false, - false, + UpdateContext.ignoreRollback, + true, ); if (launchState.didRollback || launchState.consumedFirstTime) { this.persistState(launchState); + if (launchState.consumedFirstTime) { + this.setKv('firstLoadMarked', 'true'); + } + } + if (launchState.consumedFirstTime) { + UpdateContext.ignoreRollback = true; } let version = launchState.loadVersion || ''; From b2a79e1994a7ed3e8934e0638231b1b1988db562 Mon Sep 17 00:00:00 2001 From: sunnylqm Date: Mon, 29 Jun 2026 18:53:49 +0800 Subject: [PATCH 2/3] cleanup --- harmony/pushy/src/main/ets/UpdateContext.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/harmony/pushy/src/main/ets/UpdateContext.ts b/harmony/pushy/src/main/ets/UpdateContext.ts index fb6adf59..82433a24 100644 --- a/harmony/pushy/src/main/ets/UpdateContext.ts +++ b/harmony/pushy/src/main/ets/UpdateContext.ts @@ -281,6 +281,8 @@ export class UpdateContext { public clearFirstTime(): void { this.runStateOperation(STATE_OP_CLEAR_FIRST_TIME, '', { cleanUp: true }); + this.preferences.deleteSync('firstLoadMarked'); + this.flushPreferences('clear first time'); } public clearRollbackMark(): void { @@ -373,7 +375,8 @@ export class UpdateContext { public consumeFirstLoadMarker(): boolean { const marked = this.readString('firstLoadMarked') === 'true'; if (marked) { - this.setKv('firstLoadMarked', 'false'); + this.preferences.deleteSync('firstLoadMarked'); + this.flushPreferences('clear first load marker'); } return marked; } From d36a66b6d25a5cdac24ece82cf09fc7aad913b37 Mon Sep 17 00:00:00 2001 From: sunnylqm Date: Mon, 29 Jun 2026 19:00:58 +0800 Subject: [PATCH 3/3] fix(harmony): batch first-load marker persistence --- harmony/pushy/src/main/ets/UpdateContext.ts | 28 +++++++++++++-------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/harmony/pushy/src/main/ets/UpdateContext.ts b/harmony/pushy/src/main/ets/UpdateContext.ts index 82433a24..7d70b4a7 100644 --- a/harmony/pushy/src/main/ets/UpdateContext.ts +++ b/harmony/pushy/src/main/ets/UpdateContext.ts @@ -73,9 +73,8 @@ export class UpdateContext { public getBuildTime(): string { try { - const content = this.context.resourceManager.getRawFileContentSync( - 'meta.json', - ); + const content = + this.context.resourceManager.getRawFileContentSync('meta.json'); const metaData = JSON.parse( new util.TextDecoder().decodeToString(content), ) as Record; @@ -183,6 +182,8 @@ export class UpdateContext { clearExisting?: boolean; removeStaleHash?: boolean; cleanUp?: boolean; + markFirstLoadMarker?: boolean; + clearFirstLoadMarker?: boolean; } = {}, ): void { if (options.clearExisting) { @@ -192,6 +193,12 @@ export class UpdateContext { if (options.removeStaleHash && state.staleVersionToDelete) { this.preferences.deleteSync(`hash_${state.staleVersionToDelete}`); } + if (options.markFirstLoadMarker) { + this.preferences.putSync('firstLoadMarked', 'true'); + } + if (options.clearFirstLoadMarker) { + this.preferences.deleteSync('firstLoadMarked'); + } this.flushPreferences('persist state'); if (options.cleanUp) { this.cleanUp(); @@ -204,6 +211,7 @@ export class UpdateContext { options: { removeStaleHash?: boolean; cleanUp?: boolean; + clearFirstLoadMarker?: boolean; } = {}, ): StateCoreResult { const nextState = NativePatchCore.runStateCore( @@ -280,9 +288,10 @@ export class UpdateContext { } public clearFirstTime(): void { - this.runStateOperation(STATE_OP_CLEAR_FIRST_TIME, '', { cleanUp: true }); - this.preferences.deleteSync('firstLoadMarked'); - this.flushPreferences('clear first time'); + this.runStateOperation(STATE_OP_CLEAR_FIRST_TIME, '', { + cleanUp: true, + clearFirstLoadMarker: true, + }); } public clearRollbackMark(): void { @@ -391,10 +400,9 @@ export class UpdateContext { true, ); if (launchState.didRollback || launchState.consumedFirstTime) { - this.persistState(launchState); - if (launchState.consumedFirstTime) { - this.setKv('firstLoadMarked', 'true'); - } + this.persistState(launchState, { + markFirstLoadMarker: launchState.consumedFirstTime, + }); } if (launchState.consumedFirstTime) { UpdateContext.ignoreRollback = true;