Skip to content

Commit 210e6bb

Browse files
committed
add bundlehash
1 parent 4989803 commit 210e6bb

30 files changed

Lines changed: 360 additions & 12 deletions

android/jni/Android.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ LOCAL_SRC_FILES := \
2424
../../cpp/patch_core/archive_patch_core.cpp \
2525
../../cpp/patch_core/patch_core.cpp \
2626
../../cpp/patch_core/patch_core_android.cpp \
27+
../../cpp/patch_core/sha256_util.cpp \
2728
../../cpp/patch_core/state_core.cpp \
2829
../../cpp/patch_core/update_core_android.cpp \
30+
lzma/C/Sha256.c \
2931
$(Hdp_Files)
3032

3133
include $(BUILD_SHARED_LIBRARY)

android/jni/Application.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ APP_CFLAGS += -ffunction-sections -fdata-sections
55
APP_CFLAGS += -Oz -fno-unwind-tables -fno-asynchronous-unwind-tables
66
APP_CPPFLAGS += -std=c++17 -Oz -fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables
77
APP_LDFLAGS += -Wl,--gc-sections -Wl,--exclude-libs,ALL
8+
APP_LDFLAGS += -Wl,--icf=all
89
APP_BUILD_SCRIPT := Android.mk
910
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
1011
APP_STL := c++_static
-193 KB
Binary file not shown.
-110 KB
Binary file not shown.

android/lib/x86/librnupdate.so

-188 KB
Binary file not shown.

android/lib/x86_64/librnupdate.so

-190 KB
Binary file not shown.

android/src/main/java/cn/reactnative/modules/update/UpdateContext.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44
import android.content.SharedPreferences;
55
import android.content.pm.PackageInfo;
66
import android.content.pm.PackageManager;
7+
import android.content.res.AssetManager;
78
import android.os.Build;
89
import android.os.Environment;
910
import android.util.Log;
1011
import com.facebook.react.ReactInstanceManager;
12+
import java.io.ByteArrayOutputStream;
1113
import java.io.File;
14+
import java.io.IOException;
15+
import java.io.InputStream;
1216
import java.util.concurrent.Executor;
1317
import java.util.concurrent.Executors;
1418

