From 37573fbca602972389cc4eb20d5ce6d6de9c5578 Mon Sep 17 00:00:00 2001 From: lishutong Date: Thu, 1 Jul 2021 17:59:52 +0000 Subject: [PATCH 1/2] Update to new update_metadata.proto which support COW merge operation. Now update_metadata.js will be able to parse COW merge operations in the OTA packages. Please refer to change 1736935 for more details. No-Typo-Check: auto-generated artifacts Test: Mannual tested. Change-Id: Ie18125524b991173b0599704eca51004fd0c0243 --- tools/otagui/.eslintignore | 1 + .../otagui/src/services/update_metadata_pb.js | 113 +++++++++++++++++- 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 tools/otagui/.eslintignore diff --git a/tools/otagui/.eslintignore b/tools/otagui/.eslintignore new file mode 100644 index 000000000..1e2c54fad --- /dev/null +++ b/tools/otagui/.eslintignore @@ -0,0 +1 @@ +src/services/update_metadata_pb.js \ No newline at end of file diff --git a/tools/otagui/src/services/update_metadata_pb.js b/tools/otagui/src/services/update_metadata_pb.js index 578c9bc16..6c8351c38 100644 --- a/tools/otagui/src/services/update_metadata_pb.js +++ b/tools/otagui/src/services/update_metadata_pb.js @@ -1249,6 +1249,7 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { * @property {number|Long|null} [dstLength] InstallOperation dstLength * @property {Uint8Array|null} [dataSha256Hash] InstallOperation dataSha256Hash * @property {Uint8Array|null} [srcSha256Hash] InstallOperation srcSha256Hash + * @property {Object.|null} [xorMap] InstallOperation xorMap */ /** @@ -1262,6 +1263,7 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { function InstallOperation(properties) { this.srcExtents = []; this.dstExtents = []; + this.xorMap = {}; if (properties) for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -1340,6 +1342,14 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { */ InstallOperation.prototype.srcSha256Hash = $util.newBuffer([]); + /** + * InstallOperation xorMap. + * @member {Object.} xorMap + * @memberof chromeos_update_engine.InstallOperation + * @instance + */ + InstallOperation.prototype.xorMap = $util.emptyObject; + /** * Creates a new InstallOperation instance using the specified properties. * @function create @@ -1383,6 +1393,9 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { writer.uint32(/* id 8, wireType 2 =*/66).bytes(message.dataSha256Hash); if (message.srcSha256Hash != null && Object.hasOwnProperty.call(message, "srcSha256Hash")) writer.uint32(/* id 9, wireType 2 =*/74).bytes(message.srcSha256Hash); + if (message.xorMap != null && Object.hasOwnProperty.call(message, "xorMap")) + for (let keys = Object.keys(message.xorMap), i = 0; i < keys.length; ++i) + writer.uint32(/* id 10, wireType 2 =*/82).fork().uint32(/* id 1, wireType 0 =*/8).uint32(keys[i]).uint32(/* id 2, wireType 0 =*/16).uint32(message.xorMap[keys[i]]).ldelim(); return writer; }; @@ -1413,7 +1426,7 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { InstallOperation.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - let end = length === undefined ? reader.len : reader.pos + length, message = new $root.chromeos_update_engine.InstallOperation(); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.chromeos_update_engine.InstallOperation(), key, value; while (reader.pos < end) { let tag = reader.uint32(); switch (tag >>> 3) { @@ -1448,6 +1461,28 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { case 9: message.srcSha256Hash = reader.bytes(); break; + case 10: + if (message.xorMap === $util.emptyObject) + message.xorMap = {}; + let end2 = reader.uint32() + reader.pos; + key = 0; + value = 0; + while (reader.pos < end2) { + let tag2 = reader.uint32(); + switch (tag2 >>> 3) { + case 1: + key = reader.uint32(); + break; + case 2: + value = reader.uint32(); + break; + default: + reader.skipType(tag2 & 7); + break; + } + } + message.xorMap[key] = value; + break; default: reader.skipType(tag & 7); break; @@ -1537,6 +1572,17 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { if (message.srcSha256Hash != null && message.hasOwnProperty("srcSha256Hash")) if (!(message.srcSha256Hash && typeof message.srcSha256Hash.length === "number" || $util.isString(message.srcSha256Hash))) return "srcSha256Hash: buffer expected"; + if (message.xorMap != null && message.hasOwnProperty("xorMap")) { + if (!$util.isObject(message.xorMap)) + return "xorMap: object expected"; + let key = Object.keys(message.xorMap); + for (let i = 0; i < key.length; ++i) { + if (!$util.key32Re.test(key[i])) + return "xorMap: integer key{k:uint32} expected"; + if (!$util.isInteger(message.xorMap[key[i]])) + return "xorMap: integer{k:uint32} expected"; + } + } return null; }; @@ -1664,6 +1710,13 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { $util.base64.decode(object.srcSha256Hash, message.srcSha256Hash = $util.newBuffer($util.base64.length(object.srcSha256Hash)), 0); else if (object.srcSha256Hash.length) message.srcSha256Hash = object.srcSha256Hash; + if (object.xorMap) { + if (typeof object.xorMap !== "object") + throw TypeError(".chromeos_update_engine.InstallOperation.xorMap: object expected"); + message.xorMap = {}; + for (let keys = Object.keys(object.xorMap), i = 0; i < keys.length; ++i) + message.xorMap[keys[i]] = object.xorMap[keys[i]] >>> 0; + } return message; }; @@ -1684,6 +1737,8 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { object.srcExtents = []; object.dstExtents = []; } + if (options.objects || options.defaults) + object.xorMap = {}; if (options.defaults) { object.type = options.enums === String ? "REPLACE" : 0; if ($util.Long) { @@ -1757,6 +1812,12 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { object.dataSha256Hash = options.bytes === String ? $util.base64.encode(message.dataSha256Hash, 0, message.dataSha256Hash.length) : options.bytes === Array ? Array.prototype.slice.call(message.dataSha256Hash) : message.dataSha256Hash; if (message.srcSha256Hash != null && message.hasOwnProperty("srcSha256Hash")) object.srcSha256Hash = options.bytes === String ? $util.base64.encode(message.srcSha256Hash, 0, message.srcSha256Hash.length) : options.bytes === Array ? Array.prototype.slice.call(message.srcSha256Hash) : message.srcSha256Hash; + let keys2; + if (message.xorMap && (keys2 = Object.keys(message.xorMap)).length) { + object.xorMap = {}; + for (let j = 0; j < keys2.length; ++j) + object.xorMap[keys2[j]] = message.xorMap[keys2[j]]; + } return object; }; @@ -1815,6 +1876,7 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { * @property {chromeos_update_engine.CowMergeOperation.Type|null} [type] CowMergeOperation type * @property {chromeos_update_engine.IExtent|null} [srcExtent] CowMergeOperation srcExtent * @property {chromeos_update_engine.IExtent|null} [dstExtent] CowMergeOperation dstExtent + * @property {number|Long|null} [srcOffset] CowMergeOperation srcOffset */ /** @@ -1856,6 +1918,14 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { */ CowMergeOperation.prototype.dstExtent = null; + /** + * CowMergeOperation srcOffset. + * @member {number|Long} srcOffset + * @memberof chromeos_update_engine.CowMergeOperation + * @instance + */ + CowMergeOperation.prototype.srcOffset = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + /** * Creates a new CowMergeOperation instance using the specified properties. * @function create @@ -1886,6 +1956,8 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { $root.chromeos_update_engine.Extent.encode(message.srcExtent, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); if (message.dstExtent != null && Object.hasOwnProperty.call(message, "dstExtent")) $root.chromeos_update_engine.Extent.encode(message.dstExtent, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.srcOffset != null && Object.hasOwnProperty.call(message, "srcOffset")) + writer.uint32(/* id 4, wireType 0 =*/32).uint64(message.srcOffset); return writer; }; @@ -1929,6 +2001,9 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { case 3: message.dstExtent = $root.chromeos_update_engine.Extent.decode(reader, reader.uint32()); break; + case 4: + message.srcOffset = reader.uint64(); + break; default: reader.skipType(tag & 7); break; @@ -1969,6 +2044,8 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { default: return "type: enum value expected"; case 0: + case 1: + case 2: break; } if (message.srcExtent != null && message.hasOwnProperty("srcExtent")) { @@ -1981,6 +2058,9 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { if (error) return "dstExtent." + error; } + if (message.srcOffset != null && message.hasOwnProperty("srcOffset")) + if (!$util.isInteger(message.srcOffset) && !(message.srcOffset && $util.isInteger(message.srcOffset.low) && $util.isInteger(message.srcOffset.high))) + return "srcOffset: integer|Long expected"; return null; }; @@ -2001,6 +2081,14 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { case 0: message.type = 0; break; + case "COW_XOR": + case 1: + message.type = 1; + break; + case "COW_REPLACE": + case 2: + message.type = 2; + break; } if (object.srcExtent != null) { if (typeof object.srcExtent !== "object") @@ -2012,6 +2100,15 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { throw TypeError(".chromeos_update_engine.CowMergeOperation.dstExtent: object expected"); message.dstExtent = $root.chromeos_update_engine.Extent.fromObject(object.dstExtent); } + if (object.srcOffset != null) + if ($util.Long) + (message.srcOffset = $util.Long.fromValue(object.srcOffset)).unsigned = true; + else if (typeof object.srcOffset === "string") + message.srcOffset = parseInt(object.srcOffset, 10); + else if (typeof object.srcOffset === "number") + message.srcOffset = object.srcOffset; + else if (typeof object.srcOffset === "object") + message.srcOffset = new $util.LongBits(object.srcOffset.low >>> 0, object.srcOffset.high >>> 0).toNumber(true); return message; }; @@ -2032,6 +2129,11 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { object.type = options.enums === String ? "COW_COPY" : 0; object.srcExtent = null; object.dstExtent = null; + if ($util.Long) { + let long = new $util.Long(0, 0, true); + object.srcOffset = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.srcOffset = options.longs === String ? "0" : 0; } if (message.type != null && message.hasOwnProperty("type")) object.type = options.enums === String ? $root.chromeos_update_engine.CowMergeOperation.Type[message.type] : message.type; @@ -2039,6 +2141,11 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { object.srcExtent = $root.chromeos_update_engine.Extent.toObject(message.srcExtent, options); if (message.dstExtent != null && message.hasOwnProperty("dstExtent")) object.dstExtent = $root.chromeos_update_engine.Extent.toObject(message.dstExtent, options); + if (message.srcOffset != null && message.hasOwnProperty("srcOffset")) + if (typeof message.srcOffset === "number") + object.srcOffset = options.longs === String ? String(message.srcOffset) : message.srcOffset; + else + object.srcOffset = options.longs === String ? $util.Long.prototype.toString.call(message.srcOffset) : options.longs === Number ? new $util.LongBits(message.srcOffset.low >>> 0, message.srcOffset.high >>> 0).toNumber(true) : message.srcOffset; return object; }; @@ -2058,10 +2165,14 @@ export const chromeos_update_engine = $root.chromeos_update_engine = (() => { * @name chromeos_update_engine.CowMergeOperation.Type * @enum {number} * @property {number} COW_COPY=0 COW_COPY value + * @property {number} COW_XOR=1 COW_XOR value + * @property {number} COW_REPLACE=2 COW_REPLACE value */ CowMergeOperation.Type = (function() { const valuesById = {}, values = Object.create(valuesById); values[valuesById[0] = "COW_COPY"] = 0; + values[valuesById[1] = "COW_XOR"] = 1; + values[valuesById[2] = "COW_REPLACE"] = 2; return values; })(); From b7e6e67a8a2ecd5475b14d43cf34761acfa6a5d9 Mon Sep 17 00:00:00 2001 From: lishutong Date: Thu, 1 Jul 2021 19:28:37 +0000 Subject: [PATCH 2/2] Add support for analysing the COW merge operations in OTA packages. Now the OTA_analysis is able to do statistics over how many blocks are being operated by different types of COW merge operations. Also refactor part of payload.js. Test: Mannual tested. Change-Id: Icd24f2c0aa42f968438965378b05a7021bafb88c --- .../src/components/PayloadComposition.vue | 31 ++--- tools/otagui/src/services/echarts_data.js | 7 +- tools/otagui/src/services/payload.js | 18 ++- .../src/services/payload_composition.js | 108 +++++++++++++++--- 4 files changed, 121 insertions(+), 43 deletions(-) diff --git a/tools/otagui/src/components/PayloadComposition.vue b/tools/otagui/src/components/PayloadComposition.vue index 47b67baf5..fe8b16a31 100644 --- a/tools/otagui/src/components/PayloadComposition.vue +++ b/tools/otagui/src/components/PayloadComposition.vue @@ -9,6 +9,9 @@ +
@@ -17,11 +20,7 @@