@onekeyfe/react-native-jpush 0.0.0-stage → 6.7.0-23
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/LICENSE +21 -0
- package/README.md +56 -2
- package/ReactNativeJpush.podspec +66 -0
- package/android/CMakeLists.txt +24 -0
- package/android/build.gradle +144 -0
- package/android/fcm/build.gradle +36 -0
- package/android/fcm/consumer-rules.pro +2 -0
- package/android/fcm/src/main/AndroidManifest.xml +25 -0
- package/android/fcm/src/main/java/com/onekey/jpush/fcm/FcmInitProvider.java +25 -0
- package/android/fcm/src/main/java/com/onekey/jpush/fcm/FcmMessagingService.java +84 -0
- package/android/fcm/src/main/java/com/onekey/jpush/fcm/FcmPushManager.java +69 -0
- package/android/fcm/src/test/java/com/onekey/jpush/fcm/FcmAdapterTest.java +684 -0
- package/android/fcm/src/test/java/com/onekey/jpush/fcm/FcmManifestTest.java +54 -0
- package/android/gradle.properties +4 -0
- package/android/src/main/AndroidManifest.xml +143 -0
- package/android/src/main/cpp/cpp-adapter.cpp +6 -0
- package/android/src/main/java/cn/android/service/JTransitActivity.java +19 -0
- package/android/src/main/java/cn/jiguang/android/BuildConfig.java +10 -0
- package/android/src/main/java/cn/jiguang/android/IDataShare.java +190 -0
- package/android/src/main/java/cn/jiguang/api/BaseLogger.java +82 -0
- package/android/src/main/java/cn/jiguang/api/JAction.java +22 -0
- package/android/src/main/java/cn/jiguang/api/JActionExtra.java +21 -0
- package/android/src/main/java/cn/jiguang/api/JAnalyticsAction.java +11 -0
- package/android/src/main/java/cn/jiguang/api/JCoreInterface.java +228 -0
- package/android/src/main/java/cn/jiguang/api/JCoreManager.java +156 -0
- package/android/src/main/java/cn/jiguang/api/JDispatchAction.java +66 -0
- package/android/src/main/java/cn/jiguang/api/MultiSpHelper.java +114 -0
- package/android/src/main/java/cn/jiguang/api/ReportCallBack.java +9 -0
- package/android/src/main/java/cn/jiguang/api/SdkType.java +13 -0
- package/android/src/main/java/cn/jiguang/api/utils/JCollectionAuth.java +28 -0
- package/android/src/main/java/cn/jiguang/core/JCoreCrypto.java +545 -0
- package/android/src/main/java/cn/jiguang/core/JCoreStorage.java +737 -0
- package/android/src/main/java/cn/jiguang/core/JCoreTcpEngine.java +1395 -0
- package/android/src/main/java/cn/jiguang/core/JCoreWireCodec.java +1716 -0
- package/android/src/main/java/cn/jiguang/internal/ActionManager.java +63 -0
- package/android/src/main/java/cn/jiguang/internal/JConstants.java +61 -0
- package/android/src/main/java/cn/jiguang/internal/JCoreHelperAction.java +12 -0
- package/android/src/main/java/cn/jiguang/internal/JCoreInternalHelper.java +102 -0
- package/android/src/main/java/cn/jiguang/net/DefaultHostVerifier.java +40 -0
- package/android/src/main/java/cn/jiguang/net/HttpRequest.java +78 -0
- package/android/src/main/java/cn/jiguang/net/HttpResponse.java +48 -0
- package/android/src/main/java/cn/jiguang/net/HttpUtils.java +106 -0
- package/android/src/main/java/cn/jiguang/plugins/core/JCoreModule.java +91 -0
- package/android/src/main/java/cn/jiguang/plugins/core/JCorePackage.java +27 -0
- package/android/src/main/java/cn/jiguang/plugins/push/JPushModule.java +773 -0
- package/android/src/main/java/cn/jiguang/plugins/push/JPushPackage.java +25 -0
- package/android/src/main/java/cn/jiguang/plugins/push/common/JConstants.java +88 -0
- package/android/src/main/java/cn/jiguang/plugins/push/common/JLogger.java +122 -0
- package/android/src/main/java/cn/jiguang/plugins/push/helper/JPushHelper.java +710 -0
- package/android/src/main/java/cn/jiguang/plugins/push/receiver/JPushBroadcastReceiver.java +37 -0
- package/android/src/main/java/cn/jiguang/plugins/push/receiver/JPushModuleReceiver.java +264 -0
- package/android/src/main/java/cn/jiguang/plugins/service/JCoreModuleService.java +7 -0
- package/android/src/main/java/cn/jpush/android/api/BasicPushNotificationBuilder.java +83 -0
- package/android/src/main/java/cn/jpush/android/api/CallBackParams.java +50 -0
- package/android/src/main/java/cn/jpush/android/api/CmdMessage.java +33 -0
- package/android/src/main/java/cn/jpush/android/api/CustomMessage.java +28 -0
- package/android/src/main/java/cn/jpush/android/api/CustomPushNotificationBuilder.java +81 -0
- package/android/src/main/java/cn/jpush/android/api/DefaultPushNotificationBuilder.java +90 -0
- package/android/src/main/java/cn/jpush/android/api/InAppSlotParams.java +65 -0
- package/android/src/main/java/cn/jpush/android/api/InstrumentedActivity.java +17 -0
- package/android/src/main/java/cn/jpush/android/api/InstrumentedListActivity.java +17 -0
- package/android/src/main/java/cn/jpush/android/api/JPushInterface.java +490 -0
- package/android/src/main/java/cn/jpush/android/api/JPushMessage.java +121 -0
- package/android/src/main/java/cn/jpush/android/api/JThirdPlatFormInterface.java +247 -0
- package/android/src/main/java/cn/jpush/android/api/MultiActionsNotificationBuilder.java +72 -0
- package/android/src/main/java/cn/jpush/android/api/NotificationCustomButton.java +50 -0
- package/android/src/main/java/cn/jpush/android/api/NotificationMessage.java +67 -0
- package/android/src/main/java/cn/jpush/android/api/PushNotificationBuilder.java +13 -0
- package/android/src/main/java/cn/jpush/android/api/TagAliasCallback.java +8 -0
- package/android/src/main/java/cn/jpush/android/data/JPushCollectControl.java +96 -0
- package/android/src/main/java/cn/jpush/android/data/JPushConfig.java +79 -0
- package/android/src/main/java/cn/jpush/android/data/JPushConfigEx.java +41 -0
- package/android/src/main/java/cn/jpush/android/data/JPushLocalNotification.java +155 -0
- package/android/src/main/java/cn/jpush/android/helper/JCoreHelper.java +70 -0
- package/android/src/main/java/cn/jpush/android/helper/Logger.java +82 -0
- package/android/src/main/java/cn/jpush/android/local/ActionHelper.java +1293 -0
- package/android/src/main/java/cn/jpush/android/local/ActivityLifeCallBack.java +47 -0
- package/android/src/main/java/cn/jpush/android/local/JPushAction.java +67 -0
- package/android/src/main/java/cn/jpush/android/local/JPushConstants.java +34 -0
- package/android/src/main/java/cn/jpush/android/local/JPushResponse.java +26 -0
- package/android/src/main/java/cn/jpush/android/local/ProxyActivityAction.java +34 -0
- package/android/src/main/java/cn/jpush/android/service/AlarmReceiver.java +15 -0
- package/android/src/main/java/cn/jpush/android/service/BActivity.java +19 -0
- package/android/src/main/java/cn/jpush/android/service/DActivity.java +19 -0
- package/android/src/main/java/cn/jpush/android/service/DaemonService.java +17 -0
- package/android/src/main/java/cn/jpush/android/service/DataProvider.java +136 -0
- package/android/src/main/java/cn/jpush/android/service/DataShare.java +129 -0
- package/android/src/main/java/cn/jpush/android/service/DownloadProvider.java +139 -0
- package/android/src/main/java/cn/jpush/android/service/InitProvider.java +48 -0
- package/android/src/main/java/cn/jpush/android/service/JCommonService.java +79 -0
- package/android/src/main/java/cn/jpush/android/service/JNotifyActivity.java +28 -0
- package/android/src/main/java/cn/jpush/android/service/JPushMessageReceiver.java +94 -0
- package/android/src/main/java/cn/jpush/android/service/PushReceiver.java +26 -0
- package/android/src/main/java/cn/jpush/android/service/PushService.java +28 -0
- package/android/src/main/java/cn/jpush/android/service/SchedulerReceiver.java +17 -0
- package/android/src/main/java/cn/jpush/android/service/TagAliasReceiver.java +11 -0
- package/android/src/main/java/cn/jpush/android/service/WakedResultReceiver.java +24 -0
- package/android/src/main/java/cn/jpush/android/ui/FullScreenView.java +11 -0
- package/android/src/main/java/cn/jpush/android/ui/PopWinActivity.java +16 -0
- package/android/src/main/java/cn/jpush/android/ui/PushActivity.java +27 -0
- package/android/src/main/java/cn/jpush/android/ui/RoundedImageView.java +63 -0
- package/android/src/main/java/cn/jpush/android/ui/ShadowViewCard.java +56 -0
- package/android/src/main/java/cn/jpush/android/ups/ICallbackResult.java +5 -0
- package/android/src/main/java/cn/jpush/android/ups/JPushUPSManager.java +37 -0
- package/android/src/main/java/cn/jpush/android/ups/TokenResult.java +47 -0
- package/android/src/main/java/cn/jpush/android/ups/UPSRegisterCallBack.java +4 -0
- package/android/src/main/java/cn/jpush/android/ups/UPSTurnCallBack.java +4 -0
- package/android/src/main/java/cn/jpush/android/ups/UPSUnRegisterCallBack.java +4 -0
- package/android/src/main/java/com/margelo/nitro/reactnativejpush/ReactNativeJpush.kt +455 -0
- package/android/src/main/java/com/margelo/nitro/reactnativejpush/ReactNativeJpushPackage.kt +50 -0
- package/android/src/main/res/values/jpush_string.xml +7 -0
- package/android/src/main/res/values/jpush_style.xml +22 -0
- package/android/src/test/java/com/margelo/nitro/reactnativejpush/JPushCloudHandshakeTest.java +110 -0
- package/android/src/test/java/com/margelo/nitro/reactnativejpush/JPushHandshakeFailureTest.java +73 -0
- package/android/src/test/java/com/margelo/nitro/reactnativejpush/ReactNativeJpushProtocolTest.java +908 -0
- package/ios/ReactNativeJpush.swift +522 -0
- package/ios/bridge/RCTJCoreModule.h +5 -0
- package/ios/bridge/RCTJCoreModule.m +31 -0
- package/ios/bridge/RCTJPushEventQueue.h +14 -0
- package/ios/bridge/RCTJPushEventQueue.m +23 -0
- package/ios/bridge/RCTJPushModule.h +37 -0
- package/ios/bridge/RCTJPushModule.m +1165 -0
- package/ios/include/JCOREService.h +3 -0
- package/ios/include/JGCOREAPI.h +14 -0
- package/ios/include/JGInforCollectionAuth.h +17 -0
- package/ios/include/JGInforCollectionAuthItems.h +2 -0
- package/ios/include/JGPushNotificationTrigger.h +2 -0
- package/ios/include/JPUSHService.h +359 -0
- package/ios/jcore/JCOREConfiguration.h +141 -0
- package/ios/jcore/JCOREConfiguration.m +703 -0
- package/ios/jcore/JCORECrypto.h +73 -0
- package/ios/jcore/JCORECrypto.m +649 -0
- package/ios/jcore/JCORESisResolver.h +56 -0
- package/ios/jcore/JCORESisResolver.m +525 -0
- package/ios/jcore/JCORETcpSession.h +42 -0
- package/ios/jcore/JCORETcpSession.m +956 -0
- package/ios/jcore/JCOREWireProtocol.h +274 -0
- package/ios/jcore/JCOREWireProtocol.m +1453 -0
- package/ios/jpush/JPUSHModels.m +214 -0
- package/ios/jpush/JPUSHNotificationManager.h +34 -0
- package/ios/jpush/JPUSHNotificationManager.m +360 -0
- package/ios/jpush/JPUSHService.m +794 -0
- package/ios/tests/ReactNativeJpushTests.m +148 -0
- package/lib/module/ReactNativeJpush.nitro.js +4 -0
- package/lib/module/ReactNativeJpush.nitro.js.map +1 -0
- package/lib/module/index.js +801 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/ReactNativeJpush.nitro.d.ts +60 -0
- package/lib/typescript/src/ReactNativeJpush.nitro.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +235 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/nitro.json +23 -0
- package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +75 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__string_std__string.hpp +76 -0
- package/nitrogen/generated/android/c++/JHybridReactNativeJpushSpec.cpp +310 -0
- package/nitrogen/generated/android/c++/JHybridReactNativeJpushSpec.hpp +115 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativejpush/Func_void_bool.kt +78 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativejpush/Func_void_std__string_std__string.kt +78 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativejpush/HybridReactNativeJpushSpec.kt +274 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativejpush/reactnativejpushOnLoad.kt +35 -0
- package/nitrogen/generated/android/reactnativejpush+autolinking.cmake +81 -0
- package/nitrogen/generated/android/reactnativejpush+autolinking.gradle +27 -0
- package/nitrogen/generated/android/reactnativejpushOnLoad.cpp +58 -0
- package/nitrogen/generated/android/reactnativejpushOnLoad.hpp +34 -0
- package/nitrogen/generated/ios/ReactNativeJpush+autolinking.rb +62 -0
- package/nitrogen/generated/ios/ReactNativeJpush-Swift-Cxx-Bridge.cpp +49 -0
- package/nitrogen/generated/ios/ReactNativeJpush-Swift-Cxx-Bridge.hpp +147 -0
- package/nitrogen/generated/ios/ReactNativeJpush-Swift-Cxx-Umbrella.hpp +46 -0
- package/nitrogen/generated/ios/ReactNativeJpushAutolinking.mm +33 -0
- package/nitrogen/generated/ios/ReactNativeJpushAutolinking.swift +26 -0
- package/nitrogen/generated/ios/c++/HybridReactNativeJpushSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridReactNativeJpushSpecSwift.hpp +402 -0
- package/nitrogen/generated/ios/swift/Func_void_bool.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string_std__string.swift +46 -0
- package/nitrogen/generated/ios/swift/HybridReactNativeJpushSpec.swift +107 -0
- package/nitrogen/generated/ios/swift/HybridReactNativeJpushSpec_cxx.swift +723 -0
- package/nitrogen/generated/shared/c++/HybridReactNativeJpushSpec.cpp +73 -0
- package/nitrogen/generated/shared/c++/HybridReactNativeJpushSpec.hpp +116 -0
- package/package.json +174 -4
- package/src/ReactNativeJpush.nitro.ts +93 -0
- package/src/index.tsx +1090 -0
package/android/src/test/java/com/margelo/nitro/reactnativejpush/ReactNativeJpushProtocolTest.java
ADDED
|
@@ -0,0 +1,908 @@
|
|
|
1
|
+
package com.margelo.nitro.reactnativejpush;
|
|
2
|
+
|
|
3
|
+
import static org.junit.Assert.assertArrayEquals;
|
|
4
|
+
import static org.junit.Assert.assertEquals;
|
|
5
|
+
import static org.junit.Assert.assertNotNull;
|
|
6
|
+
import static org.junit.Assert.assertTrue;
|
|
7
|
+
|
|
8
|
+
import cn.jiguang.api.JCoreInterface;
|
|
9
|
+
import cn.jiguang.api.JCoreManager;
|
|
10
|
+
import cn.jiguang.core.JCoreCrypto;
|
|
11
|
+
import cn.jiguang.core.JCoreStorage;
|
|
12
|
+
import cn.jiguang.core.JCoreTcpEngine;
|
|
13
|
+
import cn.jiguang.core.JCoreWireCodec;
|
|
14
|
+
import cn.jiguang.plugins.push.JPushModule;
|
|
15
|
+
import cn.jiguang.plugins.push.common.JLogger;
|
|
16
|
+
import cn.jiguang.plugins.push.helper.JPushHelper;
|
|
17
|
+
import cn.jiguang.plugins.push.receiver.JPushModuleReceiver;
|
|
18
|
+
import cn.jpush.android.api.CustomMessage;
|
|
19
|
+
import cn.jpush.android.api.JPushInterface;
|
|
20
|
+
import cn.jpush.android.api.JPushMessage;
|
|
21
|
+
import cn.jpush.android.api.NotificationMessage;
|
|
22
|
+
import cn.jpush.android.data.JPushLocalNotification;
|
|
23
|
+
import cn.jpush.android.local.ActionHelper;
|
|
24
|
+
import cn.jpush.android.ups.JPushUPSManager;
|
|
25
|
+
import java.io.File;
|
|
26
|
+
import java.io.InputStream;
|
|
27
|
+
import java.io.OutputStream;
|
|
28
|
+
import java.net.DatagramPacket;
|
|
29
|
+
import java.net.DatagramSocket;
|
|
30
|
+
import java.net.InetAddress;
|
|
31
|
+
import java.net.InetSocketAddress;
|
|
32
|
+
import java.net.ServerSocket;
|
|
33
|
+
import java.net.Socket;
|
|
34
|
+
import java.nio.charset.StandardCharsets;
|
|
35
|
+
import java.nio.file.Files;
|
|
36
|
+
import java.util.Arrays;
|
|
37
|
+
import java.util.Collections;
|
|
38
|
+
import java.util.LinkedHashMap;
|
|
39
|
+
import java.util.List;
|
|
40
|
+
import java.util.Map;
|
|
41
|
+
import java.util.Set;
|
|
42
|
+
import java.util.concurrent.CountDownLatch;
|
|
43
|
+
import java.util.concurrent.TimeUnit;
|
|
44
|
+
import java.util.concurrent.atomic.AtomicInteger;
|
|
45
|
+
import org.junit.Test;
|
|
46
|
+
|
|
47
|
+
public class ReactNativeJpushProtocolTest {
|
|
48
|
+
/**
|
|
49
|
+
* Non-production demo test AppKey used solely for automated native unit and protocol tests.
|
|
50
|
+
* Never used in production environments.
|
|
51
|
+
*/
|
|
52
|
+
public static final String DEMO_TEST_APP_KEY = "1f2027d3cfb1b51dac664c42";
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Non-production sandbox package name bound to DEMO_TEST_APP_KEY for automated Android tests.
|
|
56
|
+
* Intentionally avoids 'onekey' and 'jpush' identifiers to prevent production confusion or vendor filtering.
|
|
57
|
+
*/
|
|
58
|
+
public static final String DEMO_TEST_PACKAGE_NAME = "com.devstudio.msgbench";
|
|
59
|
+
|
|
60
|
+
@Test
|
|
61
|
+
public void testCryptoPrimitivesAndSeedDerivation() throws Exception {
|
|
62
|
+
long seed = 123456789L;
|
|
63
|
+
String keyA = JCoreCrypto.generateSeedKey(seed);
|
|
64
|
+
String keyB = JCoreCrypto.generateSeedKey(seed);
|
|
65
|
+
assertEquals(32L, (long) keyA.length());
|
|
66
|
+
assertEquals(keyA, keyB);
|
|
67
|
+
|
|
68
|
+
byte[] plain = "OneKey JPush Clean SDK Crypto Payload 2026".getBytes(StandardCharsets.UTF_8);
|
|
69
|
+
byte[] aesEnc = JCoreCrypto.aes256CbcSeedEncrypt(plain, seed);
|
|
70
|
+
byte[] aesDec = JCoreCrypto.aes256CbcSeedDecrypt(aesEnc, seed);
|
|
71
|
+
assertArrayEquals(plain, aesDec);
|
|
72
|
+
|
|
73
|
+
byte[] sm4Key = JCoreCrypto.hexDecode("0123456789abcdeffedcba9876543210");
|
|
74
|
+
byte[] sm4Iv = new byte[16];
|
|
75
|
+
byte[] sm4Enc = JCoreCrypto.sm4CbcEncrypt(plain, sm4Key, sm4Iv);
|
|
76
|
+
byte[] sm4Dec = JCoreCrypto.sm4CbcDecrypt(sm4Enc, sm4Key, sm4Iv);
|
|
77
|
+
assertArrayEquals(plain, sm4Dec);
|
|
78
|
+
|
|
79
|
+
byte[] gz = JCoreCrypto.gzipCompress(plain);
|
|
80
|
+
byte[] ungz = JCoreCrypto.gzipDecompress(gz);
|
|
81
|
+
assertArrayEquals(plain, ungz);
|
|
82
|
+
|
|
83
|
+
String b64 = JCoreCrypto.base64Encode(plain);
|
|
84
|
+
byte[] b64Decoded = JCoreCrypto.base64Decode(b64);
|
|
85
|
+
assertArrayEquals(plain, b64Decoded);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@Test
|
|
89
|
+
public void testUdpSis10BytePacketWithDemoTestAppKey() {
|
|
90
|
+
List<String> failedIps = Collections.singletonList("198.51.100.1:7000");
|
|
91
|
+
String sisReqJson = JCoreWireCodec.buildSisRequestJson(
|
|
92
|
+
1,
|
|
93
|
+
DEMO_TEST_APP_KEY,
|
|
94
|
+
900100200L,
|
|
95
|
+
"46000",
|
|
96
|
+
failedIps,
|
|
97
|
+
1
|
|
98
|
+
);
|
|
99
|
+
assertTrue(sisReqJson.contains(DEMO_TEST_APP_KEY));
|
|
100
|
+
assertTrue(sisReqJson.contains("5.1.1"));
|
|
101
|
+
|
|
102
|
+
byte[] udpPacket = JCoreWireCodec.encodeUdpSisPacket(
|
|
103
|
+
sisReqJson,
|
|
104
|
+
0x00123456
|
|
105
|
+
);
|
|
106
|
+
assertTrue(udpPacket.length > 10);
|
|
107
|
+
int hdrLen = ((udpPacket[0] & 0xFF) << 8) | (udpPacket[1] & 0xFF);
|
|
108
|
+
assertEquals((long) udpPacket.length, (long) hdrLen);
|
|
109
|
+
assertEquals((long) 'U', (long) ((char) udpPacket[2]));
|
|
110
|
+
assertEquals((long) 'G', (long) ((char) udpPacket[3]));
|
|
111
|
+
|
|
112
|
+
String decodedJson = JCoreWireCodec.decodeUdpSisPacket(udpPacket);
|
|
113
|
+
assertEquals(sisReqJson, decodedJson);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@Test
|
|
117
|
+
public void testAsymmetric24ByteClientAnd20ByteServerFramesWithDemoTestAppKey() {
|
|
118
|
+
byte[] regBody = JCoreWireCodec.buildRegisterPayload(
|
|
119
|
+
DEMO_TEST_APP_KEY,
|
|
120
|
+
"developer-default",
|
|
121
|
+
DEMO_TEST_PACKAGE_NAME,
|
|
122
|
+
"dev_001"
|
|
123
|
+
);
|
|
124
|
+
int registerSeed = 0x13572468;
|
|
125
|
+
byte[] clientRegFrame = JCoreWireCodec.encodeClientFrame(
|
|
126
|
+
JCoreWireCodec.CMD_REGISTER,
|
|
127
|
+
JCoreWireCodec.VER_REGISTER,
|
|
128
|
+
JCoreWireCodec.ALG_AES_CBC,
|
|
129
|
+
0,
|
|
130
|
+
1L,
|
|
131
|
+
registerSeed,
|
|
132
|
+
0L,
|
|
133
|
+
regBody
|
|
134
|
+
);
|
|
135
|
+
assertTrue(clientRegFrame.length >= 24 && ((clientRegFrame.length - 24) % 16 == 0));
|
|
136
|
+
|
|
137
|
+
JCoreWireCodec.DecodedFrame decodedReg = JCoreWireCodec.decodeClientFrame(clientRegFrame, 0L);
|
|
138
|
+
assertNotNull(decodedReg);
|
|
139
|
+
assertEquals((long) JCoreWireCodec.CMD_REGISTER, (long) decodedReg.command);
|
|
140
|
+
assertEquals((long) JCoreWireCodec.VER_REGISTER, (long) decodedReg.version);
|
|
141
|
+
assertEquals((long) registerSeed, (long) decodedReg.sessionId);
|
|
142
|
+
|
|
143
|
+
JCoreWireCodec.RegisterRequest parsedReg = JCoreWireCodec.parseRegisterRequest(decodedReg.body);
|
|
144
|
+
assertNotNull(parsedReg);
|
|
145
|
+
assertEquals(DEMO_TEST_APP_KEY, parsedReg.appKey);
|
|
146
|
+
assertEquals(DEMO_TEST_PACKAGE_NAME, parsedReg.packageName);
|
|
147
|
+
|
|
148
|
+
long assignedUid = 900100200L;
|
|
149
|
+
byte[] serverRegBody = JCoreWireCodec.buildRegisterResponsePayload(
|
|
150
|
+
assignedUid,
|
|
151
|
+
"pwd_demo_2026",
|
|
152
|
+
"1a0018970a900100200",
|
|
153
|
+
"dev_001"
|
|
154
|
+
);
|
|
155
|
+
byte[] serverRegFrame = JCoreWireCodec.encodeResponseFrame(
|
|
156
|
+
JCoreWireCodec.CMD_REGISTER,
|
|
157
|
+
JCoreWireCodec.VER_REGISTER,
|
|
158
|
+
JCoreWireCodec.ALG_AES_CBC,
|
|
159
|
+
0,
|
|
160
|
+
1L,
|
|
161
|
+
registerSeed,
|
|
162
|
+
assignedUid,
|
|
163
|
+
0,
|
|
164
|
+
serverRegBody
|
|
165
|
+
);
|
|
166
|
+
assertTrue(serverRegFrame.length >= 20 && ((serverRegFrame.length - 20) % 16 == 0));
|
|
167
|
+
|
|
168
|
+
JCoreWireCodec.DecodedFrame decodedServerReg = JCoreWireCodec.decodeServerFrame(serverRegFrame, assignedUid);
|
|
169
|
+
assertNotNull(decodedServerReg);
|
|
170
|
+
JCoreWireCodec.RegisterResponse regResp = JCoreWireCodec.parseRegisterResponse(decodedServerReg);
|
|
171
|
+
assertNotNull(regResp);
|
|
172
|
+
assertEquals(0L, (long) regResp.statusCode);
|
|
173
|
+
assertEquals(assignedUid, regResp.uid);
|
|
174
|
+
assertEquals("1a0018970a900100200", regResp.registrationId);
|
|
175
|
+
|
|
176
|
+
byte[] tagPayload = JCoreWireCodec.buildTagOperationPayload(1, 21, Arrays.asList("btc", "eth"));
|
|
177
|
+
byte[] tagFrame = JCoreWireCodec.encodeClientFrame(
|
|
178
|
+
JCoreWireCodec.CMD_TAG_OP,
|
|
179
|
+
JCoreWireCodec.VER_TAG_OP,
|
|
180
|
+
JCoreWireCodec.ALG_SM4_CBC,
|
|
181
|
+
0,
|
|
182
|
+
2L,
|
|
183
|
+
0x22334455,
|
|
184
|
+
assignedUid,
|
|
185
|
+
tagPayload
|
|
186
|
+
);
|
|
187
|
+
JCoreWireCodec.DecodedFrame decodedTag = JCoreWireCodec.decodeClientFrame(tagFrame, assignedUid);
|
|
188
|
+
assertNotNull(decodedTag);
|
|
189
|
+
JCoreWireCodec.OperationPayload tagOp = JCoreWireCodec.parseOperationPayload(
|
|
190
|
+
JCoreWireCodec.CMD_TAG_OP,
|
|
191
|
+
decodedTag.body
|
|
192
|
+
);
|
|
193
|
+
assertNotNull(tagOp);
|
|
194
|
+
assertEquals("add", tagOp.op);
|
|
195
|
+
|
|
196
|
+
Map<String, Object> props = new LinkedHashMap<String, Object>();
|
|
197
|
+
props.put("tier", "pro");
|
|
198
|
+
byte[] propPayload = JCoreWireCodec.buildPropertyOperationPayload(1, 23, props);
|
|
199
|
+
assertNotNull(propPayload);
|
|
200
|
+
assertTrue(propPayload.length > 2);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
@Test
|
|
204
|
+
public void testEmptyRegistrationBeforeHandshakeMultiRuntimeEventsAndManifestExportedFalse() throws Exception {
|
|
205
|
+
// 1. Fresh state before TCP Register (cmd=0) must return "" for getRegistrationID (no fake 1a0018970a...)
|
|
206
|
+
JCoreStorage.clearRegistration(null);
|
|
207
|
+
assertEquals("", JPushInterface.getRegistrationID(null));
|
|
208
|
+
assertEquals(0L, JCoreStorage.getUid(null));
|
|
209
|
+
assertEquals("", JCoreStorage.getPassword(null));
|
|
210
|
+
|
|
211
|
+
// 2. Cold-start queueing and multi-runtime (main + bg) Nitro event fan-out
|
|
212
|
+
JPushModule.clearActiveReactContexts();
|
|
213
|
+
JPushHelper.clearNitroListeners();
|
|
214
|
+
|
|
215
|
+
Map<String, Object> coldStartPayload = new LinkedHashMap<String, Object>();
|
|
216
|
+
coldStartPayload.put("messageID", "nitro_cold_01");
|
|
217
|
+
coldStartPayload.put("title", "NitroCold");
|
|
218
|
+
JPushHelper.sendEventMap("NotificationEvent", coldStartPayload);
|
|
219
|
+
|
|
220
|
+
final List<String> mainReceivedNames = new java.util.ArrayList<String>();
|
|
221
|
+
final List<String> mainReceivedJsons = new java.util.ArrayList<String>();
|
|
222
|
+
final List<String> bgReceivedNames = new java.util.ArrayList<String>();
|
|
223
|
+
final List<String> bgReceivedJsons = new java.util.ArrayList<String>();
|
|
224
|
+
|
|
225
|
+
int mainListenerId = JPushHelper.registerNitroListener(new JPushHelper.NitroEventListener() {
|
|
226
|
+
@Override
|
|
227
|
+
public void onEvent(String eventName, String payloadJson) {
|
|
228
|
+
mainReceivedNames.add(eventName);
|
|
229
|
+
mainReceivedJsons.add(payloadJson);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
int bgListenerId = JPushHelper.registerNitroListener(new JPushHelper.NitroEventListener() {
|
|
233
|
+
@Override
|
|
234
|
+
public void onEvent(String eventName, String payloadJson) {
|
|
235
|
+
bgReceivedNames.add(eventName);
|
|
236
|
+
bgReceivedJsons.add(payloadJson);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
assertTrue(mainListenerId > 0);
|
|
240
|
+
assertTrue(bgListenerId > 0);
|
|
241
|
+
assertEquals(1L, (long) mainReceivedNames.size());
|
|
242
|
+
assertEquals("NotificationEvent", mainReceivedNames.get(0));
|
|
243
|
+
assertTrue(mainReceivedJsons.get(0).contains("nitro_cold_01"));
|
|
244
|
+
|
|
245
|
+
Map<String, Object> eventPayload = new LinkedHashMap<String, Object>();
|
|
246
|
+
eventPayload.put("messageID", "multi_rt_msg_1");
|
|
247
|
+
eventPayload.put("title", "MultiRuntime");
|
|
248
|
+
JPushHelper.sendEventMap("NotificationEvent", eventPayload);
|
|
249
|
+
|
|
250
|
+
assertEquals(2L, (long) mainReceivedNames.size());
|
|
251
|
+
assertEquals(1L, (long) bgReceivedNames.size());
|
|
252
|
+
assertEquals("NotificationEvent", mainReceivedNames.get(1));
|
|
253
|
+
assertEquals("NotificationEvent", bgReceivedNames.get(0));
|
|
254
|
+
assertTrue(mainReceivedJsons.get(1).contains("multi_rt_msg_1"));
|
|
255
|
+
assertTrue(bgReceivedJsons.get(0).contains("multi_rt_msg_1"));
|
|
256
|
+
|
|
257
|
+
JPushHelper.unregisterNitroListener(mainListenerId);
|
|
258
|
+
JPushHelper.unregisterNitroListener(bgListenerId);
|
|
259
|
+
JPushHelper.clearNitroListeners();
|
|
260
|
+
|
|
261
|
+
// 2b. Verify JPushModuleReceiver callbacks on plain JVM (without Arguments.createMap() or ReactApplicationContext)
|
|
262
|
+
JPushModuleReceiver receiver = new JPushModuleReceiver();
|
|
263
|
+
CustomMessage customMsg = new CustomMessage();
|
|
264
|
+
customMsg.messageId = "cm_101";
|
|
265
|
+
customMsg.title = "CustomTitle";
|
|
266
|
+
customMsg.message = "CustomBody";
|
|
267
|
+
customMsg.extra = "{\"count\":42,\"flag\":true}";
|
|
268
|
+
receiver.onMessage(null, customMsg);
|
|
269
|
+
|
|
270
|
+
NotificationMessage arrivedMsg = new NotificationMessage();
|
|
271
|
+
arrivedMsg.msgId = "nm_102";
|
|
272
|
+
arrivedMsg.notificationType = 0;
|
|
273
|
+
arrivedMsg.notificationTitle = "ArrivedTitle";
|
|
274
|
+
arrivedMsg.notificationContent = "ArrivedBody";
|
|
275
|
+
arrivedMsg.notificationExtras = "{\"amount\":100}";
|
|
276
|
+
receiver.onNotifyMessageArrived(null, arrivedMsg);
|
|
277
|
+
|
|
278
|
+
JPushMessage tagMsg = new JPushMessage();
|
|
279
|
+
tagMsg.setSequence(11);
|
|
280
|
+
tagMsg.setErrorCode(0);
|
|
281
|
+
tagMsg.setTags(new java.util.HashSet<String>(Arrays.asList("tag_a", "tag_b")));
|
|
282
|
+
receiver.onTagOperatorResult(null, tagMsg);
|
|
283
|
+
|
|
284
|
+
JPushMessage aliasMsg = new JPushMessage();
|
|
285
|
+
aliasMsg.setSequence(12);
|
|
286
|
+
aliasMsg.setErrorCode(0);
|
|
287
|
+
aliasMsg.setAlias("user_alias_01");
|
|
288
|
+
receiver.onAliasOperatorResult(null, aliasMsg);
|
|
289
|
+
|
|
290
|
+
JPushMessage propMsg = new JPushMessage();
|
|
291
|
+
propMsg.setSequence(13);
|
|
292
|
+
propMsg.setErrorCode(0);
|
|
293
|
+
Map<String, Object> propMap = new LinkedHashMap<String, Object>();
|
|
294
|
+
propMap.put("vip", Boolean.TRUE);
|
|
295
|
+
propMsg.setPros(propMap);
|
|
296
|
+
receiver.onPropertyOperatorResult(null, propMsg);
|
|
297
|
+
|
|
298
|
+
final List<String> receiverEvents = new java.util.ArrayList<String>();
|
|
299
|
+
int recvListenerId = JPushHelper.registerNitroListener(new JPushHelper.NitroEventListener() {
|
|
300
|
+
@Override
|
|
301
|
+
public void onEvent(String eventName, String payloadJson) {
|
|
302
|
+
receiverEvents.add(eventName + ":" + payloadJson);
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
JPushHelper.unregisterNitroListener(recvListenerId);
|
|
306
|
+
JPushHelper.clearNitroListeners();
|
|
307
|
+
assertEquals(5L, (long) receiverEvents.size());
|
|
308
|
+
assertTrue(receiverEvents.get(0).startsWith("CustomMessageEvent:") && receiverEvents.get(0).contains("\"42\""));
|
|
309
|
+
assertTrue(receiverEvents.get(1).startsWith("NotificationEvent:") && receiverEvents.get(1).contains("\"100\""));
|
|
310
|
+
assertTrue(receiverEvents.get(2).startsWith("TagAliasEvent:") && receiverEvents.get(2).contains("tag_a"));
|
|
311
|
+
assertTrue(receiverEvents.get(3).startsWith("TagAliasEvent:") && receiverEvents.get(3).contains("user_alias_01"));
|
|
312
|
+
assertTrue(receiverEvents.get(4).startsWith("TagAliasEvent:") && receiverEvents.get(4).contains("vip"));
|
|
313
|
+
|
|
314
|
+
// 2c. Verify JCoreStorage.appendLocalLog cap and JLogger -> JCoreInterface.readNewLogs forwarding
|
|
315
|
+
JCoreInterface.enableSDKLocalLog(null, true, false);
|
|
316
|
+
JCoreInterface.readNewLogs(null);
|
|
317
|
+
StringBuilder longLine = new StringBuilder();
|
|
318
|
+
for (int i = 0; i < 600; i++) {
|
|
319
|
+
longLine.append("0123456789");
|
|
320
|
+
}
|
|
321
|
+
for (int i = 0; i < 10; i++) {
|
|
322
|
+
JCoreStorage.appendLocalLog("line_" + i + "_" + longLine.toString());
|
|
323
|
+
}
|
|
324
|
+
JLogger.i("jlogger_forwarded_marker_01");
|
|
325
|
+
String cappedLogs = JCoreInterface.readNewLogs(null);
|
|
326
|
+
assertTrue(cappedLogs.length() <= 32768);
|
|
327
|
+
assertTrue(cappedLogs.contains("jlogger_forwarded_marker_01"));
|
|
328
|
+
JCoreInterface.enableSDKLocalLog(null, false, false);
|
|
329
|
+
|
|
330
|
+
// 2d. Verify JCoreInterface.setHeartbeatInterval and JCoreManager.unRegister
|
|
331
|
+
JCoreInterface.setHeartbeatInterval(null, 120);
|
|
332
|
+
assertEquals(120000L, JCoreTcpEngine.getInstance().getHeartbeatIntervalMs());
|
|
333
|
+
JCoreTcpEngine.getInstance().setHeartbeatIntervalMs(290000L);
|
|
334
|
+
JCoreStorage.updateRegistration(null, 550011L, "unreg_pwd", "reg_550011", "dev_550011");
|
|
335
|
+
JCoreStorage.setServerRegistered(null, true);
|
|
336
|
+
JCoreStorage.setConnected(null, true);
|
|
337
|
+
JCoreManager.unRegister(null);
|
|
338
|
+
assertEquals(false, JCoreStorage.isServerRegistered(null));
|
|
339
|
+
assertEquals(0L, JCoreStorage.getUid(null));
|
|
340
|
+
assertEquals("", JCoreStorage.getRegistrationId(null));
|
|
341
|
+
assertEquals(false, JCoreStorage.isConnected(null));
|
|
342
|
+
|
|
343
|
+
// 2e. Verify JPushUPSManager.registerToken resolves appKey when appId is empty
|
|
344
|
+
JCoreStorage.setPushStopped(null, true);
|
|
345
|
+
JPushUPSManager.registerToken(null, "", "ups_appkey_fallback_01", "ups_secret", null);
|
|
346
|
+
assertEquals("ups_appkey_fallback_01", JCoreStorage.getAppKey(null));
|
|
347
|
+
JCoreTcpEngine.getInstance().stop(null);
|
|
348
|
+
JCoreStorage.setPushStopped(null, false);
|
|
349
|
+
|
|
350
|
+
// 2f. Verify delayed addLocalNotification scheduling and removeLocalNotification cancellation
|
|
351
|
+
ActionHelper.getInstance().clearActiveNotificationIds();
|
|
352
|
+
JPushLocalNotification cancelledLn = new JPushLocalNotification();
|
|
353
|
+
cancelledLn.setNotificationId(77001L);
|
|
354
|
+
cancelledLn.setTitle("CancelledTitle");
|
|
355
|
+
cancelledLn.setContent("CancelledContent");
|
|
356
|
+
cancelledLn.setBroadcastTime(300L);
|
|
357
|
+
JPushInterface.addLocalNotification(null, cancelledLn);
|
|
358
|
+
assertTrue(!ActionHelper.getInstance().getActiveNotificationIds().contains(Integer.valueOf(77001)));
|
|
359
|
+
JPushInterface.removeLocalNotification(null, 77001L);
|
|
360
|
+
|
|
361
|
+
JPushLocalNotification firedLn = new JPushLocalNotification();
|
|
362
|
+
firedLn.setNotificationId(77002L);
|
|
363
|
+
firedLn.setTitle("FiredTitle");
|
|
364
|
+
firedLn.setContent("FiredContent");
|
|
365
|
+
firedLn.setBroadcastTime(70L);
|
|
366
|
+
JPushInterface.addLocalNotification(null, firedLn);
|
|
367
|
+
assertTrue(!ActionHelper.getInstance().getActiveNotificationIds().contains(Integer.valueOf(77002)));
|
|
368
|
+
Thread.sleep(360L);
|
|
369
|
+
assertTrue(!ActionHelper.getInstance().getActiveNotificationIds().contains(Integer.valueOf(77001)));
|
|
370
|
+
assertTrue(ActionHelper.getInstance().getActiveNotificationIds().contains(Integer.valueOf(77002)));
|
|
371
|
+
ActionHelper.getInstance().clearActiveNotificationIds();
|
|
372
|
+
|
|
373
|
+
// 2g. Verify ActionHelper server response parsing (getAlias, getAllTags, checkTagBindState)
|
|
374
|
+
// and rollback on non-zero statusCode for Tag/Alias/Property/MobileNumber
|
|
375
|
+
final ServerSocket opServer = new ServerSocket(0, 5, InetAddress.getByName("127.0.0.1"));
|
|
376
|
+
final int opPort = opServer.getLocalPort();
|
|
377
|
+
final long opUid = 660033L;
|
|
378
|
+
Thread opServerThread = new Thread(new Runnable() {
|
|
379
|
+
@Override
|
|
380
|
+
public void run() {
|
|
381
|
+
Socket client = null;
|
|
382
|
+
try {
|
|
383
|
+
opServer.setSoTimeout(5000);
|
|
384
|
+
client = opServer.accept();
|
|
385
|
+
client.setSoTimeout(5000);
|
|
386
|
+
InputStream in = client.getInputStream();
|
|
387
|
+
OutputStream out = client.getOutputStream();
|
|
388
|
+
|
|
389
|
+
JCoreWireCodec.DecodedFrame loginFrame = JCoreWireCodec.readClientFrameFromStream(in, opUid);
|
|
390
|
+
if (loginFrame != null && loginFrame.command == JCoreWireCodec.CMD_LOGIN) {
|
|
391
|
+
byte[] loginResp = JCoreWireCodec.buildLoginResponsePayload(6601, 520, "", 1700001000);
|
|
392
|
+
out.write(JCoreWireCodec.encodeResponseFrame(
|
|
393
|
+
JCoreWireCodec.CMD_LOGIN,
|
|
394
|
+
JCoreWireCodec.VER_LOGIN,
|
|
395
|
+
loginFrame.requestId,
|
|
396
|
+
6601,
|
|
397
|
+
opUid,
|
|
398
|
+
0,
|
|
399
|
+
loginResp
|
|
400
|
+
));
|
|
401
|
+
out.flush();
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
while (!client.isClosed()) {
|
|
405
|
+
JCoreWireCodec.DecodedFrame req = JCoreWireCodec.readClientFrameFromStream(in, opUid);
|
|
406
|
+
if (req == null) {
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
if (req.command == JCoreWireCodec.CMD_HEARTBEAT) {
|
|
410
|
+
out.write(JCoreWireCodec.encodeResponseFrame(
|
|
411
|
+
JCoreWireCodec.CMD_HEARTBEAT,
|
|
412
|
+
JCoreWireCodec.VER_HEARTBEAT,
|
|
413
|
+
req.requestId,
|
|
414
|
+
6601,
|
|
415
|
+
opUid,
|
|
416
|
+
0,
|
|
417
|
+
new byte[0]
|
|
418
|
+
));
|
|
419
|
+
out.flush();
|
|
420
|
+
} else if (req.command == JCoreWireCodec.CMD_ALIAS_OP) {
|
|
421
|
+
if (req.requestId == 301L) {
|
|
422
|
+
byte[] body = JCoreWireCodec.buildJsonCommandPayload("{\"alias\":\"srv_alias_301\"}");
|
|
423
|
+
out.write(JCoreWireCodec.encodeResponseFrame(
|
|
424
|
+
JCoreWireCodec.CMD_ALIAS_OP,
|
|
425
|
+
JCoreWireCodec.VER_ALIAS_OP,
|
|
426
|
+
req.requestId,
|
|
427
|
+
6601,
|
|
428
|
+
opUid,
|
|
429
|
+
0,
|
|
430
|
+
body
|
|
431
|
+
));
|
|
432
|
+
} else {
|
|
433
|
+
byte[] errBody = JCoreWireCodec.buildJsonCommandPayload("{\"code\":6002}");
|
|
434
|
+
out.write(JCoreWireCodec.encodeResponseFrame(
|
|
435
|
+
JCoreWireCodec.CMD_ALIAS_OP,
|
|
436
|
+
JCoreWireCodec.VER_ALIAS_OP,
|
|
437
|
+
req.requestId,
|
|
438
|
+
6601,
|
|
439
|
+
opUid,
|
|
440
|
+
6002,
|
|
441
|
+
errBody
|
|
442
|
+
));
|
|
443
|
+
}
|
|
444
|
+
out.flush();
|
|
445
|
+
} else if (req.command == JCoreWireCodec.CMD_TAG_OP) {
|
|
446
|
+
if (req.requestId == 303L) {
|
|
447
|
+
byte[] body = JCoreWireCodec.buildJsonCommandPayload("{\"tags\":[\"srv_t1\",\"srv_t2\"]}");
|
|
448
|
+
out.write(JCoreWireCodec.encodeResponseFrame(
|
|
449
|
+
JCoreWireCodec.CMD_TAG_OP,
|
|
450
|
+
JCoreWireCodec.VER_TAG_OP,
|
|
451
|
+
req.requestId,
|
|
452
|
+
6601,
|
|
453
|
+
opUid,
|
|
454
|
+
0,
|
|
455
|
+
body
|
|
456
|
+
));
|
|
457
|
+
} else if (req.requestId == 305L) {
|
|
458
|
+
byte[] body = JCoreWireCodec.buildJsonCommandPayload("{\"bind\":true}");
|
|
459
|
+
out.write(JCoreWireCodec.encodeResponseFrame(
|
|
460
|
+
JCoreWireCodec.CMD_TAG_OP,
|
|
461
|
+
JCoreWireCodec.VER_TAG_OP,
|
|
462
|
+
req.requestId,
|
|
463
|
+
6601,
|
|
464
|
+
opUid,
|
|
465
|
+
0,
|
|
466
|
+
body
|
|
467
|
+
));
|
|
468
|
+
} else {
|
|
469
|
+
byte[] errBody = JCoreWireCodec.buildJsonCommandPayload("{\"code\":6002}");
|
|
470
|
+
out.write(JCoreWireCodec.encodeResponseFrame(
|
|
471
|
+
JCoreWireCodec.CMD_TAG_OP,
|
|
472
|
+
JCoreWireCodec.VER_TAG_OP,
|
|
473
|
+
req.requestId,
|
|
474
|
+
6601,
|
|
475
|
+
opUid,
|
|
476
|
+
6002,
|
|
477
|
+
errBody
|
|
478
|
+
));
|
|
479
|
+
}
|
|
480
|
+
out.flush();
|
|
481
|
+
} else if (req.command == JCoreWireCodec.CMD_PROPERTY_OP) {
|
|
482
|
+
out.write(JCoreWireCodec.encodeResponseFrame(
|
|
483
|
+
JCoreWireCodec.CMD_PROPERTY_OP,
|
|
484
|
+
JCoreWireCodec.VER_PROPERTY_OP,
|
|
485
|
+
req.requestId,
|
|
486
|
+
6601,
|
|
487
|
+
opUid,
|
|
488
|
+
6002,
|
|
489
|
+
new byte[0]
|
|
490
|
+
));
|
|
491
|
+
out.flush();
|
|
492
|
+
} else if (req.command == JCoreWireCodec.CMD_MOBILE_NUMBER) {
|
|
493
|
+
out.write(JCoreWireCodec.encodeResponseFrame(
|
|
494
|
+
JCoreWireCodec.CMD_MOBILE_NUMBER,
|
|
495
|
+
JCoreWireCodec.VER_MOBILE_NUMBER,
|
|
496
|
+
req.requestId,
|
|
497
|
+
6601,
|
|
498
|
+
opUid,
|
|
499
|
+
6002,
|
|
500
|
+
new byte[0]
|
|
501
|
+
));
|
|
502
|
+
out.flush();
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
} catch (Throwable ignored) {
|
|
506
|
+
} finally {
|
|
507
|
+
try {
|
|
508
|
+
if (client != null) client.close();
|
|
509
|
+
} catch (Throwable ignored) {}
|
|
510
|
+
try {
|
|
511
|
+
opServer.close();
|
|
512
|
+
} catch (Throwable ignored) {}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}, "test-op-rollback-server");
|
|
516
|
+
opServerThread.setDaemon(true);
|
|
517
|
+
opServerThread.start();
|
|
518
|
+
|
|
519
|
+
ActionHelper.getInstance().registerReceiver(receiver);
|
|
520
|
+
final List<String> opEvents = new java.util.ArrayList<String>();
|
|
521
|
+
final CountDownLatch rollbackDoneLatch = new CountDownLatch(4);
|
|
522
|
+
final CountDownLatch queryDoneLatch = new CountDownLatch(3);
|
|
523
|
+
int opListenerId = JPushHelper.registerNitroListener(new JPushHelper.NitroEventListener() {
|
|
524
|
+
@Override
|
|
525
|
+
public void onEvent(String eventName, String payloadJson) {
|
|
526
|
+
if ("TagAliasEvent".equals(eventName) || "MobileNumberEvent".equals(eventName)) {
|
|
527
|
+
opEvents.add(eventName + ":" + payloadJson);
|
|
528
|
+
if (payloadJson.contains("302") || payloadJson.contains("304") || payloadJson.contains("306") || payloadJson.contains("307")) {
|
|
529
|
+
rollbackDoneLatch.countDown();
|
|
530
|
+
}
|
|
531
|
+
if (payloadJson.contains("301") || payloadJson.contains("303") || payloadJson.contains("305")) {
|
|
532
|
+
queryDoneLatch.countDown();
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
JCoreStorage.updateRegistration(null, opUid, "op_pwd", "reg_op_660033", "dev_op_01");
|
|
539
|
+
JCoreStorage.setServerRegistered(null, true);
|
|
540
|
+
JCoreStorage.saveAlias(null, "old_local_alias");
|
|
541
|
+
JCoreStorage.saveTags(null, new java.util.HashSet<String>(Arrays.asList("old_local_tag")));
|
|
542
|
+
JCoreStorage.saveProperties(null, Collections.<String, Object>singletonMap("tier", "gold"));
|
|
543
|
+
JCoreStorage.saveMobileNumber(null, "13800000001");
|
|
544
|
+
|
|
545
|
+
JCoreTcpEngine.getInstance().setRequireServerAckForOperations(true);
|
|
546
|
+
JCoreTcpEngine.getInstance().setCustomEndpoint("127.0.0.1", opPort);
|
|
547
|
+
JCoreTcpEngine.getInstance().triggerReconnectNow(null);
|
|
548
|
+
assertTrue(JCoreTcpEngine.getInstance().awaitHandshake(3000L));
|
|
549
|
+
|
|
550
|
+
JPushInterface.setAlias(null, 302, "rejected_alias_302");
|
|
551
|
+
JPushInterface.setTags(null, 304, new java.util.HashSet<String>(Arrays.asList("rejected_tag_304")));
|
|
552
|
+
JPushInterface.setProperties(null, 306, Collections.<String, Object>singletonMap("tier", "rejected_tier"));
|
|
553
|
+
JPushInterface.setMobileNumber(null, 307, "13999999999");
|
|
554
|
+
|
|
555
|
+
assertTrue(rollbackDoneLatch.await(4000L, TimeUnit.MILLISECONDS));
|
|
556
|
+
assertEquals("old_local_alias", JCoreStorage.getAlias(null));
|
|
557
|
+
assertTrue(JCoreStorage.getTags(null).contains("old_local_tag"));
|
|
558
|
+
assertTrue(!JCoreStorage.getTags(null).contains("rejected_tag_304"));
|
|
559
|
+
assertEquals("gold", JCoreStorage.getProperties(null).get("tier"));
|
|
560
|
+
assertEquals("13800000001", JCoreStorage.getMobileNumber(null));
|
|
561
|
+
|
|
562
|
+
JPushInterface.getAlias(null, 301);
|
|
563
|
+
JPushInterface.getAllTags(null, 303);
|
|
564
|
+
JPushInterface.checkTagBindState(null, 305, "unbound_local_tag");
|
|
565
|
+
|
|
566
|
+
assertTrue(queryDoneLatch.await(4000L, TimeUnit.MILLISECONDS));
|
|
567
|
+
assertEquals("srv_alias_301", JCoreStorage.getAlias(null));
|
|
568
|
+
assertTrue(JCoreStorage.getTags(null).contains("srv_t1") && JCoreStorage.getTags(null).contains("srv_t2"));
|
|
569
|
+
boolean sawServerBindTrue = false;
|
|
570
|
+
for (String ev : opEvents) {
|
|
571
|
+
if (ev.contains("unbound_local_tag") && ev.contains("true")) {
|
|
572
|
+
sawServerBindTrue = true;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
assertTrue(sawServerBindTrue);
|
|
576
|
+
|
|
577
|
+
JPushHelper.unregisterNitroListener(opListenerId);
|
|
578
|
+
JPushHelper.clearNitroListeners();
|
|
579
|
+
JCoreTcpEngine.getInstance().setRequireServerAckForOperations(false);
|
|
580
|
+
JCoreTcpEngine.getInstance().setCustomEndpoint("", 0);
|
|
581
|
+
JCoreTcpEngine.getInstance().stop(null);
|
|
582
|
+
JCoreStorage.clearRegistration(null);
|
|
583
|
+
|
|
584
|
+
// 2h. Verify JPushInterface.setProperties / deleteProperties / cleanProperties emit TagAliasEvent with pros
|
|
585
|
+
// via JPushModuleReceiver.onPropertyOperatorResult, and JPushBroadcastReceiver ignores intents with
|
|
586
|
+
// "jpush_already_dispatched" == true while JPushModuleReceiver.onNotifyMessageOpened clears stale NOTIFICATION_BUNDLE.
|
|
587
|
+
final List<String> propEvents = new java.util.ArrayList<String>();
|
|
588
|
+
int propListenerId = JPushHelper.registerNitroListener(new JPushHelper.NitroEventListener() {
|
|
589
|
+
@Override
|
|
590
|
+
public void onEvent(String eventName, String payloadJson) {
|
|
591
|
+
propEvents.add(eventName + ":" + payloadJson);
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
ActionHelper.getInstance().registerReceiver(receiver);
|
|
595
|
+
Map<String, Object> setPropsInput = new LinkedHashMap<String, Object>();
|
|
596
|
+
setPropsInput.put("region", "apac");
|
|
597
|
+
setPropsInput.put("plan", "enterprise");
|
|
598
|
+
JPushInterface.setProperties(null, 401, setPropsInput);
|
|
599
|
+
assertEquals("apac", JCoreStorage.getProperties(null).get("region"));
|
|
600
|
+
assertEquals("enterprise", JCoreStorage.getProperties(null).get("plan"));
|
|
601
|
+
|
|
602
|
+
Map<String, Object> delPropsInput = new LinkedHashMap<String, Object>();
|
|
603
|
+
delPropsInput.put("region", "");
|
|
604
|
+
JPushInterface.deleteProperties(null, 402, delPropsInput);
|
|
605
|
+
assertTrue(!JCoreStorage.getProperties(null).containsKey("region"));
|
|
606
|
+
assertEquals("enterprise", JCoreStorage.getProperties(null).get("plan"));
|
|
607
|
+
|
|
608
|
+
JPushInterface.cleanProperties(null, 403);
|
|
609
|
+
assertTrue(JCoreStorage.getProperties(null).isEmpty());
|
|
610
|
+
|
|
611
|
+
assertEquals(3L, (long) propEvents.size());
|
|
612
|
+
assertTrue(propEvents.get(0).startsWith("TagAliasEvent:") && propEvents.get(0).contains("401") && propEvents.get(0).contains("enterprise"));
|
|
613
|
+
assertTrue(propEvents.get(1).startsWith("TagAliasEvent:") && propEvents.get(1).contains("402") && propEvents.get(1).contains("region"));
|
|
614
|
+
assertTrue(propEvents.get(2).startsWith("TagAliasEvent:") && propEvents.get(2).contains("403"));
|
|
615
|
+
JPushHelper.unregisterNitroListener(propListenerId);
|
|
616
|
+
JPushHelper.clearNitroListeners();
|
|
617
|
+
|
|
618
|
+
android.os.Bundle staleBundle = new android.os.Bundle();
|
|
619
|
+
cn.jiguang.plugins.push.receiver.JPushBroadcastReceiver.NOTIFICATION_BUNDLE = staleBundle;
|
|
620
|
+
NotificationMessage openedMsg = new NotificationMessage();
|
|
621
|
+
openedMsg.msgId = "nm_open_404";
|
|
622
|
+
openedMsg.notificationTitle = "OpenTitle";
|
|
623
|
+
openedMsg.notificationContent = "OpenBody";
|
|
624
|
+
receiver.onNotifyMessageOpened(null, openedMsg);
|
|
625
|
+
assertEquals(null, cn.jiguang.plugins.push.receiver.JPushBroadcastReceiver.NOTIFICATION_BUNDLE);
|
|
626
|
+
|
|
627
|
+
cn.jiguang.plugins.push.receiver.JPushBroadcastReceiver broadcastReceiver =
|
|
628
|
+
new cn.jiguang.plugins.push.receiver.JPushBroadcastReceiver();
|
|
629
|
+
android.content.Intent alreadyDispatchedIntent = new android.content.Intent(JPushInterface.ACTION_NOTIFICATION_OPENED) {
|
|
630
|
+
@Override
|
|
631
|
+
public String getAction() {
|
|
632
|
+
return JPushInterface.ACTION_NOTIFICATION_OPENED;
|
|
633
|
+
}
|
|
634
|
+
@Override
|
|
635
|
+
public boolean getBooleanExtra(String name, boolean defaultValue) {
|
|
636
|
+
if ("jpush_already_dispatched".equals(name)) {
|
|
637
|
+
return true;
|
|
638
|
+
}
|
|
639
|
+
return defaultValue;
|
|
640
|
+
}
|
|
641
|
+
@Override
|
|
642
|
+
public android.os.Bundle getExtras() {
|
|
643
|
+
return new android.os.Bundle();
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
broadcastReceiver.onReceive(null, alreadyDispatchedIntent);
|
|
647
|
+
assertEquals(null, cn.jiguang.plugins.push.receiver.JPushBroadcastReceiver.NOTIFICATION_BUNDLE);
|
|
648
|
+
JPushHelper.clearNitroListeners();
|
|
649
|
+
|
|
650
|
+
// 3. Verify AndroidManifest.xml has android:exported="false" on all 5 internal activities
|
|
651
|
+
File manifestFile = new File("src/main/AndroidManifest.xml");
|
|
652
|
+
if (!manifestFile.exists()) {
|
|
653
|
+
manifestFile = new File("android/src/main/AndroidManifest.xml");
|
|
654
|
+
}
|
|
655
|
+
if (!manifestFile.exists()) {
|
|
656
|
+
manifestFile = new File(
|
|
657
|
+
System.getProperty("user.dir"),
|
|
658
|
+
"native-modules/react-native-jpush/android/src/main/AndroidManifest.xml"
|
|
659
|
+
);
|
|
660
|
+
}
|
|
661
|
+
assertTrue(manifestFile.exists());
|
|
662
|
+
String xml = new String(Files.readAllBytes(manifestFile.toPath()), StandardCharsets.UTF_8);
|
|
663
|
+
assertTrue(!xml.contains("android:exported=\"true\""));
|
|
664
|
+
for (String activityName : new String[] {
|
|
665
|
+
"cn.jpush.android.ui.PopWinActivity",
|
|
666
|
+
"cn.jpush.android.ui.PushActivity",
|
|
667
|
+
"cn.jpush.android.service.JNotifyActivity",
|
|
668
|
+
"cn.android.service.JTransitActivity",
|
|
669
|
+
"cn.jpush.android.service.DActivity"
|
|
670
|
+
}) {
|
|
671
|
+
int idx = xml.indexOf(activityName);
|
|
672
|
+
assertTrue(idx > 0);
|
|
673
|
+
int endTag = xml.indexOf(">", idx);
|
|
674
|
+
String activityHeader = xml.substring(idx, endTag);
|
|
675
|
+
assertTrue(activityHeader.contains("android:exported=\"false\""));
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
// 4. Verify periodic heartbeat timer sends additional CMD_HEARTBEAT frames after initial login
|
|
679
|
+
final ServerSocket hbServer = new ServerSocket(0, 5, InetAddress.getByName("127.0.0.1"));
|
|
680
|
+
final int hbPort = hbServer.getLocalPort();
|
|
681
|
+
final AtomicInteger heartbeatsReceived = new AtomicInteger(0);
|
|
682
|
+
final CountDownLatch twoHeartbeatsLatch = new CountDownLatch(1);
|
|
683
|
+
final long testUid = 880011L;
|
|
684
|
+
|
|
685
|
+
Thread hbThread = new Thread(new Runnable() {
|
|
686
|
+
@Override
|
|
687
|
+
public void run() {
|
|
688
|
+
Socket client = null;
|
|
689
|
+
try {
|
|
690
|
+
hbServer.setSoTimeout(5000);
|
|
691
|
+
client = hbServer.accept();
|
|
692
|
+
client.setSoTimeout(5000);
|
|
693
|
+
InputStream in = client.getInputStream();
|
|
694
|
+
OutputStream out = client.getOutputStream();
|
|
695
|
+
|
|
696
|
+
JCoreWireCodec.DecodedFrame loginFrame = JCoreWireCodec.readClientFrameFromStream(in, testUid);
|
|
697
|
+
if (loginFrame != null && loginFrame.command == JCoreWireCodec.CMD_LOGIN) {
|
|
698
|
+
byte[] loginResp = JCoreWireCodec.buildLoginResponsePayload(7701, 520, "", 1700000600);
|
|
699
|
+
out.write(JCoreWireCodec.encodeResponseFrame(
|
|
700
|
+
JCoreWireCodec.CMD_LOGIN,
|
|
701
|
+
JCoreWireCodec.VER_LOGIN,
|
|
702
|
+
loginFrame.requestId,
|
|
703
|
+
7701,
|
|
704
|
+
testUid,
|
|
705
|
+
0,
|
|
706
|
+
loginResp
|
|
707
|
+
));
|
|
708
|
+
out.flush();
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
while (!client.isClosed()) {
|
|
712
|
+
JCoreWireCodec.DecodedFrame frame = JCoreWireCodec.readClientFrameFromStream(in, testUid);
|
|
713
|
+
if (frame == null) {
|
|
714
|
+
break;
|
|
715
|
+
}
|
|
716
|
+
if (frame.command == JCoreWireCodec.CMD_HEARTBEAT) {
|
|
717
|
+
out.write(JCoreWireCodec.encodeResponseFrame(
|
|
718
|
+
JCoreWireCodec.CMD_HEARTBEAT,
|
|
719
|
+
JCoreWireCodec.VER_HEARTBEAT,
|
|
720
|
+
frame.requestId,
|
|
721
|
+
7701,
|
|
722
|
+
testUid,
|
|
723
|
+
0,
|
|
724
|
+
new byte[0]
|
|
725
|
+
));
|
|
726
|
+
out.flush();
|
|
727
|
+
if (heartbeatsReceived.incrementAndGet() >= 2) {
|
|
728
|
+
twoHeartbeatsLatch.countDown();
|
|
729
|
+
break;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
} catch (Throwable ignored) {
|
|
734
|
+
} finally {
|
|
735
|
+
try {
|
|
736
|
+
if (client != null) client.close();
|
|
737
|
+
} catch (Throwable ignored) {}
|
|
738
|
+
try {
|
|
739
|
+
hbServer.close();
|
|
740
|
+
} catch (Throwable ignored) {}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
}, "test-periodic-heartbeat-server");
|
|
744
|
+
hbThread.setDaemon(true);
|
|
745
|
+
hbThread.start();
|
|
746
|
+
|
|
747
|
+
JCoreStorage.updateRegistration(null, testUid, "hb_pwd", "reg_hb_880011", "dev_hb_01");
|
|
748
|
+
JCoreStorage.setServerRegistered(null, true);
|
|
749
|
+
JCoreTcpEngine.getInstance().setHeartbeatIntervalMs(60L);
|
|
750
|
+
JCoreTcpEngine.getInstance().setCustomEndpoint("127.0.0.1", hbPort);
|
|
751
|
+
JCoreTcpEngine.getInstance().triggerReconnectNow(null);
|
|
752
|
+
assertTrue(JCoreTcpEngine.getInstance().awaitHandshake(3000L));
|
|
753
|
+
assertTrue(twoHeartbeatsLatch.await(3000L, TimeUnit.MILLISECONDS));
|
|
754
|
+
assertTrue(heartbeatsReceived.get() >= 2);
|
|
755
|
+
JCoreTcpEngine.getInstance().setHeartbeatIntervalMs(290000L);
|
|
756
|
+
JCoreTcpEngine.getInstance().stop(null);
|
|
757
|
+
JCoreStorage.clearRegistration(null);
|
|
758
|
+
|
|
759
|
+
// 5. Verify connectAndHandshake automatic SIS resolution when candidateEndpoints is empty, customPort == 0,
|
|
760
|
+
// and JCoreStorage has no cached lastGoodIp or sisIps:
|
|
761
|
+
// (a) When SIS resolves to an unreachable port, connectAndHandshake must NOT set fake connected=true.
|
|
762
|
+
// (b) When SIS resolves to a live TCP server, connectAndHandshake connects without setCustomEndpoint.
|
|
763
|
+
ServerSocket deadProbe = new ServerSocket(0, 1, InetAddress.getByName("127.0.0.1"));
|
|
764
|
+
final int deadTcpPort = deadProbe.getLocalPort();
|
|
765
|
+
deadProbe.close();
|
|
766
|
+
|
|
767
|
+
final ServerSocket sisTcpServer = new ServerSocket(0, 5, InetAddress.getByName("127.0.0.1"));
|
|
768
|
+
final int sisTcpPort = sisTcpServer.getLocalPort();
|
|
769
|
+
final DatagramSocket sisUdpServer = new DatagramSocket(0, InetAddress.getByName("127.0.0.1"));
|
|
770
|
+
final int sisUdpPort = sisUdpServer.getLocalPort();
|
|
771
|
+
final AtomicInteger sisQueryCount = new AtomicInteger(0);
|
|
772
|
+
|
|
773
|
+
Thread sisUdpThread = new Thread(new Runnable() {
|
|
774
|
+
@Override
|
|
775
|
+
public void run() {
|
|
776
|
+
try {
|
|
777
|
+
sisUdpServer.setSoTimeout(15000);
|
|
778
|
+
for (int i = 0; i < 2; i++) {
|
|
779
|
+
byte[] buf = new byte[2048];
|
|
780
|
+
DatagramPacket req = new DatagramPacket(buf, buf.length);
|
|
781
|
+
sisUdpServer.receive(req);
|
|
782
|
+
int queryIdx = sisQueryCount.incrementAndGet();
|
|
783
|
+
int targetPort = (queryIdx == 1) ? deadTcpPort : sisTcpPort;
|
|
784
|
+
String sisJson = "{\"ips\":[\"127.0.0.1:" + targetPort + "\"]}";
|
|
785
|
+
byte[] encoded = JCoreWireCodec.encodeUdpSisPacket(sisJson, 0x234567);
|
|
786
|
+
DatagramPacket resp = new DatagramPacket(
|
|
787
|
+
encoded,
|
|
788
|
+
encoded.length,
|
|
789
|
+
req.getAddress(),
|
|
790
|
+
req.getPort()
|
|
791
|
+
);
|
|
792
|
+
sisUdpServer.send(resp);
|
|
793
|
+
}
|
|
794
|
+
} catch (Throwable ignored) {
|
|
795
|
+
} finally {
|
|
796
|
+
sisUdpServer.close();
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}, "test-auto-sis-udp-server");
|
|
800
|
+
sisUdpThread.setDaemon(true);
|
|
801
|
+
sisUdpThread.start();
|
|
802
|
+
|
|
803
|
+
Thread sisTcpThread = new Thread(new Runnable() {
|
|
804
|
+
@Override
|
|
805
|
+
public void run() {
|
|
806
|
+
Socket client = null;
|
|
807
|
+
try {
|
|
808
|
+
sisTcpServer.setSoTimeout(15000);
|
|
809
|
+
client = sisTcpServer.accept();
|
|
810
|
+
client.setSoTimeout(10000);
|
|
811
|
+
InputStream in = client.getInputStream();
|
|
812
|
+
OutputStream out = client.getOutputStream();
|
|
813
|
+
|
|
814
|
+
JCoreWireCodec.DecodedFrame regFrame = JCoreWireCodec.readClientFrameFromStream(in, 0L);
|
|
815
|
+
if (regFrame != null && regFrame.command == JCoreWireCodec.CMD_REGISTER) {
|
|
816
|
+
byte[] regResp = JCoreWireCodec.buildRegisterResponsePayload(
|
|
817
|
+
990022L,
|
|
818
|
+
"sis_pwd",
|
|
819
|
+
"reg_auto_sis_990022",
|
|
820
|
+
"dev_auto_sis_01"
|
|
821
|
+
);
|
|
822
|
+
out.write(JCoreWireCodec.encodeResponseFrame(
|
|
823
|
+
JCoreWireCodec.CMD_REGISTER,
|
|
824
|
+
JCoreWireCodec.VER_REGISTER,
|
|
825
|
+
regFrame.requestId,
|
|
826
|
+
regFrame.sessionId,
|
|
827
|
+
990022L,
|
|
828
|
+
0,
|
|
829
|
+
regResp
|
|
830
|
+
));
|
|
831
|
+
out.flush();
|
|
832
|
+
}
|
|
833
|
+
JCoreWireCodec.DecodedFrame loginFrame = JCoreWireCodec.readClientFrameFromStream(in, 990022L);
|
|
834
|
+
if (loginFrame != null && loginFrame.command == JCoreWireCodec.CMD_LOGIN) {
|
|
835
|
+
byte[] loginResp = JCoreWireCodec.buildLoginResponsePayload(8802, 520, "", 1700000900);
|
|
836
|
+
out.write(JCoreWireCodec.encodeResponseFrame(
|
|
837
|
+
JCoreWireCodec.CMD_LOGIN,
|
|
838
|
+
JCoreWireCodec.VER_LOGIN,
|
|
839
|
+
loginFrame.requestId,
|
|
840
|
+
8802,
|
|
841
|
+
990022L,
|
|
842
|
+
0,
|
|
843
|
+
loginResp
|
|
844
|
+
));
|
|
845
|
+
out.flush();
|
|
846
|
+
}
|
|
847
|
+
JCoreWireCodec.DecodedFrame hbFrame = JCoreWireCodec.readClientFrameFromStream(in, 990022L);
|
|
848
|
+
if (hbFrame != null && hbFrame.command == JCoreWireCodec.CMD_HEARTBEAT) {
|
|
849
|
+
out.write(JCoreWireCodec.encodeResponseFrame(
|
|
850
|
+
JCoreWireCodec.CMD_HEARTBEAT,
|
|
851
|
+
JCoreWireCodec.VER_HEARTBEAT,
|
|
852
|
+
hbFrame.requestId,
|
|
853
|
+
8802,
|
|
854
|
+
990022L,
|
|
855
|
+
0,
|
|
856
|
+
new byte[0]
|
|
857
|
+
));
|
|
858
|
+
out.flush();
|
|
859
|
+
}
|
|
860
|
+
// Keep socket open until client closes it after assertions
|
|
861
|
+
while (!client.isClosed() && in.read() != -1) {
|
|
862
|
+
// wait for client close
|
|
863
|
+
}
|
|
864
|
+
} catch (Throwable ignored) {
|
|
865
|
+
} finally {
|
|
866
|
+
try {
|
|
867
|
+
if (client != null) client.close();
|
|
868
|
+
} catch (Throwable ignored) {}
|
|
869
|
+
try {
|
|
870
|
+
sisTcpServer.close();
|
|
871
|
+
} catch (Throwable ignored) {}
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
}, "test-auto-sis-tcp-server");
|
|
875
|
+
sisTcpThread.setDaemon(true);
|
|
876
|
+
sisTcpThread.start();
|
|
877
|
+
|
|
878
|
+
JCoreStorage.clearRegistration(null);
|
|
879
|
+
JCoreStorage.saveSisConfig(null, "{\"ips\":[],\"ssl_ips\":[]}");
|
|
880
|
+
JCoreStorage.setLastGoodIp(null, "");
|
|
881
|
+
JCoreTcpEngine.getInstance().setCustomEndpoint("", 0);
|
|
882
|
+
JCoreTcpEngine.getInstance().setCandidateEndpoints(Collections.<String>emptyList());
|
|
883
|
+
JCoreTcpEngine.getInstance().setCustomSisUrl("udp-only");
|
|
884
|
+
JCoreTcpEngine.getInstance().setDefaultSisUdpEndpoint("127.0.0.1", sisUdpPort);
|
|
885
|
+
assertEquals(0L, (long) JCoreTcpEngine.getInstance().getCustomPort());
|
|
886
|
+
assertTrue(JCoreStorage.getSisIps(null).isEmpty());
|
|
887
|
+
|
|
888
|
+
// (a) First SIS query returns deadTcpPort -> connectAndHandshake must NOT set fake connected=true,
|
|
889
|
+
// and deadTcpPort is now cached in sisIps and recorded in failedIps.
|
|
890
|
+
JCoreTcpEngine.getInstance().connectAndHandshake(null);
|
|
891
|
+
assertEquals(false, JCoreStorage.isConnected(null));
|
|
892
|
+
assertEquals("", JPushInterface.getRegistrationID(null));
|
|
893
|
+
assertTrue(JCoreStorage.getSisIps(null).contains("127.0.0.1:" + deadTcpPort));
|
|
894
|
+
assertTrue(JCoreStorage.getFailedIps(null).contains("127.0.0.1:" + deadTcpPort));
|
|
895
|
+
|
|
896
|
+
// (b) Without clearing sisIps, all cached SIS IPs are in failedIps (!hasHealthyCandidate) ->
|
|
897
|
+
// connectAndHandshake automatically re-runs SIS resolution (second SIS query returns live sisTcpPort)
|
|
898
|
+
// and connects cleanly!
|
|
899
|
+
JCoreTcpEngine.getInstance().connectAndHandshake(null);
|
|
900
|
+
assertEquals(true, JCoreStorage.isConnected(null));
|
|
901
|
+
assertEquals("reg_auto_sis_990022", JPushInterface.getRegistrationID(null));
|
|
902
|
+
assertTrue(JCoreStorage.getSisIps(null).contains("127.0.0.1:" + sisTcpPort));
|
|
903
|
+
|
|
904
|
+
JCoreTcpEngine.getInstance().setCustomSisUrl("");
|
|
905
|
+
JCoreTcpEngine.getInstance().setDefaultSisUdpEndpoint("s.jpush.cn", 19000);
|
|
906
|
+
JCoreTcpEngine.getInstance().stop(null);
|
|
907
|
+
}
|
|
908
|
+
}
|