@@ -35,6 +39,9 @@ public class UpdateContext {
3539
private static final int STATE_OP_CLEAR_ROLLBACK_MARK = 5;
3640
private static final int STATE_OP_RESOLVE_LAUNCH = 6;
3741
private static final String KEY_FIRST_LOAD_MARKED = "firstLoadMarked";
42+
private static final String KEY_BUNDLE_HASH_CACHE_IDENTITY = "bundleHashCacheIdentity";
43+
private static final String KEY_BUNDLE_HASH_CACHE_VALUE = "bundleHashCacheValue";
44+
private static final String EMBEDDED_BUNDLE_ASSET_NAME = "index.android.bundle";
3845

3946
// Singleton instance
4047
private static UpdateContext sInstance;
@@ -55,6 +62,8 @@ private static native StateCoreResult runStateCore(
5562
boolean flagB
5663
);
5764

65+
private static native String hashBytes(byte[] data);
66+
5867
public UpdateContext(Context context) {
5968
this.context = context.getApplicationContext();
6069
this.executor = Executors.newSingleThreadExecutor();
@@ -110,6 +119,47 @@ public boolean getIsUsingBundleUrl() {
110119
return isUsingBundleUrl;
111120
}
112121

122+
public String getBundleHash() {
123+
String identity = "embedded:" + getPackageVersion() + ":" + getBuildTime();
124+
String cachedIdentity = sp.getString(KEY_BUNDLE_HASH_CACHE_IDENTITY, null);
125+
String cachedValue = sp.getString(KEY_BUNDLE_HASH_CACHE_VALUE, null);
126+
if (identity.equals(cachedIdentity) && cachedValue != null && !cachedValue.isEmpty()) {
127+
return cachedValue;
128+
}
129+
130+
String bundleHash = hashAsset(EMBEDDED_BUNDLE_ASSET_NAME);
131+
if (bundleHash == null) {
132+
return "";
133+
}
134+
135+
SharedPreferences.Editor editor = sp.edit();
136+
editor.putString(KEY_BUNDLE_HASH_CACHE_IDENTITY, identity);
137+
editor.putString(KEY_BUNDLE_HASH_CACHE_VALUE, bundleHash);
138+
persistEditor(editor, "cache bundle hash");
139+
return bundleHash;
140+
}
141+
142+
private String hashAsset(String assetName) {
143+
try (InputStream stream = context.getAssets().open(assetName, AssetManager.ACCESS_STREAMING)) {
144+
return hashInputStream(stream);
145+
} catch (IOException e) {
146+
if (DEBUG) {
147+
Log.w(TAG, "Failed to hash asset bundle " + assetName, e);
148+
}
149+
return null;
150+
}
151+
}
152+
153+
private String hashInputStream(InputStream stream) throws IOException {
154+
ByteArrayOutputStream output = new ByteArrayOutputStream();
155+
byte[] buffer = new byte[8192];
156+
int read;
157+
while ((read = stream.read(buffer)) != -1) {
158+
output.write(buffer, 0, read);
159+
}
160+
return hashBytes(output.toByteArray());
161+
}
162+
113163
private void enqueue(DownloadTaskParams params) {
114164
executor.execute(new DownloadTask(context, params));
115165
}

android/src/main/java/cn/reactnative/modules/update/UpdateModuleSupport.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ static Map<String, Object> getConstants(UpdateContext updateContext) {
2323
constants.put("currentVersion", currentVersion);
2424
constants.put("currentVersionInfo", updateContext.getKv("hash_" + currentVersion));
2525
constants.put("buildTime", updateContext.getBuildTime());
26+
constants.put("bundleHash", updateContext.getBundleHash());
2627
constants.put("isUsingBundleUrl", updateContext.getIsUsingBundleUrl());
2728

2829
boolean isFirstTime = updateContext.consumeFirstLoadMarker();

cpp/patch_core/patch_core.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include <unistd.h>
1010

1111
#include <set>
12-
#include <sstream>
1312
#include <vector>
1413

1514
extern "C" {
@@ -31,12 +30,19 @@ class HdiffBundlePatcher final : public BundlePatcher {
3130
};
3231

3332
Status MakeErrnoStatus(const std::string& message, int err = errno) {
34-
std::ostringstream stream;
35-
stream << message;
36-
if (err != 0) {
37-
stream << ": " << std::strerror(err);
33+
if (err == 0) {
34+
return Status::Error(message);
3835
}
39-
return Status::Error(stream.str());
36+
return Status::Error(message + ": " + std::strerror(err));
37+
}
38+
39+
std::string IntToString(int value) {
40+
char buffer[32] = {0};
41+
const int written = std::snprintf(buffer, sizeof(buffer), "%d", value);
42+
if (written <= 0) {
43+
return "0";
44+
}
45+
return std::string(buffer, static_cast<size_t>(written));
4046
}
4147

4248
bool EndsWithSlash(const std::string& path) {
@@ -522,9 +528,8 @@ Status HdiffBundlePatcher::Apply(
522528
destination_bundle_path.c_str(),
523529
bundle_patch_path.c_str());
524530
if (result != 0) {
525-
std::ostringstream stream;
526-
stream << "Failed to apply bundle patch, hpatch error " << result;
527-
return Status::Error(stream.str());
531+
return Status::Error(
532+
"Failed to apply bundle patch, hpatch error " + IntToString(result));
528533
}
529534
return Status::Ok();
530535
}

cpp/patch_core/sha256_util.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include "sha256_util.h"
2+
3+
namespace pushy {
4+
namespace crypto {
5+
6+
namespace {
7+
8+
std::string ToHexString(const Byte* digest, size_t size) {
9+
static constexpr char kHexDigits[] = "0123456789abcdef";
10+
std::string hex(size * 2, '\0');
11+
for (size_t index = 0; index < size; ++index) {
12+
const unsigned char byte = digest[index];
13+
hex[index * 2] = kHexDigits[byte >> 4];
14+
hex[index * 2 + 1] = kHexDigits[byte & 0x0f];
15+
}
16+
return hex;
17+
}
18+
19+
} // namespace
20+
21+
Sha256Hasher::Sha256Hasher() {
22+
Sha256_Init(&context_);
23+
}
24+
25+
void Sha256Hasher::Update(const void* data, size_t size) {
26+
if (finalized_ || data == nullptr || size == 0) {
27+
return;
28+
}
29+
Sha256_Update(
30+
&context_,
31+
static_cast<const Byte*>(data),
32+
size);
33+
}
34+
35+
std::string Sha256Hasher::FinalHex() {
36+
Byte digest[SHA256_DIGEST_SIZE] = {0};
37+
Sha256_Final(&context_, digest);
38+
finalized_ = true;
39+
return ToHexString(digest, SHA256_DIGEST_SIZE);
40+
}
41+
42+
std::string Sha256Hex(const void* data, size_t size) {
43+
Sha256Hasher hasher;
44+
hasher.Update(data, size);
45+
return hasher.FinalHex();
46+
}
47+
48+
} // namespace crypto
49+
} // namespace pushy

0 commit comments

Comments
 (0)