react-native-update 10.38.3 → 10.38.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/harmony/pushy/src/main/cpp/CMakeLists.txt +70 -0
- package/harmony/pushy/src/main/cpp/PushyPackage.h +55 -0
- package/harmony/pushy/src/main/cpp/PushyTurboModule.cpp +142 -0
- package/harmony/pushy/src/main/cpp/PushyTurboModule.h +38 -0
- package/harmony/pushy/src/main/cpp/pushy.c +117 -0
- package/harmony/pushy/src/main/cpp/pushy.cpp +856 -0
- package/harmony/pushy/src/main/cpp/pushy.h +8 -0
- package/harmony/pushy/src/main/ets/DownloadTask.ts +610 -0
- package/harmony/pushy/src/main/ets/DownloadTaskParams.ts +19 -0
- package/harmony/pushy/src/main/ets/EventHub.ts +39 -0
- package/harmony/pushy/src/main/ets/Logger.ts +52 -0
- package/harmony/pushy/src/main/ets/NativePatchCore.ts +87 -0
- package/harmony/pushy/src/main/ets/PushyFileJSBundleProvider.ets +50 -0
- package/harmony/pushy/src/main/ets/PushyPackage.ts +22 -0
- package/harmony/pushy/src/main/ets/PushyTurboModule.ts +139 -0
- package/harmony/pushy/src/main/ets/SaveFile.ts +34 -0
- package/harmony/pushy/src/main/ets/UpdateContext.ts +346 -0
- package/harmony/pushy/src/main/ets/UpdateModuleImpl.ts +123 -0
- package/harmony/pushy/src/main/module.json5 +7 -0
- package/harmony/pushy/src/main/resources/base/element/string.json +8 -0
- package/harmony/pushy/src/main/resources/en_US/element/string.json +8 -0
- package/harmony/pushy/src/main/resources/zh_CN/element/string.json +8 -0
- package/harmony/pushy.har +0 -0
- package/package.json +1 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import hilog from '@ohos.hilog';
|
|
2
|
+
|
|
3
|
+
class Logger {
|
|
4
|
+
private domain: number;
|
|
5
|
+
private prefix: string;
|
|
6
|
+
private format: string = '%{public}s,%{public}s';
|
|
7
|
+
private isDebug: boolean;
|
|
8
|
+
|
|
9
|
+
constructor(
|
|
10
|
+
prefix: string = 'MyApp',
|
|
11
|
+
domain: number = 0xff00,
|
|
12
|
+
isDebug = false,
|
|
13
|
+
) {
|
|
14
|
+
this.prefix = prefix;
|
|
15
|
+
this.domain = domain;
|
|
16
|
+
this.isDebug = isDebug;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private normalizeArgs(args: string[]): [string, string] {
|
|
20
|
+
if (args.length === 0) {
|
|
21
|
+
return ['', ''];
|
|
22
|
+
}
|
|
23
|
+
if (args.length === 1) {
|
|
24
|
+
return [args[0], ''];
|
|
25
|
+
}
|
|
26
|
+
return [args[0], args.slice(1).join(' ')];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
debug(...args: string[]): void {
|
|
30
|
+
if (this.isDebug) {
|
|
31
|
+
const [tag, message] = this.normalizeArgs(args);
|
|
32
|
+
hilog.debug(this.domain, this.prefix, this.format, tag, message);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
info(...args: string[]): void {
|
|
37
|
+
const [tag, message] = this.normalizeArgs(args);
|
|
38
|
+
hilog.info(this.domain, this.prefix, this.format, tag, message);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
warn(...args: string[]): void {
|
|
42
|
+
const [tag, message] = this.normalizeArgs(args);
|
|
43
|
+
hilog.warn(this.domain, this.prefix, this.format, tag, message);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
error(...args: string[]): void {
|
|
47
|
+
const [tag, message] = this.normalizeArgs(args);
|
|
48
|
+
hilog.error(this.domain, this.prefix, this.format, tag, message);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default new Logger('pushy', 0xff00, false);
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import NativeUpdateCore from 'librnupdate.so';
|
|
2
|
+
|
|
3
|
+
export const STATE_OP_SWITCH_VERSION = 1;
|
|
4
|
+
export const STATE_OP_MARK_SUCCESS = 2;
|
|
5
|
+
export const STATE_OP_ROLLBACK = 3;
|
|
6
|
+
export const STATE_OP_CLEAR_FIRST_TIME = 4;
|
|
7
|
+
export const STATE_OP_CLEAR_ROLLBACK_MARK = 5;
|
|
8
|
+
export const STATE_OP_RESOLVE_LAUNCH = 6;
|
|
9
|
+
|
|
10
|
+
export const ARCHIVE_PATCH_TYPE_FULL = 1;
|
|
11
|
+
export const ARCHIVE_PATCH_TYPE_FROM_PACKAGE = 2;
|
|
12
|
+
export const ARCHIVE_PATCH_TYPE_FROM_PPK = 3;
|
|
13
|
+
|
|
14
|
+
export interface StateCoreResult {
|
|
15
|
+
packageVersion?: string;
|
|
16
|
+
buildTime?: string;
|
|
17
|
+
currentVersion?: string;
|
|
18
|
+
lastVersion?: string;
|
|
19
|
+
firstTime: boolean;
|
|
20
|
+
firstTimeOk: boolean;
|
|
21
|
+
rolledBackVersion?: string;
|
|
22
|
+
changed?: boolean;
|
|
23
|
+
staleVersionToDelete?: string;
|
|
24
|
+
loadVersion?: string;
|
|
25
|
+
didRollback?: boolean;
|
|
26
|
+
consumedFirstTime?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface ArchivePatchPlanResult {
|
|
30
|
+
mergeSourceSubdir?: string;
|
|
31
|
+
enableMerge: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface CopyGroupResult {
|
|
35
|
+
from: string;
|
|
36
|
+
toPaths: string[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface FileSourcePatchRequest {
|
|
40
|
+
copyFroms: string[];
|
|
41
|
+
copyTos: string[];
|
|
42
|
+
deletes: string[];
|
|
43
|
+
sourceRoot: string;
|
|
44
|
+
targetRoot: string;
|
|
45
|
+
originBundlePath: string;
|
|
46
|
+
bundlePatchPath: string;
|
|
47
|
+
bundleOutputPath: string;
|
|
48
|
+
mergeSourceSubdir?: string;
|
|
49
|
+
enableMerge?: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface NativePatchCoreBindings {
|
|
53
|
+
hdiffPatch(
|
|
54
|
+
origin: Uint8Array,
|
|
55
|
+
patch: Uint8Array,
|
|
56
|
+
): ArrayBuffer | Uint8Array;
|
|
57
|
+
syncStateWithBinaryVersion(
|
|
58
|
+
packageVersion: string,
|
|
59
|
+
buildTime: string,
|
|
60
|
+
state: StateCoreResult,
|
|
61
|
+
): StateCoreResult;
|
|
62
|
+
runStateCore(
|
|
63
|
+
operation: number,
|
|
64
|
+
state: StateCoreResult,
|
|
65
|
+
stringArg?: string,
|
|
66
|
+
flagA?: boolean,
|
|
67
|
+
flagB?: boolean,
|
|
68
|
+
): StateCoreResult;
|
|
69
|
+
buildArchivePatchPlan(
|
|
70
|
+
patchType: number,
|
|
71
|
+
entryNames: string[],
|
|
72
|
+
copyFroms: string[],
|
|
73
|
+
copyTos: string[],
|
|
74
|
+
deletes: string[],
|
|
75
|
+
bundlePatchEntryName?: string,
|
|
76
|
+
): ArchivePatchPlanResult;
|
|
77
|
+
buildCopyGroups(copyFroms: string[], copyTos: string[]): CopyGroupResult[];
|
|
78
|
+
applyPatchFromFileSource(options: FileSourcePatchRequest): void;
|
|
79
|
+
cleanupOldEntries(
|
|
80
|
+
rootDir: string,
|
|
81
|
+
keepCurrent: string,
|
|
82
|
+
keepPrevious: string,
|
|
83
|
+
maxAgeDays: number,
|
|
84
|
+
): void;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export default NativeUpdateCore as unknown as NativePatchCoreBindings;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FileJSBundle,
|
|
3
|
+
JSBundleProvider,
|
|
4
|
+
JSBundleProviderError,
|
|
5
|
+
} from '@rnoh/react-native-openharmony';
|
|
6
|
+
import common from '@ohos.app.ability.common';
|
|
7
|
+
import fs from '@ohos.file.fs';
|
|
8
|
+
import { UpdateContext } from './UpdateContext';
|
|
9
|
+
|
|
10
|
+
export class PushyFileJSBundleProvider extends JSBundleProvider {
|
|
11
|
+
private updateContext: UpdateContext;
|
|
12
|
+
private path: string = '';
|
|
13
|
+
|
|
14
|
+
constructor(context: common.UIAbilityContext) {
|
|
15
|
+
super();
|
|
16
|
+
this.updateContext = new UpdateContext(context);
|
|
17
|
+
this.path = this.updateContext.getBundleUrl();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getURL(): string {
|
|
21
|
+
return this.path;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async getBundle(): Promise<FileJSBundle> {
|
|
25
|
+
if (!this.path) {
|
|
26
|
+
throw new JSBundleProviderError({
|
|
27
|
+
whatHappened: 'No pushy bundle found. using default bundle',
|
|
28
|
+
howCanItBeFixed: [''],
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
await fs.access(this.path, fs.OpenMode.READ_ONLY);
|
|
33
|
+
return {
|
|
34
|
+
filePath: this.path,
|
|
35
|
+
};
|
|
36
|
+
} catch (error) {
|
|
37
|
+
throw new JSBundleProviderError({
|
|
38
|
+
whatHappened: `Couldn't load JSBundle from ${this.path}`,
|
|
39
|
+
extraData: error,
|
|
40
|
+
howCanItBeFixed: [
|
|
41
|
+
`Check if a bundle exists at "${this.path}" on your device.`,
|
|
42
|
+
],
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
getAppKeys(): string[] {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { RNPackage, TurboModulesFactory } from '@rnoh/react-native-openharmony/ts';
|
|
2
|
+
import type { TurboModule, TurboModuleContext } from '@rnoh/react-native-openharmony/ts';
|
|
3
|
+
import { PushyTurboModule } from './PushyTurboModule';
|
|
4
|
+
|
|
5
|
+
class PushyTurboModulesFactory extends TurboModulesFactory {
|
|
6
|
+
createTurboModule(name: string): TurboModule | null {
|
|
7
|
+
if (name === 'Pushy') {
|
|
8
|
+
return new PushyTurboModule(this.ctx);
|
|
9
|
+
}
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
hasTurboModule(name: string): boolean {
|
|
14
|
+
return name === 'Pushy';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class PushyPackage extends RNPackage {
|
|
19
|
+
createTurboModulesFactory(ctx: TurboModuleContext): TurboModulesFactory {
|
|
20
|
+
return new PushyTurboModulesFactory(ctx);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TurboModule,
|
|
3
|
+
TurboModuleContext,
|
|
4
|
+
} from '@rnoh/react-native-openharmony/ts';
|
|
5
|
+
import common from '@ohos.app.ability.common';
|
|
6
|
+
import { bundleManager } from '@kit.AbilityKit';
|
|
7
|
+
import logger from './Logger';
|
|
8
|
+
import { UpdateModuleImpl } from './UpdateModuleImpl';
|
|
9
|
+
import { UpdateContext } from './UpdateContext';
|
|
10
|
+
import { EventHub } from './EventHub';
|
|
11
|
+
import { util } from '@kit.ArkTS';
|
|
12
|
+
|
|
13
|
+
const TAG = 'PushyTurboModule';
|
|
14
|
+
|
|
15
|
+
export class PushyTurboModule extends TurboModule {
|
|
16
|
+
mUiCtx: common.UIAbilityContext;
|
|
17
|
+
context: UpdateContext;
|
|
18
|
+
|
|
19
|
+
constructor(protected ctx: TurboModuleContext) {
|
|
20
|
+
super(ctx);
|
|
21
|
+
logger.debug(TAG, ',PushyTurboModule constructor');
|
|
22
|
+
this.mUiCtx = ctx.uiAbilityContext;
|
|
23
|
+
this.context = new UpdateContext(this.mUiCtx);
|
|
24
|
+
EventHub.getInstance().setRNInstance(ctx.rnInstance);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getConstants(): Object {
|
|
28
|
+
logger.debug(TAG, ',call getConstants');
|
|
29
|
+
const context = this.mUiCtx;
|
|
30
|
+
let bundleFlags =
|
|
31
|
+
bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION;
|
|
32
|
+
let packageVersion = '';
|
|
33
|
+
try {
|
|
34
|
+
const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlags);
|
|
35
|
+
packageVersion = bundleInfo?.versionName || 'Unknown';
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error('Failed to get bundle info:', error);
|
|
38
|
+
}
|
|
39
|
+
let buildTime = '';
|
|
40
|
+
try {
|
|
41
|
+
const resourceManager = this.mUiCtx.resourceManager;
|
|
42
|
+
const content = resourceManager.getRawFileContentSync('meta.json');
|
|
43
|
+
const metaData = JSON.parse(
|
|
44
|
+
new util.TextDecoder().decodeToString(content),
|
|
45
|
+
);
|
|
46
|
+
if (metaData.pushy_build_time) {
|
|
47
|
+
buildTime = String(metaData.pushy_build_time);
|
|
48
|
+
}
|
|
49
|
+
} catch {}
|
|
50
|
+
this.context.syncStateWithBinaryVersion(packageVersion, buildTime);
|
|
51
|
+
|
|
52
|
+
const currentVersion = this.context.getCurrentVersion();
|
|
53
|
+
const currentVersionInfo = currentVersion
|
|
54
|
+
? this.context.getKv(`hash_${currentVersion}`)
|
|
55
|
+
: '';
|
|
56
|
+
const isFirstTime = this.context.isFirstTime();
|
|
57
|
+
const rolledBackVersion = this.context.rolledBackVersion();
|
|
58
|
+
const uuid = this.context.getKv('uuid');
|
|
59
|
+
const isUsingBundleUrl = this.context.getIsUsingBundleUrl();
|
|
60
|
+
|
|
61
|
+
if (rolledBackVersion) {
|
|
62
|
+
this.context.clearRollbackMark();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
downloadRootDir: `${context.filesDir}/_update`,
|
|
67
|
+
currentVersionInfo,
|
|
68
|
+
packageVersion,
|
|
69
|
+
currentVersion,
|
|
70
|
+
buildTime,
|
|
71
|
+
isUsingBundleUrl,
|
|
72
|
+
isFirstTime,
|
|
73
|
+
rolledBackVersion,
|
|
74
|
+
uuid,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
setLocalHashInfo(hash: string, info: string): boolean {
|
|
79
|
+
logger.debug(TAG, ',call setLocalHashInfo');
|
|
80
|
+
return UpdateModuleImpl.setLocalHashInfo(this.context, hash, info);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
getLocalHashInfo(hash: string): string {
|
|
84
|
+
return UpdateModuleImpl.getLocalHashInfo(this.context, hash);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async setUuid(uuid: string): Promise<void> {
|
|
88
|
+
logger.debug(TAG, ',call setUuid');
|
|
89
|
+
return UpdateModuleImpl.setUuid(this.context, uuid);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async reloadUpdate(options: { hash: string }): Promise<void> {
|
|
93
|
+
logger.debug(TAG, ',call reloadUpdate');
|
|
94
|
+
return UpdateModuleImpl.reloadUpdate(this.context, this.mUiCtx, options);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async setNeedUpdate(options: { hash: string }): Promise<boolean> {
|
|
98
|
+
logger.debug(TAG, ',call setNeedUpdate');
|
|
99
|
+
return UpdateModuleImpl.setNeedUpdate(this.context, options);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async markSuccess(): Promise<boolean> {
|
|
103
|
+
logger.debug(TAG, ',call markSuccess');
|
|
104
|
+
return UpdateModuleImpl.markSuccess(this.context);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async downloadPatchFromPpk(options: {
|
|
108
|
+
updateUrl: string;
|
|
109
|
+
hash: string;
|
|
110
|
+
originHash: string;
|
|
111
|
+
}): Promise<void> {
|
|
112
|
+
logger.debug(TAG, ',call downloadPatchFromPpk');
|
|
113
|
+
return UpdateModuleImpl.downloadPatchFromPpk(this.context, options);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async downloadPatchFromPackage(options: {
|
|
117
|
+
updateUrl: string;
|
|
118
|
+
hash: string;
|
|
119
|
+
}): Promise<void> {
|
|
120
|
+
logger.debug(TAG, ',call downloadPatchFromPackage');
|
|
121
|
+
return UpdateModuleImpl.downloadPatchFromPackage(this.context, options);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async downloadFullUpdate(options: {
|
|
125
|
+
updateUrl: string;
|
|
126
|
+
hash: string;
|
|
127
|
+
}): Promise<void> {
|
|
128
|
+
logger.debug(TAG, ',call downloadFullUpdate');
|
|
129
|
+
return UpdateModuleImpl.downloadFullUpdate(this.context, options);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
addListener(_eventName: string): void {
|
|
133
|
+
logger.debug(TAG, ',call addListener');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
removeListeners(_count: number): void {
|
|
137
|
+
logger.debug(TAG, ',call removeListeners');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import resourceManager from '@ohos.resourceManager';
|
|
2
|
+
import fs, { ReadOptions } from '@ohos.file.fs';
|
|
3
|
+
|
|
4
|
+
const COPY_BUFFER_SIZE = 64 * 1024;
|
|
5
|
+
|
|
6
|
+
export const saveFileToSandbox = (
|
|
7
|
+
from: resourceManager.RawFileDescriptor,
|
|
8
|
+
toPath: string,
|
|
9
|
+
) => {
|
|
10
|
+
let to = fs.openSync(toPath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
|
|
11
|
+
|
|
12
|
+
const buffer = new ArrayBuffer(COPY_BUFFER_SIZE);
|
|
13
|
+
let currentOffset = from.offset;
|
|
14
|
+
let remaining = from.length;
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
while (remaining > 0) {
|
|
18
|
+
const readOption: ReadOptions = {
|
|
19
|
+
offset: currentOffset,
|
|
20
|
+
length: Math.min(COPY_BUFFER_SIZE, remaining),
|
|
21
|
+
};
|
|
22
|
+
const readLength = fs.readSync(from.fd, buffer, readOption);
|
|
23
|
+
if (readLength <= 0) {
|
|
24
|
+
throw new Error(`Unexpected EOF while copying resource to ${toPath}`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
fs.writeSync(to.fd, buffer, { length: readLength });
|
|
28
|
+
currentOffset += readLength;
|
|
29
|
+
remaining -= readLength;
|
|
30
|
+
}
|
|
31
|
+
} finally {
|
|
32
|
+
fs.close(to);
|
|
33
|
+
}
|
|
34
|
+
};
|