@revopush/react-native-code-push 0.0.1

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.
Files changed (174) hide show
  1. package/.azurepipelines/build-rn-code-push-1es.yml +104 -0
  2. package/.azurepipelines/test-rn-code-push.yml +94 -0
  3. package/.config/CredScanSuppressions.json +14 -0
  4. package/.node-version +1 -0
  5. package/AlertAdapter.js +24 -0
  6. package/CONTRIBUTING.md +134 -0
  7. package/CodePush.js +671 -0
  8. package/CodePush.podspec +28 -0
  9. package/LICENSE.md +13 -0
  10. package/README.md +413 -0
  11. package/SECURITY.md +41 -0
  12. package/android/app/build.gradle +48 -0
  13. package/android/app/proguard-rules.pro +25 -0
  14. package/android/app/src/main/AndroidManifest.xml +5 -0
  15. package/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +444 -0
  16. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushConstants.java +35 -0
  17. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushDialog.java +102 -0
  18. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushInstallMode.java +16 -0
  19. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushInvalidPublicKeyException.java +12 -0
  20. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushInvalidUpdateException.java +7 -0
  21. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushMalformedDataException.java +12 -0
  22. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java +848 -0
  23. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushNotInitializedException.java +12 -0
  24. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushTelemetryManager.java +175 -0
  25. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUnknownException.java +12 -0
  26. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateManager.java +383 -0
  27. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateState.java +15 -0
  28. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java +275 -0
  29. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUtils.java +238 -0
  30. package/android/app/src/main/java/com/microsoft/codepush/react/DownloadProgress.java +30 -0
  31. package/android/app/src/main/java/com/microsoft/codepush/react/DownloadProgressCallback.java +5 -0
  32. package/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java +203 -0
  33. package/android/app/src/main/java/com/microsoft/codepush/react/ReactHostHolder.java +11 -0
  34. package/android/app/src/main/java/com/microsoft/codepush/react/ReactInstanceHolder.java +17 -0
  35. package/android/app/src/main/java/com/microsoft/codepush/react/SettingsManager.java +173 -0
  36. package/android/app/src/main/java/com/microsoft/codepush/react/TLSSocketFactory.java +72 -0
  37. package/android/build.gradle +24 -0
  38. package/android/codepush.gradle +162 -0
  39. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  40. package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  41. package/android/gradle.properties +20 -0
  42. package/android/gradlew +164 -0
  43. package/android/gradlew.bat +90 -0
  44. package/android/settings.gradle +1 -0
  45. package/docs/api-android.md +52 -0
  46. package/docs/api-ios.md +31 -0
  47. package/docs/api-js.md +592 -0
  48. package/docs/multi-deployment-testing-android.md +55 -0
  49. package/docs/multi-deployment-testing-ios.md +59 -0
  50. package/docs/setup-android.md +92 -0
  51. package/docs/setup-ios.md +137 -0
  52. package/ios/CodePush/Base64/Base64/MF_Base64Additions.h +34 -0
  53. package/ios/CodePush/Base64/Base64/MF_Base64Additions.m +252 -0
  54. package/ios/CodePush/Base64/README.md +47 -0
  55. package/ios/CodePush/CodePush.h +235 -0
  56. package/ios/CodePush/CodePush.m +1122 -0
  57. package/ios/CodePush/CodePushConfig.m +116 -0
  58. package/ios/CodePush/CodePushDownloadHandler.m +130 -0
  59. package/ios/CodePush/CodePushErrorUtils.m +20 -0
  60. package/ios/CodePush/CodePushPackage.m +602 -0
  61. package/ios/CodePush/CodePushTelemetryManager.m +175 -0
  62. package/ios/CodePush/CodePushUpdateUtils.m +376 -0
  63. package/ios/CodePush/CodePushUtils.m +9 -0
  64. package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithm.h +69 -0
  65. package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmFactory.h +16 -0
  66. package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmFactory.m +51 -0
  67. package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmNone.h +15 -0
  68. package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmNone.m +55 -0
  69. package/ios/CodePush/JWT/Core/Algorithms/ESFamily/JWTAlgorithmESBase.h +24 -0
  70. package/ios/CodePush/JWT/Core/Algorithms/ESFamily/JWTAlgorithmESBase.m +41 -0
  71. package/ios/CodePush/JWT/Core/Algorithms/HSFamily/JWTAlgorithmHSBase.h +28 -0
  72. package/ios/CodePush/JWT/Core/Algorithms/HSFamily/JWTAlgorithmHSBase.m +205 -0
  73. package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolder.h +103 -0
  74. package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolder.m +322 -0
  75. package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolderChain.h +37 -0
  76. package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolderChain.m +145 -0
  77. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTAlgorithmRSBase.h +35 -0
  78. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTAlgorithmRSBase.m +551 -0
  79. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTRSAlgorithm.h +23 -0
  80. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKey.h +43 -0
  81. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKey.m +230 -0
  82. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKeyExtractor.h +31 -0
  83. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKeyExtractor.m +113 -0
  84. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoSecurity.h +38 -0
  85. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoSecurity.m +500 -0
  86. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaim.h +18 -0
  87. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaim.m +214 -0
  88. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSet.h +23 -0
  89. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSet.m +29 -0
  90. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetSerializer.h +19 -0
  91. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetSerializer.m +68 -0
  92. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetVerifier.h +18 -0
  93. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetVerifier.m +72 -0
  94. package/ios/CodePush/JWT/Core/Coding/JWTCoding+ResultTypes.h +67 -0
  95. package/ios/CodePush/JWT/Core/Coding/JWTCoding+ResultTypes.m +111 -0
  96. package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionOne.h +119 -0
  97. package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionOne.m +307 -0
  98. package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionThree.h +94 -0
  99. package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionThree.m +619 -0
  100. package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionTwo.h +164 -0
  101. package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionTwo.m +514 -0
  102. package/ios/CodePush/JWT/Core/Coding/JWTCoding.h +24 -0
  103. package/ios/CodePush/JWT/Core/Coding/JWTCoding.m +11 -0
  104. package/ios/CodePush/JWT/Core/FrameworkSupplement/JWT.h +52 -0
  105. package/ios/CodePush/JWT/Core/FrameworkSupplement/Map.modulemap +5 -0
  106. package/ios/CodePush/JWT/Core/Supplement/JWTBase64Coder.h +28 -0
  107. package/ios/CodePush/JWT/Core/Supplement/JWTBase64Coder.m +70 -0
  108. package/ios/CodePush/JWT/Core/Supplement/JWTDeprecations.h +22 -0
  109. package/ios/CodePush/JWT/Core/Supplement/JWTErrorDescription.h +34 -0
  110. package/ios/CodePush/JWT/Core/Supplement/JWTErrorDescription.m +73 -0
  111. package/ios/CodePush/JWT/LICENSE +19 -0
  112. package/ios/CodePush/JWT/README.md +489 -0
  113. package/ios/CodePush/RCTConvert+CodePushInstallMode.m +20 -0
  114. package/ios/CodePush/RCTConvert+CodePushUpdateState.m +20 -0
  115. package/ios/CodePush/SSZipArchive/Info.plist +26 -0
  116. package/ios/CodePush/SSZipArchive/README.md +1 -0
  117. package/ios/CodePush/SSZipArchive/SSZipArchive.h +178 -0
  118. package/ios/CodePush/SSZipArchive/SSZipArchive.m +1496 -0
  119. package/ios/CodePush/SSZipArchive/SSZipCommon.h +71 -0
  120. package/ios/CodePush/SSZipArchive/Supporting Files/PrivacyInfo.xcprivacy +23 -0
  121. package/ios/CodePush/SSZipArchive/include/ZipArchive.h +25 -0
  122. package/ios/CodePush/SSZipArchive/minizip/LICENSE +17 -0
  123. package/ios/CodePush/SSZipArchive/minizip/mz.h +273 -0
  124. package/ios/CodePush/SSZipArchive/minizip/mz_compat.c +1306 -0
  125. package/ios/CodePush/SSZipArchive/minizip/mz_compat.h +346 -0
  126. package/ios/CodePush/SSZipArchive/minizip/mz_crypt.c +187 -0
  127. package/ios/CodePush/SSZipArchive/minizip/mz_crypt.h +65 -0
  128. package/ios/CodePush/SSZipArchive/minizip/mz_crypt_apple.c +526 -0
  129. package/ios/CodePush/SSZipArchive/minizip/mz_os.c +348 -0
  130. package/ios/CodePush/SSZipArchive/minizip/mz_os.h +176 -0
  131. package/ios/CodePush/SSZipArchive/minizip/mz_os_posix.c +350 -0
  132. package/ios/CodePush/SSZipArchive/minizip/mz_strm.c +556 -0
  133. package/ios/CodePush/SSZipArchive/minizip/mz_strm.h +132 -0
  134. package/ios/CodePush/SSZipArchive/minizip/mz_strm_buf.c +383 -0
  135. package/ios/CodePush/SSZipArchive/minizip/mz_strm_buf.h +42 -0
  136. package/ios/CodePush/SSZipArchive/minizip/mz_strm_mem.c +269 -0
  137. package/ios/CodePush/SSZipArchive/minizip/mz_strm_mem.h +48 -0
  138. package/ios/CodePush/SSZipArchive/minizip/mz_strm_os.h +40 -0
  139. package/ios/CodePush/SSZipArchive/minizip/mz_strm_os_posix.c +203 -0
  140. package/ios/CodePush/SSZipArchive/minizip/mz_strm_pkcrypt.c +334 -0
  141. package/ios/CodePush/SSZipArchive/minizip/mz_strm_pkcrypt.h +46 -0
  142. package/ios/CodePush/SSZipArchive/minizip/mz_strm_split.c +429 -0
  143. package/ios/CodePush/SSZipArchive/minizip/mz_strm_split.h +43 -0
  144. package/ios/CodePush/SSZipArchive/minizip/mz_strm_wzaes.c +360 -0
  145. package/ios/CodePush/SSZipArchive/minizip/mz_strm_wzaes.h +46 -0
  146. package/ios/CodePush/SSZipArchive/minizip/mz_strm_zlib.c +389 -0
  147. package/ios/CodePush/SSZipArchive/minizip/mz_strm_zlib.h +43 -0
  148. package/ios/CodePush/SSZipArchive/minizip/mz_zip.c +2782 -0
  149. package/ios/CodePush/SSZipArchive/minizip/mz_zip.h +262 -0
  150. package/ios/CodePush/SSZipArchive/minizip/mz_zip_rw.c +1942 -0
  151. package/ios/CodePush/SSZipArchive/minizip/mz_zip_rw.h +285 -0
  152. package/ios/CodePush.xcodeproj/project.pbxproj +1052 -0
  153. package/ios/CodePush.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  154. package/ios/CodePush.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  155. package/ios/PrivacyInfo.xcprivacy +31 -0
  156. package/logging.js +6 -0
  157. package/package-mixins.js +68 -0
  158. package/package.json +82 -0
  159. package/react-native.config.js +11 -0
  160. package/request-fetch-adapter.js +52 -0
  161. package/scripts/generateBundledResourcesHash.js +125 -0
  162. package/scripts/getFilesInFolder.js +19 -0
  163. package/scripts/postlink/android/postlink.js +87 -0
  164. package/scripts/postlink/ios/postlink.js +116 -0
  165. package/scripts/postlink/run.js +11 -0
  166. package/scripts/postunlink/android/postunlink.js +74 -0
  167. package/scripts/postunlink/ios/postunlink.js +87 -0
  168. package/scripts/postunlink/run.js +11 -0
  169. package/scripts/recordFilesBeforeBundleCommand.js +41 -0
  170. package/scripts/tools/linkToolsAndroid.js +57 -0
  171. package/scripts/tools/linkToolsIos.js +130 -0
  172. package/tsconfig.json +17 -0
  173. package/tslint.json +32 -0
  174. package/typings/react-native-code-push.d.ts +455 -0
