@capawesome/cordova-live-update 0.1.0
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 +1113 -0
- package/dist/docs.json +1654 -0
- package/dist/esm/definitions.d.ts +788 -0
- package/dist/esm/definitions.js +7 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/exec.d.ts +1 -0
- package/dist/esm/exec.js +8 -0
- package/dist/esm/exec.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +46 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/plugin.js +56 -0
- package/dist/plugin.js.map +1 -0
- package/package.json +93 -0
- package/plugin.xml +268 -0
- package/src/android/capawesome-cordova-live-update.gradle +12 -0
- package/src/android/capawesome-live-update.xml +5 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/LiveUpdate.java +1480 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/LiveUpdateConfig.java +105 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/LiveUpdateHttpClient.java +114 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/LiveUpdatePathHandler.java +96 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/LiveUpdatePlugin.java +550 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/LiveUpdatePreferences.java +151 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/Manifest.java +58 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/ManifestItem.java +37 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/api/GetChannelsResponseItem.java +28 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/api/GetLatestBundleResponse.java +74 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/events/DownloadBundleProgressEvent.java +33 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/events/NextBundleSetEvent.java +26 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/options/DeleteBundleOptions.java +18 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/options/DownloadBundleOptions.java +66 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/options/FetchChannelsOptions.java +39 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/options/FetchLatestBundleOptions.java +25 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/options/SetChannelOptions.java +18 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/options/SetConfigOptions.java +20 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/options/SetCustomIdOptions.java +18 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/options/SetNextBundleOptions.java +21 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/options/SyncOptions.java +25 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/ChannelResult.java +29 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/FetchChannelsResult.java +29 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/FetchLatestBundleResult.java +69 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/GetBlockedBundlesResult.java +28 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/GetBundlesResult.java +28 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/GetChannelResult.java +22 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/GetConfigResult.java +40 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/GetCurrentBundleResult.java +22 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/GetCustomIdResult.java +22 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/GetDeviceIdResult.java +22 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/GetDownloadedBundlesResult.java +28 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/GetNextBundleResult.java +22 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/GetVersionCodeResult.java +21 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/GetVersionNameResult.java +22 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/IsSyncingResult.java +27 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/ReadyResult.java +32 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/classes/results/SyncResult.java +22 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/enums/ArtifactType.java +6 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/interfaces/Callback.java +5 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/interfaces/DownloadProgressCallback.java +5 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/interfaces/EmptyCallback.java +5 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/interfaces/NonEmptyCallback.java +7 -0
- package/src/android/io/capawesome/cordova/plugins/liveupdate/interfaces/Result.java +8 -0
- package/src/ios/LiveUpdate.swift +895 -0
- package/src/ios/LiveUpdateArtifactType.swift +4 -0
- package/src/ios/LiveUpdateChannelResult.swift +18 -0
- package/src/ios/LiveUpdateConfig.swift +11 -0
- package/src/ios/LiveUpdateDeleteBundleOptions.swift +13 -0
- package/src/ios/LiveUpdateDownloadBundleOptions.swift +41 -0
- package/src/ios/LiveUpdateDownloadBundleProgressEvent.swift +24 -0
- package/src/ios/LiveUpdateError.swift +62 -0
- package/src/ios/LiveUpdateFetchChannelsOptions.swift +25 -0
- package/src/ios/LiveUpdateFetchChannelsResult.swift +15 -0
- package/src/ios/LiveUpdateFetchLatestBundleOptions.swift +17 -0
- package/src/ios/LiveUpdateFetchLatestBundleResult.swift +42 -0
- package/src/ios/LiveUpdateGetBlockedBundlesResult.swift +15 -0
- package/src/ios/LiveUpdateGetBundlesResult.swift +15 -0
- package/src/ios/LiveUpdateGetChannelResult.swift +15 -0
- package/src/ios/LiveUpdateGetChannelsResponseItem.swift +4 -0
- package/src/ios/LiveUpdateGetConfigResult.swift +18 -0
- package/src/ios/LiveUpdateGetCurrentBundleResult.swift +15 -0
- package/src/ios/LiveUpdateGetCustomIdResult.swift +15 -0
- package/src/ios/LiveUpdateGetDeviceIdResult.swift +15 -0
- package/src/ios/LiveUpdateGetDownloadedBundlesResult.swift +15 -0
- package/src/ios/LiveUpdateGetLatestBundleResponse.swift +8 -0
- package/src/ios/LiveUpdateGetNextBundleResult.swift +15 -0
- package/src/ios/LiveUpdateGetVersionCodeResult.swift +15 -0
- package/src/ios/LiveUpdateGetVersionNameResult.swift +15 -0
- package/src/ios/LiveUpdateHttpClient.swift +58 -0
- package/src/ios/LiveUpdateIsSyncingResult.swift +15 -0
- package/src/ios/LiveUpdateManifest.swift +19 -0
- package/src/ios/LiveUpdateManifestItem.swift +5 -0
- package/src/ios/LiveUpdateNextBundleSetEvent.swift +15 -0
- package/src/ios/LiveUpdatePlugin.swift +521 -0
- package/src/ios/LiveUpdatePreferences.swift +116 -0
- package/src/ios/LiveUpdateReadyResult.swift +21 -0
- package/src/ios/LiveUpdateResult.swift +5 -0
- package/src/ios/LiveUpdateSchemeHandler.swift +286 -0
- package/src/ios/LiveUpdateSetChannelOptions.swift +13 -0
- package/src/ios/LiveUpdateSetConfigOptions.swift +13 -0
- package/src/ios/LiveUpdateSetCustomIdOptions.swift +13 -0
- package/src/ios/LiveUpdateSetNextBundleOptions.swift +13 -0
- package/src/ios/LiveUpdateSyncOptions.swift +17 -0
- package/src/ios/LiveUpdateSyncResult.swift +15 -0
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
package io.capawesome.cordova.plugins.liveupdate;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.content.res.Resources;
|
|
5
|
+
import android.util.Log;
|
|
6
|
+
import androidx.annotation.NonNull;
|
|
7
|
+
import androidx.annotation.Nullable;
|
|
8
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.events.DownloadBundleProgressEvent;
|
|
9
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.events.NextBundleSetEvent;
|
|
10
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.options.DeleteBundleOptions;
|
|
11
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.options.DownloadBundleOptions;
|
|
12
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.options.FetchChannelsOptions;
|
|
13
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.options.FetchLatestBundleOptions;
|
|
14
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.options.SetChannelOptions;
|
|
15
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.options.SetConfigOptions;
|
|
16
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.options.SetCustomIdOptions;
|
|
17
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.options.SetNextBundleOptions;
|
|
18
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.options.SyncOptions;
|
|
19
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.results.FetchChannelsResult;
|
|
20
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.results.FetchLatestBundleResult;
|
|
21
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.results.GetBlockedBundlesResult;
|
|
22
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.results.GetConfigResult;
|
|
23
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.results.GetCurrentBundleResult;
|
|
24
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.results.GetDownloadedBundlesResult;
|
|
25
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.results.GetNextBundleResult;
|
|
26
|
+
import io.capawesome.cordova.plugins.liveupdate.classes.results.IsSyncingResult;
|
|
27
|
+
import io.capawesome.cordova.plugins.liveupdate.interfaces.EmptyCallback;
|
|
28
|
+
import io.capawesome.cordova.plugins.liveupdate.interfaces.NonEmptyCallback;
|
|
29
|
+
import io.capawesome.cordova.plugins.liveupdate.interfaces.Result;
|
|
30
|
+
import java.util.Iterator;
|
|
31
|
+
import java.util.Map;
|
|
32
|
+
import java.util.concurrent.ConcurrentHashMap;
|
|
33
|
+
import org.apache.cordova.CallbackContext;
|
|
34
|
+
import org.apache.cordova.CordovaPlugin;
|
|
35
|
+
import org.apache.cordova.CordovaPluginPathHandler;
|
|
36
|
+
import org.apache.cordova.PluginResult;
|
|
37
|
+
import org.json.JSONArray;
|
|
38
|
+
import org.json.JSONException;
|
|
39
|
+
import org.json.JSONObject;
|
|
40
|
+
|
|
41
|
+
public class LiveUpdatePlugin extends CordovaPlugin {
|
|
42
|
+
|
|
43
|
+
public static final String TAG = "LiveUpdate";
|
|
44
|
+
public static final String VERSION = "0.1.0";
|
|
45
|
+
public static final String SHARED_PREFERENCES_NAME = "CapawesomeLiveUpdate"; // DO NOT CHANGE
|
|
46
|
+
public static final String ERROR_APP_ID_MISSING = "appId must be configured.";
|
|
47
|
+
public static final String ERROR_BUNDLE_EXISTS = "bundle already exists.";
|
|
48
|
+
public static final String ERROR_BUNDLE_ID_MISSING = "bundleId must be provided.";
|
|
49
|
+
public static final String ERROR_BUNDLE_INDEX_HTML_MISSING = "The bundle does not contain an index.html file.";
|
|
50
|
+
public static final String ERROR_BUNDLE_NOT_FOUND = "bundle not found.";
|
|
51
|
+
public static final String ERROR_CHECKSUM_CALCULATION_FAILED = "Failed to calculate checksum.";
|
|
52
|
+
public static final String ERROR_CHECKSUM_MISMATCH = "Checksum mismatch.";
|
|
53
|
+
public static final String ERROR_CUSTOM_ID_MISSING = "customId must be provided.";
|
|
54
|
+
public static final String ERROR_DOWNLOAD_FAILED = "Bundle could not be downloaded.";
|
|
55
|
+
public static final String ERROR_HTTP_TIMEOUT = "Request timed out.";
|
|
56
|
+
public static final String ERROR_URL_MISSING = "url must be provided.";
|
|
57
|
+
public static final String ERROR_SIGNATURE_VERIFICATION_FAILED = "Signature verification failed.";
|
|
58
|
+
public static final String ERROR_PUBLIC_KEY_INVALID = "Invalid public key.";
|
|
59
|
+
public static final String ERROR_SIGNATURE_MISSING = "Bundle does not contain a signature.";
|
|
60
|
+
public static final String ERROR_SYNC_IN_PROGRESS = "Sync is already in progress.";
|
|
61
|
+
public static final String ERROR_UNKNOWN_ERROR = "An unknown error has occurred.";
|
|
62
|
+
public static final String ERROR_PLUGIN_NOT_INITIALIZED = "LiveUpdate plugin failed to initialize.";
|
|
63
|
+
public static final String ERROR_LISTENER_ID_MISSING = "listenerId must be provided.";
|
|
64
|
+
public static final String EVENT_DOWNLOAD_BUNDLE_PROGRESS = "downloadBundleProgress";
|
|
65
|
+
public static final String EVENT_NEXT_BUNDLE_SET = "nextBundleSet";
|
|
66
|
+
|
|
67
|
+
@Nullable
|
|
68
|
+
private LiveUpdateConfig config;
|
|
69
|
+
|
|
70
|
+
@Nullable
|
|
71
|
+
private LiveUpdate implementation;
|
|
72
|
+
|
|
73
|
+
@Nullable
|
|
74
|
+
private LiveUpdatePathHandler pathHandler;
|
|
75
|
+
|
|
76
|
+
@Nullable
|
|
77
|
+
private CordovaPluginPathHandler cordovaPathHandler;
|
|
78
|
+
|
|
79
|
+
private final Map<String, ListenerRegistration> listeners = new ConcurrentHashMap<>();
|
|
80
|
+
|
|
81
|
+
private static final class ListenerRegistration {
|
|
82
|
+
|
|
83
|
+
@NonNull
|
|
84
|
+
final String eventName;
|
|
85
|
+
|
|
86
|
+
@NonNull
|
|
87
|
+
final CallbackContext callback;
|
|
88
|
+
|
|
89
|
+
ListenerRegistration(@NonNull String eventName, @NonNull CallbackContext callback) {
|
|
90
|
+
this.eventName = eventName;
|
|
91
|
+
this.callback = callback;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@Override
|
|
96
|
+
protected void pluginInitialize() {
|
|
97
|
+
super.pluginInitialize();
|
|
98
|
+
try {
|
|
99
|
+
config = loadLiveUpdateConfig();
|
|
100
|
+
if (pathHandler == null) {
|
|
101
|
+
pathHandler = new LiveUpdatePathHandler();
|
|
102
|
+
}
|
|
103
|
+
implementation = new LiveUpdate(config, this, pathHandler);
|
|
104
|
+
} catch (Exception exception) {
|
|
105
|
+
Log.e(TAG, "Failed to initialize LiveUpdate plugin: " + exception.getMessage(), exception);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@Override
|
|
110
|
+
public CordovaPluginPathHandler getPathHandler() {
|
|
111
|
+
if (pathHandler == null) {
|
|
112
|
+
pathHandler = new LiveUpdatePathHandler();
|
|
113
|
+
}
|
|
114
|
+
if (cordovaPathHandler == null) {
|
|
115
|
+
cordovaPathHandler = new CordovaPluginPathHandler(pathHandler);
|
|
116
|
+
}
|
|
117
|
+
return cordovaPathHandler;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@Override
|
|
121
|
+
public void onResume(boolean multitasking) {
|
|
122
|
+
super.onResume(multitasking);
|
|
123
|
+
if (implementation != null) {
|
|
124
|
+
implementation.handleOnResume();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@Override
|
|
129
|
+
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
|
|
130
|
+
if (implementation == null || config == null) {
|
|
131
|
+
callbackContext.error(ERROR_PLUGIN_NOT_INITIALIZED);
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
switch (action) {
|
|
136
|
+
case "clearBlockedBundles":
|
|
137
|
+
implementation.clearBlockedBundles();
|
|
138
|
+
resolve(callbackContext);
|
|
139
|
+
return true;
|
|
140
|
+
case "deleteBundle":
|
|
141
|
+
executeDeleteBundle(args, callbackContext);
|
|
142
|
+
return true;
|
|
143
|
+
case "downloadBundle":
|
|
144
|
+
executeDownloadBundle(args, callbackContext);
|
|
145
|
+
return true;
|
|
146
|
+
case "fetchChannels":
|
|
147
|
+
executeFetchChannels(args, callbackContext);
|
|
148
|
+
return true;
|
|
149
|
+
case "fetchLatestBundle":
|
|
150
|
+
executeFetchLatestBundle(args, callbackContext);
|
|
151
|
+
return true;
|
|
152
|
+
case "getBlockedBundles":
|
|
153
|
+
implementation.getBlockedBundles(resultCallback(callbackContext));
|
|
154
|
+
return true;
|
|
155
|
+
case "getBundles":
|
|
156
|
+
implementation.getBundles(resultCallback(callbackContext));
|
|
157
|
+
return true;
|
|
158
|
+
case "getChannel":
|
|
159
|
+
implementation.getChannel(resultCallback(callbackContext));
|
|
160
|
+
return true;
|
|
161
|
+
case "getConfig":
|
|
162
|
+
implementation.getConfig(resultCallback(callbackContext));
|
|
163
|
+
return true;
|
|
164
|
+
case "getCurrentBundle":
|
|
165
|
+
implementation.getCurrentBundle(resultCallback(callbackContext));
|
|
166
|
+
return true;
|
|
167
|
+
case "getCustomId":
|
|
168
|
+
implementation.getCustomId(resultCallback(callbackContext));
|
|
169
|
+
return true;
|
|
170
|
+
case "getDeviceId":
|
|
171
|
+
implementation.getDeviceId(resultCallback(callbackContext));
|
|
172
|
+
return true;
|
|
173
|
+
case "getDownloadedBundles":
|
|
174
|
+
implementation.getDownloadedBundles(resultCallback(callbackContext));
|
|
175
|
+
return true;
|
|
176
|
+
case "getNextBundle":
|
|
177
|
+
implementation.getNextBundle(resultCallback(callbackContext));
|
|
178
|
+
return true;
|
|
179
|
+
case "getVersionCode":
|
|
180
|
+
implementation.getVersionCode(resultCallback(callbackContext));
|
|
181
|
+
return true;
|
|
182
|
+
case "getVersionName":
|
|
183
|
+
implementation.getVersionName(resultCallback(callbackContext));
|
|
184
|
+
return true;
|
|
185
|
+
case "isSyncing":
|
|
186
|
+
implementation.isSyncing(resultCallback(callbackContext));
|
|
187
|
+
return true;
|
|
188
|
+
case "ready":
|
|
189
|
+
implementation.ready(resultCallback(callbackContext));
|
|
190
|
+
return true;
|
|
191
|
+
case "reload":
|
|
192
|
+
implementation.reload();
|
|
193
|
+
resolve(callbackContext);
|
|
194
|
+
return true;
|
|
195
|
+
case "reset":
|
|
196
|
+
implementation.reset();
|
|
197
|
+
resolve(callbackContext);
|
|
198
|
+
return true;
|
|
199
|
+
case "resetConfig":
|
|
200
|
+
implementation.resetConfig();
|
|
201
|
+
resolve(callbackContext);
|
|
202
|
+
return true;
|
|
203
|
+
case "setChannel":
|
|
204
|
+
executeSetChannel(args, callbackContext);
|
|
205
|
+
return true;
|
|
206
|
+
case "setConfig":
|
|
207
|
+
executeSetConfig(args, callbackContext);
|
|
208
|
+
return true;
|
|
209
|
+
case "setCustomId":
|
|
210
|
+
executeSetCustomId(args, callbackContext);
|
|
211
|
+
return true;
|
|
212
|
+
case "setNextBundle":
|
|
213
|
+
executeSetNextBundle(args, callbackContext);
|
|
214
|
+
return true;
|
|
215
|
+
case "sync":
|
|
216
|
+
executeSync(args, callbackContext);
|
|
217
|
+
return true;
|
|
218
|
+
case "addListener":
|
|
219
|
+
executeAddListener(args, callbackContext);
|
|
220
|
+
return true;
|
|
221
|
+
case "removeListener":
|
|
222
|
+
executeRemoveListener(args, callbackContext);
|
|
223
|
+
return true;
|
|
224
|
+
case "removeAllListeners":
|
|
225
|
+
executeRemoveAllListeners(callbackContext);
|
|
226
|
+
return true;
|
|
227
|
+
default:
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
} catch (Exception exception) {
|
|
231
|
+
reject(callbackContext, exception);
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private void executeDeleteBundle(JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
237
|
+
JSONObject options = args.optJSONObject(0);
|
|
238
|
+
String bundleId = options == null ? null : (options.isNull("bundleId") ? null : options.optString("bundleId", null));
|
|
239
|
+
if (bundleId == null) {
|
|
240
|
+
callbackContext.error(ERROR_BUNDLE_ID_MISSING);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
implementation.deleteBundle(new DeleteBundleOptions(bundleId), emptyCallback(callbackContext));
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
private void executeDownloadBundle(JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
247
|
+
JSONObject options = args.optJSONObject(0);
|
|
248
|
+
if (options == null) {
|
|
249
|
+
callbackContext.error(ERROR_BUNDLE_ID_MISSING);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
String artifactType = options.optString("artifactType", "zip");
|
|
253
|
+
String bundleId = options.isNull("bundleId") ? null : options.optString("bundleId", null);
|
|
254
|
+
if (bundleId == null) {
|
|
255
|
+
callbackContext.error(ERROR_BUNDLE_ID_MISSING);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
String checksum = options.isNull("checksum") ? null : options.optString("checksum", null);
|
|
259
|
+
String signature = options.isNull("signature") ? null : options.optString("signature", null);
|
|
260
|
+
String url = options.isNull("url") ? null : options.optString("url", null);
|
|
261
|
+
if (url == null) {
|
|
262
|
+
callbackContext.error(ERROR_URL_MISSING);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
implementation.downloadBundle(
|
|
266
|
+
new DownloadBundleOptions(artifactType, bundleId, checksum, signature, url),
|
|
267
|
+
emptyCallback(callbackContext)
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
private void executeFetchChannels(JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
272
|
+
if (config.getAppId() == null || config.getAppId().isEmpty()) {
|
|
273
|
+
callbackContext.error(ERROR_APP_ID_MISSING);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
JSONObject options = args.optJSONObject(0);
|
|
277
|
+
if (options == null) {
|
|
278
|
+
options = new JSONObject();
|
|
279
|
+
}
|
|
280
|
+
implementation.fetchChannels(new FetchChannelsOptions(options), nonEmptyCallback(callbackContext));
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
private void executeFetchLatestBundle(JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
284
|
+
if (config.getAppId() == null || config.getAppId().isEmpty()) {
|
|
285
|
+
callbackContext.error(ERROR_APP_ID_MISSING);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
JSONObject options = args.optJSONObject(0);
|
|
289
|
+
if (options == null) {
|
|
290
|
+
options = new JSONObject();
|
|
291
|
+
}
|
|
292
|
+
implementation.fetchLatestBundle(new FetchLatestBundleOptions(options), nonEmptyCallback(callbackContext));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
private void executeSetChannel(JSONArray args, CallbackContext callbackContext) {
|
|
296
|
+
JSONObject options = args.optJSONObject(0);
|
|
297
|
+
String channel = options == null || options.isNull("channel") ? null : options.optString("channel", null);
|
|
298
|
+
implementation.setChannel(new SetChannelOptions(channel), emptyCallback(callbackContext));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
private void executeSetConfig(JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
302
|
+
JSONObject options = args.optJSONObject(0);
|
|
303
|
+
if (options == null) {
|
|
304
|
+
options = new JSONObject();
|
|
305
|
+
}
|
|
306
|
+
implementation.setConfig(new SetConfigOptions(options));
|
|
307
|
+
resolve(callbackContext);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
private void executeSetCustomId(JSONArray args, CallbackContext callbackContext) {
|
|
311
|
+
JSONObject options = args.optJSONObject(0);
|
|
312
|
+
String customId = options == null || options.isNull("customId") ? null : options.optString("customId", null);
|
|
313
|
+
if (customId == null) {
|
|
314
|
+
callbackContext.error(ERROR_CUSTOM_ID_MISSING);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
implementation.setCustomId(new SetCustomIdOptions(customId), emptyCallback(callbackContext));
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
private void executeSetNextBundle(JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
321
|
+
JSONObject options = args.optJSONObject(0);
|
|
322
|
+
if (options == null) {
|
|
323
|
+
options = new JSONObject();
|
|
324
|
+
}
|
|
325
|
+
implementation.setNextBundle(new SetNextBundleOptions(options), emptyCallback(callbackContext));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
private void executeSync(JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
329
|
+
if (config.getAppId() == null || config.getAppId().isEmpty()) {
|
|
330
|
+
callbackContext.error(ERROR_APP_ID_MISSING);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
JSONObject options = args.optJSONObject(0);
|
|
334
|
+
if (options == null) {
|
|
335
|
+
options = new JSONObject();
|
|
336
|
+
}
|
|
337
|
+
implementation.sync(new SyncOptions(options), nonEmptyCallback(callbackContext));
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
private void executeAddListener(JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
341
|
+
String eventName = args.optString(0, null);
|
|
342
|
+
String listenerId = args.optString(1, null);
|
|
343
|
+
if (eventName == null || listenerId == null) {
|
|
344
|
+
callbackContext.error(ERROR_LISTENER_ID_MISSING);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
listeners.put(listenerId, new ListenerRegistration(eventName, callbackContext));
|
|
348
|
+
// Keep the callback alive so we can deliver events to it later.
|
|
349
|
+
PluginResult ack = new PluginResult(PluginResult.Status.NO_RESULT);
|
|
350
|
+
ack.setKeepCallback(true);
|
|
351
|
+
callbackContext.sendPluginResult(ack);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
private void executeRemoveListener(JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
355
|
+
JSONObject options = args.optJSONObject(0);
|
|
356
|
+
String listenerId = options == null || options.isNull("listenerId") ? null : options.optString("listenerId", null);
|
|
357
|
+
if (listenerId == null) {
|
|
358
|
+
callbackContext.error(ERROR_LISTENER_ID_MISSING);
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
ListenerRegistration entry = listeners.remove(listenerId);
|
|
362
|
+
if (entry != null) {
|
|
363
|
+
releaseCallback(entry.callback);
|
|
364
|
+
}
|
|
365
|
+
resolve(callbackContext);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
private void executeRemoveAllListeners(CallbackContext callbackContext) {
|
|
369
|
+
Iterator<Map.Entry<String, ListenerRegistration>> it = listeners.entrySet().iterator();
|
|
370
|
+
while (it.hasNext()) {
|
|
371
|
+
ListenerRegistration entry = it.next().getValue();
|
|
372
|
+
releaseCallback(entry.callback);
|
|
373
|
+
it.remove();
|
|
374
|
+
}
|
|
375
|
+
resolve(callbackContext);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
public void notifyDownloadBundleProgressListeners(@NonNull DownloadBundleProgressEvent event) {
|
|
379
|
+
try {
|
|
380
|
+
notifyListeners(EVENT_DOWNLOAD_BUNDLE_PROGRESS, event.toJSObject());
|
|
381
|
+
} catch (JSONException e) {
|
|
382
|
+
Log.e(TAG, "Failed to serialize downloadBundleProgress event: " + e.getMessage(), e);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
public void notifyNextBundleSetListeners(@NonNull NextBundleSetEvent event) {
|
|
387
|
+
try {
|
|
388
|
+
notifyListeners(EVENT_NEXT_BUNDLE_SET, event.toJSObject());
|
|
389
|
+
} catch (JSONException e) {
|
|
390
|
+
Log.e(TAG, "Failed to serialize nextBundleSet event: " + e.getMessage(), e);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
private void notifyListeners(@NonNull String eventName, @NonNull JSONObject data) {
|
|
395
|
+
for (ListenerRegistration entry : listeners.values()) {
|
|
396
|
+
if (!entry.eventName.equals(eventName)) {
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
PluginResult result = new PluginResult(PluginResult.Status.OK, data);
|
|
400
|
+
result.setKeepCallback(true);
|
|
401
|
+
entry.callback.sendPluginResult(result);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
public Context getContext() {
|
|
406
|
+
return cordova.getActivity().getApplicationContext();
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
public void reloadWebView() {
|
|
410
|
+
cordova
|
|
411
|
+
.getActivity()
|
|
412
|
+
.runOnUiThread(() -> {
|
|
413
|
+
if (webView != null && webView.getView() instanceof android.webkit.WebView) {
|
|
414
|
+
((android.webkit.WebView) webView.getView()).reload();
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
private void releaseCallback(@NonNull CallbackContext callback) {
|
|
420
|
+
PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
|
|
421
|
+
result.setKeepCallback(false);
|
|
422
|
+
callback.sendPluginResult(result);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
private void resolve(@NonNull CallbackContext callbackContext) {
|
|
426
|
+
callbackContext.success();
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
private void resolve(@NonNull CallbackContext callbackContext, @NonNull JSONObject result) {
|
|
430
|
+
callbackContext.success(result);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
private void reject(@NonNull CallbackContext callbackContext, @NonNull Exception exception) {
|
|
434
|
+
String message = exception.getMessage();
|
|
435
|
+
if (exception instanceof java.net.SocketTimeoutException) {
|
|
436
|
+
message = ERROR_HTTP_TIMEOUT;
|
|
437
|
+
} else if (message == null) {
|
|
438
|
+
message = ERROR_UNKNOWN_ERROR;
|
|
439
|
+
}
|
|
440
|
+
Log.e(TAG, message, exception);
|
|
441
|
+
callbackContext.error(message);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
private EmptyCallback emptyCallback(@NonNull CallbackContext callbackContext) {
|
|
445
|
+
return new EmptyCallback() {
|
|
446
|
+
@Override
|
|
447
|
+
public void success() {
|
|
448
|
+
resolve(callbackContext);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
@Override
|
|
452
|
+
public void error(@NonNull Exception exception) {
|
|
453
|
+
reject(callbackContext, exception);
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
private <T extends Result> NonEmptyCallback<T> nonEmptyCallback(@NonNull CallbackContext callbackContext) {
|
|
459
|
+
return new NonEmptyCallback<T>() {
|
|
460
|
+
@Override
|
|
461
|
+
public void success(@NonNull T result) {
|
|
462
|
+
try {
|
|
463
|
+
resolve(callbackContext, result.toJSObject());
|
|
464
|
+
} catch (JSONException e) {
|
|
465
|
+
reject(callbackContext, e);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
@Override
|
|
470
|
+
public void error(@NonNull Exception exception) {
|
|
471
|
+
reject(callbackContext, exception);
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
private <T extends Result> NonEmptyCallback<T> resultCallback(@NonNull CallbackContext callbackContext) {
|
|
477
|
+
return nonEmptyCallback(callbackContext);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
@NonNull
|
|
481
|
+
private LiveUpdateConfig loadLiveUpdateConfig() {
|
|
482
|
+
LiveUpdateConfig cfg = new LiveUpdateConfig();
|
|
483
|
+
Context ctx = getContext();
|
|
484
|
+
Resources res = ctx.getResources();
|
|
485
|
+
String pkg = ctx.getPackageName();
|
|
486
|
+
|
|
487
|
+
String appId = readStringRes(res, pkg, "capawesome_live_update_app_id");
|
|
488
|
+
if (appId != null) {
|
|
489
|
+
cfg.setAppId(appId);
|
|
490
|
+
}
|
|
491
|
+
String defaultChannel = readStringRes(res, pkg, "capawesome_live_update_default_channel");
|
|
492
|
+
if (defaultChannel != null) {
|
|
493
|
+
cfg.setDefaultChannel(defaultChannel);
|
|
494
|
+
}
|
|
495
|
+
String autoUpdateStrategy = readStringRes(res, pkg, "capawesome_live_update_auto_update_strategy");
|
|
496
|
+
if (autoUpdateStrategy != null) {
|
|
497
|
+
cfg.setAutoUpdateStrategy(autoUpdateStrategy);
|
|
498
|
+
}
|
|
499
|
+
String publicKey = readStringRes(res, pkg, "capawesome_live_update_public_key");
|
|
500
|
+
if (publicKey != null) {
|
|
501
|
+
cfg.setPublicKey(publicKey);
|
|
502
|
+
}
|
|
503
|
+
String serverDomain = readStringRes(res, pkg, "capawesome_live_update_server_domain");
|
|
504
|
+
if (serverDomain != null) {
|
|
505
|
+
cfg.setServerDomain(serverDomain);
|
|
506
|
+
}
|
|
507
|
+
cfg.setHttpTimeout(parseIntSafe(readStringRes(res, pkg, "capawesome_live_update_http_timeout"), cfg.getHttpTimeout()));
|
|
508
|
+
cfg.setReadyTimeout(parseIntSafe(readStringRes(res, pkg, "capawesome_live_update_ready_timeout"), cfg.getReadyTimeout()));
|
|
509
|
+
cfg.setAutoDeleteBundles(
|
|
510
|
+
parseBoolSafe(readStringRes(res, pkg, "capawesome_live_update_auto_delete_bundles"), cfg.getAutoDeleteBundles())
|
|
511
|
+
);
|
|
512
|
+
cfg.setAutoBlockRolledBackBundles(
|
|
513
|
+
parseBoolSafe(
|
|
514
|
+
readStringRes(res, pkg, "capawesome_live_update_auto_block_rolled_back_bundles"),
|
|
515
|
+
cfg.getAutoBlockRolledBackBundles()
|
|
516
|
+
)
|
|
517
|
+
);
|
|
518
|
+
return cfg;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
@Nullable
|
|
522
|
+
static String readStringRes(@NonNull Resources res, @NonNull String pkg, @NonNull String key) {
|
|
523
|
+
int resId = res.getIdentifier(key, "string", pkg);
|
|
524
|
+
if (resId == 0) {
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
// Cordova injects a single-space sentinel for "unset" preferences (see
|
|
528
|
+
// plugin.xml). Treat whitespace-only values as null.
|
|
529
|
+
String value = res.getString(resId).trim();
|
|
530
|
+
return value.isEmpty() ? null : value;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
private static int parseIntSafe(@Nullable String value, int fallback) {
|
|
534
|
+
if (value == null || value.isEmpty()) {
|
|
535
|
+
return fallback;
|
|
536
|
+
}
|
|
537
|
+
try {
|
|
538
|
+
return Integer.parseInt(value);
|
|
539
|
+
} catch (NumberFormatException e) {
|
|
540
|
+
return fallback;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
private static boolean parseBoolSafe(@Nullable String value, boolean fallback) {
|
|
545
|
+
if (value == null || value.isEmpty()) {
|
|
546
|
+
return fallback;
|
|
547
|
+
}
|
|
548
|
+
return Boolean.parseBoolean(value);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
package io.capawesome.cordova.plugins.liveupdate;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import android.content.Context;
|
|
5
|
+
import android.content.SharedPreferences;
|
|
6
|
+
import androidx.annotation.NonNull;
|
|
7
|
+
import androidx.annotation.Nullable;
|
|
8
|
+
|
|
9
|
+
public class LiveUpdatePreferences {
|
|
10
|
+
|
|
11
|
+
@NonNull
|
|
12
|
+
private final Context context;
|
|
13
|
+
|
|
14
|
+
@NonNull
|
|
15
|
+
private final SharedPreferences.Editor settingsEditor;
|
|
16
|
+
|
|
17
|
+
private final String appIdKey = "appId"; // DO NOT CHANGE
|
|
18
|
+
private final String blockedBundleIdsKey = "blockedBundleIds"; // DO NOT CHANGE
|
|
19
|
+
private final String channelKey = "channel"; // DO NOT CHANGE
|
|
20
|
+
private final String deviceIdKey = "deviceId"; // DO NOT CHANGE
|
|
21
|
+
private final String customIdKey = "customId"; // DO NOT CHANGE
|
|
22
|
+
private final String lastVersionCodeKey = "lastVersionCode"; // DO NOT CHANGE
|
|
23
|
+
private final String nextBundleIdKey = "nextBundleId"; // DO NOT CHANGE
|
|
24
|
+
private final String previousBundleIdKey = "previousBundleId"; // DO NOT CHANGE
|
|
25
|
+
|
|
26
|
+
public LiveUpdatePreferences(@NonNull Context context) {
|
|
27
|
+
this.context = context;
|
|
28
|
+
this.settingsEditor = context.getSharedPreferences(LiveUpdatePlugin.SHARED_PREFERENCES_NAME, Activity.MODE_PRIVATE).edit();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@Nullable
|
|
32
|
+
public String getAppId() {
|
|
33
|
+
return context.getSharedPreferences(LiveUpdatePlugin.SHARED_PREFERENCES_NAME, Activity.MODE_PRIVATE).getString(appIdKey, null);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Nullable
|
|
37
|
+
public String getChannel() {
|
|
38
|
+
return context.getSharedPreferences(LiveUpdatePlugin.SHARED_PREFERENCES_NAME, Activity.MODE_PRIVATE).getString(channelKey, null);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@Nullable
|
|
42
|
+
public String getCustomId() {
|
|
43
|
+
return context.getSharedPreferences(LiveUpdatePlugin.SHARED_PREFERENCES_NAME, Activity.MODE_PRIVATE).getString(customIdKey, null);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@Nullable
|
|
47
|
+
public String getDeviceIdForApp(@Nullable String appId) {
|
|
48
|
+
if (appId == null) {
|
|
49
|
+
return context
|
|
50
|
+
.getSharedPreferences(LiveUpdatePlugin.SHARED_PREFERENCES_NAME, Activity.MODE_PRIVATE)
|
|
51
|
+
.getString(deviceIdKey, null);
|
|
52
|
+
} else {
|
|
53
|
+
return context
|
|
54
|
+
.getSharedPreferences(LiveUpdatePlugin.SHARED_PREFERENCES_NAME, Activity.MODE_PRIVATE)
|
|
55
|
+
.getString(deviceIdKey + "_" + appId, null);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public int getLastVersionCode() {
|
|
60
|
+
return context.getSharedPreferences(LiveUpdatePlugin.SHARED_PREFERENCES_NAME, Activity.MODE_PRIVATE).getInt(lastVersionCodeKey, -1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@Nullable
|
|
64
|
+
public String getNextBundleId() {
|
|
65
|
+
return context
|
|
66
|
+
.getSharedPreferences(LiveUpdatePlugin.SHARED_PREFERENCES_NAME, Activity.MODE_PRIVATE)
|
|
67
|
+
.getString(nextBundleIdKey, null);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@Nullable
|
|
71
|
+
public String getPreviousBundleId() {
|
|
72
|
+
return context
|
|
73
|
+
.getSharedPreferences(LiveUpdatePlugin.SHARED_PREFERENCES_NAME, Activity.MODE_PRIVATE)
|
|
74
|
+
.getString(previousBundleIdKey, null);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@Nullable
|
|
78
|
+
public String getBlockedBundleIds() {
|
|
79
|
+
return context
|
|
80
|
+
.getSharedPreferences(LiveUpdatePlugin.SHARED_PREFERENCES_NAME, Activity.MODE_PRIVATE)
|
|
81
|
+
.getString(blockedBundleIdsKey, null);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public void setAppId(@Nullable String appId) {
|
|
85
|
+
if (appId == null) {
|
|
86
|
+
settingsEditor.remove(appIdKey);
|
|
87
|
+
} else {
|
|
88
|
+
settingsEditor.putString(appIdKey, appId);
|
|
89
|
+
}
|
|
90
|
+
settingsEditor.apply();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public void setBlockedBundleIds(@Nullable String blockedBundleIds) {
|
|
94
|
+
if (blockedBundleIds == null) {
|
|
95
|
+
settingsEditor.remove(blockedBundleIdsKey);
|
|
96
|
+
} else {
|
|
97
|
+
settingsEditor.putString(blockedBundleIdsKey, blockedBundleIds);
|
|
98
|
+
}
|
|
99
|
+
settingsEditor.apply();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public void setChannel(@Nullable String channel) {
|
|
103
|
+
if (channel == null) {
|
|
104
|
+
settingsEditor.remove(channelKey);
|
|
105
|
+
} else {
|
|
106
|
+
settingsEditor.putString(channelKey, channel);
|
|
107
|
+
}
|
|
108
|
+
settingsEditor.apply();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
public void setCustomId(@Nullable String customId) {
|
|
112
|
+
if (customId == null) {
|
|
113
|
+
settingsEditor.remove(customIdKey);
|
|
114
|
+
} else {
|
|
115
|
+
settingsEditor.putString(customIdKey, customId);
|
|
116
|
+
}
|
|
117
|
+
settingsEditor.apply();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public void setDeviceIdForApp(@Nullable String appId, @NonNull String deviceId) {
|
|
121
|
+
if (appId == null) {
|
|
122
|
+
settingsEditor.putString(deviceIdKey, deviceId);
|
|
123
|
+
} else {
|
|
124
|
+
settingsEditor.putString(deviceIdKey + "_" + appId, deviceId);
|
|
125
|
+
}
|
|
126
|
+
settingsEditor.apply();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
public void setLastVersionCode(int versionCode) {
|
|
130
|
+
settingsEditor.putInt(lastVersionCodeKey, versionCode);
|
|
131
|
+
settingsEditor.apply();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
public void setNextBundleId(@Nullable String bundleId) {
|
|
135
|
+
if (bundleId == null) {
|
|
136
|
+
settingsEditor.remove(nextBundleIdKey);
|
|
137
|
+
} else {
|
|
138
|
+
settingsEditor.putString(nextBundleIdKey, bundleId);
|
|
139
|
+
}
|
|
140
|
+
settingsEditor.apply();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
public void setPreviousBundleId(@Nullable String bundleId) {
|
|
144
|
+
if (bundleId == null) {
|
|
145
|
+
settingsEditor.remove(previousBundleIdKey);
|
|
146
|
+
} else {
|
|
147
|
+
settingsEditor.putString(previousBundleIdKey, bundleId);
|
|
148
|
+
}
|
|
149
|
+
settingsEditor.apply();
|
|
150
|
+
}
|
|
151
|
+
}
|