This repository was archived by the owner on Feb 2, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathandroid-device-hash-service.ts
101 lines (80 loc) · 3.47 KB
/
android-device-hash-service.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import * as path from "path";
import * as temp from "temp";
import { cache } from "../../decorators";
import { executeActionByChunks } from "../../helpers";
import { DEFAULT_CHUNK_SIZE } from "../../constants";
export class AndroidDeviceHashService implements Mobile.IAndroidDeviceHashService {
private static HASH_FILE_NAME = "hashes";
private static DEVICE_ROOT_PATH = "/data/local/tmp";
constructor(private adb: Mobile.IDeviceAndroidDebugBridge,
private appIdentifier: string,
private $fs: IFileSystem,
private $mobileHelper: Mobile.IMobileHelper) {
}
@cache()
public get hashFileDevicePath(): string {
return this.$mobileHelper.buildDevicePath(AndroidDeviceHashService.DEVICE_ROOT_PATH, this.appIdentifier, AndroidDeviceHashService.HASH_FILE_NAME);
}
public async doesShasumFileExistsOnDevice(): Promise<boolean> {
const lsResult = await this.adb.executeShellCommand(["ls", this.hashFileDevicePath]);
return !!(lsResult && lsResult.trim() === this.hashFileDevicePath);
}
public async getShasumsFromDevice(): Promise<IStringDictionary> {
const hashFileLocalPath = await this.downloadHashFileFromDevice();
if (this.$fs.exists(hashFileLocalPath)) {
return this.$fs.readJson(hashFileLocalPath);
}
return null;
}
public async uploadHashFileToDevice(data: IStringDictionary): Promise<void> {
this.$fs.writeJson(this.hashFileLocalPath, data);
await this.adb.executeCommand(["push", this.hashFileLocalPath, this.hashFileDevicePath]);
}
public async updateHashes(localToDevicePaths: Mobile.ILocalToDevicePathData[]): Promise<boolean> {
const oldShasums = await this.getShasumsFromDevice();
if (oldShasums) {
await this.generateHashesFromLocalToDevicePaths(localToDevicePaths, oldShasums);
await this.uploadHashFileToDevice(oldShasums);
return true;
}
return false;
}
public async generateHashesFromLocalToDevicePaths(localToDevicePaths: Mobile.ILocalToDevicePathData[], shasums: IStringDictionary): Promise<string[]> {
const devicePaths: string[] = [];
const action = async (localToDevicePathData: Mobile.ILocalToDevicePathData) => {
const localPath = localToDevicePathData.getLocalPath();
if (this.$fs.getFsStats(localPath).isFile()) {
// TODO: Use relative to project path for key
// This will speed up livesync on the same device for the same project on different PCs.
shasums[localPath] = await this.$fs.getFileShasum(localPath);
}
devicePaths.push(`"${localToDevicePathData.getDevicePath()}"`);
};
await executeActionByChunks<Mobile.ILocalToDevicePathData>(localToDevicePaths, DEFAULT_CHUNK_SIZE, action);
return devicePaths;
}
public async removeHashes(localToDevicePaths: Mobile.ILocalToDevicePathData[]): Promise<boolean> {
const oldShasums = await this.getShasumsFromDevice();
if (oldShasums) {
const fileToShasumDictionary = <IStringDictionary>(_.omit(oldShasums, localToDevicePaths.map(ldp => ldp.getLocalPath())));
await this.uploadHashFileToDevice(fileToShasumDictionary);
return true;
}
return false;
}
@cache()
private get hashFileLocalPath(): string {
return path.join(this.tempDir, AndroidDeviceHashService.HASH_FILE_NAME);
}
@cache()
private get tempDir(): string {
temp.track();
return temp.mkdirSync(`android-device-hash-service-${this.appIdentifier}`);
}
private async downloadHashFileFromDevice(): Promise<string> {
if (!this.$fs.exists(this.hashFileLocalPath)) {
await this.adb.executeCommand(["pull", this.hashFileDevicePath, this.tempDir]);
}
return this.hashFileLocalPath;
}
}