@@ -0,0 +1,203 @@
1
+ package com.microsoft.codepush.react;
2
+
3
+ import java.io.BufferedInputStream;
4
+ import java.io.BufferedReader;
5
+ import java.io.File;
6
+ import java.io.FileInputStream;
7
+ import java.io.FileOutputStream;
8
+ import java.io.IOException;
9
+ import java.io.InputStreamReader;
10
+ import java.io.PrintWriter;
11
+ import java.util.zip.ZipEntry;
12
+ import java.util.zip.ZipInputStream;
13
+
14
+ public class FileUtils {
15
+
16
+ private static final int WRITE_BUFFER_SIZE = 1024 * 8;
17
+
18
+ public static void copyDirectoryContents(String sourceDirectoryPath, String destinationDirectoryPath) throws IOException {
19
+ File sourceDir = new File(sourceDirectoryPath);
20
+ File destDir = new File(destinationDirectoryPath);
21
+ if (!destDir.exists()) {
22
+ destDir.mkdir();
23
+ }
24
+
25
+ for (File sourceFile : sourceDir.listFiles()) {
26
+ if (sourceFile.isDirectory()) {
27
+ copyDirectoryContents(
28
+ CodePushUtils.appendPathComponent(sourceDirectoryPath, sourceFile.getName()),
29
+ CodePushUtils.appendPathComponent(destinationDirectoryPath, sourceFile.getName()));
30
+ } else {
31
+ File destFile = new File(destDir, sourceFile.getName());
32
+ FileInputStream fromFileStream = null;
33
+ BufferedInputStream fromBufferedStream = null;
34
+ FileOutputStream destStream = null;
35
+ byte[] buffer = new byte[WRITE_BUFFER_SIZE];
36
+ try {
37
+ fromFileStream = new FileInputStream(sourceFile);
38
+ fromBufferedStream = new BufferedInputStream(fromFileStream);
39
+ destStream = new FileOutputStream(destFile);
40
+ int bytesRead;
41
+ while ((bytesRead = fromBufferedStream.read(buffer)) > 0) {
42
+ destStream.write(buffer, 0, bytesRead);
43
+ }
44
+ } finally {
45
+ try {
46
+ if (fromFileStream != null) fromFileStream.close();
47
+ if (fromBufferedStream != null) fromBufferedStream.close();
48
+ if (destStream != null) destStream.close();
49
+ } catch (IOException e) {
50
+ throw new CodePushUnknownException("Error closing IO resources.", e);
51
+ }
52
+ }
53
+ }
54
+ }
55
+ }
56
+
57
+ public static void deleteDirectoryAtPath(String directoryPath) {
58
+ if (directoryPath == null) {
59
+ CodePushUtils.log("deleteDirectoryAtPath attempted with null directoryPath");
60
+ return;
61
+ }
62
+ File file = new File(directoryPath);
63
+ if (file.exists()) {
64
+ deleteFileOrFolderSilently(file);
65
+ }
66
+ }
67
+
68
+ public static void deleteFileAtPathSilently(String path) {
69
+ deleteFileOrFolderSilently(new File(path));
70
+ }
71
+
72
+ public static void deleteFileOrFolderSilently(File file) {
73
+ if (file.isDirectory()) {
74
+ File[] files = file.listFiles();
75
+ for (File fileEntry : files) {
76
+ if (fileEntry.isDirectory()) {
77
+ deleteFileOrFolderSilently(fileEntry);
78
+ } else {
79
+ fileEntry.delete();
80
+ }
81
+ }
82
+ }
83
+
84
+ if (!file.delete()) {
85
+ CodePushUtils.log("Error deleting file " + file.getName());
86
+ }
87
+ }
88
+
89
+ public static boolean fileAtPathExists(String filePath) {
90
+ return new File(filePath).exists();
91
+ }
92
+
93
+ public static void moveFile(File fileToMove, String newFolderPath, String newFileName) {
94
+ File newFolder = new File(newFolderPath);
95
+ if (!newFolder.exists()) {
96
+ newFolder.mkdirs();
97
+ }
98
+
99
+ File newFilePath = new File(newFolderPath, newFileName);
100
+ if (!fileToMove.renameTo(newFilePath)) {
101
+ throw new CodePushUnknownException("Unable to move file from " +
102
+ fileToMove.getAbsolutePath() + " to " + newFilePath.getAbsolutePath() + ".");
103
+ }
104
+ }
105
+
106
+ public static String readFileToString(String filePath) throws IOException {
107
+ FileInputStream fin = null;
108
+ BufferedReader reader = null;
109
+ try {
110
+ File fl = new File(filePath);
111
+ fin = new FileInputStream(fl);
112
+ reader = new BufferedReader(new InputStreamReader(fin));
113
+ StringBuilder sb = new StringBuilder();
114
+ String line = null;
115
+ while ((line = reader.readLine()) != null) {
116
+ sb.append(line).append("\n");
117
+ }
118
+
119
+ return sb.toString();
120
+ } finally {
121
+ if (reader != null) reader.close();
122
+ if (fin != null) fin.close();
123
+ }
124
+ }
125
+
126
+ private static String validateFileName(String fileName, File destinationFolder) throws IOException {
127
+ String destinationFolderCanonicalPath = destinationFolder.getCanonicalPath() + File.separator;
128
+
129
+ File file = new File(destinationFolderCanonicalPath, fileName);
130
+ String canonicalPath = file.getCanonicalPath();
131
+
132
+ if (!canonicalPath.startsWith(destinationFolderCanonicalPath)) {
133
+ throw new IllegalStateException("File is outside extraction target directory.");
134
+ }
135
+
136
+ return canonicalPath;
137
+ }
138
+
139
+ public static void unzipFile(File zipFile, String destination) throws IOException {
140
+ FileInputStream fileStream = null;
141
+ BufferedInputStream bufferedStream = null;
142
+ ZipInputStream zipStream = null;
143
+ try {
144
+ fileStream = new FileInputStream(zipFile);
145
+ bufferedStream = new BufferedInputStream(fileStream);
146
+ zipStream = new ZipInputStream(bufferedStream);
147
+ ZipEntry entry;
148
+
149
+ File destinationFolder = new File(destination);
150
+ if (destinationFolder.exists()) {
151
+ deleteFileOrFolderSilently(destinationFolder);
152
+ }
153
+
154
+ destinationFolder.mkdirs();
155
+
156
+ byte[] buffer = new byte[WRITE_BUFFER_SIZE];
157
+ while ((entry = zipStream.getNextEntry()) != null) {
158
+ String fileName = validateFileName(entry.getName(), destinationFolder);
159
+ File file = new File(fileName);
160
+ if (entry.isDirectory()) {
161
+ file.mkdirs();
162
+ } else {
163
+ File parent = file.getParentFile();
164
+ if (!parent.exists()) {
165
+ parent.mkdirs();
166
+ }
167
+
168
+ FileOutputStream fout = new FileOutputStream(file);
169
+ try {
170
+ int numBytesRead;
171
+ while ((numBytesRead = zipStream.read(buffer)) != -1) {
172
+ fout.write(buffer, 0, numBytesRead);
173
+ }
174
+ } finally {
175
+ fout.close();
176
+ }
177
+ }
178
+ long time = entry.getTime();
179
+ if (time > 0) {
180
+ file.setLastModified(time);
181
+ }
182
+ }
183
+ } finally {
184
+ try {
185
+ if (zipStream != null) zipStream.close();
186
+ if (bufferedStream != null) bufferedStream.close();
187
+ if (fileStream != null) fileStream.close();
188
+ } catch (IOException e) {
189
+ throw new CodePushUnknownException("Error closing IO resources.", e);
190
+ }
191
+ }
192
+ }
193
+
194
+ public static void writeStringToFile(String content, String filePath) throws IOException {
195
+ PrintWriter out = null;
196
+ try {
197
+ out = new PrintWriter(filePath);
198
+ out.print(content);
199
+ } finally {
200
+ if (out != null) out.close();
201
+ }
202
+ }
203
+ }
@@ -0,0 +1,11 @@
1
+ package com.microsoft.codepush.react;
2
+
3
+ import com.facebook.react.ReactHost;
4
+ import com.facebook.react.runtime.ReactHostDelegate;
5
+
6
+ /**
7
+ * Provides access to a {@link ReactHostDelegate}
8
+ */
9
+ public interface ReactHostHolder {
10
+ ReactHost getReactHost();
11
+ }
@@ -0,0 +1,17 @@
1
+ package com.microsoft.codepush.react;
2
+
3
+ import com.facebook.react.ReactInstanceManager;
4
+
5
+ /**
6
+ * Provides access to a {@link ReactInstanceManager}.
7
+ *
8
+ * ReactNativeHost already implements this interface, if you make use of that react-native
9
+ * component (just add `implements ReactInstanceHolder`).
10
+ */
11
+ public interface ReactInstanceHolder {
12
+
13
+ /**
14
+ * Get the current {@link ReactInstanceManager} instance. May return null.
15
+ */
16
+ ReactInstanceManager getReactInstanceManager();
17
+ }
@@ -0,0 +1,173 @@
1
+ package com.microsoft.codepush.react;
2
+
3
+ import android.content.Context;
4
+ import android.content.SharedPreferences;
5
+
6
+ import org.json.JSONArray;
7
+ import org.json.JSONException;
8
+ import org.json.JSONObject;
9
+
10
+ public class SettingsManager {
11
+
12
+ private SharedPreferences mSettings;
13
+
14
+ public SettingsManager(Context applicationContext) {
15
+ mSettings = applicationContext.getSharedPreferences(CodePushConstants.CODE_PUSH_PREFERENCES, 0);
16
+ }
17
+
18
+ public JSONArray getFailedUpdates() {
19
+ String failedUpdatesString = mSettings.getString(CodePushConstants.FAILED_UPDATES_KEY, null);
20
+ if (failedUpdatesString == null) {
21
+ return new JSONArray();
22
+ }
23
+
24
+ try {
25
+ return new JSONArray(failedUpdatesString);
26
+ } catch (JSONException e) {
27
+ // Unrecognized data format, clear and replace with expected format.
28
+ JSONArray emptyArray = new JSONArray();
29
+ mSettings.edit().putString(CodePushConstants.FAILED_UPDATES_KEY, emptyArray.toString()).commit();
30
+ return emptyArray;
31
+ }
32
+ }
33
+
34
+ public JSONObject getPendingUpdate() {
35
+ String pendingUpdateString = mSettings.getString(CodePushConstants.PENDING_UPDATE_KEY, null);
36
+ if (pendingUpdateString == null) {
37
+ return null;
38
+ }
39
+
40
+ try {
41
+ return new JSONObject(pendingUpdateString);
42
+ } catch (JSONException e) {
43
+ // Should not happen.
44
+ CodePushUtils.log("Unable to parse pending update metadata " + pendingUpdateString +
45
+ " stored in SharedPreferences");
46
+ return null;
47
+ }
48
+ }
49
+
50
+
51
+ public boolean isFailedHash(String packageHash) {
52
+ JSONArray failedUpdates = getFailedUpdates();
53
+ if (packageHash != null) {
54
+ for (int i = 0; i < failedUpdates.length(); i++) {
55
+ try {
56
+ JSONObject failedPackage = failedUpdates.getJSONObject(i);
57
+ String failedPackageHash = failedPackage.getString(CodePushConstants.PACKAGE_HASH_KEY);
58
+ if (packageHash.equals(failedPackageHash)) {
59
+ return true;
60
+ }
61
+ } catch (JSONException e) {
62
+ throw new CodePushUnknownException("Unable to read failedUpdates data stored in SharedPreferences.", e);
63
+ }
64
+ }
65
+ }
66
+
67
+ return false;
68
+ }
69
+
70
+ public boolean isPendingUpdate(String packageHash) {
71
+ JSONObject pendingUpdate = getPendingUpdate();
72
+
73
+ try {
74
+ return pendingUpdate != null &&
75
+ !pendingUpdate.getBoolean(CodePushConstants.PENDING_UPDATE_IS_LOADING_KEY) &&
76
+ (packageHash == null || pendingUpdate.getString(CodePushConstants.PENDING_UPDATE_HASH_KEY).equals(packageHash));
77
+ } catch (JSONException e) {
78
+ throw new CodePushUnknownException("Unable to read pending update metadata in isPendingUpdate.", e);
79
+ }
80
+ }
81
+
82
+ public void removeFailedUpdates() {
83
+ mSettings.edit().remove(CodePushConstants.FAILED_UPDATES_KEY).commit();
84
+ }
85
+
86
+ public void removePendingUpdate() {
87
+ mSettings.edit().remove(CodePushConstants.PENDING_UPDATE_KEY).commit();
88
+ }
89
+
90
+ public void saveFailedUpdate(JSONObject failedPackage) {
91
+ try {
92
+ if (isFailedHash(failedPackage.getString(CodePushConstants.PACKAGE_HASH_KEY))) {
93
+ // Do not need to add the package if it is already in the failedUpdates.
94
+ return;
95
+ }
96
+ } catch (JSONException e) {
97
+ throw new CodePushUnknownException("Unable to read package hash from package.", e);
98
+ }
99
+
100
+ String failedUpdatesString = mSettings.getString(CodePushConstants.FAILED_UPDATES_KEY, null);
101
+ JSONArray failedUpdates;
102
+ if (failedUpdatesString == null) {
103
+ failedUpdates = new JSONArray();
104
+ } else {
105
+ try {
106
+ failedUpdates = new JSONArray(failedUpdatesString);
107
+ } catch (JSONException e) {
108
+ // Should not happen.
109
+ throw new CodePushMalformedDataException("Unable to parse failed updates information " +
110
+ failedUpdatesString + " stored in SharedPreferences", e);
111
+ }
112
+ }
113
+
114
+ failedUpdates.put(failedPackage);
115
+ mSettings.edit().putString(CodePushConstants.FAILED_UPDATES_KEY, failedUpdates.toString()).commit();
116
+ }
117
+
118
+ public JSONObject getLatestRollbackInfo() {
119
+ String latestRollbackInfoString = mSettings.getString(CodePushConstants.LATEST_ROLLBACK_INFO_KEY, null);
120
+ if (latestRollbackInfoString == null) {
121
+ return null;
122
+ }
123
+
124
+ try {
125
+ return new JSONObject(latestRollbackInfoString);
126
+ } catch (JSONException e) {
127
+ // Should not happen.
128
+ CodePushUtils.log("Unable to parse latest rollback metadata " + latestRollbackInfoString +
129
+ " stored in SharedPreferences");
130
+ return null;
131
+ }
132
+ }
133
+
134
+ public void setLatestRollbackInfo(String packageHash) {
135
+ JSONObject latestRollbackInfo = getLatestRollbackInfo();
136
+ int count = 0;
137
+
138
+ if (latestRollbackInfo != null) {
139
+ try {
140
+ String latestRollbackPackageHash = latestRollbackInfo.getString(CodePushConstants.LATEST_ROLLBACK_PACKAGE_HASH_KEY);
141
+ if (latestRollbackPackageHash.equals(packageHash)) {
142
+ count = latestRollbackInfo.getInt(CodePushConstants.LATEST_ROLLBACK_COUNT_KEY);
143
+ }
144
+ } catch (JSONException e) {
145
+ CodePushUtils.log("Unable to parse latest rollback info.");
146
+ }
147
+ } else {
148
+ latestRollbackInfo = new JSONObject();
149
+ }
150
+
151
+ try {
152
+ latestRollbackInfo.put(CodePushConstants.LATEST_ROLLBACK_PACKAGE_HASH_KEY, packageHash);
153
+ latestRollbackInfo.put(CodePushConstants.LATEST_ROLLBACK_TIME_KEY, System.currentTimeMillis());
154
+ latestRollbackInfo.put(CodePushConstants.LATEST_ROLLBACK_COUNT_KEY, count + 1);
155
+ mSettings.edit().putString(CodePushConstants.LATEST_ROLLBACK_INFO_KEY, latestRollbackInfo.toString()).commit();
156
+ } catch (JSONException e) {
157
+ throw new CodePushUnknownException("Unable to save latest rollback info.", e);
158
+ }
159
+ }
160
+
161
+ public void savePendingUpdate(String packageHash, boolean isLoading) {
162
+ JSONObject pendingUpdate = new JSONObject();
163
+ try {
164
+ pendingUpdate.put(CodePushConstants.PENDING_UPDATE_HASH_KEY, packageHash);
165
+ pendingUpdate.put(CodePushConstants.PENDING_UPDATE_IS_LOADING_KEY, isLoading);
166
+ mSettings.edit().putString(CodePushConstants.PENDING_UPDATE_KEY, pendingUpdate.toString()).commit();
167
+ } catch (JSONException e) {
168
+ // Should not happen.
169
+ throw new CodePushUnknownException("Unable to save pending update.", e);
170
+ }
171
+ }
172
+
173
+ }
@@ -0,0 +1,72 @@
1
+ package com.microsoft.codepush.react;
2
+
3
+ import java.io.IOException;
4
+ import java.net.InetAddress;
5
+ import java.net.Socket;
6
+ import java.net.UnknownHostException;
7
+ import java.security.KeyManagementException;
8
+ import java.security.NoSuchAlgorithmException;
9
+
10
+ import javax.net.ssl.SSLContext;
11
+ import javax.net.ssl.SSLSocket;
12
+ import javax.net.ssl.SSLSocketFactory;
13
+
14
+ public class TLSSocketFactory extends SSLSocketFactory {
15
+
16
+ private SSLSocketFactory delegate;
17
+
18
+ public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
19
+ SSLContext context = SSLContext.getInstance("TLS");
20
+ context.init(null, null, null);
21
+ delegate = context.getSocketFactory();
22
+ }
23
+
24
+ @Override
25
+ public String[] getDefaultCipherSuites() {
26
+ return delegate.getDefaultCipherSuites();
27
+ }
28
+
29
+ @Override
30
+ public String[] getSupportedCipherSuites() {
31
+ return delegate.getSupportedCipherSuites();
32
+ }
33
+
34
+ @Override
35
+ public Socket createSocket() throws IOException {
36
+ return enableTLSOnSocket(delegate.createSocket());
37
+ }
38
+
39
+ @Override
40
+ public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
41
+ return enableTLSOnSocket(delegate.createSocket(s, host, port, autoClose));
42
+ }
43
+
44
+ @Override
45
+ public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
46
+ return enableTLSOnSocket(delegate.createSocket(host, port));
47
+ }
48
+
49
+ @Override
50
+ public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
51
+ throws IOException, UnknownHostException {
52
+ return enableTLSOnSocket(delegate.createSocket(host, port, localHost, localPort));
53
+ }
54
+
55
+ @Override
56
+ public Socket createSocket(InetAddress host, int port) throws IOException {
57
+ return enableTLSOnSocket(delegate.createSocket(host, port));
58
+ }
59
+
60
+ @Override
61
+ public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
62
+ throws IOException {
63
+ return enableTLSOnSocket(delegate.createSocket(address, port, localAddress, localPort));
64
+ }
65
+
66
+ private Socket enableTLSOnSocket(Socket socket) {
67
+ if (socket != null && (socket instanceof SSLSocket)) {
68
+ ((SSLSocket) socket).setEnabledProtocols(new String[] { "TLSv1.1", "TLSv1.2" });
69
+ }
70
+ return socket;
71
+ }
72
+ }
@@ -0,0 +1,24 @@
1
+ // Top-level build file where you can add configuration options common to all sub-projects/modules.
2
+
3
+ buildscript {
4
+ repositories {
5
+ google()
6
+ mavenCentral()
7
+ }
8
+ dependencies {
9
+ classpath 'com.android.tools.build:gradle:1.3.0'
10
+
11
+ // NOTE: Do not place your application dependencies here; they belong
12
+ // in the individual module build.gradle files
13
+ }
14
+ }
15
+
16
+ allprojects {
17
+ android {
18
+ namespace "com.microsoft.codepush.react"
19
+ }
20
+ repositories {
21
+ mavenLocal()
22
+ mavenCentral()
23
+ }
24
+ }
@@ -0,0 +1,162 @@
1
+ // Adapted from https://raw.githubusercontent.com/facebook/react-native/d16ff3bd8b92fa84a9007bf5ebedd8153e4c089d/react.gradle
2
+
3
+ import java.nio.file.Paths;
4
+
5
+ def config = project.extensions.findByName("react") ?: [:]
6
+ def bundleAssetName = config.bundleAssetName ? config.bundleAssetName.get() : "index.android.bundle"
7
+
8
+ // because elvis operator
9
+ def elvisFile(thing) {
10
+ return thing ? file(thing) : null;
11
+ }
12
+
13
+ void runBefore(String dependentTaskName, Task task) {
14
+ Task dependentTask = tasks.findByPath(dependentTaskName);
15
+ if (dependentTask != null) {
16
+ dependentTask.dependsOn task
17
+ }
18
+ }
19
+
20
+ /**
21
+ * Finds the path of the installed npm package with the given name using Node's
22
+ * module resolution algorithm, which searches "node_modules" directories up to
23
+ * the file system root. This handles various cases, including:
24
+ *
25
+ * - Working in the open-source RN repo:
26
+ * Gradle: /path/to/react-native/ReactAndroid
27
+ * Node module: /path/to/react-native/node_modules/[package]
28
+ *
29
+ * - Installing RN as a dependency of an app and searching for hoisted
30
+ * dependencies:
31
+ * Gradle: /path/to/app/node_modules/react-native/ReactAndroid
32
+ * Node module: /path/to/app/node_modules/[package]
33
+ *
34
+ * - Working in a larger repo (e.g., Facebook) that contains RN:
35
+ * Gradle: /path/to/repo/path/to/react-native/ReactAndroid
36
+ * Node module: /path/to/repo/node_modules/[package]
37
+ *
38
+ * The search begins at the given base directory (a File object). The returned
39
+ * path is a string.
40
+ */
41
+ static def findNodeModulePath(baseDir, packageName) {
42
+ def basePath = baseDir.toPath().normalize()
43
+ // Node's module resolution algorithm searches up to the root directory,
44
+ // after which the base path will be null
45
+ while (basePath) {
46
+ def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName)
47
+ if (candidatePath.toFile().exists()) {
48
+ return candidatePath.toString()
49
+ }
50
+ basePath = basePath.getParent()
51
+ }
52
+ return null
53
+ }
54
+
55
+ android.buildTypes.each { buildType ->
56
+ // to prevent incorrect long value restoration from strings.xml we need to wrap it with double quotes
57
+ // https://github.com/microsoft/cordova-plugin-code-push/issues/264
58
+ buildType.resValue 'string', "CODE_PUSH_APK_BUILD_TIME", String.format("\"%d\"", System.currentTimeMillis())
59
+ }
60
+
61
+ gradle.projectsEvaluated {
62
+ def debuggableVariants = config.debuggableVariants ? config.debuggableVariants.get() : ['debug']
63
+
64
+ android.applicationVariants.all { variant ->
65
+ // No code push for debuggable variants
66
+ if (debuggableVariants.contains(variant.name)) {
67
+ return;
68
+ }
69
+
70
+ def nodeModulesPath;
71
+ if (project.hasProperty('nodeModulesPath')) {
72
+ nodeModulesPath = "${project.nodeModulesPath}/@revopush/react-native-code-push"
73
+ } else {
74
+ nodeModulesPath = findNodeModulePath(projectDir, "@revopush/react-native-code-push")
75
+ }
76
+
77
+ def targetName = variant.name.capitalize()
78
+ def targetPath = variant.dirName
79
+
80
+ def jsBundleDir;
81
+ def resourcesDir;
82
+ def jsBundleFile;
83
+
84
+ // Additional node commandline arguments
85
+ def nodeExecutableAndArgs = config.nodeExecutableAndArgs ? config.nodeExecutableAndArgs.get(): ["node"]
86
+ def extraPackagerArgs = config.extraPackagerArgs ? config.extraPackagerArgs.get() : []
87
+
88
+ // Make this task run right after the bundle task
89
+ def generateBundledResourcesHash;
90
+
91
+ def reactBundleTask = tasks.findByName("createBundle${targetName}JsAndAssets")
92
+ if (reactBundleTask) {
93
+ jsBundleDir = reactBundleTask.property('jsBundleDir').asFile.get()
94
+ resourcesDir = reactBundleTask.property('resourcesDir').asFile.get()
95
+
96
+ // mitigates Resource and asset merger: Duplicate resources error
97
+ project.delete(files("${jsBundleDir}"))
98
+
99
+ jsBundleDir.mkdirs()
100
+ resourcesDir.mkdirs()
101
+
102
+ jsBundleFile = file("$jsBundleDir/$bundleAssetName")
103
+
104
+ generateBundledResourcesHash = tasks.create(
105
+ name: "generateBundledResourcesHash${targetName}",
106
+ type: Exec) {
107
+ commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/scripts/generateBundledResourcesHash.js", resourcesDir, jsBundleFile, jsBundleDir)
108
+
109
+ enabled !debuggableVariants.contains(variant.name) ?: targetName.toLowerCase().contains("release")
110
+ }
111
+
112
+ runBefore("merge${targetName}Resources", generateBundledResourcesHash)
113
+ runBefore("merge${targetName}Assets", generateBundledResourcesHash)
114
+ } else {
115
+ def jsBundleDirConfigName = "jsBundleDir${targetName}"
116
+ jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ? elvisFile(config."$jsBundleDirConfigName").get():
117
+ file("$buildDir/intermediates/assets/${targetPath}")
118
+
119
+ def resourcesDirConfigName = "resourcesDir${targetName}"
120
+ resourcesDir = elvisFile(config."${resourcesDirConfigName}") ? elvisFile(config."${resourcesDirConfigName}").get():
121
+ file("$buildDir/intermediates/res/merged/${targetPath}")
122
+
123
+ // In case version of 'Android Plugin for Gradle'' is lower than 1.3.0
124
+ // '$buildDir' has slightly different structure - 'merged' folder
125
+ // does not exists so '${targetPath}' folder contains directly in 'res' folder.
126
+ if (!resourcesDir.exists() && file("$buildDir/intermediates/res/${targetPath}").exists()) {
127
+ resourcesDir = file("$buildDir/intermediates/res/${targetPath}")
128
+ }
129
+
130
+ jsBundleFile = file("$jsBundleDir/$bundleAssetName")
131
+
132
+ def resourcesMapTempFileName = "CodePushResourcesMap-" + java.util.UUID.randomUUID().toString().substring(0,8) + ".json"
133
+
134
+ generateBundledResourcesHash = tasks.create(
135
+ name: "generateBundledResourcesHash${targetName}",
136
+ type: Exec) {
137
+ commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/scripts/generateBundledResourcesHash.js", resourcesDir, jsBundleFile, jsBundleDir, resourcesMapTempFileName)
138
+ }
139
+
140
+ // Make this task run right before the bundle task
141
+ def recordFilesBeforeBundleCommand = tasks.create(
142
+ name: "recordFilesBeforeBundleCommand${targetName}",
143
+ type: Exec) {
144
+ commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/scripts/recordFilesBeforeBundleCommand.js", resourcesDir, resourcesMapTempFileName)
145
+ }
146
+
147
+ recordFilesBeforeBundleCommand.dependsOn("merge${targetName}Resources")
148
+ recordFilesBeforeBundleCommand.dependsOn("merge${targetName}Assets")
149
+ runBefore("bundle${targetName}JsAndAssets", recordFilesBeforeBundleCommand)
150
+
151
+ // We need to generate and record the resources map, but we use it to generate the bundle hash
152
+ generateBundledResourcesHash.dependsOn("recordFilesBeforeBundleCommand${targetName}")
153
+ }
154
+
155
+ generateBundledResourcesHash.dependsOn("createBundle${targetName}JsAndAssets")
156
+
157
+ runBefore("processArmeabi-v7a${targetName}Resources", generateBundledResourcesHash)
158
+ runBefore("processX86${targetName}Resources", generateBundledResourcesHash)
159
+ runBefore("processUniversal${targetName}Resources", generateBundledResourcesHash)
160
+ runBefore("process${targetName}Resources", generateBundledResourcesHash)
161
+ }
162
+ }
@@ -0,0 +1,5 @@
1
+ distributionBase=GRADLE_USER_HOME
2
+ distributionPath=wrapper/dists
3
+ zipStoreBase=GRADLE_USER_HOME
4
+ zipStorePath=wrapper/dists
5
+ distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip